From 86f603ee49b16b08428a8f66d758856deb1db9e4 Mon Sep 17 00:00:00 2001 From: Murad Biashimov Date: Fri, 10 Jan 2025 14:00:32 +0100 Subject: [PATCH] refactor: ResourceDataSet should not take the schema Resources like service users can't share the code, when the schema is mandatory. --- internal/schemautil/schemautil.go | 53 +++++++++++++------ .../sdkprovider/service/account/account.go | 1 - .../service/account/account_team.go | 1 - .../service/account/account_team_member.go | 2 - .../alloydbomni/alloydbomni_database.go | 2 +- .../service/alloydbomni/alloydbomni_user.go | 2 +- .../service/kafka/kafka_native_acl.go | 4 +- .../sdkprovider/service/kafka/kafka_quota.go | 1 - .../kafka/mirrormaker_replication_flow.go | 2 +- .../organization_application_user.go | 2 +- .../organization_application_user_token.go | 4 +- .../organization/organization_user_group.go | 1 - .../organization_user_list_data_source.go | 2 +- .../organization/organizational_unit.go | 10 +--- internal/sdkprovider/service/pg/pg_user.go | 2 +- 15 files changed, 49 insertions(+), 40 deletions(-) diff --git a/internal/schemautil/schemautil.go b/internal/schemautil/schemautil.go index 5f116c3a6..0013fb415 100644 --- a/internal/schemautil/schemautil.go +++ b/internal/schemautil/schemautil.go @@ -12,6 +12,7 @@ import ( "github.com/aiven/aiven-go-client/v2" "github.com/aiven/go-client-codegen/handler/service" "github.com/docker/go-units" + "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -344,7 +345,12 @@ func CopyServiceUserGenPropertiesFromAPIResponseToTerraform( // // Warning: doesn't support nested sets. // Warning: not tested with nested objects. -func ResourceDataGet(d *schema.ResourceData, dto any, fns ...KVModifier) error { +func ResourceDataGet(d *schema.ResourceData, dto any, fns ...KVModifier) (err error) { + defer func() { + // cty.Value might panic + err = recoverPanic("failed to get resource data") + }() + rawConfig := d.GetRawConfig() if rawConfig.IsNull() { return nil @@ -408,10 +414,15 @@ type KVModifier func(k string, v any) (string, any) // // Use: // -// err := ResourceDataSet(s, d, dto) -func ResourceDataSet(s map[string]*schema.Schema, d *schema.ResourceData, dto any, fns ...KVModifier) error { +// err := ResourceDataSet(d, dto) +func ResourceDataSet(d *schema.ResourceData, dto any, fns ...KVModifier) (err error) { + defer func() { + // cty.Value might panic + err = recoverPanic("failed to set resource data") + }() + var m map[string]any - err := Remarshal(dto, &m) + err = Remarshal(dto, &m) if err != nil { return err } @@ -424,8 +435,9 @@ func ResourceDataSet(s map[string]*schema.Schema, d *schema.ResourceData, dto an } } - m = serializeSet(s, m) - for k := range s { + c := d.GetRawConfig() + m = serializeSet(c, m) + for k := range c.AsValueMap() { if v, ok := m[k]; ok { if err = d.Set(k, v); err != nil { return err @@ -435,28 +447,27 @@ func ResourceDataSet(s map[string]*schema.Schema, d *schema.ResourceData, dto an return nil } -func serializeSet(s map[string]*schema.Schema, m map[string]any) map[string]any { - for k, prop := range s { +func serializeSet(c cty.Value, m map[string]any) map[string]any { + for k, prop := range c.AsValueMap() { value, ok := m[k] if !ok { continue } - res, ok := prop.Elem.(*schema.Resource) - if !ok { - continue - } - // When we have an object, we need to convert it to a list. // So there is no difference between a single object and a list of objects. var items []any switch element := value.(type) { case map[string]any: - items = append(items, serializeSet(res.Schema, element)) + items = append(items, serializeSet(prop, element)) case []any: for _, v := range element { - items = append(items, serializeSet(res.Schema, v.(map[string]any))) + items = append(items, serializeSet(prop, v.(map[string]any))) } + default: + // Scalar types + m[k] = value + continue } m[k] = items @@ -503,3 +514,15 @@ func Remarshal(in, out any) error { } return json.Unmarshal(b, out) } + +func recoverPanic(msg string) error { + r := recover() + switch v := r.(type) { + case nil: + return nil + case error: + return fmt.Errorf("%s: %w", msg, v) + default: + return fmt.Errorf("%s: %v", msg, v) + } +} diff --git a/internal/sdkprovider/service/account/account.go b/internal/sdkprovider/service/account/account.go index 4525bffe7..ad0e97b7f 100644 --- a/internal/sdkprovider/service/account/account.go +++ b/internal/sdkprovider/service/account/account.go @@ -114,7 +114,6 @@ func resourceAccountRead(ctx context.Context, d *schema.ResourceData, client avn } if err = schemautil.ResourceDataSet( - aivenAccountSchema, d, resp, schemautil.RenameAliases(map[string]string{ diff --git a/internal/sdkprovider/service/account/account_team.go b/internal/sdkprovider/service/account/account_team.go index a07edf891..7f190d7ca 100644 --- a/internal/sdkprovider/service/account/account_team.go +++ b/internal/sdkprovider/service/account/account_team.go @@ -98,7 +98,6 @@ func resourceAccountTeamRead(ctx context.Context, d *schema.ResourceData, client } if err = schemautil.ResourceDataSet( - aivenAccountTeamSchema, d, resp, schemautil.RenameAlias("team_name", "name"), diff --git a/internal/sdkprovider/service/account/account_team_member.go b/internal/sdkprovider/service/account/account_team_member.go index 7c25d2bbf..9979f3189 100644 --- a/internal/sdkprovider/service/account/account_team_member.go +++ b/internal/sdkprovider/service/account/account_team_member.go @@ -117,7 +117,6 @@ func resourceAccountTeamMemberRead(ctx context.Context, d *schema.ResourceData, for _, invite := range resp { if invite.UserEmail == userEmail { if err = schemautil.ResourceDataSet( - aivenAccountTeamMemberSchema, d, invite, schemautil.RenameAliases(map[string]string{}), @@ -146,7 +145,6 @@ func resourceAccountTeamMemberRead(ctx context.Context, d *schema.ResourceData, for _, member := range respTI { if member.UserEmail == userEmail { if err = schemautil.ResourceDataSet( - aivenAccountTeamMemberSchema, d, member, ); err != nil { diff --git a/internal/sdkprovider/service/alloydbomni/alloydbomni_database.go b/internal/sdkprovider/service/alloydbomni/alloydbomni_database.go index 83fbc9311..3edc266e7 100644 --- a/internal/sdkprovider/service/alloydbomni/alloydbomni_database.go +++ b/internal/sdkprovider/service/alloydbomni/alloydbomni_database.go @@ -91,7 +91,7 @@ func resourceAlloyDBOmniDatabaseRead(ctx context.Context, d *schema.ResourceData return err } - return schemautil.ResourceDataSet(aivenAlloyDBOmniDatabaseSchema, d, db) + return schemautil.ResourceDataSet(d, db) } func resourceAlloyDBOmniDatabaseDelete(ctx context.Context, d *schema.ResourceData, client avngen.Client) error { diff --git a/internal/sdkprovider/service/alloydbomni/alloydbomni_user.go b/internal/sdkprovider/service/alloydbomni/alloydbomni_user.go index 2b7202469..4f4174e21 100644 --- a/internal/sdkprovider/service/alloydbomni/alloydbomni_user.go +++ b/internal/sdkprovider/service/alloydbomni/alloydbomni_user.go @@ -169,7 +169,7 @@ func resourceAlloyDBOmniUserRead(ctx context.Context, d *schema.ResourceData, cl return schemautil.ResourceReadHandleNotFound(err, d) } - err = schemautil.ResourceDataSet(aivenAlloyDBOmniUserSchema, d, user) + err = schemautil.ResourceDataSet(d, user) if err != nil { return err } diff --git a/internal/sdkprovider/service/kafka/kafka_native_acl.go b/internal/sdkprovider/service/kafka/kafka_native_acl.go index f2484bae4..567735702 100644 --- a/internal/sdkprovider/service/kafka/kafka_native_acl.go +++ b/internal/sdkprovider/service/kafka/kafka_native_acl.go @@ -104,7 +104,7 @@ func resourceKafkaNativeACLCreate(ctx context.Context, d *schema.ResourceData, c return err } - err = schemautil.ResourceDataSet(aivenKafkaNativeACLSchema, d, acl) + err = schemautil.ResourceDataSet(d, acl) if err != nil { return err } @@ -129,7 +129,7 @@ func resourceKafkaNativeACLRead(ctx context.Context, d *schema.ResourceData, cli return err } - err = schemautil.ResourceDataSet(aivenKafkaNativeACLSchema, d, acl) + err = schemautil.ResourceDataSet(d, acl) return err } diff --git a/internal/sdkprovider/service/kafka/kafka_quota.go b/internal/sdkprovider/service/kafka/kafka_quota.go index 8c4687cc8..95fd6533f 100644 --- a/internal/sdkprovider/service/kafka/kafka_quota.go +++ b/internal/sdkprovider/service/kafka/kafka_quota.go @@ -180,7 +180,6 @@ func resourceKafkaQuotaRead(ctx context.Context, d *schema.ResourceData, client } return schemautil.ResourceDataSet( - aivenKafkaQuotaSchema, d, resp, schemautil.RenameAliasesReverse(quotaFieldsAliases), diff --git a/internal/sdkprovider/service/kafka/mirrormaker_replication_flow.go b/internal/sdkprovider/service/kafka/mirrormaker_replication_flow.go index 0d3f02d2a..1653f6cc7 100644 --- a/internal/sdkprovider/service/kafka/mirrormaker_replication_flow.go +++ b/internal/sdkprovider/service/kafka/mirrormaker_replication_flow.go @@ -189,7 +189,7 @@ func resourceMirrorMakerReplicationFlowRead(ctx context.Context, d *schema.Resou } err = schemautil.ResourceDataSet( - aivenMirrorMakerReplicationFlowSchema, d, dto, schemautil.RenameAliasesReverse(dtoFieldsAliases), + d, dto, schemautil.RenameAliasesReverse(dtoFieldsAliases), func(k string, v any) (string, any) { if k == configPropsKey { // This field is received as a string diff --git a/internal/sdkprovider/service/organization/organization_application_user.go b/internal/sdkprovider/service/organization/organization_application_user.go index 09f87f3cd..29c015cd1 100644 --- a/internal/sdkprovider/service/organization/organization_application_user.go +++ b/internal/sdkprovider/service/organization/organization_application_user.go @@ -107,7 +107,7 @@ func resourceOrganizationApplicationUserRead(ctx context.Context, d *schema.Reso } // Sets name and user_id - err = schemautil.ResourceDataSet(aivenOrganizationApplicationUserSchema, d, user) + err = schemautil.ResourceDataSet(d, user) if err != nil { return err } diff --git a/internal/sdkprovider/service/organization/organization_application_user_token.go b/internal/sdkprovider/service/organization/organization_application_user_token.go index 7f7926259..40b11cfde 100644 --- a/internal/sdkprovider/service/organization/organization_application_user_token.go +++ b/internal/sdkprovider/service/organization/organization_application_user_token.go @@ -141,7 +141,7 @@ func resourceOrganizationApplicationUserTokenCreate(ctx context.Context, d *sche return err } - err = schemautil.ResourceDataSet(aivenOrganizationApplicationUserTokenSchema, d, token) + err = schemautil.ResourceDataSet(d, token) if err != nil { return err } @@ -173,7 +173,7 @@ func resourceOrganizationApplicationUserTokenRead(ctx context.Context, d *schema return fmt.Errorf("application user token not found") } - err = schemautil.ResourceDataSet(aivenOrganizationApplicationUserTokenSchema, d, token) + err = schemautil.ResourceDataSet(d, token) if err != nil { return err } diff --git a/internal/sdkprovider/service/organization/organization_user_group.go b/internal/sdkprovider/service/organization/organization_user_group.go index 6bd0c271f..ebbcf56b3 100644 --- a/internal/sdkprovider/service/organization/organization_user_group.go +++ b/internal/sdkprovider/service/organization/organization_user_group.go @@ -100,7 +100,6 @@ func resourceOrganizationUserGroupRead(ctx context.Context, d *schema.ResourceDa } if err = schemautil.ResourceDataSet( - aivenOrganizationUserGroupSchema, d, resp, schemautil.RenameAliases(map[string]string{ diff --git a/internal/sdkprovider/service/organization/organization_user_list_data_source.go b/internal/sdkprovider/service/organization/organization_user_list_data_source.go index fce852517..13b2230aa 100644 --- a/internal/sdkprovider/service/organization/organization_user_list_data_source.go +++ b/internal/sdkprovider/service/organization/organization_user_list_data_source.go @@ -151,7 +151,7 @@ func datasourceOrganizationUserListRead(ctx context.Context, d *schema.ResourceD d.SetId(organizationID) users := map[string]any{"users": list} - return schemautil.ResourceDataSet(datasourceOrganizationUserListSchema(), d, users) + return schemautil.ResourceDataSet(d, users) } func GetOrganizationByName(ctx context.Context, client avngen.Client, name string) (string, error) { diff --git a/internal/sdkprovider/service/organization/organizational_unit.go b/internal/sdkprovider/service/organization/organizational_unit.go index 5e55015dd..1af465cb9 100644 --- a/internal/sdkprovider/service/organization/organizational_unit.go +++ b/internal/sdkprovider/service/organization/organizational_unit.go @@ -109,15 +109,7 @@ func resourceOrganizationalUnitRead(ctx context.Context, d *schema.ResourceData, } } - if err = schemautil.ResourceDataSet( - aivenOrganizationalUnitSchema, - d, - resp, - ); err != nil { - return err - } - - return nil + return schemautil.ResourceDataSet(d, resp) } func determineMixedOrganizationConstraintIDToStore( diff --git a/internal/sdkprovider/service/pg/pg_user.go b/internal/sdkprovider/service/pg/pg_user.go index b69cd59ff..c38dac2d6 100644 --- a/internal/sdkprovider/service/pg/pg_user.go +++ b/internal/sdkprovider/service/pg/pg_user.go @@ -156,7 +156,7 @@ func ReadResourcePGUser(ctx context.Context, d *schema.ResourceData, client avng return schemautil.ResourceReadHandleNotFound(err, d) } - err = schemautil.ResourceDataSet(SchemaResourcePGUser, d, user) + err = schemautil.ResourceDataSet(d, user) if err != nil { return err }