hashicorp / terraform-plugin-codegen-openapi

OpenAPI to Terraform Provider Code Generation Specification
Mozilla Public License 2.0
49 stars 6 forks source link

Expose the `tags.description` field in the Open API spec to use as resource/data source schema description #123

Open andreaangiolillo opened 6 months ago

andreaangiolillo commented 6 months ago

Use Cases or Problem Statement

The autogen tool does not populate the Schema.Description and Schema.MarkdownDescription fields for a TF resource or data source.

Example:

What is happening

func DataSourceSchema(ctx context.Context) schema.Schema {
    return schema.Schema{
        Attributes: map[string]schema.Attribute{
            "id": schema.StringAttribute{
                Computed:            true,
                Description:         "Unique 24-hexadecimal digit string that identifies the search deployment.",
                MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the search deployment.",
            },
            "cluster_name": schema.StringAttribute{
                Required:            true,
                Description:         "Label that identifies the cluster to return the search nodes for.",
                MarkdownDescription: "Label that identifies the cluster to return the search nodes for.",
            },
            "project_id": schema.StringAttribute{
                Required:            true,
                Description:         "Unique 24-hexadecimal digit string that identifies your project.",
                MarkdownDescription: "Unique 24-hexadecimal digit string that identifies your project.",
            },

Expectation

func DataSourceSchema(ctx context.Context) schema.Schema {
    return schema.Schema{
        MarkdownDescription: "Provides a Search Deployment data source.",
        Description: "Provides a Search Deployment data source.",
        Attributes: map[string]schema.Attribute{
            "id": schema.StringAttribute{
                Computed:            true,
                Description:         "Unique 24-hexadecimal digit string that identifies the search deployment.",
                MarkdownDescription: "Unique 24-hexadecimal digit string that identifies the search deployment.",
            },
            "cluster_name": schema.StringAttribute{
                Required:            true,
                Description:         "Label that identifies the cluster to return the search nodes for.",
                MarkdownDescription: "Label that identifies the cluster to return the search nodes for.",
            },
            "project_id": schema.StringAttribute{
                Required:            true,
                Description:         "Unique 24-hexadecimal digit string that identifies your project.",
                MarkdownDescription: "Unique 24-hexadecimal digit string that identifies your project.",
            }

Proposal

Use the tags.name and tags.description in the OpenAPI spec to populate these fields. Another option would be to auto-populate these fields with a predefined format such as "Define a data source for { .Name }."

Additional Information

No response

Code of Conduct

austinvalle commented 6 months ago

Hey there @andreaangiolillo šŸ‘‹šŸ» , thanks for raising this issue!

Your request seems reasonable to me... there are two downstream issues that needs to be completed first that I have just created, but they should be relatively straightforward:

  1. The provider code spec will need to be updated to include the Description + MarkdownDescription, opened an issue to track that here: https://github.com/hashicorp/terraform-plugin-codegen-spec/issues/81
  2. The framework generator will need to be updated to generate the code, here: https://github.com/hashicorp/terraform-plugin-codegen-framework/issues/112

More importantly, we'll need to make a design decision on where in the OpenAPI spec to extract the description. You mentioned using tags.name and tags.description, do you happen to have some examples in the MongoDB OpenAPI spec that you think would make good resource/data source descriptions?

There definitely can be some form of fallback logic to try and ensure there is some type of description, like using the tags.name with a predefined format, we just want to ensure that the descriptions we generate are valuable and not likely to be overridden šŸ˜†

Regardless of how we decide to extract the description, we'd likely want to also add an override to the generator config for the description. Like so:

resources:
  pet:
    # create, read, update, delete configuration
    # ...
    schema:
      description: The `pet` terraform resource manages dogs, cats, birds, and more!
austinvalle commented 6 months ago

Further thoughts on using tags. Since they are defined at the operation level, we'd just need to decide which operation we should use for resource descriptions (which use both the GET and POST operation for type mapping). Data sources could use the GET operation tags and provider schema could use the top-level openapi.tags.

I'd lean towards using the POST operation by default, then maybe falling back to the GET if not found.

austinvalle commented 6 months ago

Another option would be to take the top-level description of the requestBody schema (for resources), and responseBody for data sources. Which ideally would be describing the resource itself, like kubernetes: https://github.com/kubernetes/kubernetes/blob/83e6636096548f4b49a94ece6bc4a26fd67e4449/api/openapi-spec/v3/api__v1_openapi.json#L878-L879

"io.k8s.api.core.v1.ConfigMap": {
  "description": "ConfigMap holds configuration data for pods to consume.",
  "properties": {
    // Schema of resource is currently mapped here
  }
}
bflad commented 6 months ago

Off-handedly (not a true real world knowledge opinion, sorry!), I agree with you that a precedence for managed resources of requestBody description then POST/create operation description feels like they would be the most well suited defaults for describing the managed resource itself. šŸ‘

andreaangiolillo commented 6 months ago

do you happen to have some examples in the MongoDB OpenAPI spec that you think would make good resource/data source descriptions?

The MongoDB Atlas API doc is available here. The documentation is autogenerated via OpenAPI Spec that is available by clicking the Download button Screenshot 2024-01-15 at 11 08 02

To answer your question, this is the tag of the database user which may be a good description of the resource.

{
"description": "Returns, adds, edits, and removes database users.",
"name": "Database Users"
},

Unfortunately, I don't think there is a perfect solution. I'd be also happy with using a format such as "Define a data source for { .Name }." and provide a way to override it if needed. Thanks!