From 09da4aae36fe902ab8fd7c90827e045ec6726f88 Mon Sep 17 00:00:00 2001 From: David MICHENEAU Date: Thu, 9 Jan 2025 09:58:16 +0100 Subject: [PATCH 1/2] feat: add org certificate resource --- docs/data-sources/org_certificate_library | 31 ++ docs/data-sources/org_certificate_library.md | 32 ++ docs/resources/org_certificate_library.md | 31 ++ .../data-source.tf | 3 + go.mod | 5 + go.sum | 4 + .../org/certificate_library_datasource.go | 77 ++-- .../org/certificate_library_resource.go | 330 ++++++++++++++++++ .../org/certificate_library_schema.go | 83 ++++- .../org/certificate_library_schema_test.go | 42 +-- .../provider/org/certificate_library_types.go | 38 +- internal/provider/provider_resources.go | 4 + internal/testsacc/acctest_resources_test.go | 3 + ...org_certificate_library_datasource_test.go | 17 +- .../org_certificate_library_resource_test.go | 121 +++++++ .../data-sources/org_certificate_library.tmpl | 18 + 16 files changed, 771 insertions(+), 68 deletions(-) create mode 100644 docs/data-sources/org_certificate_library create mode 100644 docs/data-sources/org_certificate_library.md create mode 100644 docs/resources/org_certificate_library.md create mode 100644 examples/data-sources/cloudavenue_org_certificate_library/data-source.tf create mode 100644 internal/provider/org/certificate_library_resource.go create mode 100644 internal/testsacc/org_certificate_library_resource_test.go create mode 100644 templates/data-sources/org_certificate_library.tmpl diff --git a/docs/data-sources/org_certificate_library b/docs/data-sources/org_certificate_library new file mode 100644 index 00000000..7f7dc1f6 --- /dev/null +++ b/docs/data-sources/org_certificate_library @@ -0,0 +1,31 @@ +--- +page_title: "cloudavenue_org_certificate_library Data Source - cloudavenue" +subcategory: "ORG (Organization)" +description: |- + The cloudavenue_org_certificate_library data source allows you to retrieve information about an certificate in your organization library. +--- + +# cloudavenue_org_certificate_library (Data Source) + +The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization library. + +## Example Usage + +```terraform +data "cloudavenue_alb_certificate_library" "example" { + name = "my-certificate-library" +} +``` + + +## Schema + +### Optional + +- `id` (String) The ID of the certificate library. Ensure that one and only one attribute from this collection is set : `name`, `id`. +- `name` (String) The name of the certificate library. Ensure that one and only one attribute from this collection is set : `name`, `id`. + +### Read-Only + +- `certificate` (String) The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed. +- `description` (String) The description of the certificate library. diff --git a/docs/data-sources/org_certificate_library.md b/docs/data-sources/org_certificate_library.md new file mode 100644 index 00000000..4fb13b22 --- /dev/null +++ b/docs/data-sources/org_certificate_library.md @@ -0,0 +1,32 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cloudavenue_org_certificate_library Data Source - cloudavenue" +subcategory: "" +description: |- + The cloudavenue_org_certificate_library data source allows you to retrieve information about an certificate in your organization library. +--- + +# cloudavenue_org_certificate_library (Data Source) + +The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization library. + +## Example Usage + +```terraform +data "cloudavenue_alb_certificate_library" "example" { + name = "my-certificate-library" +} +``` + + +## Schema + +### Optional + +- `id` (String) The ID of the certificate library. Ensure that one and only one attribute from this collection is set : `name`, `id`. +- `name` (String) The name of the certificate library. Ensure that one and only one attribute from this collection is set : `name`, `id`. + +### Read-Only + +- `certificate` (String) The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed. +- `description` (String) The description of the certificate library. diff --git a/docs/resources/org_certificate_library.md b/docs/resources/org_certificate_library.md new file mode 100644 index 00000000..d666ce8f --- /dev/null +++ b/docs/resources/org_certificate_library.md @@ -0,0 +1,31 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cloudavenue_org_certificate_library Resource - cloudavenue" +subcategory: "" +description: |- + The cloudavenue_org_certificate_library resource allows you to manage certificate in your organization library. +--- + +# cloudavenue_org_certificate_library (Resource) + +The `cloudavenue_org_certificate_library` resource allows you to manage certificate in your organization library. + + + + +## Schema + +### Required + +- `certificate` (String) (ForceNew) The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed. +- `name` (String) The name of the certificate library. + +### Optional + +- `description` (String) The description of the certificate library. +- `passphrase` (String, Sensitive) (ForceNew) The passphrase of the private key. +- `private_key` (String, Sensitive) (ForceNew) The private key of the certificate in PEM format. + +### Read-Only + +- `id` (String) The ID of the certificate library. diff --git a/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf b/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf new file mode 100644 index 00000000..2a9b855e --- /dev/null +++ b/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf @@ -0,0 +1,3 @@ +data "cloudavenue_alb_certificate_library" "example" { + name = "my-certificate-library" +} \ No newline at end of file diff --git a/go.mod b/go.mod index 7bdca2b9..74f07aaf 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,8 @@ require ( github.com/iancoleman/strcase v0.3.0 github.com/orange-cloudavenue/cloudavenue-sdk-go v0.20.1 github.com/orange-cloudavenue/common-go/print v0.0.0-20250109171729-2be550d5d3ac + github.com/k0kubun/pp v3.0.1+incompatible + github.com/orange-cloudavenue/cloudavenue-sdk-go v0.18.1 github.com/orange-cloudavenue/common-go/utils v0.0.0-20240119163616-66b473d92339 github.com/orange-cloudavenue/terraform-plugin-framework-planmodifiers v1.4.0 github.com/orange-cloudavenue/terraform-plugin-framework-superschema v1.9.1 @@ -92,6 +94,7 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.12.3 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -133,3 +136,5 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) + +replace github.com/orange-cloudavenue/cloudavenue-sdk-go => /Users/micheneaudavid/go/src/github.com/orange-cloudavenue/cloudavenue-sdk-go diff --git a/go.sum b/go.sum index ed724c61..223da4d5 100644 --- a/go.sum +++ b/go.sum @@ -207,6 +207,10 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40= +github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= diff --git a/internal/provider/org/certificate_library_datasource.go b/internal/provider/org/certificate_library_datasource.go index 74528b5b..0e510117 100644 --- a/internal/provider/org/certificate_library_datasource.go +++ b/internal/provider/org/certificate_library_datasource.go @@ -5,10 +5,16 @@ import ( "context" "fmt" + "github.com/vmware/go-vcloud-director/v2/govcd" + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/datasource" + supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes" + + commoncloudavenue "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/common/cloudavenue" + v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/metrics" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/org" @@ -29,7 +35,7 @@ type CertificateLibraryDatasource struct { } // Init Initializes the data source. -func (d *CertificateLibraryDatasource) Init(ctx context.Context, dm *CertificateLibraryDatasourcesGoModel) (diags diag.Diagnostics) { +func (d *CertificateLibraryDatasource) Init(ctx context.Context, dm *CertificateLibraryDatasourceModel) (diags diag.Diagnostics) { // Uncomment the following lines if you need to access to the Org d.org, diags = org.Init(d.client) if diags.HasError() { @@ -44,7 +50,7 @@ func (d *CertificateLibraryDatasource) Metadata(ctx context.Context, req datasou } func (d *CertificateLibraryDatasource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { - resp.Schema = certificateLibraryDatasourceSchema(ctx).GetDataSource(ctx) + resp.Schema = certificateLibrarySchema(ctx).GetDataSource(ctx) } func (d *CertificateLibraryDatasource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { @@ -67,10 +73,7 @@ func (d *CertificateLibraryDatasource) Configure(ctx context.Context, req dataso func (d *CertificateLibraryDatasource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { defer metrics.New("data.cloudavenue_org_certificate_library", d.client.GetOrgName(), metrics.Read)() - config := &CertificateLibraryDatasourcesGoModel{} - - // If the data source don't have same schema/structure as the resource, you can use the following code: - // config := &CertificateLibraryDatasourceModel{} + config := &CertificateLibraryDatasourceModel{} // Read Terraform configuration data into the model resp.Diagnostics.Append(req.Config.Get(ctx, config)...) @@ -84,27 +87,49 @@ func (d *CertificateLibraryDatasource) Read(ctx context.Context, req datasource. return } - /* - Implement the data source read logic here. - */ - - // If read function is identical to the resource, you can use the following code: - /* - s := &CertificateLibraryDatasourcesGoResource{ - client: d.client, - // org: d.org, - // vdc: d.vdc, - // vapp: d.vapp, - } + // Read data from the API + data, _, diags := d.read(config) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } - // Read data from the API - data, _, diags := s.read(ctx, config) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +// read reads the data from the API and returns the data to be saved in the Terraform state. +func (d *CertificateLibraryDatasource) read(config *CertificateLibraryDatasourceModel) (data *CertificateLibraryDatasourceModel, found bool, diags diag.Diagnostics) { + var ( + certificate *v1.CertificateLibraryModel + err error + ) + + // Get CertificateLibrary + if config.ID.IsKnown() { + certificate, err = d.org.GetOrgCertificateLibrary(config.ID.Get()) + } else { + certificate, err = d.org.GetOrgCertificateLibrary(config.Name.Get()) + } + if err != nil { + if commoncloudavenue.IsNotFound(err) || govcd.IsNotFound(err) { + return nil, false, diags } + diags.AddError("error while fetching certificate library: %s", err.Error()) + return nil, true, diags + } + + data = &CertificateLibraryDatasourceModel{ + ID: supertypes.NewStringNull(), + Name: supertypes.NewStringNull(), + Description: supertypes.NewStringNull(), + Certificate: supertypes.NewStringNull(), + } + + data.ID.Set(certificate.ID) + data.Name.Set(certificate.Name) + data.Description.Set(certificate.Description) + data.Certificate.Set(certificate.Certificate) - // Save data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) - */ + return data, true, nil } diff --git a/internal/provider/org/certificate_library_resource.go b/internal/provider/org/certificate_library_resource.go new file mode 100644 index 00000000..c9ba5e62 --- /dev/null +++ b/internal/provider/org/certificate_library_resource.go @@ -0,0 +1,330 @@ +package org + +import ( + "context" + "fmt" + "strings" + + "github.com/vmware/go-vcloud-director/v2/govcd" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/path" + + "github.com/hashicorp/terraform-plugin-framework/resource" + + commoncloudavenue "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/common/cloudavenue" + v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/metrics" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/mutex" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/org" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &CertificateLibraryResource{} + _ resource.ResourceWithConfigure = &CertificateLibraryResource{} + _ resource.ResourceWithImportState = &CertificateLibraryResource{} + // _ resource.ResourceWithModifyPlan = &CertificateLibraryResource{} + // _ resource.ResourceWithUpgradeState = &CertificateLibraryResource{} + // _ resource.ResourceWithValidateConfig = &CertificateLibraryResource{}. +) + +// NewCertificateLibraryResource is a helper function to simplify the provider implementation. +func NewCertificateLibraryResource() resource.Resource { + return &CertificateLibraryResource{} +} + +// CertificateLibraryResource is the resource implementation. +type CertificateLibraryResource struct { + client *client.CloudAvenue + org org.Org +} + +// Init Initializes the resource. +func (r *CertificateLibraryResource) Init(ctx context.Context, rm *CertificateLibraryModel) (diags diag.Diagnostics) { + // Uncomment the following lines if you need to access to the Org + r.org, diags = org.Init(r.client) + if diags.HasError() { + return + } + + return +} + +// Metadata returns the resource type name. +func (r *CertificateLibraryResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_" + categoryName + "_certificate_library" +} + +// Schema defines the schema for the resource. +func (r *CertificateLibraryResource) Schema(ctx context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = certificateLibrarySchema(ctx).GetResource(ctx) +} + +func (r *CertificateLibraryResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*client.CloudAvenue) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *client.CloudAvenue, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + r.client = client +} + +// Create creates the resource and sets the initial Terraform state. +func (r *CertificateLibraryResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + defer metrics.New("cloudavenue_org_certificate_library", r.client.GetOrgName(), metrics.Create)() + + plan := &CertificateLibraryModel{} + + // Retrieve values from plan + resp.Diagnostics.Append(req.Plan.Get(ctx, plan)...) + if resp.Diagnostics.HasError() { + return + } + + // Init the resource + resp.Diagnostics.Append(r.Init(ctx, plan)...) + if resp.Diagnostics.HasError() { + return + } + + /* + Implement the resource creation logic here. + */ + + // Lock the resource organization + mutex.GlobalMutex.KvLock(ctx, r.org.GetID()) + defer mutex.GlobalMutex.KvUnlock(ctx, r.org.GetID()) + + // Set the SDK certificate library Model + certLibrarySDKModel := plan.ToSDKCertificateLibraryModel() + + // Create the certificate library + newCertificate, err := r.org.CreateOrgCertificateLibrary(certLibrarySDKModel) + if err != nil { + resp.Diagnostics.AddError("error while creating certificate library: %s", err.Error()) + return + } + + // Set ID + plan.ID.Set(newCertificate.ID) + + // Use generic read function to refresh the state + state, found, d := r.read(plan) + if !found { + resp.Diagnostics.AddError("Resource not found", fmt.Sprintf("The certificate library '%s' was not found after creation.", plan.Name.Get())) + return + } + if d.HasError() { + resp.Diagnostics.Append(d...) + return + } + + // Set state to fully populated data + resp.Diagnostics.Append(resp.State.Set(ctx, state)...) +} + +// Read refreshes the Terraform state with the latest data. +func (r *CertificateLibraryResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + defer metrics.New("cloudavenue_org_certificate_library", r.client.GetOrgName(), metrics.Read)() + + state := &CertificateLibraryModel{} + + // Get current state + resp.Diagnostics.Append(req.State.Get(ctx, state)...) + if resp.Diagnostics.HasError() { + return + } + + // Init the resource + resp.Diagnostics.Append(r.Init(ctx, state)...) + if resp.Diagnostics.HasError() { + return + } + + // Refresh the state + stateRefreshed, found, d := r.read(state) + if !found { + resp.State.RemoveResource(ctx) + return + } + if d.HasError() { + resp.Diagnostics.Append(d...) + return + } + + // Set refreshed state + resp.Diagnostics.Append(resp.State.Set(ctx, stateRefreshed)...) +} + +// Update updates the resource and sets the updated Terraform state on success. +func (r *CertificateLibraryResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + defer metrics.New("cloudavenue_org_certificate_library", r.client.GetOrgName(), metrics.Update)() + + var ( + plan = &CertificateLibraryModel{} + state = &CertificateLibraryModel{} + ) + + // Get current plan and state + resp.Diagnostics.Append(req.Plan.Get(ctx, plan)...) + resp.Diagnostics.Append(req.State.Get(ctx, state)...) + if resp.Diagnostics.HasError() { + return + } + + // Init the resource + resp.Diagnostics.Append(r.Init(ctx, state)...) + if resp.Diagnostics.HasError() { + return + } + + /* + Implement the resource update here + */ + + // Lock the resource organization + mutex.GlobalMutex.KvLock(ctx, r.org.GetID()) + defer mutex.GlobalMutex.KvUnlock(ctx, r.org.GetID()) + + // Set the SDK certificate library Model + certLibrarySDKModel := plan.ToSDKCertificateLibraryModel() + + // Update the certificate library + _, err := certLibrarySDKModel.Update() + if err != nil { + resp.Diagnostics.AddError("error while updating certificate library: %s", err.Error()) + return + } + + // Use generic read function to refresh the state + stateRefreshed, _, d := r.read(plan) + if d.HasError() { + resp.Diagnostics.Append(d...) + return + } + + // Set state to fully populated data + resp.Diagnostics.Append(resp.State.Set(ctx, stateRefreshed)...) +} + +// Delete deletes the resource and removes the Terraform state on success. +func (r *CertificateLibraryResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + defer metrics.New("cloudavenue_org_certificate_library", r.client.GetOrgName(), metrics.Delete)() + + state := &CertificateLibraryModel{} + + // Get current state + resp.Diagnostics.Append(req.State.Get(ctx, state)...) + if resp.Diagnostics.HasError() { + return + } + + // Init the resource + resp.Diagnostics.Append(r.Init(ctx, state)...) + if resp.Diagnostics.HasError() { + return + } + + /* + Implement the resource deletion here + */ + + // Lock the resource organization + mutex.GlobalMutex.KvLock(ctx, r.org.GetID()) + defer mutex.GlobalMutex.KvUnlock(ctx, r.org.GetID()) + + // Use generic read function to refresh the state + stateRefreshed, _, d := r.read(state) + if d.HasError() { + resp.Diagnostics.Append(d...) + return + } + + // Delete the certificate library + err := stateRefreshed.ToSDKCertificateLibraryModel().Delete() + if err != nil { + resp.Diagnostics.AddError("error while deleting certificate library: %s", err.Error()) + return + } +} + +func (r *CertificateLibraryResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + defer metrics.New("cloudavenue_org_certificate_library", r.client.GetOrgName(), metrics.Import)() + + // * ID format is CertificateIdOrName + + // * Import with custom logic + idParts := strings.Split(req.ID, ".") + if len(idParts) > 1 { + resp.Diagnostics.AddError( + "Unexpected Import Identifier", + fmt.Sprintf("Expected import identifier with format: CertificateIdOrName. Got: %q", req.ID), + ) + return + } + + // Init the resource + resp.Diagnostics.Append(r.Init(ctx, &CertificateLibraryModel{})...) + if resp.Diagnostics.HasError() { + return + } + + // Get the certificate library + certificate, err := r.org.GetOrgCertificateLibrary(req.ID) + if err != nil { + resp.Diagnostics.AddError("error while importing certificate library: %s", err.Error()) + return + } + + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), certificate.ID)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), certificate.Name)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("description"), certificate.Description)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("certificate"), certificate.Certificate)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("private_key"), certificate.PrivateKey)...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("passphrase"), certificate.Passphrase)...) +} + +// * CustomFuncs + +// read is a generic read function that can be used by the resource Create, Read and Update functions. +func (r *CertificateLibraryResource) read(planOrState *CertificateLibraryModel) (stateRefreshed *CertificateLibraryModel, found bool, diags diag.Diagnostics) { + stateRefreshed = planOrState.Copy() + + var ( + certificate *v1.CertificateLibraryModel + err error + ) + + // Get CertificateLibrary + if planOrState.ID.IsKnown() { + certificate, err = r.org.GetOrgCertificateLibrary(planOrState.ID.Get()) + } else { + certificate, err = r.org.GetOrgCertificateLibrary(planOrState.Name.Get()) + } + if err != nil { + if commoncloudavenue.IsNotFound(err) || govcd.IsNotFound(err) { + return nil, false, diags + } + diags.AddError("error while fetching certificate library: %s", err.Error()) + return nil, false, diags + } + + // Set the refreshed state + stateRefreshed.ID.Set(certificate.ID) + stateRefreshed.Name.Set(certificate.Name) + stateRefreshed.Description.Set(certificate.Description) + stateRefreshed.Certificate.Set(certificate.Certificate) + // No need to set the private key and passphrase as they are not returned by the API (security reasons) + + return stateRefreshed, true, nil +} diff --git a/internal/provider/org/certificate_library_schema.go b/internal/provider/org/certificate_library_schema.go index bc9ce099..9df78f7c 100644 --- a/internal/provider/org/certificate_library_schema.go +++ b/internal/provider/org/certificate_library_schema.go @@ -3,9 +3,17 @@ package org import ( "context" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + schemaD "github.com/hashicorp/terraform-plugin-framework/datasource/schema" schemaR "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + superschema "github.com/FrangipaneTeam/terraform-plugin-framework-superschema" ) @@ -61,44 +69,95 @@ import ( // 1. Define the schema in the file internal/provider/org/certificate_library_datasources_go_schema.go // 2. Add the resource or data source to the file internal/provider/provider_resources.go or internal/provider/provider_data_sources.go respectively // 3. Launch the following command to generate golang structs for the schema: -// go run ./cmd/types-generator/*.go -file internal/provider/org/certificate_library_datasources_go_schema.go -resource cloudavenue_org_certificate_library_datasources_go -is-resource. -func certificateLibraryDatasourceSchema(_ context.Context) superschema.Schema { +// go run ./cmd/types-generator/*.go -file internal/provider/org/certificate_library_datasources_go_schema.go -resource cloudavenue_org_certificate_library -is-resource. +func certificateLibrarySchema(_ context.Context) superschema.Schema { return superschema.Schema{ Resource: superschema.SchemaDetails{ - MarkdownDescription: "The `cloudavenue_org_certificate_library_datasources_go` resource allows you to manage ...", + MarkdownDescription: "The `cloudavenue_org_certificate_library` resource allows you to manage certificate in your organization library.", }, DataSource: superschema.SchemaDetails{ - MarkdownDescription: "The `cloudavenue_org_certificate_library_datasources_go` data source allows you to retrieve information about an ...", + MarkdownDescription: "The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization library.", }, Attributes: map[string]superschema.Attribute{ "id": superschema.SuperStringAttribute{ Common: &schemaR.StringAttribute{ Computed: true, - MarkdownDescription: "The ID of the certificate_library_datasources_go.", + MarkdownDescription: "The ID of the certificate library.", + }, + Resource: &schemaR.StringAttribute{ + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + DataSource: &schemaD.StringAttribute{ + Optional: true, + Validators: []validator.String{ + stringvalidator.ExactlyOneOf(path.MatchRoot("name"), path.MatchRoot("id")), + }, }, }, "name": superschema.SuperStringAttribute{ Common: &schemaR.StringAttribute{ - MarkdownDescription: "The name of the certificate_library_datasources_go.", + MarkdownDescription: "The name of the certificate library.", }, Resource: &schemaR.StringAttribute{ Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, }, DataSource: &schemaD.StringAttribute{ Computed: true, + Optional: true, + Validators: []validator.String{ + stringvalidator.ExactlyOneOf(path.MatchRoot("name"), path.MatchRoot("id")), + }, }, }, - "single": superschema.SuperSingleNestedAttributeOf[struct{}]{ - Common: &schemaR.SingleNestedAttribute{ - MarkdownDescription: "The name of the index document.", + "description": superschema.SuperStringAttribute{ + Common: &schemaR.StringAttribute{ + MarkdownDescription: "The description of the certificate library.", }, - Resource: &schemaR.SingleNestedAttribute{ + Resource: &schemaR.StringAttribute{ Optional: true, }, - DataSource: &schemaD.SingleNestedAttribute{ + DataSource: &schemaD.StringAttribute{ Computed: true, }, - Attributes: superschema.Attributes{}, + }, + "certificate": superschema.SuperStringAttribute{ + Common: &schemaR.StringAttribute{ + MarkdownDescription: "The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed.", + }, + Resource: &schemaR.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + DataSource: &schemaD.StringAttribute{ + Computed: true, + }, + }, + "private_key": superschema.SuperStringAttribute{ + Resource: &schemaR.StringAttribute{ + MarkdownDescription: "The private key of the certificate in PEM format.", + Optional: true, + Sensitive: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + }, + "passphrase": superschema.SuperStringAttribute{ + Resource: &schemaR.StringAttribute{ + MarkdownDescription: "The passphrase of the private key.", + Optional: true, + Sensitive: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, }, }, } diff --git a/internal/provider/org/certificate_library_schema_test.go b/internal/provider/org/certificate_library_schema_test.go index 878dab0b..1a0515b9 100644 --- a/internal/provider/org/certificate_library_schema_test.go +++ b/internal/provider/org/certificate_library_schema_test.go @@ -5,33 +5,34 @@ import ( "testing" fwdatasource "github.com/hashicorp/terraform-plugin-framework/datasource" -) + fwresource "github.com/hashicorp/terraform-plugin-framework/resource" -// TODO : Comment or uncomment the following imports if you are using resources or/and datasources + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/org" +) -// Unit test for the schema of the resource cloudavenue_org_CertificateLibraryDatasourcesGo -// func TestCertificateLibraryDatasourcesGoResourceSchema(t *testing.T) { -// t.Parallel() +// Unit test for the schema of the resource cloudavenue_org_certificate_library. +func TestCertificateLibraryResourceSchema(t *testing.T) { + t.Parallel() -// ctx := context.Background() -// schemaResponse := &fwresource.SchemaResponse{} + ctx := context.Background() + schemaResponse := &fwresource.SchemaResponse{} -// // Instantiate the resource.Resource and call its Schema method -// org.NewCertificateLibraryDatasource().Schema(ctx, fwresource.SchemaRequest{}, schemaResponse) + // Instantiate the resource.Resource and call its Schema method + org.NewCertificateLibraryResource().Schema(ctx, fwresource.SchemaRequest{}, schemaResponse) -// if schemaResponse.Diagnostics.HasError() { -// t.Fatalf("Schema method diagnostics: %+v", schemaResponse.Diagnostics) -// } + if schemaResponse.Diagnostics.HasError() { + t.Fatalf("Schema method diagnostics: %+v", schemaResponse.Diagnostics) + } -// // Validate the schema -// diagnostics := schemaResponse.Schema.ValidateImplementation(ctx) + // Validate the schema + diagnostics := schemaResponse.Schema.ValidateImplementation(ctx) -// if diagnostics.HasError() { -// t.Fatalf("Schema validation diagnostics: %+v", diagnostics) -// } -// } + if diagnostics.HasError() { + t.Fatalf("Schema validation diagnostics: %+v", diagnostics) + } +} -// Unit test for the schema of the datasource cloudavenue_org_CertificateLibraryDatasourcesGo +// Unit test for the schema of the datasource cloudavenue_org_certificate_library func TestCertificateLibraryDatasourceSchema(t *testing.T) { t.Parallel() @@ -40,8 +41,7 @@ func TestCertificateLibraryDatasourceSchema(t *testing.T) { schemaResponse := &fwdatasource.SchemaResponse{} // Instantiate the datasource.Datasource and call its Schema method - - // org.NewCertificateLibraryDatasource().Schema(ctx, fwdatasource.SchemaRequest{}, schemaResponse) + org.NewCertificateLibraryDatasource().Schema(ctx, fwdatasource.SchemaRequest{}, schemaResponse) if schemaResponse.Diagnostics.HasError() { t.Fatalf("Schema method diagnostics: %+v", schemaResponse.Diagnostics) diff --git a/internal/provider/org/certificate_library_types.go b/internal/provider/org/certificate_library_types.go index 98c604a8..f1b3a53a 100644 --- a/internal/provider/org/certificate_library_types.go +++ b/internal/provider/org/certificate_library_types.go @@ -2,8 +2,42 @@ package org import ( supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes" + + v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/pkg/utils" ) -type CertificateLibraryDatasourcesGoModel struct { - ID supertypes.StringValue `tfsdk:"id"` +type CertificateLibraryModel struct { + ID supertypes.StringValue `tfsdk:"id"` + Name supertypes.StringValue `tfsdk:"name"` + Description supertypes.StringValue `tfsdk:"description"` + Certificate supertypes.StringValue `tfsdk:"certificate"` + PrivateKey supertypes.StringValue `tfsdk:"private_key"` + Passphrase supertypes.StringValue `tfsdk:"passphrase"` +} + +type CertificateLibraryDatasourceModel struct { + ID supertypes.StringValue `tfsdk:"id"` + Name supertypes.StringValue `tfsdk:"name"` + Description supertypes.StringValue `tfsdk:"description"` + Certificate supertypes.StringValue `tfsdk:"certificate"` +} + +// ToSDKCertificateLibraryModel converts the data Terraform to the SDK model. +func (rm *CertificateLibraryModel) ToSDKCertificateLibraryModel() *v1.CertificateLibraryModel { + return &v1.CertificateLibraryModel{ + ID: rm.ID.Get(), + Name: rm.Name.Get(), + Description: rm.Description.Get(), + Certificate: rm.Certificate.Get(), + PrivateKey: rm.PrivateKey.Get(), + Passphrase: rm.Passphrase.Get(), + } +} + +// Copy returns a copy of the CertificateLibraryModel. +func (rm *CertificateLibraryModel) Copy() *CertificateLibraryModel { + x := &CertificateLibraryModel{} + utils.ModelCopy(rm, x) + return x } diff --git a/internal/provider/provider_resources.go b/internal/provider/provider_resources.go index c2827f68..6be3649d 100644 --- a/internal/provider/provider_resources.go +++ b/internal/provider/provider_resources.go @@ -20,6 +20,7 @@ import ( "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/edgegw" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/iam" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/network" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/org" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/publicip" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/s3" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/vapp" @@ -110,5 +111,8 @@ func (p *cloudavenueProvider) Resources(_ context.Context) []func() resource.Res s3.NewBucketACLResource, s3.NewCredentialResource, s3.NewBucketPolicyResource, + + // * ORG + org.NewCertificateLibraryResource, } } diff --git a/internal/testsacc/acctest_resources_test.go b/internal/testsacc/acctest_resources_test.go index 9f466e22..9099d04a 100644 --- a/internal/testsacc/acctest_resources_test.go +++ b/internal/testsacc/acctest_resources_test.go @@ -74,5 +74,8 @@ func GetResourceConfig() map[testsacc.ResourceName]func() *testsacc.ResourceConf // * IAM IAMUserResourceName: testsacc.NewResourceConfig(NewIAMUserResourceTest()), IAMUserSAMLResourceName: testsacc.NewResourceConfig(NewIAMUserSAMLResourceTest()), + + // * ORG + ORGCertificateLibraryResourceName: testsacc.NewResourceConfig(NewORGCertificateLibraryResourceTest()), } } diff --git a/internal/testsacc/org_certificate_library_datasource_test.go b/internal/testsacc/org_certificate_library_datasource_test.go index c98d9e1f..acdb6cba 100644 --- a/internal/testsacc/org_certificate_library_datasource_test.go +++ b/internal/testsacc/org_certificate_library_datasource_test.go @@ -6,13 +6,14 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/urn" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/helpers/testsacc" ) var _ testsacc.TestACC = &OrgCertificateLibraryDatasource{} const ( - OrgCertificateLibraryDatasourceName = testsacc.ResourceName("data.cloudavenue_org_certificate_library_datasources_go") + OrgCertificateLibraryDatasourceName = testsacc.ResourceName("data.cloudavenue_org_certificate_library") ) type OrgCertificateLibraryDatasource struct{} @@ -35,17 +36,19 @@ func (r *OrgCertificateLibraryDatasource) DependenciesConfig() (resp testsacc.De func (r *OrgCertificateLibraryDatasource) Tests(ctx context.Context) map[testsacc.TestName]func(ctx context.Context, resourceName string) testsacc.Test { return map[testsacc.TestName]func(ctx context.Context, resourceName string) testsacc.Test{ // * Test One (example) - "example": func(_ context.Context, _ string) testsacc.Test { + "example": func(_ context.Context, resourceName string) testsacc.Test { return testsacc.Test{ // ! Create testing Create: testsacc.TFConfig{ TFConfig: ` - data "cloudavenue_org_certificate_library_datasources_go" "example" { - foo_id = cloudavenue_foo_bar.example.id + data "cloudavenue_org_certificate_library" "example" { + name = "cert-auto-self-sign" }`, - // Here use resource config test to test the data source - // the field example is the name of the test - // Checks: GetResourceConfig()[org_CertificateLibraryDatasourcesGoResourceName]().GetDefaultChecks() + Checks: []resource.TestCheckFunc{ + resource.TestCheckResourceAttrWith(resourceName, "id", urn.TestIsType(urn.CertificateLibraryItem)), + resource.TestCheckResourceAttrSet(resourceName, "name"), + resource.TestCheckResourceAttrSet(resourceName, "certificate"), + }, }, } }, diff --git a/internal/testsacc/org_certificate_library_resource_test.go b/internal/testsacc/org_certificate_library_resource_test.go new file mode 100644 index 00000000..60bc4913 --- /dev/null +++ b/internal/testsacc/org_certificate_library_resource_test.go @@ -0,0 +1,121 @@ +package testsacc + +import ( + "context" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + + "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/urn" + "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/helpers/testsacc" +) + +var _ testsacc.TestACC = &ORGCertificateLibraryResource{} + +const ( + ORGCertificateLibraryResourceName = testsacc.ResourceName("cloudavenue_org_certificate_library") +) + +type ORGCertificateLibraryResource struct{} + +func NewORGCertificateLibraryResourceTest() testsacc.TestACC { + return &ORGCertificateLibraryResource{} +} + +// GetResourceName returns the name of the resource. +func (r *ORGCertificateLibraryResource) GetResourceName() string { + return ORGCertificateLibraryResourceName.String() +} + +func (r *ORGCertificateLibraryResource) DependenciesConfig() (resp testsacc.DependenciesConfigResponse) { + return +} + +func (r *ORGCertificateLibraryResource) Tests(ctx context.Context) map[testsacc.TestName]func(ctx context.Context, resourceName string) testsacc.Test { + return map[testsacc.TestName]func(ctx context.Context, resourceName string) testsacc.Test{ + // * First test named "example" + "example": func(_ context.Context, resourceName string) testsacc.Test { + return testsacc.Test{ + CommonChecks: []resource.TestCheckFunc{ + resource.TestCheckResourceAttrWith(resourceName, "id", urn.TestIsType(urn.CertificateLibraryItem)), + }, + // ! Create testing + Create: testsacc.TFConfig{ + TFConfig: ` + resource "cloudavenue_org_certificate_library" "example" { + name = "example" + description = "This is a certificate" + certificate = file("/Users/micheneaudavid/cav-cert.pem") + private_key = file("/Users/micheneaudavid/cav-key.pem") + }`, + Checks: []resource.TestCheckFunc{ + resource.TestCheckResourceAttr(resourceName, "name", "example"), + resource.TestCheckResourceAttr(resourceName, "description", "This is a certificate"), + resource.TestCheckResourceAttrSet(resourceName, "certificate"), + resource.TestCheckResourceAttrSet(resourceName, "private_key"), + resource.TestCheckNoResourceAttr(resourceName, "passphrase"), + }, + }, + // ! Updates testing + Updates: []testsacc.TFConfig{ + { + TFConfig: ` + resource "cloudavenue_org_certificate_library" "example" { + name = "example updated" + description = "This is a certificate updated" + certificate = file("/Users/micheneaudavid/cav-cert.pem") + private_key = file("/Users/micheneaudavid/cav-key.pem") + }`, + Checks: []resource.TestCheckFunc{ + resource.TestCheckResourceAttr(resourceName, "name", "example updated"), + resource.TestCheckResourceAttr(resourceName, "description", "This is a certificate updated"), + resource.TestCheckResourceAttrSet(resourceName, "certificate"), + resource.TestCheckResourceAttrSet(resourceName, "private_key"), + resource.TestCheckNoResourceAttr(resourceName, "passphrase"), + }, + }, + { + TFConfig: testsacc.GenerateFromTemplate(resourceName, ` + resource "cloudavenue_org_certificate_library" "example" { + name = "example updated" + description = "This is a certificate updated" + certificate = file("/Users/micheneaudavid/cav-cert.pem") + private_key = file("/Users/micheneaudavid/cav-key.pem") + passphrase = "password" + }`), + Checks: []resource.TestCheckFunc{ + resource.TestCheckResourceAttr(resourceName, "name", "example updated"), + resource.TestCheckResourceAttr(resourceName, "description", "This is a certificate updated"), + resource.TestCheckResourceAttrSet(resourceName, "certificate"), + resource.TestCheckResourceAttrSet(resourceName, "private_key"), + resource.TestCheckResourceAttrSet(resourceName, "passphrase"), + }, + }, + }, + // ! Imports testing + Imports: []testsacc.TFImport{ + { + ImportStateIDBuilder: []string{"id"}, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"passphrase", "private_key"}, + }, + { + ImportStateIDBuilder: []string{"name"}, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"passphrase", "private_key"}, + }, + }, + } + }, + } +} + +func TestAccORGCertificateLibraryResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { TestAccPreCheck(t) }, + ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories, + Steps: testsacc.GenerateTests(&ORGCertificateLibraryResource{}), + }) +} diff --git a/templates/data-sources/org_certificate_library.tmpl b/templates/data-sources/org_certificate_library.tmpl new file mode 100644 index 00000000..a212416f --- /dev/null +++ b/templates/data-sources/org_certificate_library.tmpl @@ -0,0 +1,18 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "ORG (Organization)" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +{{ if .HasExample -}} +## Example Usage + +{{ tffile .ExampleFile }} +{{- end }} + +{{ .SchemaMarkdown | trimspace }} From 1ab991c95305762587c99f845c026da4d1fbaba5 Mon Sep 17 00:00:00 2001 From: Mickael Stanislas Date: Thu, 16 Jan 2025 17:30:44 +0100 Subject: [PATCH 2/2] feat(org): add new ress/data org_certificate_library --- .changelog/904.txt | 7 + docs/data-sources/org_certificate_library | 31 ---- docs/data-sources/org_certificate_library.md | 11 +- docs/resources/org_certificate_library.md | 23 ++- .../data-source.tf | 4 +- .../import.sh | 1 + .../resource.tf | 6 + go.mod | 12 +- go.sum | 18 +-- .../alb/service_engine_group_schema.go | 4 +- .../alb/service_engine_group_types.go | 2 +- .../alb/service_engine_groups_schema.go | 4 +- .../alb/service_engine_groups_types.go | 2 +- .../org/certificate_library_datasource.go | 85 +++++------ .../org/certificate_library_resource.go | 139 ++++++++---------- .../org/certificate_library_schema.go | 69 +-------- .../provider/org/certificate_library_types.go | 8 +- internal/testsacc/acctest_datasources_test.go | 3 + ...org_certificate_library_datasource_test.go | 24 ++- .../org_certificate_library_resource_test.go | 77 ++++++---- ...y.tmpl => org_certificate_library.md.tmpl} | 2 +- .../resources/org_certificate_library.md.tmpl | 25 ++++ 22 files changed, 258 insertions(+), 299 deletions(-) create mode 100644 .changelog/904.txt delete mode 100644 docs/data-sources/org_certificate_library create mode 100644 examples/resources/cloudavenue_org_certificate_library/import.sh create mode 100644 examples/resources/cloudavenue_org_certificate_library/resource.tf rename templates/data-sources/{org_certificate_library.tmpl => org_certificate_library.md.tmpl} (90%) create mode 100644 templates/resources/org_certificate_library.md.tmpl diff --git a/.changelog/904.txt b/.changelog/904.txt new file mode 100644 index 00000000..7fa35626 --- /dev/null +++ b/.changelog/904.txt @@ -0,0 +1,7 @@ +```release-note:feature +`resource/cloudavenue_org_certificate_library` - Added new resource to manage certificate in the Cloud Avenue Organization. +``` + +```release-note:feature +`datasource/cloudavenue_org_certificate_library` - Added new datasource to get certificate information in the Cloud Avenue Organization. +``` \ No newline at end of file diff --git a/docs/data-sources/org_certificate_library b/docs/data-sources/org_certificate_library deleted file mode 100644 index 7f7dc1f6..00000000 --- a/docs/data-sources/org_certificate_library +++ /dev/null @@ -1,31 +0,0 @@ ---- -page_title: "cloudavenue_org_certificate_library Data Source - cloudavenue" -subcategory: "ORG (Organization)" -description: |- - The cloudavenue_org_certificate_library data source allows you to retrieve information about an certificate in your organization library. ---- - -# cloudavenue_org_certificate_library (Data Source) - -The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization library. - -## Example Usage - -```terraform -data "cloudavenue_alb_certificate_library" "example" { - name = "my-certificate-library" -} -``` - - -## Schema - -### Optional - -- `id` (String) The ID of the certificate library. Ensure that one and only one attribute from this collection is set : `name`, `id`. -- `name` (String) The name of the certificate library. Ensure that one and only one attribute from this collection is set : `name`, `id`. - -### Read-Only - -- `certificate` (String) The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed. -- `description` (String) The description of the certificate library. diff --git a/docs/data-sources/org_certificate_library.md b/docs/data-sources/org_certificate_library.md index 4fb13b22..559f3225 100644 --- a/docs/data-sources/org_certificate_library.md +++ b/docs/data-sources/org_certificate_library.md @@ -1,19 +1,18 @@ --- -# generated by https://github.com/hashicorp/terraform-plugin-docs page_title: "cloudavenue_org_certificate_library Data Source - cloudavenue" -subcategory: "" +subcategory: "Organization" description: |- - The cloudavenue_org_certificate_library data source allows you to retrieve information about an certificate in your organization library. + The cloudavenue_org_certificate_library data source allows you to retrieve information about an certificate in your organization's library. --- # cloudavenue_org_certificate_library (Data Source) -The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization library. +The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization's library. ## Example Usage ```terraform -data "cloudavenue_alb_certificate_library" "example" { +data "cloudavenue_org_certificate_library" "example" { name = "my-certificate-library" } ``` @@ -28,5 +27,5 @@ data "cloudavenue_alb_certificate_library" "example" { ### Read-Only -- `certificate` (String) The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed. +- `certificate` (String) The certificate content. It can be a PEM encoded certificate or a certificate chain. - `description` (String) The description of the certificate library. diff --git a/docs/resources/org_certificate_library.md b/docs/resources/org_certificate_library.md index d666ce8f..73cb7427 100644 --- a/docs/resources/org_certificate_library.md +++ b/docs/resources/org_certificate_library.md @@ -1,16 +1,24 @@ --- -# generated by https://github.com/hashicorp/terraform-plugin-docs page_title: "cloudavenue_org_certificate_library Resource - cloudavenue" -subcategory: "" +subcategory: "Organization" description: |- - The cloudavenue_org_certificate_library resource allows you to manage certificate in your organization library. + The cloudavenue_org_certificate_library resource allows you to manage certificate in your organization's library. --- # cloudavenue_org_certificate_library (Resource) -The `cloudavenue_org_certificate_library` resource allows you to manage certificate in your organization library. +The `cloudavenue_org_certificate_library` resource allows you to manage certificate in your organization's library. +## Example Usage +```terraform +resource "cloudavenue_org_certificate_library" "example" { + name = "company-certificate" + description = "dev environment certificate" + certificate = chomp(file("/my/certificate/path/cert.pem")) + private_key = chomp(file("/my/certificate/path/key.pem")) +} +``` ## Schema @@ -29,3 +37,10 @@ The `cloudavenue_org_certificate_library` resource allows you to manage certific ### Read-Only - `id` (String) The ID of the certificate library. + +## Import + +Import is supported using the following syntax: +```shell +terraform import cloudavenue_org_certificate_library.example nameOrID +``` \ No newline at end of file diff --git a/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf b/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf index 2a9b855e..34643547 100644 --- a/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf +++ b/examples/data-sources/cloudavenue_org_certificate_library/data-source.tf @@ -1,3 +1,3 @@ -data "cloudavenue_alb_certificate_library" "example" { +data "cloudavenue_org_certificate_library" "example" { name = "my-certificate-library" -} \ No newline at end of file +} diff --git a/examples/resources/cloudavenue_org_certificate_library/import.sh b/examples/resources/cloudavenue_org_certificate_library/import.sh new file mode 100644 index 00000000..2d31d129 --- /dev/null +++ b/examples/resources/cloudavenue_org_certificate_library/import.sh @@ -0,0 +1 @@ +terraform import cloudavenue_org_certificate_library.example nameOrID \ No newline at end of file diff --git a/examples/resources/cloudavenue_org_certificate_library/resource.tf b/examples/resources/cloudavenue_org_certificate_library/resource.tf new file mode 100644 index 00000000..2ee74b95 --- /dev/null +++ b/examples/resources/cloudavenue_org_certificate_library/resource.tf @@ -0,0 +1,6 @@ +resource "cloudavenue_org_certificate_library" "example" { + name = "company-certificate" + description = "dev environment certificate" + certificate = chomp(file("/my/certificate/path/cert.pem")) + private_key = chomp(file("/my/certificate/path/key.pem")) +} diff --git a/go.mod b/go.mod index 74f07aaf..8e13cd7b 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,6 @@ toolchain go1.23.3 require ( github.com/FrangipaneTeam/terraform-analytic-tool v0.0.12 - github.com/FrangipaneTeam/terraform-plugin-framework-superschema v1.8.1 - github.com/FrangipaneTeam/terraform-plugin-framework-supertypes v0.4.0 github.com/aws/aws-sdk-go v1.55.6 github.com/drhodes/golorem v0.0.0-20220328165741-da82e5b29246 github.com/google/uuid v1.6.0 @@ -21,10 +19,9 @@ require ( github.com/hashicorp/terraform-plugin-log v0.9.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 github.com/iancoleman/strcase v0.3.0 - github.com/orange-cloudavenue/cloudavenue-sdk-go v0.20.1 + github.com/madflojo/testcerts v1.4.0 + github.com/orange-cloudavenue/cloudavenue-sdk-go v0.21.1 github.com/orange-cloudavenue/common-go/print v0.0.0-20250109171729-2be550d5d3ac - github.com/k0kubun/pp v3.0.1+incompatible - github.com/orange-cloudavenue/cloudavenue-sdk-go v0.18.1 github.com/orange-cloudavenue/common-go/utils v0.0.0-20240119163616-66b473d92339 github.com/orange-cloudavenue/terraform-plugin-framework-planmodifiers v1.4.0 github.com/orange-cloudavenue/terraform-plugin-framework-superschema v1.9.1 @@ -67,7 +64,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.24.0 // indirect github.com/go-redis/redis/v8 v8.11.5 // indirect - github.com/go-resty/resty/v2 v2.16.3 // indirect + github.com/go-resty/resty/v2 v2.16.5 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/cli v1.1.6 // indirect @@ -94,7 +91,6 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.12.3 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -136,5 +132,3 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) - -replace github.com/orange-cloudavenue/cloudavenue-sdk-go => /Users/micheneaudavid/go/src/github.com/orange-cloudavenue/cloudavenue-sdk-go diff --git a/go.sum b/go.sum index 223da4d5..6a3c2a45 100644 --- a/go.sum +++ b/go.sum @@ -4,10 +4,6 @@ github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/FrangipaneTeam/terraform-analytic-tool v0.0.12 h1:rbh0EtyILnuyu07RuOhrEVXXXRcrxSvKSVtOO14h5ok= github.com/FrangipaneTeam/terraform-analytic-tool v0.0.12/go.mod h1:j3TxedNm9WrKKseOSBKxnNtquuXa0FQChO/QdcvPKtg= -github.com/FrangipaneTeam/terraform-plugin-framework-superschema v1.8.1 h1:ov6LOLLANE9nZVQ1DrpMLuITkejMzTbZLE54xtxZ14A= -github.com/FrangipaneTeam/terraform-plugin-framework-superschema v1.8.1/go.mod h1:AkcBw7L/PhgCm1A4P4adGrbEjE7i2maeCn/Jeh5t5Lo= -github.com/FrangipaneTeam/terraform-plugin-framework-supertypes v0.4.0 h1:5lFfjKOhBxBQNwQ63PZWBc5Unqgi5ppYq9RDoN05N+k= -github.com/FrangipaneTeam/terraform-plugin-framework-supertypes v0.4.0/go.mod h1:klzXBi/0nMGXBh4bzRjP2wef+HE6rfCMia81Glc2+eY= github.com/Kunde21/markdownfmt/v3 v3.1.0 h1:KiZu9LKs+wFFBQKhrZJrFZwtLnCCWJahL+S+E/3VnM0= github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= @@ -103,8 +99,8 @@ github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= -github.com/go-resty/resty/v2 v2.16.3 h1:zacNT7lt4b8M/io2Ahj6yPypL7bqx9n1iprfQuodV+E= -github.com/go-resty/resty/v2 v2.16.3/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= +github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM= +github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -207,10 +203,6 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/k0kubun/pp v3.0.1+incompatible h1:3tqvf7QgUnZ5tXO6pNAZlrvHgl6DvifjDrd9g2S9Z40= -github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -225,6 +217,8 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/madflojo/testcerts v1.4.0 h1:I09gN0C1ly9IgeVNcAqKk8RAKIJTe3QnFrrPBDyvzN4= +github.com/madflojo/testcerts v1.4.0/go.mod h1:MW8sh39gLnkKh4K0Nc55AyHEDl9l/FBLDUsQhpmkuo0= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= @@ -266,8 +260,8 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/orange-cloudavenue/cloudavenue-sdk-go v0.20.1 h1:5oJ/xg5q+USbwKDkDGpIAyB4hyYiNBECHJyrtVY8wAQ= -github.com/orange-cloudavenue/cloudavenue-sdk-go v0.20.1/go.mod h1:flkZyfFFO60w78vhTackWb1FxoEm5EVA8yakrrJRN1I= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.21.1 h1:Uy/AkLQM/KQzDMFBCVR7vh4BppgROa/GK5UNfXbP7e0= +github.com/orange-cloudavenue/cloudavenue-sdk-go v0.21.1/go.mod h1:1jc0W7Me1Oq0kSPoJNYcH6emJ5HruIIsh1//Wp26AJQ= github.com/orange-cloudavenue/common-go/print v0.0.0-20250109171729-2be550d5d3ac h1:f1Fd70+PMDTK6FE4gHdNfoHSQHLn5pfJMTjZPzOWZtc= github.com/orange-cloudavenue/common-go/print v0.0.0-20250109171729-2be550d5d3ac/go.mod h1:IYtCusqpEGS0dhC6F8X9GHrrt1gp1zHaNhSKGYV59Xg= github.com/orange-cloudavenue/common-go/utils v0.0.0-20240119163616-66b473d92339 h1:DEKcWLGbEhu/I6kn9NAXhVCFrbPhR+Ef7oLmpLVnnPM= diff --git a/internal/provider/alb/service_engine_group_schema.go b/internal/provider/alb/service_engine_group_schema.go index 816b0b2e..ee92e31a 100644 --- a/internal/provider/alb/service_engine_group_schema.go +++ b/internal/provider/alb/service_engine_group_schema.go @@ -3,14 +3,14 @@ package alb import ( "context" + superschema "github.com/orange-cloudavenue/terraform-plugin-framework-superschema" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/schema/validator" schemaD "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - - superschema "github.com/FrangipaneTeam/terraform-plugin-framework-superschema" ) func serviceEngineGroupSchema(_ context.Context) superschema.Schema { diff --git a/internal/provider/alb/service_engine_group_types.go b/internal/provider/alb/service_engine_group_types.go index 82a00f51..32e9c2ab 100644 --- a/internal/provider/alb/service_engine_group_types.go +++ b/internal/provider/alb/service_engine_group_types.go @@ -1,7 +1,7 @@ package alb import ( - supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes" + supertypes "github.com/orange-cloudavenue/terraform-plugin-framework-supertypes" ) type serviceEngineGroupModel struct { diff --git a/internal/provider/alb/service_engine_groups_schema.go b/internal/provider/alb/service_engine_groups_schema.go index 3cabe928..0491de7c 100644 --- a/internal/provider/alb/service_engine_groups_schema.go +++ b/internal/provider/alb/service_engine_groups_schema.go @@ -3,14 +3,14 @@ package alb import ( "context" + superschema "github.com/orange-cloudavenue/terraform-plugin-framework-superschema" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/schema/validator" schemaD "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - - superschema "github.com/FrangipaneTeam/terraform-plugin-framework-superschema" ) func serviceEngineGroupsSchema(ctx context.Context) superschema.Schema { diff --git a/internal/provider/alb/service_engine_groups_types.go b/internal/provider/alb/service_engine_groups_types.go index 5055b111..42b2eef4 100644 --- a/internal/provider/alb/service_engine_groups_types.go +++ b/internal/provider/alb/service_engine_groups_types.go @@ -1,6 +1,6 @@ package alb -import supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes" +import supertypes "github.com/orange-cloudavenue/terraform-plugin-framework-supertypes" type serviceEngineGroupsModel struct { ID supertypes.StringValue `tfsdk:"id"` diff --git a/internal/provider/org/certificate_library_datasource.go b/internal/provider/org/certificate_library_datasource.go index 0e510117..83bdf803 100644 --- a/internal/provider/org/certificate_library_datasource.go +++ b/internal/provider/org/certificate_library_datasource.go @@ -5,19 +5,14 @@ import ( "context" "fmt" - "github.com/vmware/go-vcloud-director/v2/govcd" - "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/datasource" - supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes" + "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1/org" - commoncloudavenue "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/common/cloudavenue" - v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/metrics" - "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/org" ) var ( @@ -30,18 +25,21 @@ func NewCertificateLibraryDatasource() datasource.DataSource { } type CertificateLibraryDatasource struct { - client *client.CloudAvenue - org org.Org + client *client.CloudAvenue + orgClient *org.Client } // Init Initializes the data source. func (d *CertificateLibraryDatasource) Init(ctx context.Context, dm *CertificateLibraryDatasourceModel) (diags diag.Diagnostics) { - // Uncomment the following lines if you need to access to the Org - d.org, diags = org.Init(d.client) - if diags.HasError() { - return + var err error + + org, err := d.client.CAVSDK.V1.Org() + if err != nil { + diags.AddError("Error initializing ORG client", err.Error()) } + d.orgClient = org.Client + return } @@ -87,49 +85,36 @@ func (d *CertificateLibraryDatasource) Read(ctx context.Context, req datasource. return } - // Read data from the API - data, _, diags := d.read(config) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - - // Save data into Terraform state - resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) -} + /* + Implement the data source read logic here. + */ -// read reads the data from the API and returns the data to be saved in the Terraform state. -func (d *CertificateLibraryDatasource) read(config *CertificateLibraryDatasourceModel) (data *CertificateLibraryDatasourceModel, found bool, diags diag.Diagnostics) { - var ( - certificate *v1.CertificateLibraryModel - err error - ) - - // Get CertificateLibrary - if config.ID.IsKnown() { - certificate, err = d.org.GetOrgCertificateLibrary(config.ID.Get()) - } else { - certificate, err = d.org.GetOrgCertificateLibrary(config.Name.Get()) + s := &CertificateLibraryResource{ + client: d.client, + orgClient: d.orgClient, } - if err != nil { - if commoncloudavenue.IsNotFound(err) || govcd.IsNotFound(err) { - return nil, false, diags - } - diags.AddError("error while fetching certificate library: %s", err.Error()) - return nil, true, diags + + configResource := &CertificateLibraryModel{ + ID: config.ID, + Name: config.Name, } - data = &CertificateLibraryDatasourceModel{ - ID: supertypes.NewStringNull(), - Name: supertypes.NewStringNull(), - Description: supertypes.NewStringNull(), - Certificate: supertypes.NewStringNull(), + // Read data from the API + data, found, diags := s.read(ctx, configResource) + if !found { + resp.Diagnostics.AddError("Resource not found", fmt.Sprintf("The Certificate %s(%s) was not found", config.Name.Get(), config.ID.Get())) + return + } + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } - data.ID.Set(certificate.ID) - data.Name.Set(certificate.Name) - data.Description.Set(certificate.Description) - data.Certificate.Set(certificate.Certificate) + config.ID.Set(data.ID.Get()) + config.Name.Set(data.Name.Get()) + config.Description.Set(data.Description.Get()) + config.Certificate.Set(data.Certificate.Get()) - return data, true, nil + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &config)...) } diff --git a/internal/provider/org/certificate_library_resource.go b/internal/provider/org/certificate_library_resource.go index c9ba5e62..cfe52119 100644 --- a/internal/provider/org/certificate_library_resource.go +++ b/internal/provider/org/certificate_library_resource.go @@ -3,21 +3,17 @@ package org import ( "context" "fmt" - "strings" "github.com/vmware/go-vcloud-director/v2/govcd" "github.com/hashicorp/terraform-plugin-framework/diag" - "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" - commoncloudavenue "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/common/cloudavenue" - v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" + "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/urn" + "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1/org" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/client" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/metrics" - "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/mutex" - "github.com/orange-cloudavenue/terraform-provider-cloudavenue/internal/provider/common/org" ) // Ensure the implementation satisfies the expected interfaces. @@ -25,9 +21,6 @@ var ( _ resource.Resource = &CertificateLibraryResource{} _ resource.ResourceWithConfigure = &CertificateLibraryResource{} _ resource.ResourceWithImportState = &CertificateLibraryResource{} - // _ resource.ResourceWithModifyPlan = &CertificateLibraryResource{} - // _ resource.ResourceWithUpgradeState = &CertificateLibraryResource{} - // _ resource.ResourceWithValidateConfig = &CertificateLibraryResource{}. ) // NewCertificateLibraryResource is a helper function to simplify the provider implementation. @@ -37,18 +30,21 @@ func NewCertificateLibraryResource() resource.Resource { // CertificateLibraryResource is the resource implementation. type CertificateLibraryResource struct { - client *client.CloudAvenue - org org.Org + client *client.CloudAvenue + orgClient *org.Client } // Init Initializes the resource. func (r *CertificateLibraryResource) Init(ctx context.Context, rm *CertificateLibraryModel) (diags diag.Diagnostics) { - // Uncomment the following lines if you need to access to the Org - r.org, diags = org.Init(r.client) - if diags.HasError() { - return + var err error + + org, err := r.client.CAVSDK.V1.Org() + if err != nil { + diags.AddError("Error initializing ORG client", err.Error()) } + r.orgClient = org.Client + return } @@ -101,27 +97,19 @@ func (r *CertificateLibraryResource) Create(ctx context.Context, req resource.Cr Implement the resource creation logic here. */ - // Lock the resource organization - mutex.GlobalMutex.KvLock(ctx, r.org.GetID()) - defer mutex.GlobalMutex.KvUnlock(ctx, r.org.GetID()) - - // Set the SDK certificate library Model - certLibrarySDKModel := plan.ToSDKCertificateLibraryModel() - // Create the certificate library - newCertificate, err := r.org.CreateOrgCertificateLibrary(certLibrarySDKModel) + newCertificate, err := r.orgClient.CreateCertificateInLibrary(plan.ToSDKCertificateLibraryModel()) if err != nil { - resp.Diagnostics.AddError("error while creating certificate library: %s", err.Error()) + resp.Diagnostics.AddError("error while creating certificate %s in library", err.Error()) return } - // Set ID - plan.ID.Set(newCertificate.ID) + plan.ID.Set(newCertificate.Certificate.ID) // Use generic read function to refresh the state - state, found, d := r.read(plan) + state, found, d := r.read(ctx, plan) if !found { - resp.Diagnostics.AddError("Resource not found", fmt.Sprintf("The certificate library '%s' was not found after creation.", plan.Name.Get())) + resp.Diagnostics.AddError("Resource not found", fmt.Sprintf("The certificate '%s' was not found after creation.", plan.Name.Get())) return } if d.HasError() { @@ -152,7 +140,7 @@ func (r *CertificateLibraryResource) Read(ctx context.Context, req resource.Read } // Refresh the state - stateRefreshed, found, d := r.read(state) + stateRefreshed, found, d := r.read(ctx, state) if !found { resp.State.RemoveResource(ctx) return @@ -192,22 +180,22 @@ func (r *CertificateLibraryResource) Update(ctx context.Context, req resource.Up Implement the resource update here */ - // Lock the resource organization - mutex.GlobalMutex.KvLock(ctx, r.org.GetID()) - defer mutex.GlobalMutex.KvUnlock(ctx, r.org.GetID()) + certificate, err := r.orgClient.GetCertificateFromLibrary(state.ID.Get()) + if err != nil { + resp.Diagnostics.AddError("error while fetching certificate : %s", err.Error()) + return + } - // Set the SDK certificate library Model - certLibrarySDKModel := plan.ToSDKCertificateLibraryModel() + certificate.Certificate = plan.ToSDKCertificateLibraryModel() // Update the certificate library - _, err := certLibrarySDKModel.Update() - if err != nil { - resp.Diagnostics.AddError("error while updating certificate library: %s", err.Error()) + if err := certificate.Update(); err != nil { + resp.Diagnostics.AddError("error while updating certificate %s", err.Error()) return } // Use generic read function to refresh the state - stateRefreshed, _, d := r.read(plan) + stateRefreshed, _, d := r.read(ctx, plan) if d.HasError() { resp.Diagnostics.Append(d...) return @@ -239,21 +227,14 @@ func (r *CertificateLibraryResource) Delete(ctx context.Context, req resource.De Implement the resource deletion here */ - // Lock the resource organization - mutex.GlobalMutex.KvLock(ctx, r.org.GetID()) - defer mutex.GlobalMutex.KvUnlock(ctx, r.org.GetID()) - - // Use generic read function to refresh the state - stateRefreshed, _, d := r.read(state) - if d.HasError() { - resp.Diagnostics.Append(d...) + certificate, err := r.orgClient.GetCertificateFromLibrary(state.ID.Get()) + if err != nil { + resp.Diagnostics.AddError("error while fetching certificate : %s", err.Error()) return } - // Delete the certificate library - err := stateRefreshed.ToSDKCertificateLibraryModel().Delete() - if err != nil { - resp.Diagnostics.AddError("error while deleting certificate library: %s", err.Error()) + if err := certificate.Delete(); err != nil { + resp.Diagnostics.AddError("error while deleting certificate : %s", err.Error()) return } } @@ -263,56 +244,53 @@ func (r *CertificateLibraryResource) ImportState(ctx context.Context, req resour // * ID format is CertificateIdOrName - // * Import with custom logic - idParts := strings.Split(req.ID, ".") - if len(idParts) > 1 { - resp.Diagnostics.AddError( - "Unexpected Import Identifier", - fmt.Sprintf("Expected import identifier with format: CertificateIdOrName. Got: %q", req.ID), - ) - return - } + config := &CertificateLibraryModel{} // Init the resource - resp.Diagnostics.Append(r.Init(ctx, &CertificateLibraryModel{})...) + resp.Diagnostics.Append(r.Init(ctx, config)...) if resp.Diagnostics.HasError() { return } - // Get the certificate library - certificate, err := r.org.GetOrgCertificateLibrary(req.ID) - if err != nil { - resp.Diagnostics.AddError("error while importing certificate library: %s", err.Error()) + if urn.IsCertificateLibraryItem(req.ID) { + config.ID.Set(req.ID) + } else { + config.Name.Set(req.ID) + } + + // Use generic read function to refresh the state + stateRefreshed, found, d := r.read(ctx, config) + if !found { + resp.Diagnostics.AddError("Resource not found", fmt.Sprintf("The certificate '%s' was not found after import.", req.ID)) + return + } + if d.HasError() { + resp.Diagnostics.Append(d...) return } - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), certificate.ID)...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), certificate.Name)...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("description"), certificate.Description)...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("certificate"), certificate.Certificate)...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("private_key"), certificate.PrivateKey)...) - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("passphrase"), certificate.Passphrase)...) + // Set state to fully populated data + resp.Diagnostics.Append(resp.State.Set(ctx, stateRefreshed)...) } // * CustomFuncs // read is a generic read function that can be used by the resource Create, Read and Update functions. -func (r *CertificateLibraryResource) read(planOrState *CertificateLibraryModel) (stateRefreshed *CertificateLibraryModel, found bool, diags diag.Diagnostics) { +func (r *CertificateLibraryResource) read(_ context.Context, planOrState *CertificateLibraryModel) (stateRefreshed *CertificateLibraryModel, found bool, diags diag.Diagnostics) { stateRefreshed = planOrState.Copy() var ( - certificate *v1.CertificateLibraryModel + certificate *org.CertificateClient err error ) - // Get CertificateLibrary if planOrState.ID.IsKnown() { - certificate, err = r.org.GetOrgCertificateLibrary(planOrState.ID.Get()) + certificate, err = r.orgClient.GetCertificateFromLibrary(planOrState.ID.Get()) } else { - certificate, err = r.org.GetOrgCertificateLibrary(planOrState.Name.Get()) + certificate, err = r.orgClient.GetCertificateFromLibrary(planOrState.Name.Get()) } if err != nil { - if commoncloudavenue.IsNotFound(err) || govcd.IsNotFound(err) { + if govcd.IsNotFound(err) { return nil, false, diags } diags.AddError("error while fetching certificate library: %s", err.Error()) @@ -320,11 +298,10 @@ func (r *CertificateLibraryResource) read(planOrState *CertificateLibraryModel) } // Set the refreshed state - stateRefreshed.ID.Set(certificate.ID) - stateRefreshed.Name.Set(certificate.Name) - stateRefreshed.Description.Set(certificate.Description) - stateRefreshed.Certificate.Set(certificate.Certificate) - // No need to set the private key and passphrase as they are not returned by the API (security reasons) + stateRefreshed.ID.Set(certificate.Certificate.ID) + stateRefreshed.Name.Set(certificate.Certificate.Name) + stateRefreshed.Description.Set(certificate.Certificate.Description) + stateRefreshed.Certificate.Set(certificate.Certificate.Certificate) return stateRefreshed, true, nil } diff --git a/internal/provider/org/certificate_library_schema.go b/internal/provider/org/certificate_library_schema.go index 9df78f7c..cb4c33c3 100644 --- a/internal/provider/org/certificate_library_schema.go +++ b/internal/provider/org/certificate_library_schema.go @@ -3,6 +3,8 @@ package org import ( "context" + superschema "github.com/orange-cloudavenue/terraform-plugin-framework-superschema" + "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/schema/validator" @@ -13,70 +15,15 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" - - superschema "github.com/FrangipaneTeam/terraform-plugin-framework-superschema" ) -// TODO : Remove unused imports. -// ! This is outside import block because golangci-lint remove commented import. -// * Hashicorp Validators -// "github.com/Hashicorp/terraform-plugin-framework-validators/stringvalidator" -// "github.com/Hashicorp/terraform-plugin-framework-validators/boolvalidator" -// "github.com/Hashicorp/terraform-plugin-framework-validators/int64validator" -// "github.com/Hashicorp/terraform-plugin-framework-validators/float64validator" -// "github.com/Hashicorp/terraform-plugin-framework-validators/listvalidator" -// "github.com/Hashicorp/terraform-plugin-framework-validators/mapvalidator" -// "github.com/Hashicorp/terraform-plugin-framework-validators/setvalidator" - -// * Hashicorp Plan Modifiers Resource -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/mapplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" - -// * Hashicorp Plan Modifiers DataSource -// "github.com/hashicorp/terraform-plugin-framework/datasource/schema/stringplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/datasource/schema/boolplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/datasource/schema/int64planmodifier" -// "github.com/hashicorp/terraform-plugin-framework/datasource/schema/listplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/datasource/schema/mapplanmodifier" -// "github.com/hashicorp/terraform-plugin-framework/datasource/schema/setplanmodifier" - -// * Hashicorp Default Values -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default" -// "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - -// * FrangipaneTeam Custom Validators -// fstringvalidator "github.com/FrangipaneTeam/terraform-plugin-framework-validators/stringvalidator" -// fboolvalidator "github.com/FrangipaneTeam/terraform-plugin-framework-validators/boolvalidator" -// fint64validator "github.com/FrangipaneTeam/terraform-plugin-framework-validators/int64validator" -// flistvalidator "github.com/FrangipaneTeam/terraform-plugin-framework-validators/listvalidator" -// fmapvalidator "github.com/FrangipaneTeam/terraform-plugin-framework-validators/mapvalidator" -// fsetvalidator "github.com/FrangipaneTeam/terraform-plugin-framework-validators/setvalidator" - -// * FrangipaneTeam Custom Plan Modifiers -// fstringplanmodifier "github.com/FrangipaneTeam/terraform-plugin-framework-planmodifiers/stringplanmodifier" -// fboolplanmodifier "github.com/FrangipaneTeam/terraform-plugin-framework-planmodifiers/boolplanmodifier" -// fint64planmodifier "github.com/FrangipaneTeam/terraform-plugin-framework-planmodifiers/int64planmodifier" -// flistplanmodifier "github.com/FrangipaneTeam/terraform-plugin-framework-planmodifiers/listplanmodifier" -// fmapplanmodifier "github.com/FrangipaneTeam/terraform-plugin-framework-planmodifiers/mapplanmodifier" -// fsetplanmodifier "github.com/FrangipaneTeam/terraform-plugin-framework-planmodifiers/setplanmodifier" - -// How to use types generator: -// 1. Define the schema in the file internal/provider/org/certificate_library_datasources_go_schema.go -// 2. Add the resource or data source to the file internal/provider/provider_resources.go or internal/provider/provider_data_sources.go respectively -// 3. Launch the following command to generate golang structs for the schema: -// go run ./cmd/types-generator/*.go -file internal/provider/org/certificate_library_datasources_go_schema.go -resource cloudavenue_org_certificate_library -is-resource. func certificateLibrarySchema(_ context.Context) superschema.Schema { return superschema.Schema{ Resource: superschema.SchemaDetails{ - MarkdownDescription: "The `cloudavenue_org_certificate_library` resource allows you to manage certificate in your organization library.", + MarkdownDescription: "The `cloudavenue_org_certificate_library` resource allows you to manage certificate in your organization's library.", }, DataSource: superschema.SchemaDetails{ - MarkdownDescription: "The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization library.", + MarkdownDescription: "The `cloudavenue_org_certificate_library` data source allows you to retrieve information about an certificate in your organization's library.", }, Attributes: map[string]superschema.Attribute{ "id": superschema.SuperStringAttribute{ @@ -102,9 +49,6 @@ func certificateLibrarySchema(_ context.Context) superschema.Schema { }, Resource: &schemaR.StringAttribute{ Required: true, - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, }, DataSource: &schemaD.StringAttribute{ Computed: true, @@ -127,10 +71,11 @@ func certificateLibrarySchema(_ context.Context) superschema.Schema { }, "certificate": superschema.SuperStringAttribute{ Common: &schemaR.StringAttribute{ - MarkdownDescription: "The certificate content. It can be a PEM encoded certificate or a certificate chain. Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed.", + MarkdownDescription: "The certificate content. It can be a PEM encoded certificate or a certificate chain.", }, Resource: &schemaR.StringAttribute{ - Required: true, + Required: true, + MarkdownDescription: "Contains all strings including the BEGIN CERTIFICATE and END CERTIFICATE lines. No empty lines are allowed.", PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, diff --git a/internal/provider/org/certificate_library_types.go b/internal/provider/org/certificate_library_types.go index f1b3a53a..c291e670 100644 --- a/internal/provider/org/certificate_library_types.go +++ b/internal/provider/org/certificate_library_types.go @@ -1,9 +1,9 @@ package org import ( - supertypes "github.com/FrangipaneTeam/terraform-plugin-framework-supertypes" + supertypes "github.com/orange-cloudavenue/terraform-plugin-framework-supertypes" - v1 "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1" + "github.com/orange-cloudavenue/cloudavenue-sdk-go/v1/org" "github.com/orange-cloudavenue/terraform-provider-cloudavenue/pkg/utils" ) @@ -24,8 +24,8 @@ type CertificateLibraryDatasourceModel struct { } // ToSDKCertificateLibraryModel converts the data Terraform to the SDK model. -func (rm *CertificateLibraryModel) ToSDKCertificateLibraryModel() *v1.CertificateLibraryModel { - return &v1.CertificateLibraryModel{ +func (rm *CertificateLibraryModel) ToSDKCertificateLibraryModel() org.CertificateModel { + return org.CertificateModel{ ID: rm.ID.Get(), Name: rm.Name.Get(), Description: rm.Description.Get(), diff --git a/internal/testsacc/acctest_datasources_test.go b/internal/testsacc/acctest_datasources_test.go index aed5aae1..75380328 100644 --- a/internal/testsacc/acctest_datasources_test.go +++ b/internal/testsacc/acctest_datasources_test.go @@ -73,5 +73,8 @@ func GetDataSourceConfig() map[testsacc.ResourceName]func() *testsacc.ResourceCo // * VApp VAppDatasourceName: testsacc.NewResourceConfig(NewVAppDatasourceTest()), VAppIsolatedNetworkDataSourceName: testsacc.NewResourceConfig(NewVAppIsolatedNetworkDataSourceTest()), + + // * Org + OrgCertificateLibraryDatasourceName: testsacc.NewResourceConfig(NewOrgCertificateLibraryDatasourceTest()), } } diff --git a/internal/testsacc/org_certificate_library_datasource_test.go b/internal/testsacc/org_certificate_library_datasource_test.go index acdb6cba..8d08186d 100644 --- a/internal/testsacc/org_certificate_library_datasource_test.go +++ b/internal/testsacc/org_certificate_library_datasource_test.go @@ -28,8 +28,7 @@ func (r *OrgCertificateLibraryDatasource) GetResourceName() string { } func (r *OrgCertificateLibraryDatasource) DependenciesConfig() (resp testsacc.DependenciesConfigResponse) { - // Add dependencies config to the resource - // resp.Append(GetResourceConfig()[OrgCertificateLibraryDatasourcesGoResourceName]().GetDefaultConfig), + resp.Append(GetResourceConfig()[ORGCertificateLibraryResourceName]().GetDefaultConfig) return } @@ -42,7 +41,23 @@ func (r *OrgCertificateLibraryDatasource) Tests(ctx context.Context) map[testsac Create: testsacc.TFConfig{ TFConfig: ` data "cloudavenue_org_certificate_library" "example" { - name = "cert-auto-self-sign" + name = cloudavenue_org_certificate_library.example.name + }`, + Checks: []resource.TestCheckFunc{ + resource.TestCheckResourceAttrWith(resourceName, "id", urn.TestIsType(urn.CertificateLibraryItem)), + resource.TestCheckResourceAttrSet(resourceName, "name"), + resource.TestCheckResourceAttrSet(resourceName, "certificate"), + }, + }, + } + }, + "example_id": func(_ context.Context, resourceName string) testsacc.Test { + return testsacc.Test{ + // ! Create testing + Create: testsacc.TFConfig{ + TFConfig: ` + data "cloudavenue_org_certificate_library" "example_id" { + id = cloudavenue_org_certificate_library.example.id }`, Checks: []resource.TestCheckFunc{ resource.TestCheckResourceAttrWith(resourceName, "id", urn.TestIsType(urn.CertificateLibraryItem)), @@ -56,6 +71,9 @@ func (r *OrgCertificateLibraryDatasource) Tests(ctx context.Context) map[testsac } func TestAccOrgCertificateLibraryDatasource(t *testing.T) { + cleanup := orgCertificateLibraryResourcePreCheck() + defer cleanup() + resource.Test(t, resource.TestCase{ PreCheck: func() { TestAccPreCheck(t) }, ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories, diff --git a/internal/testsacc/org_certificate_library_resource_test.go b/internal/testsacc/org_certificate_library_resource_test.go index 60bc4913..d9599843 100644 --- a/internal/testsacc/org_certificate_library_resource_test.go +++ b/internal/testsacc/org_certificate_library_resource_test.go @@ -2,8 +2,11 @@ package testsacc import ( "context" + "os" "testing" + "github.com/madflojo/testcerts" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/orange-cloudavenue/cloudavenue-sdk-go/pkg/urn" @@ -38,56 +41,52 @@ func (r *ORGCertificateLibraryResource) Tests(ctx context.Context) map[testsacc. return testsacc.Test{ CommonChecks: []resource.TestCheckFunc{ resource.TestCheckResourceAttrWith(resourceName, "id", urn.TestIsType(urn.CertificateLibraryItem)), + resource.TestCheckResourceAttrSet(resourceName, "certificate"), + resource.TestCheckResourceAttrSet(resourceName, "private_key"), }, // ! Create testing Create: testsacc.TFConfig{ - TFConfig: ` + TFConfig: testsacc.GenerateFromTemplate(resourceName, ` resource "cloudavenue_org_certificate_library" "example" { - name = "example" - description = "This is a certificate" - certificate = file("/Users/micheneaudavid/cav-cert.pem") - private_key = file("/Users/micheneaudavid/cav-key.pem") - }`, + name = {{ generate . "name" }} + description = {{ generate . "description" }} + certificate = chomp(file("/tmp/cert.pem")) + private_key = chomp(file("/tmp/key.pem")) + }`), Checks: []resource.TestCheckFunc{ - resource.TestCheckResourceAttr(resourceName, "name", "example"), - resource.TestCheckResourceAttr(resourceName, "description", "This is a certificate"), - resource.TestCheckResourceAttrSet(resourceName, "certificate"), - resource.TestCheckResourceAttrSet(resourceName, "private_key"), + resource.TestCheckResourceAttr(resourceName, "name", testsacc.GetValueFromTemplate(resourceName, "name")), + resource.TestCheckResourceAttr(resourceName, "description", testsacc.GetValueFromTemplate(resourceName, "description")), resource.TestCheckNoResourceAttr(resourceName, "passphrase"), }, }, // ! Updates testing Updates: []testsacc.TFConfig{ { - TFConfig: ` + TFConfig: testsacc.GenerateFromTemplate(resourceName, ` resource "cloudavenue_org_certificate_library" "example" { - name = "example updated" - description = "This is a certificate updated" - certificate = file("/Users/micheneaudavid/cav-cert.pem") - private_key = file("/Users/micheneaudavid/cav-key.pem") - }`, + name = {{ generate . "name" }} + description = {{ get . "description" }} + certificate = chomp(file("/tmp/cert.pem")) + private_key = chomp(file("/tmp/key.pem")) + }`), Checks: []resource.TestCheckFunc{ - resource.TestCheckResourceAttr(resourceName, "name", "example updated"), - resource.TestCheckResourceAttr(resourceName, "description", "This is a certificate updated"), - resource.TestCheckResourceAttrSet(resourceName, "certificate"), - resource.TestCheckResourceAttrSet(resourceName, "private_key"), + resource.TestCheckResourceAttr(resourceName, "name", testsacc.GetValueFromTemplate(resourceName, "name")), + resource.TestCheckResourceAttr(resourceName, "description", testsacc.GetValueFromTemplate(resourceName, "description")), resource.TestCheckNoResourceAttr(resourceName, "passphrase"), }, }, { TFConfig: testsacc.GenerateFromTemplate(resourceName, ` resource "cloudavenue_org_certificate_library" "example" { - name = "example updated" - description = "This is a certificate updated" - certificate = file("/Users/micheneaudavid/cav-cert.pem") - private_key = file("/Users/micheneaudavid/cav-key.pem") + name = {{ generate . "name" }} + description = {{ generate . "description" }} + certificate = chomp(file("/tmp/cert.pem")) + private_key = chomp(file("/tmp/key.pem")) passphrase = "password" }`), Checks: []resource.TestCheckFunc{ - resource.TestCheckResourceAttr(resourceName, "name", "example updated"), - resource.TestCheckResourceAttr(resourceName, "description", "This is a certificate updated"), - resource.TestCheckResourceAttrSet(resourceName, "certificate"), - resource.TestCheckResourceAttrSet(resourceName, "private_key"), + resource.TestCheckResourceAttr(resourceName, "name", testsacc.GetValueFromTemplate(resourceName, "name")), + resource.TestCheckResourceAttr(resourceName, "description", testsacc.GetValueFromTemplate(resourceName, "description")), resource.TestCheckResourceAttrSet(resourceName, "passphrase"), }, }, @@ -112,7 +111,29 @@ func (r *ORGCertificateLibraryResource) Tests(ctx context.Context) map[testsacc. } } +const ( + orgCertificateLibraryCertFile = "/tmp/cert.pem" + orgCertificateLibraryKeyFile = "/tmp/key.pem" +) + +func orgCertificateLibraryResourcePreCheck() (cleanup func()) { + if err := testcerts.GenerateCertsToFile( + orgCertificateLibraryCertFile, + orgCertificateLibraryKeyFile, + ); err != nil { + panic(err) + } + + return func() { + os.Remove(orgCertificateLibraryCertFile) + os.Remove(orgCertificateLibraryKeyFile) + } +} + func TestAccORGCertificateLibraryResource(t *testing.T) { + cleanup := orgCertificateLibraryResourcePreCheck() + defer cleanup() + resource.Test(t, resource.TestCase{ PreCheck: func() { TestAccPreCheck(t) }, ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories, diff --git a/templates/data-sources/org_certificate_library.tmpl b/templates/data-sources/org_certificate_library.md.tmpl similarity index 90% rename from templates/data-sources/org_certificate_library.tmpl rename to templates/data-sources/org_certificate_library.md.tmpl index a212416f..179a4b55 100644 --- a/templates/data-sources/org_certificate_library.tmpl +++ b/templates/data-sources/org_certificate_library.md.tmpl @@ -1,6 +1,6 @@ --- page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" -subcategory: "ORG (Organization)" +subcategory: "Organization" description: |- {{ .Description | plainmarkdown | trimspace | prefixlines " " }} --- diff --git a/templates/resources/org_certificate_library.md.tmpl b/templates/resources/org_certificate_library.md.tmpl new file mode 100644 index 00000000..cec68c1d --- /dev/null +++ b/templates/resources/org_certificate_library.md.tmpl @@ -0,0 +1,25 @@ +--- +page_title: "{{.Name}} {{.Type}} - {{.ProviderName}}" +subcategory: "Organization" +description: |- +{{ .Description | plainmarkdown | trimspace | prefixlines " " }} +--- + +# {{.Name}} ({{.Type}}) + +{{ .Description | trimspace }} + +{{ if .HasExample -}} +## Example Usage + +{{ tffile .ExampleFile }} +{{- end }} + +{{ .SchemaMarkdown | trimspace }} + +{{ if .HasImport -}} +## Import + +Import is supported using the following syntax: +{{ codefile "shell" .ImportFile }} +{{- end }} \ No newline at end of file