From 699be350ede99e913f860a0406e70ab53c328e1f Mon Sep 17 00:00:00 2001 From: David Debeau Date: Wed, 21 Aug 2024 13:17:00 -0500 Subject: [PATCH 01/13] Create test for CreateRepo --- quay_api/test/api_repository_test.go | 53 ++++++++++++++++------------ 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/quay_api/test/api_repository_test.go b/quay_api/test/api_repository_test.go index 783d69c..de9f4cf 100644 --- a/quay_api/test/api_repository_test.go +++ b/quay_api/test/api_repository_test.go @@ -1,26 +1,18 @@ -/* -Quay Frontend - -Testing RepositoryAPIService - -*/ - -// Code generated by OpenAPI Generator (https://openapi-generator.tech); - package quay_api import ( "context" - openapiclient "github.com/enthought/terraform-provider-quay/quay_api" + "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "testing" + + "github.com/enthought/terraform-provider-quay/quay_api" ) func Test_quay_api_RepositoryAPIService(t *testing.T) { - - configuration := openapiclient.NewConfiguration() - apiClient := openapiclient.NewAPIClient(configuration) + configuration := newConfiguration() + apiClient := quay_api.NewAPIClient(configuration) t.Run("Test RepositoryAPIService ChangeRepoVisibility", func(t *testing.T) { @@ -36,14 +28,31 @@ func Test_quay_api_RepositoryAPIService(t *testing.T) { }) t.Run("Test RepositoryAPIService CreateRepo", func(t *testing.T) { - - t.Skip("skip test") // remove to run test - - httpRes, err := apiClient.RepositoryAPI.CreateRepo(context.Background()).Execute() - - require.Nil(t, err) - assert.Equal(t, 200, httpRes.StatusCode) - + orgName := "create-repo" + repoName := "test" + + // Ensure org is destroyed + defer func(organization quay_api.ApiDeleteAdminedOrganizationRequest) { + _, err := organization.Execute() + handleQuayAPIError(t, err) + }(apiClient.OrganizationAPI.DeleteAdminedOrganization(context.Background(), orgName)) + + // Create org + newOrg := quay_api.NewNewOrg(orgName, orgName+"@example.com") + httpRes, err := apiClient.OrganizationAPI.CreateOrganization(context.Background()).Body(*newOrg).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) + + // Create repo + newRepo := quay_api.NewRepo{ + Repository: repoName, + Visibility: "private", + Namespace: &orgName, + Description: "test", + } + httpRes, err = apiClient.RepositoryAPI.CreateRepo(context.Background()).Body(newRepo).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) }) t.Run("Test RepositoryAPIService DeleteRepository", func(t *testing.T) { From 7a79b9d4149da2b0e45aaa53263035fe79e18b73 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Wed, 21 Aug 2024 13:22:15 -0500 Subject: [PATCH 02/13] Create test for DeleteRepo --- quay_api/test/api_repository_test.go | 32 ++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/quay_api/test/api_repository_test.go b/quay_api/test/api_repository_test.go index de9f4cf..07dad6b 100644 --- a/quay_api/test/api_repository_test.go +++ b/quay_api/test/api_repository_test.go @@ -56,16 +56,36 @@ func Test_quay_api_RepositoryAPIService(t *testing.T) { }) t.Run("Test RepositoryAPIService DeleteRepository", func(t *testing.T) { + orgName := "delete-repo" + repoName := "test" - t.Skip("skip test") // remove to run test - - var repository string + // Ensure org is destroyed + defer func(organization quay_api.ApiDeleteAdminedOrganizationRequest) { + _, err := organization.Execute() + handleQuayAPIError(t, err) + }(apiClient.OrganizationAPI.DeleteAdminedOrganization(context.Background(), orgName)) - httpRes, err := apiClient.RepositoryAPI.DeleteRepository(context.Background(), repository).Execute() + // Create org + newOrg := quay_api.NewNewOrg(orgName, orgName+"@example.com") + httpRes, err := apiClient.OrganizationAPI.CreateOrganization(context.Background()).Body(*newOrg).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) - require.Nil(t, err) - assert.Equal(t, 200, httpRes.StatusCode) + // Create repo + newRepo := quay_api.NewRepo{ + Repository: repoName, + Visibility: "private", + Namespace: &orgName, + Description: "test", + } + httpRes, err = apiClient.RepositoryAPI.CreateRepo(context.Background()).Body(newRepo).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) + // Delete repo + httpRes, err = apiClient.RepositoryAPI.DeleteRepository(context.Background(), orgName+"/"+repoName).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 204, httpRes.StatusCode) }) t.Run("Test RepositoryAPIService GetRepo", func(t *testing.T) { From a140546a87a816b8fc61d8172247786697c51a47 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Wed, 21 Aug 2024 13:28:10 -0500 Subject: [PATCH 03/13] Create test for GetRepo --- quay_api/test/api_repository_test.go | 30 +++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/quay_api/test/api_repository_test.go b/quay_api/test/api_repository_test.go index 07dad6b..e4427d4 100644 --- a/quay_api/test/api_repository_test.go +++ b/quay_api/test/api_repository_test.go @@ -89,16 +89,36 @@ func Test_quay_api_RepositoryAPIService(t *testing.T) { }) t.Run("Test RepositoryAPIService GetRepo", func(t *testing.T) { + orgName := "get-repo" + repoName := "test" - t.Skip("skip test") // remove to run test + // Ensure org is destroyed + defer func(organization quay_api.ApiDeleteAdminedOrganizationRequest) { + _, err := organization.Execute() + handleQuayAPIError(t, err) + }(apiClient.OrganizationAPI.DeleteAdminedOrganization(context.Background(), orgName)) - var repository string + // Create org + newOrg := quay_api.NewNewOrg(orgName, orgName+"@example.com") + httpRes, err := apiClient.OrganizationAPI.CreateOrganization(context.Background()).Body(*newOrg).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) - httpRes, err := apiClient.RepositoryAPI.GetRepo(context.Background(), repository).Execute() + // Create repo + newRepo := quay_api.NewRepo{ + Repository: repoName, + Visibility: "private", + Namespace: &orgName, + Description: "test", + } + httpRes, err = apiClient.RepositoryAPI.CreateRepo(context.Background()).Body(newRepo).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) - require.Nil(t, err) + // Get repo + httpRes, err = apiClient.RepositoryAPI.GetRepo(context.Background(), orgName+"/"+repoName).Execute() + handleQuayAPIError(t, err) assert.Equal(t, 200, httpRes.StatusCode) - }) t.Run("Test RepositoryAPIService ListRepos", func(t *testing.T) { From 34f7d7d52d97e019adc5bc3fd8a91ffe3e54a88f Mon Sep 17 00:00:00 2001 From: David Debeau Date: Wed, 21 Aug 2024 13:34:33 -0500 Subject: [PATCH 04/13] Create test for UpdateRepo --- quay_api/test/api_repository_test.go | 30 +++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/quay_api/test/api_repository_test.go b/quay_api/test/api_repository_test.go index e4427d4..22e5f3e 100644 --- a/quay_api/test/api_repository_test.go +++ b/quay_api/test/api_repository_test.go @@ -133,16 +133,36 @@ func Test_quay_api_RepositoryAPIService(t *testing.T) { }) t.Run("Test RepositoryAPIService UpdateRepo", func(t *testing.T) { + orgName := "update-repo" + repoName := "test" - t.Skip("skip test") // remove to run test + // Ensure org is destroyed + defer func(organization quay_api.ApiDeleteAdminedOrganizationRequest) { + _, err := organization.Execute() + handleQuayAPIError(t, err) + }(apiClient.OrganizationAPI.DeleteAdminedOrganization(context.Background(), orgName)) - var repository string + // Create org + newOrg := quay_api.NewNewOrg(orgName, orgName+"@example.com") + httpRes, err := apiClient.OrganizationAPI.CreateOrganization(context.Background()).Body(*newOrg).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) - httpRes, err := apiClient.RepositoryAPI.UpdateRepo(context.Background(), repository).Execute() + // Create repo + newRepo := quay_api.NewRepo{ + Repository: repoName, + Visibility: "private", + Namespace: &orgName, + Description: "test", + } + httpRes, err = apiClient.RepositoryAPI.CreateRepo(context.Background()).Body(newRepo).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) + // Update repo + newRepoUpdate := quay_api.NewRepoUpdate("test2") + httpRes, err = apiClient.RepositoryAPI.UpdateRepo(context.Background(), orgName+"/"+repoName).Body(*newRepoUpdate).Execute() require.Nil(t, err) assert.Equal(t, 200, httpRes.StatusCode) - }) - } From bc8de2d0ecf6926605f141b82312f985165c8d12 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Wed, 21 Aug 2024 13:40:20 -0500 Subject: [PATCH 05/13] Create test for ChangeRepoVisibility --- quay_api/test/api_repository_test.go | 33 +++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/quay_api/test/api_repository_test.go b/quay_api/test/api_repository_test.go index 22e5f3e..2055a1d 100644 --- a/quay_api/test/api_repository_test.go +++ b/quay_api/test/api_repository_test.go @@ -15,16 +15,37 @@ func Test_quay_api_RepositoryAPIService(t *testing.T) { apiClient := quay_api.NewAPIClient(configuration) t.Run("Test RepositoryAPIService ChangeRepoVisibility", func(t *testing.T) { + orgName := "change-repo-visibility" + repoName := "test" - t.Skip("skip test") // remove to run test + // Ensure org is destroyed + defer func(organization quay_api.ApiDeleteAdminedOrganizationRequest) { + _, err := organization.Execute() + handleQuayAPIError(t, err) + }(apiClient.OrganizationAPI.DeleteAdminedOrganization(context.Background(), orgName)) - var repository string + // Create org + newOrg := quay_api.NewNewOrg(orgName, orgName+"@example.com") + httpRes, err := apiClient.OrganizationAPI.CreateOrganization(context.Background()).Body(*newOrg).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) - httpRes, err := apiClient.RepositoryAPI.ChangeRepoVisibility(context.Background(), repository).Execute() + // Create repo + newRepo := quay_api.NewRepo{ + Repository: repoName, + Visibility: "private", + Namespace: &orgName, + Description: "test", + } + httpRes, err = apiClient.RepositoryAPI.CreateRepo(context.Background()).Body(newRepo).Execute() + handleQuayAPIError(t, err) + assert.Equal(t, 201, httpRes.StatusCode) - require.Nil(t, err) + // Change repo visibility + newVisibility := quay_api.NewChangeVisibility("public") + httpRes, err = apiClient.RepositoryAPI.ChangeRepoVisibility(context.Background(), orgName+"/"+repoName).Body(*newVisibility).Execute() + handleQuayAPIError(t, err) assert.Equal(t, 200, httpRes.StatusCode) - }) t.Run("Test RepositoryAPIService CreateRepo", func(t *testing.T) { @@ -162,7 +183,7 @@ func Test_quay_api_RepositoryAPIService(t *testing.T) { // Update repo newRepoUpdate := quay_api.NewRepoUpdate("test2") httpRes, err = apiClient.RepositoryAPI.UpdateRepo(context.Background(), orgName+"/"+repoName).Body(*newRepoUpdate).Execute() - require.Nil(t, err) + handleQuayAPIError(t, err) assert.Equal(t, 200, httpRes.StatusCode) }) } From 74cdd0480aba72b49dee21de0f741bf0c7418c04 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Fri, 23 Aug 2024 07:31:19 -0500 Subject: [PATCH 06/13] Create scaffolding for RepositoryResource --- code_generator/provider_code_spec.json | 74 +++++++++++ internal/provider/provider.go | 1 + internal/provider/repository_resource.go | 115 ++++++++++++++++++ .../repository_resource_gen.go | 60 +++++++++ 4 files changed, 250 insertions(+) create mode 100644 internal/provider/repository_resource.go create mode 100644 internal/resource_repository/repository_resource_gen.go diff --git a/code_generator/provider_code_spec.json b/code_generator/provider_code_spec.json index 07d2301..cc6ea5f 100644 --- a/code_generator/provider_code_spec.json +++ b/code_generator/provider_code_spec.json @@ -181,6 +181,80 @@ } ] } + }, + { + "name": "repository", + "schema": { + "attributes": [ + { + "name": "description", + "string": { + "computed_optional_required": "computed_optional", + "default" : { + "static": "" + }, + "description": "Markdown description" + } + }, + { + "name": "name", + "string": { + "computed_optional_required": "required", + "description": "Repository name", + "plan_modifiers": [ + { + "custom": { + "imports": [ + { + "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + } + ], + "schema_definition": "stringplanmodifier.RequiresReplace()" + } + } + ] + } + }, + { + "name": "namespace", + "string": { + "computed_optional_required": "required", + "description": "Repository namespace. Should be an organization name or username", + "plan_modifiers": [ + { + "custom": { + "imports": [ + { + "path": "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + } + ], + "schema_definition": "stringplanmodifier.RequiresReplace()" + } + } + ] + } + }, + { + "name": "visibility", + "string": { + "computed_optional_required": "required", + "description": "Repository visibility. Should be private or public.", + "validators": [ + { + "custom": { + "imports": [ + { + "path": "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + } + ], + "schema_definition": "stringvalidator.OneOf([]string{\"private\", \"public\"}...)" + } + } + ] + } + } + ] + } } ], "datasources": [ diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 05f2c88..3063f12 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -159,5 +159,6 @@ func (p *quayProvider) Resources(_ context.Context) []func() resource.Resource { NewOrganizationResource, NewOrganizationTeamResource, NewOrganizationRobotResource, + NewRepositoryResource, } } diff --git a/internal/provider/repository_resource.go b/internal/provider/repository_resource.go new file mode 100644 index 0000000..ac4018a --- /dev/null +++ b/internal/provider/repository_resource.go @@ -0,0 +1,115 @@ +package provider + +import ( + "context" + "fmt" + "github.com/hashicorp/terraform-plugin-framework/path" + "terraform-provider-quay/internal/resource_repository" + + "github.com/enthought/terraform-provider-quay/quay_api" + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +var ( + _ resource.Resource = (*repositoryResource)(nil) + _ resource.ResourceWithConfigure = (*repositoryResource)(nil) + _ resource.ResourceWithImportState = (*repositoryResource)(nil) +) + +func NewRepositoryResource() resource.Resource { + return &repositoryResource{} +} + +type repositoryResource struct { + client *quay_api.APIClient +} + +func (r *repositoryResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_repository" +} + +func (r *repositoryResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = resource_repository.RepositoryResourceSchema(ctx) +} + +func (r *repositoryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data resource_repository.RepositoryModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Create API call logic + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *repositoryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var data resource_repository.RepositoryModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Read API call logic + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *repositoryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var data resource_repository.RepositoryModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Update API call logic + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *repositoryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data resource_repository.RepositoryModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Delete API call logic +} + +func (r *repositoryResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*quay_api.APIClient) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *quay_api.APIClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } + + r.client = client +} + +func (r *repositoryResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + // Retrieve import ID and save to name attribute + resource.ImportStatePassthroughID(ctx, path.Root("name"), req, resp) +} diff --git a/internal/resource_repository/repository_resource_gen.go b/internal/resource_repository/repository_resource_gen.go new file mode 100644 index 0000000..96cfd5f --- /dev/null +++ b/internal/resource_repository/repository_resource_gen.go @@ -0,0 +1,60 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package resource_repository + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema" +) + +func RepositoryResourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Optional: true, + Computed: true, + Description: "Markdown description", + MarkdownDescription: "Markdown description", + Default: stringdefault.StaticString(""), + }, + "name": schema.StringAttribute{ + Required: true, + Description: "Repository name", + MarkdownDescription: "Repository name", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "namespace": schema.StringAttribute{ + Required: true, + Description: "Repository namespace. Should be an organization name or username", + MarkdownDescription: "Repository namespace. Should be an organization name or username", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "visibility": schema.StringAttribute{ + Required: true, + Description: "Repository visibility. Should be private or public.", + MarkdownDescription: "Repository visibility. Should be private or public.", + Validators: []validator.String{ + stringvalidator.OneOf([]string{"private", "public"}...), + }, + }, + }, + } +} + +type RepositoryModel struct { + Description types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + Namespace types.String `tfsdk:"namespace"` + Visibility types.String `tfsdk:"visibility"` +} From 82430fb1060537e5c190d6b1698bdb57da191964 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Fri, 23 Aug 2024 10:06:04 -0500 Subject: [PATCH 07/13] Add Create, Read, Import methods to RepositoryResource --- internal/provider/repository_resource.go | 106 ++++++++++++++++-- internal/provider/repository_resource_test.go | 45 ++++++++ 2 files changed, 144 insertions(+), 7 deletions(-) create mode 100644 internal/provider/repository_resource_test.go diff --git a/internal/provider/repository_resource.go b/internal/provider/repository_resource.go index ac4018a..e00ea70 100644 --- a/internal/provider/repository_resource.go +++ b/internal/provider/repository_resource.go @@ -1,13 +1,24 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Modifications copyright (c) Enthought, Inc. +// SPDX-License-Identifier: BSD-3-Clause + package provider import ( "context" + "encoding/json" "fmt" + "github.com/hashicorp/terraform-plugin-framework/types" + "io" + "strings" + "github.com/hashicorp/terraform-plugin-framework/path" - "terraform-provider-quay/internal/resource_repository" + "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/enthought/terraform-provider-quay/quay_api" - "github.com/hashicorp/terraform-plugin-framework/resource" + "terraform-provider-quay/internal/resource_repository" ) var ( @@ -24,6 +35,13 @@ type repositoryResource struct { client *quay_api.APIClient } +type repositoryModelJSON struct { + Name string `json:"name"` + Namespace string `json:"namespace"` + Description string `json:"description"` + IsPublic bool `json:"is_public"` +} + func (r *repositoryResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_repository" } @@ -42,7 +60,25 @@ func (r *repositoryResource) Create(ctx context.Context, req resource.CreateRequ return } - // Create API call logic + // Create variables + repoName := data.Name.ValueString() + visibility := data.Visibility.ValueString() + namespace := data.Namespace.ValueString() + description := data.Description.ValueString() + + // Create repository + newRepo := quay_api.NewRepo{ + Repository: repoName, + Visibility: visibility, + Namespace: &namespace, + Description: description, + } + _, err := r.client.RepositoryAPI.CreateRepo(context.Background()).Body(newRepo).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError("Error creating Quay repository", "Could not create Quay repository, unexpected error: "+errDetail) + return + } // Save data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) @@ -50,6 +86,7 @@ func (r *repositoryResource) Create(ctx context.Context, req resource.CreateRequ func (r *repositoryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { var data resource_repository.RepositoryModel + var resRepoData repositoryModelJSON // Read Terraform prior state data into the model resp.Diagnostics.Append(req.State.Get(ctx, &data)...) @@ -58,7 +95,44 @@ func (r *repositoryResource) Read(ctx context.Context, req resource.ReadRequest, return } - // Read API call logic + // Create variables + repoName := data.Name.ValueString() + namespace := data.Namespace.ValueString() + + // Get repository + httpRes, err := r.client.RepositoryAPI.GetRepo(context.Background(), namespace+"/"+repoName).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError("Error reading Quay repository", "Could not create Quay repository, unexpected error: "+errDetail) + return + } + + body, err := io.ReadAll(httpRes.Body) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Quay repository", + "Could not read Quay repository, unexpected error: "+err.Error()) + return + } + err = json.Unmarshal(body, &resRepoData) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Quay repository", + "Could not read Quay repository, unexpected error: "+err.Error()) + return + } + + // Set visibility + if resRepoData.IsPublic { + data.Visibility = types.StringValue("public") + } else { + data.Visibility = types.StringValue("private") + } + + // Set data + data.Name = types.StringValue(resRepoData.Name) + data.Namespace = types.StringValue(resRepoData.Namespace) + data.Description = types.StringValue(resRepoData.Description) // Save updated data into Terraform state resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) @@ -90,7 +164,16 @@ func (r *repositoryResource) Delete(ctx context.Context, req resource.DeleteRequ return } - // Delete API call logic + // Create variables + repoName := data.Name.ValueString() + namespace := data.Namespace.ValueString() + + _, err := r.client.RepositoryAPI.DeleteRepository(context.Background(), namespace+"/"+repoName).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError("Error deleting Quay repository", "Could not delete Quay repository, unexpected error: "+errDetail) + return + } } func (r *repositoryResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { @@ -110,6 +193,15 @@ func (r *repositoryResource) Configure(_ context.Context, req resource.Configure } func (r *repositoryResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - // Retrieve import ID and save to name attribute - resource.ImportStatePassthroughID(ctx, path.Root("name"), req, resp) + idSplit := strings.Split(req.ID, "/") + if len(idSplit) != 2 || idSplit[0] == "" || idSplit[1] == "" { + resp.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format namespace/repository. Got: %q", req.ID), + ) + return + } + + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("namespace"), idSplit[0])...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), idSplit[1])...) } diff --git a/internal/provider/repository_resource_test.go b/internal/provider/repository_resource_test.go new file mode 100644 index 0000000..b22ea86 --- /dev/null +++ b/internal/provider/repository_resource_test.go @@ -0,0 +1,45 @@ +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccRepositoryResource(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read + { + Config: providerConfig + ` +resource "quay_organization" "org_repo" { + name = "org_repo" + email = "quay+repo@example.com" +} + +resource "quay_repository" "test" { + name = "test" + namespace = quay_organization.org_repo.name + visibility = "private" + description = "test" +} +`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("quay_repository.test", "name", "test"), + resource.TestCheckResourceAttr("quay_repository.test", "namespace", "org_repo"), + resource.TestCheckResourceAttr("quay_repository.test", "visibility", "private"), + resource.TestCheckResourceAttr("quay_repository.test", "description", "test"), + ), + }, + // Import + { + ResourceName: "quay_repository.test", + ImportState: true, + ImportStateId: "org_repo/test", + ImportStateVerify: true, + ImportStateVerifyIdentifierAttribute: "name", + }, + }, + }) +} From 45996032e6461725d79ba3342ff2c76963a216f0 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Fri, 23 Aug 2024 10:10:56 -0500 Subject: [PATCH 08/13] Make RepositoryResource visibility parameter optional --- code_generator/provider_code_spec.json | 5 ++++- internal/resource_repository/repository_resource_gen.go | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/code_generator/provider_code_spec.json b/code_generator/provider_code_spec.json index cc6ea5f..fa29efd 100644 --- a/code_generator/provider_code_spec.json +++ b/code_generator/provider_code_spec.json @@ -237,7 +237,10 @@ { "name": "visibility", "string": { - "computed_optional_required": "required", + "computed_optional_required": "computed_optional", + "default" : { + "static": "private" + }, "description": "Repository visibility. Should be private or public.", "validators": [ { diff --git a/internal/resource_repository/repository_resource_gen.go b/internal/resource_repository/repository_resource_gen.go index 96cfd5f..384b2b0 100644 --- a/internal/resource_repository/repository_resource_gen.go +++ b/internal/resource_repository/repository_resource_gen.go @@ -41,12 +41,14 @@ func RepositoryResourceSchema(ctx context.Context) schema.Schema { }, }, "visibility": schema.StringAttribute{ - Required: true, + Optional: true, + Computed: true, Description: "Repository visibility. Should be private or public.", MarkdownDescription: "Repository visibility. Should be private or public.", Validators: []validator.String{ stringvalidator.OneOf([]string{"private", "public"}...), }, + Default: stringdefault.StaticString("private"), }, }, } From daa23333452df90dace2fe484f76234dd910a986 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Fri, 23 Aug 2024 10:31:45 -0500 Subject: [PATCH 09/13] Add Update method to RepositoryResource --- internal/provider/repository_resource.go | 38 +++++++++++++++++-- internal/provider/repository_resource_test.go | 22 +++++++++++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/internal/provider/repository_resource.go b/internal/provider/repository_resource.go index e00ea70..25d82e1 100644 --- a/internal/provider/repository_resource.go +++ b/internal/provider/repository_resource.go @@ -139,19 +139,49 @@ func (r *repositoryResource) Read(ctx context.Context, req resource.ReadRequest, } func (r *repositoryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var data resource_repository.RepositoryModel + var dataState resource_repository.RepositoryModel + var dataPlan resource_repository.RepositoryModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &dataState)...) // Read Terraform plan data into the model - resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + resp.Diagnostics.Append(req.Plan.Get(ctx, &dataPlan)...) if resp.Diagnostics.HasError() { return } - // Update API call logic + // Create variables + repoName := dataPlan.Name.ValueString() + visibility := dataPlan.Visibility.ValueString() + namespace := dataPlan.Namespace.ValueString() + description := dataPlan.Description.ValueString() + + // Update description + if dataPlan.Description != dataState.Description { + updateRepo := quay_api.NewRepoUpdate(description) + _, err := r.client.RepositoryAPI.UpdateRepo(context.Background(), namespace+"/"+repoName).Body(*updateRepo).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError("Error updating Quay repository", "Could not update Quay repository, unexpected error: "+errDetail) + return + } + } + + // Update visibility + if dataPlan.Visibility != dataState.Visibility { + newVisibility := quay_api.NewChangeVisibility(visibility) + _, err := r.client.RepositoryAPI.ChangeRepoVisibility(context.Background(), namespace+"/"+repoName).Body(*newVisibility).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError("Error updating Quay repository", "Could not update Quay repository, unexpected error: "+errDetail) + return + } + } // Save updated data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) + resp.Diagnostics.Append(resp.State.Set(ctx, &dataPlan)...) } func (r *repositoryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { diff --git a/internal/provider/repository_resource_test.go b/internal/provider/repository_resource_test.go index b22ea86..c9ea49f 100644 --- a/internal/provider/repository_resource_test.go +++ b/internal/provider/repository_resource_test.go @@ -40,6 +40,28 @@ resource "quay_repository" "test" { ImportStateVerify: true, ImportStateVerifyIdentifierAttribute: "name", }, + // Update + { + Config: providerConfig + ` +resource "quay_organization" "org_repo" { + name = "org_repo" + email = "quay+repo@example.com" +} + +resource "quay_repository" "test" { + name = "test" + namespace = quay_organization.org_repo.name + visibility = "public" + description = "test2" +} +`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("quay_repository.test", "name", "test"), + resource.TestCheckResourceAttr("quay_repository.test", "namespace", "org_repo"), + resource.TestCheckResourceAttr("quay_repository.test", "visibility", "public"), + resource.TestCheckResourceAttr("quay_repository.test", "description", "test2"), + ), + }, }, }) } From 3a1e6dc152690fcd0a8f319192d7eb4e79b17511 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Fri, 23 Aug 2024 11:59:11 -0500 Subject: [PATCH 10/13] Add more RepositoryResource tests --- internal/provider/repository_resource_test.go | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/internal/provider/repository_resource_test.go b/internal/provider/repository_resource_test.go index c9ea49f..4eb9cef 100644 --- a/internal/provider/repository_resource_test.go +++ b/internal/provider/repository_resource_test.go @@ -62,6 +62,48 @@ resource "quay_repository" "test" { resource.TestCheckResourceAttr("quay_repository.test", "description", "test2"), ), }, + // Replace resource + { + Config: providerConfig + ` +resource "quay_organization" "org_repo" { + name = "org_repo" + email = "quay+repo@example.com" +} + +resource "quay_repository" "test" { + name = "test2" + namespace = quay_organization.org_repo.name + visibility = "public" + description = "test2" +} +`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("quay_repository.test", "name", "test2"), + resource.TestCheckResourceAttr("quay_repository.test", "namespace", "org_repo"), + resource.TestCheckResourceAttr("quay_repository.test", "visibility", "public"), + resource.TestCheckResourceAttr("quay_repository.test", "description", "test2"), + ), + }, + // Create with only required values + { + Config: providerConfig + ` +resource "quay_organization" "org_repo" { + name = "org_repo" + email = "quay+repo@example.com" +} + +resource "quay_repository" "test3" { + name = "test3" + namespace = quay_organization.org_repo.name +} +`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("quay_repository.test3", "name", "test3"), + resource.TestCheckResourceAttr("quay_repository.test3", "namespace", "org_repo"), + resource.TestCheckResourceAttr("quay_repository.test3", "visibility", "private"), + resource.TestCheckResourceAttr("quay_repository.test3", "description", ""), + ), + }, }, }) } From 021e2a21d4dc87922cdc941c1dd05839fa2e3ef7 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Mon, 26 Aug 2024 08:11:50 -0500 Subject: [PATCH 11/13] Create RepositoryDataSource --- code_generator/provider_code_spec.json | 35 ++++++ .../repository_data_source_gen.go | 44 +++++++ internal/provider/provider.go | 1 + internal/provider/repository_data_source.go | 107 ++++++++++++++++++ .../provider/repository_data_source_test.go | 42 +++++++ 5 files changed, 229 insertions(+) create mode 100644 internal/datasource_repository/repository_data_source_gen.go create mode 100644 internal/provider/repository_data_source.go create mode 100644 internal/provider/repository_data_source_test.go diff --git a/code_generator/provider_code_spec.json b/code_generator/provider_code_spec.json index fa29efd..79a2a18 100644 --- a/code_generator/provider_code_spec.json +++ b/code_generator/provider_code_spec.json @@ -281,6 +281,41 @@ } ] } + }, + { + "name": "repository", + "schema": { + "attributes": [ + { + "name": "description", + "string": { + "computed_optional_required": "computed", + "description": "Markdown description" + } + }, + { + "name": "name", + "string": { + "computed_optional_required": "required", + "description": "Repository name" + } + }, + { + "name": "namespace", + "string": { + "computed_optional_required": "required", + "description": "Repository namespace. Should be an organization name or username" + } + }, + { + "name": "visibility", + "string": { + "computed_optional_required": "computed", + "description": "Repository visibility. Should be private or public." + } + } + ] + } } ], "version": "0.1" diff --git a/internal/datasource_repository/repository_data_source_gen.go b/internal/datasource_repository/repository_data_source_gen.go new file mode 100644 index 0000000..890719c --- /dev/null +++ b/internal/datasource_repository/repository_data_source_gen.go @@ -0,0 +1,44 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package datasource_repository + +import ( + "context" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func RepositoryDataSourceSchema(ctx context.Context) schema.Schema { + return schema.Schema{ + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + Description: "Markdown description", + MarkdownDescription: "Markdown description", + }, + "name": schema.StringAttribute{ + Required: true, + Description: "Repository name", + MarkdownDescription: "Repository name", + }, + "namespace": schema.StringAttribute{ + Required: true, + Description: "Repository namespace. Should be an organization name or username", + MarkdownDescription: "Repository namespace. Should be an organization name or username", + }, + "visibility": schema.StringAttribute{ + Computed: true, + Description: "Repository visibility. Should be private or public.", + MarkdownDescription: "Repository visibility. Should be private or public.", + }, + }, + } +} + +type RepositoryModel struct { + Description types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + Namespace types.String `tfsdk:"namespace"` + Visibility types.String `tfsdk:"visibility"` +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 3063f12..2ed585a 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -151,6 +151,7 @@ func (p *quayProvider) Metadata(_ context.Context, _ provider.MetadataRequest, r func (p *quayProvider) DataSources(_ context.Context) []func() datasource.DataSource { return []func() datasource.DataSource{ NewOrganizationDataSource, + NewRepositoryDataSource, } } diff --git a/internal/provider/repository_data_source.go b/internal/provider/repository_data_source.go new file mode 100644 index 0000000..f873821 --- /dev/null +++ b/internal/provider/repository_data_source.go @@ -0,0 +1,107 @@ +package provider + +import ( + "context" + "encoding/json" + "fmt" + "io" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/enthought/terraform-provider-quay/quay_api" + "terraform-provider-quay/internal/datasource_repository" +) + +var ( + _ datasource.DataSource = (*repositoryDataSource)(nil) + _ datasource.DataSourceWithConfigure = (*repositoryDataSource)(nil) +) + +func NewRepositoryDataSource() datasource.DataSource { + return &repositoryDataSource{} +} + +type repositoryDataSource struct { + client *quay_api.APIClient +} + +func (d *repositoryDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_repository" +} + +func (d *repositoryDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = datasource_repository.RepositoryDataSourceSchema(ctx) +} + +func (d *repositoryDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data datasource_repository.RepositoryModel + + var resRepoData repositoryModelJSON + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Create variables + repoName := data.Name.ValueString() + namespace := data.Namespace.ValueString() + + // Get repository + httpRes, err := d.client.RepositoryAPI.GetRepo(context.Background(), namespace+"/"+repoName).Execute() + if err != nil { + errDetail := handleQuayAPIError(err) + resp.Diagnostics.AddError("Error reading Quay repository", + "Could not create Quay repository, unexpected error: "+errDetail) + return + } + + body, err := io.ReadAll(httpRes.Body) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Quay repository", + "Could not read Quay repository, unexpected error: "+err.Error()) + return + } + err = json.Unmarshal(body, &resRepoData) + if err != nil { + resp.Diagnostics.AddError( + "Error reading Quay repository", + "Could not read Quay repository, unexpected error: "+err.Error()) + return + } + + // Set visibility + if resRepoData.IsPublic { + data.Visibility = types.StringValue("public") + } else { + data.Visibility = types.StringValue("private") + } + + // Set data + data.Name = types.StringValue(resRepoData.Name) + data.Namespace = types.StringValue(resRepoData.Namespace) + data.Description = types.StringValue(resRepoData.Description) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (d *repositoryDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*quay_api.APIClient) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *quay_api.APIClient, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + } + + d.client = client +} diff --git a/internal/provider/repository_data_source_test.go b/internal/provider/repository_data_source_test.go new file mode 100644 index 0000000..190ba08 --- /dev/null +++ b/internal/provider/repository_data_source_test.go @@ -0,0 +1,42 @@ +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccRepositoryDataSource(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Create and Read + { + Config: providerConfig + ` +resource "quay_organization" "org_repo_data" { + name = "org_repo_data" + email = "quay+repo@example.com" +} + +resource "quay_repository" "test" { + name = "test" + namespace = quay_organization.org_repo_data.name + visibility = "private" + description = "test" +} + +data "quay_repository" "test" { + name = "test" + namespace = quay_organization.org_repo_data.name +} +`, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.quay_repository.test", "name", "test"), + resource.TestCheckResourceAttr("data.quay_repository.test", "namespace", "org_repo_data"), + resource.TestCheckResourceAttr("data.quay_repository.test", "visibility", "private"), + resource.TestCheckResourceAttr("data.quay_repository.test", "description", "test"), + ), + }, + }, + }) +} From b2d441b557bf480e1b4cb05f3956a487f2669f3f Mon Sep 17 00:00:00 2001 From: David Debeau Date: Mon, 26 Aug 2024 08:30:59 -0500 Subject: [PATCH 12/13] Add Repository docs --- docs/data-sources/repository.md | 37 ++++++++++++++ docs/resources/repository.md | 49 +++++++++++++++++++ .../quay_repository/data-source.tf | 8 +++ examples/resources/quay_repository/import.sh | 2 + .../resources/quay_repository/resource.tf | 11 +++++ 5 files changed, 107 insertions(+) create mode 100644 docs/data-sources/repository.md create mode 100644 docs/resources/repository.md create mode 100644 examples/data-sources/quay_repository/data-source.tf create mode 100644 examples/resources/quay_repository/import.sh create mode 100644 examples/resources/quay_repository/resource.tf diff --git a/docs/data-sources/repository.md b/docs/data-sources/repository.md new file mode 100644 index 0000000..dfc1010 --- /dev/null +++ b/docs/data-sources/repository.md @@ -0,0 +1,37 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "quay_repository Data Source - quay" +subcategory: "" +description: |- + +--- + +# quay_repository (Data Source) + + + +## Example Usage + +```terraform +data "quay_organization" "main" { + name = "main" +} + +data "quay_repository" "test" { + name = "test" + namespace = data.quay_organization.main.name +} +``` + + +## Schema + +### Required + +- `name` (String) Repository name +- `namespace` (String) Repository namespace. Should be an organization name or username + +### Read-Only + +- `description` (String) Markdown description +- `visibility` (String) Repository visibility. Should be private or public. diff --git a/docs/resources/repository.md b/docs/resources/repository.md new file mode 100644 index 0000000..390db8e --- /dev/null +++ b/docs/resources/repository.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "quay_repository Resource - quay" +subcategory: "" +description: |- + +--- + +# quay_repository (Resource) + + + +## Example Usage + +```terraform +resource "quay_organization" "main" { + name = "main" + email = "quay+main@example.com" +} + +resource "quay_repository" "test" { + name = "test" + namespace = quay_organization.main.name + visibility = "private" + description = "test" +} +``` + + +## Schema + +### Required + +- `name` (String) Repository name +- `namespace` (String) Repository namespace. Should be an organization name or username + +### Optional + +- `description` (String) Markdown description +- `visibility` (String) Repository visibility. Should be private or public. + +## Import + +Import is supported using the following syntax: + +```shell +# An organization can be imported using its name. +terraform import quay_repository.test main/test +``` diff --git a/examples/data-sources/quay_repository/data-source.tf b/examples/data-sources/quay_repository/data-source.tf new file mode 100644 index 0000000..4e3aca9 --- /dev/null +++ b/examples/data-sources/quay_repository/data-source.tf @@ -0,0 +1,8 @@ +data "quay_organization" "main" { + name = "main" +} + +data "quay_repository" "test" { + name = "test" + namespace = data.quay_organization.main.name +} diff --git a/examples/resources/quay_repository/import.sh b/examples/resources/quay_repository/import.sh new file mode 100644 index 0000000..3004a61 --- /dev/null +++ b/examples/resources/quay_repository/import.sh @@ -0,0 +1,2 @@ +# An organization can be imported using its name. +terraform import quay_repository.test main/test diff --git a/examples/resources/quay_repository/resource.tf b/examples/resources/quay_repository/resource.tf new file mode 100644 index 0000000..f1902dc --- /dev/null +++ b/examples/resources/quay_repository/resource.tf @@ -0,0 +1,11 @@ +resource "quay_organization" "main" { + name = "main" + email = "quay+main@example.com" +} + +resource "quay_repository" "test" { + name = "test" + namespace = quay_organization.main.name + visibility = "private" + description = "test" +} From 4c314da725ea527544f6b67a1691b99fc02d7201 Mon Sep 17 00:00:00 2001 From: David Debeau Date: Mon, 26 Aug 2024 08:38:07 -0500 Subject: [PATCH 13/13] Add Repository visibility default to docs --- code_generator/provider_code_spec.json | 2 +- docs/resources/repository.md | 2 +- internal/resource_repository/repository_resource_gen.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code_generator/provider_code_spec.json b/code_generator/provider_code_spec.json index 79a2a18..04fb5f5 100644 --- a/code_generator/provider_code_spec.json +++ b/code_generator/provider_code_spec.json @@ -241,7 +241,7 @@ "default" : { "static": "private" }, - "description": "Repository visibility. Should be private or public.", + "description": "Repository visibility. Should be private or public. Defaults to private.", "validators": [ { "custom": { diff --git a/docs/resources/repository.md b/docs/resources/repository.md index 390db8e..e1304de 100644 --- a/docs/resources/repository.md +++ b/docs/resources/repository.md @@ -37,7 +37,7 @@ resource "quay_repository" "test" { ### Optional - `description` (String) Markdown description -- `visibility` (String) Repository visibility. Should be private or public. +- `visibility` (String) Repository visibility. Should be private or public. Defaults to private. ## Import diff --git a/internal/resource_repository/repository_resource_gen.go b/internal/resource_repository/repository_resource_gen.go index 384b2b0..fabdda4 100644 --- a/internal/resource_repository/repository_resource_gen.go +++ b/internal/resource_repository/repository_resource_gen.go @@ -43,8 +43,8 @@ func RepositoryResourceSchema(ctx context.Context) schema.Schema { "visibility": schema.StringAttribute{ Optional: true, Computed: true, - Description: "Repository visibility. Should be private or public.", - MarkdownDescription: "Repository visibility. Should be private or public.", + Description: "Repository visibility. Should be private or public. Defaults to private.", + MarkdownDescription: "Repository visibility. Should be private or public. Defaults to private.", Validators: []validator.String{ stringvalidator.OneOf([]string{"private", "public"}...), },