diff --git a/.genignore b/.genignore index e9c8d6040..b60da54ec 100644 --- a/.genignore +++ b/.genignore @@ -1 +1,2 @@ internal/provider/connection_resource.go +internal/provider/connection_data_resource.go diff --git a/airbyte.yaml b/airbyte.yaml index 0ad62a244..a2d6ffd61 100644 --- a/airbyte.yaml +++ b/airbyte.yaml @@ -22463,6 +22463,7 @@ components: properties: streams: type: "array" + format: "set" items: $ref: "#/components/schemas/StreamConfiguration" x-speakeasy-component: true diff --git a/gen.yaml b/gen.yaml index fc4cb8367..911bc9d34 100755 --- a/gen.yaml +++ b/gen.yaml @@ -11,7 +11,7 @@ generation: oAuth2ClientCredentialsEnabled: true telemetryEnabled: true terraform: - version: 0.6.0 + version: 0.7.0 additionalDataSources: [] additionalDependencies: {} additionalResources: [] diff --git a/go.mod b/go.mod index ab6fc319a..086550ea3 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/airbytehq/terraform-provider-airbyte go 1.21 -toolchain go1.21.10 +toolchain go1.22.1 require ( github.com/cenkalti/backoff/v4 v4.2.0 diff --git a/internal/planmodifiers/setplanmodifier/unique_by_key.go b/internal/planmodifiers/setplanmodifier/unique_by_key.go index 21ac2f212..376c52abc 100644 --- a/internal/planmodifiers/setplanmodifier/unique_by_key.go +++ b/internal/planmodifiers/setplanmodifier/unique_by_key.go @@ -2,6 +2,7 @@ package setplanmodifier import ( "context" + "fmt" "github.com/airbytehq/terraform-provider-airbyte/internal/planmodifiers/utils" @@ -9,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/types" ) -// UniqueByKey returnsa plan modifier that identifies each item in a set by a primary key (e.g name) +// UniqueByKey returns plan modifier that identifies each item in a set by a primary key (e.g name) func UniqueByKey(key string) planmodifier.Set { return uniqueByKey{ key: key, @@ -42,14 +43,59 @@ func (m uniqueByKey) PlanModifySet(ctx context.Context, req planmodifier.SetRequ return } - planList := req.PlanValue.Elements() - //planItemsByKey := make(map[string]types.Object) - for i := 0; i < len(planList); i++ { - var set types.Set - diags := req.Plan.GetAttribute(ctx, req.Path, &set) - resp.Diagnostics.Append(diags...) - if resp.Diagnostics.HasError() { + // Create a map of all of the request plan elements, keyed by `m.key` + elementsByKey := make(map[string]types.Object) + for _, elem := range req.PlanValue.Elements() { + obj, ok := elem.(types.Object) + if !ok { + resp.Diagnostics.AddError( + "Error modifying set", + fmt.Sprintf("Expected object element, got %T", elem), + ) return } + + v, ok := obj.Attributes()[m.key] + if ok { + elementsByKey[v.String()] = obj + } } + + var updatedElements []types.Object + + // Walk all the elements in the response plan and update any fields that have either an unknown or unset value + for _, elem := range resp.PlanValue.Elements() { + obj, ok := elem.(types.Object) + if !ok { + resp.Diagnostics.AddError( + "Error modifying set", + fmt.Sprintf("Expected object element, got %T", elem), + ) + return + } + + elemKey := obj.Attributes()[m.key] + srcObj, ok := elementsByKey[elemKey.String()] + if !ok { + resp.Diagnostics.AddError( + "Error modifying set", + fmt.Sprintf("No object found with %s=%s", m.key, elemKey.String()), + ) + return + } + + for k, v := range srcObj.Attributes() { + obj.Attributes()[k] = v + } + + updatedElements = append(updatedElements, obj) + } + + newPlanValue, diags := types.SetValueFrom(ctx, resp.PlanValue.ElementType(ctx), updatedElements) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + resp.PlanValue = newPlanValue } diff --git a/internal/provider/connection_data_source.go b/internal/provider/connection_data_source.go index 952c8fe6e..00c65f324 100644 --- a/internal/provider/connection_data_source.go +++ b/internal/provider/connection_data_source.go @@ -58,7 +58,7 @@ func (r *ConnectionDataSource) Schema(ctx context.Context, req datasource.Schema "configurations": schema.SingleNestedAttribute{ Computed: true, Attributes: map[string]schema.Attribute{ - "streams": schema.ListNestedAttribute{ + "streams": schema.SetNestedAttribute{ Computed: true, NestedObject: schema.NestedAttributeObject{ Attributes: map[string]schema.Attribute{