diff --git a/go.mod b/go.mod index 1a7140e..00c2cc6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/SAP/terraform-provider-cloudfoundry go 1.22 require ( - github.com/cloudfoundry-community/go-cfclient/v3 v3.0.0-alpha.6.0.20240326180005-d4d9ebf1fa8b + github.com/cloudfoundry-community/go-cfclient/v3 v3.0.0-alpha.6.0.20240409184651-b04f5016321d github.com/hashicorp/terraform-plugin-docs v0.18.0 github.com/hashicorp/terraform-plugin-framework v1.7.0 github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 @@ -17,8 +17,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) -replace github.com/cloudfoundry-community/go-cfclient/v3 => github.com/Dray56/go-cfclient/v3 v3.0.0-20240401042020-3fd26f1e7e8b - require ( github.com/rivo/uniseg v0.2.0 // indirect golang.org/x/tools v0.17.0 // indirect diff --git a/go.sum b/go.sum index d25e45b..fe267b2 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,5 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/Dray56/go-cfclient/v3 v3.0.0-20240401042020-3fd26f1e7e8b h1:0+TmmhTHe/1Cw/zwW2k8clKAN8VwTaagfo55DB+FEW0= -github.com/Dray56/go-cfclient/v3 v3.0.0-20240401042020-3fd26f1e7e8b/go.mod h1:gO2kmPy5V/dcebe3ANGJXLxOQU2gTT9tHLNB8cONe1w= 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= @@ -28,6 +26,8 @@ github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZ github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudfoundry-community/go-cfclient/v3 v3.0.0-alpha.6.0.20240409184651-b04f5016321d h1:HjaXtcIQdRneHk9eOhET9Qzi2N8a55JGozti2adJMVg= +github.com/cloudfoundry-community/go-cfclient/v3 v3.0.0-alpha.6.0.20240409184651-b04f5016321d/go.mod h1:gO2kmPy5V/dcebe3ANGJXLxOQU2gTT9tHLNB8cONe1w= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= diff --git a/internal/provider/datasource_service_instance.go b/internal/provider/datasource_service_instance.go index 63bb923..40d0b44 100644 --- a/internal/provider/datasource_service_instance.go +++ b/internal/provider/datasource_service_instance.go @@ -46,8 +46,8 @@ func (d *ServiceInstanceDataSource) Schema(ctx context.Context, req datasource.S MarkdownDescription: "The ID of the service plan from which to create the service instance", Computed: true, }, - "tags": schema.SetAttribute{ - MarkdownDescription: "Set of tags used by apps to identify service instances. They are shown in the app VCAP_SERVICES env.", + "tags": schema.ListAttribute{ + MarkdownDescription: "List of tags used by apps to identify service instances. They are shown in the app VCAP_SERVICES env.", ElementType: types.StringType, Computed: true, }, diff --git a/internal/provider/resource_service_instance.go b/internal/provider/resource_service_instance.go index b2d4249..6d99c4c 100644 --- a/internal/provider/resource_service_instance.go +++ b/internal/provider/resource_service_instance.go @@ -11,6 +11,7 @@ import ( cfv3resource "github.com/cloudfoundry-community/go-cfclient/v3/resource" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" @@ -85,10 +86,13 @@ https://docs.cloudfoundry.org/devguide/services`, Optional: true, CustomType: jsontypes.NormalizedType{}, }, - "tags": schema.SetAttribute{ + "tags": schema.ListAttribute{ ElementType: types.StringType, Optional: true, - MarkdownDescription: "Set of tags used by apps to identify service instances. They are shown in the app VCAP_SERVICES env.", + MarkdownDescription: "List of tags used by apps to identify service instances. They are shown in the app VCAP_SERVICES env.", + Validators: []validator.List{ + listvalidator.SizeAtLeast(1), + }, }, "credentials": schema.StringAttribute{ MarkdownDescription: "A JSON object that is made available to apps bound to this service instance of type user-provided.", @@ -288,7 +292,7 @@ func (r *serviceInstanceResource) Create(ctx context.Context, req resource.Creat } createServiceInstance.Parameters = ¶ms } - if !plan.Tags.IsNull() && !plan.Tags.IsUnknown() { + if !plan.Tags.IsNull() { tags, diags := toTagsList(ctx, plan.Tags) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -364,7 +368,7 @@ func (r *serviceInstanceResource) Create(ctx context.Context, req resource.Creat } createServiceInstance.Credentials = &credentials } - if !plan.Tags.IsNull() && !plan.Tags.IsUnknown() { + if !plan.Tags.IsNull() { tags, diags := toTagsList(ctx, plan.Tags) resp.Diagnostics.Append(diags...) if resp.Diagnostics.HasError() { @@ -505,15 +509,13 @@ func (r *serviceInstanceResource) Update(ctx context.Context, req resource.Updat } updateServiceInstance.Parameters = ¶ms } - // check if tag is not null and update the tags - if !plan.Tags.IsNull() && !plan.Tags.IsUnknown() { - tags, diags := toTagsList(ctx, plan.Tags) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - updateServiceInstance.Tags = tags + + tags, diags := toTagsList(ctx, plan.Tags) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } + updateServiceInstance.Tags = tags updateServiceInstance.Metadata, diags = setClientMetadataForUpdate(ctx, previousState.Labels, previousState.Annotations, plan.Labels, plan.Annotations) resp.Diagnostics.Append(diags...) @@ -562,20 +564,17 @@ func (r *serviceInstanceResource) Update(ctx context.Context, req resource.Updat } updateServiceInstance.Credentials = &credentials } - if !plan.SyslogDrainURL.IsNull() { - updateServiceInstance.SyslogDrainURL = plan.SyslogDrainURL.ValueStringPointer() - } - if !plan.RouteServiceURL.IsNull() { - updateServiceInstance.RouteServiceURL = plan.RouteServiceURL.ValueStringPointer() - } - if !plan.Tags.IsNull() && !plan.Tags.IsUnknown() { - tags, diags := toTagsList(ctx, plan.Tags) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { - return - } - updateServiceInstance.Tags = tags + + updateServiceInstance.SyslogDrainURL = plan.SyslogDrainURL.ValueStringPointer() + updateServiceInstance.RouteServiceURL = plan.RouteServiceURL.ValueStringPointer() + + tags, diags := toTagsList(ctx, plan.Tags) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return } + updateServiceInstance.Tags = tags + updateServiceInstance.Metadata, diags = setClientMetadataForUpdate(ctx, previousState.Labels, previousState.Annotations, plan.Labels, plan.Annotations) resp.Diagnostics.Append(diags...) _, err := r.cfClient.ServiceInstances.UpdateUserProvided(ctx, previousState.ID.ValueString(), &updateServiceInstance) diff --git a/internal/provider/types_service_instance.go b/internal/provider/types_service_instance.go index ecdec41..f9cf600 100644 --- a/internal/provider/types_service_instance.go +++ b/internal/provider/types_service_instance.go @@ -21,7 +21,7 @@ type serviceInstanceType struct { ServicePlan types.String `tfsdk:"service_plan"` Parameters jsontypes.Normalized `tfsdk:"parameters"` LastOperation types.Object `tfsdk:"last_operation"` //LastOperationType - Tags types.Set `tfsdk:"tags"` + Tags types.List `tfsdk:"tags"` DashboardURL types.String `tfsdk:"dashboard_url"` Credentials jsontypes.Normalized `tfsdk:"credentials"` SyslogDrainURL types.String `tfsdk:"syslog_drain_url"` @@ -42,7 +42,7 @@ type datasourceServiceInstanceType struct { Space types.String `tfsdk:"space"` ServicePlan types.String `tfsdk:"service_plan"` LastOperation types.Object `tfsdk:"last_operation"` //LastOperationType - Tags types.Set `tfsdk:"tags"` + Tags types.List `tfsdk:"tags"` DashboardURL types.String `tfsdk:"dashboard_url"` SyslogDrainURL types.String `tfsdk:"syslog_drain_url"` RouteServiceURL types.String `tfsdk:"route_service_url"` @@ -126,10 +126,10 @@ func mapDataSourceServiceInstanceValuesToType(ctx context.Context, value *resour for _, t := range value.Tags { tags = append(tags, types.StringValue(t)) } - dsServiceInstanceType.Tags, diags = types.SetValueFrom(ctx, types.StringType, tags) + dsServiceInstanceType.Tags, diags = types.ListValueFrom(ctx, types.StringType, tags) diagnostics.Append(diags...) } else { - dsServiceInstanceType.Tags = types.SetNull(types.StringType) + dsServiceInstanceType.Tags = types.ListNull(types.StringType) } @@ -188,10 +188,10 @@ func mapResourceServiceInstanceValuesToType(ctx context.Context, value *resource for _, t := range value.Tags { tags = append(tags, types.StringValue(t)) } - serviceInstanceType.Tags, diags = types.SetValueFrom(ctx, types.StringType, tags) + serviceInstanceType.Tags, diags = types.ListValueFrom(ctx, types.StringType, tags) diagnostics.Append(diags...) } else { - serviceInstanceType.Tags = types.SetNull(types.StringType) + serviceInstanceType.Tags = types.ListNull(types.StringType) } @@ -233,7 +233,7 @@ func isServiceInstanceUpgradable(ctx context.Context, guid string, c cfv3client. } // toTagsList converts aliases of type types.Set into a slice of strings. -func toTagsList(ctx context.Context, tagsSet types.Set) ([]string, diag.Diagnostics) { +func toTagsList(ctx context.Context, tagsSet types.List) ([]string, diag.Diagnostics) { tags := make([]string, 0, len(tagsSet.Elements())) diags := tagsSet.ElementsAs(ctx, &tags, false)