From 99037420fe93cdba19aef2a343dbf2c598e3ca53 Mon Sep 17 00:00:00 2001 From: Murad Biashimov Date: Tue, 19 Mar 2024 13:29:44 +0100 Subject: [PATCH] fix(aiven_service_integration_endpoint): can't create external_postgresql (#1650) --- CHANGELOG.md | 1 + internal/schemautil/service.go | 29 +++---- .../service/cassandra/cassandra.go | 5 +- .../service/clickhouse/clickhouse.go | 4 +- .../service/dragonfly/dragonfly.go | 5 +- internal/sdkprovider/service/flink/flink.go | 5 +- .../sdkprovider/service/grafana/grafana.go | 4 +- .../sdkprovider/service/influxdb/influxdb.go | 5 +- internal/sdkprovider/service/kafka/kafka.go | 4 +- .../service/kafka/kafka_connect.go | 9 +- .../service/kafka/kafka_mirrormaker.go | 9 +- .../sdkprovider/service/m3db/m3aggregator.go | 9 +- internal/sdkprovider/service/m3db/m3db.go | 5 +- internal/sdkprovider/service/mysql/mysql.go | 5 +- .../service/opensearch/opensearch.go | 5 +- internal/sdkprovider/service/pg/pg.go | 9 +- internal/sdkprovider/service/redis/redis.go | 5 +- .../serviceintegration/service_integration.go | 12 +-- .../service_integration_endpoint.go | 50 +++++------ .../service_integration_endpoint_test.go | 48 +++++++++++ .../userconfig/converters/converters.go | 82 ++++++++++++++++--- 21 files changed, 179 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 325e31d13..ff377475f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ nav_order: 1 - Add `external_aws_cloudwatch_logs`, `external_elasticsearch_logs_user_config`, `external_opensearch_logs_user_config`, `prometheus_user_config` service integration configs - Fix `aiven_kafka_schema` Protobuf normalization +- Fix `aiven_service_integration_endpoint` for `external_postgresql` type - Add `AIVEN_ALLOW_IP_FILTER_PURGE` environment variable to allow purging of IP filters. This is a safety feature to prevent accidental purging of IP filters, which can lead to loss of access to services. To enable purging, set the environment variable to any value before running Terraform commands. diff --git a/internal/schemautil/service.go b/internal/schemautil/service.go index 4ce618aa8..b28794903 100644 --- a/internal/schemautil/service.go +++ b/internal/schemautil/service.go @@ -15,7 +15,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/converters" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) // defaultTimeout is the default timeout for service operations. This is not a const because it can be changed during @@ -61,6 +60,12 @@ var TechEmailsResourceSchema = &schema.Resource{ }, } +func ServiceCommonSchemaWithUserConfig(kind string) map[string]*schema.Schema { + s := ServiceCommonSchema() + converters.SetUserConfig(converters.ServiceUserConfig, kind, s) + return s +} + func ServiceCommonSchema() map[string]*schema.Schema { return map[string]*schema.Schema{ "project": CommonSchemaProjectReference, @@ -440,9 +445,7 @@ func resourceServiceCreate(ctx context.Context, d *schema.ResourceData, m interf cuc, err := ExpandService(serviceType, d) if err != nil { - return diag.Errorf( - "error converting user config options for service type %s to API format: %s", serviceType, err, - ) + return diag.FromErr(err) } _, err = client.Services.Create( @@ -529,9 +532,7 @@ func ResourceServiceUpdate(ctx context.Context, d *schema.ResourceData, m interf serviceType := d.Get("service_type").(string) cuc, err := ExpandService(serviceType, d) if err != nil { - return diag.Errorf( - "error converting user config options for service type %s to API format: %s", serviceType, err, - ) + return diag.FromErr(err) } if _, err := client.Services.Update( @@ -713,15 +714,11 @@ func copyServicePropertiesFromAPIResponseToTerraform( } } - newUserConfig, err := FlattenService(serviceType, d, s.UserConfig) + err := FlattenService(serviceType, d, s.UserConfig) if err != nil { return err } - if err := d.Set(serviceType+"_user_config", newUserConfig); err != nil { - return fmt.Errorf("cannot set `%s_user_config` : %w; Please make sure that all Aiven services have unique s names", serviceType, err) - } - params := s.URIParams if err := d.Set("service_host", params["host"]); err != nil { return err @@ -886,10 +883,10 @@ func getContactEmailListForAPI(d *schema.ResourceData, field string) *[]aiven.Co return &results } -func ExpandService(kind string, d *schema.ResourceData) (map[string]any, error) { - return converters.Expand(kind, service.GetUserConfig(kind), d) +func ExpandService(name string, d *schema.ResourceData) (map[string]any, error) { + return converters.Expand(converters.ServiceUserConfig, name, d) } -func FlattenService(kind string, d *schema.ResourceData, dto map[string]any) ([]map[string]any, error) { - return converters.Flatten(kind, service.GetUserConfig(kind), d, dto) +func FlattenService(name string, d *schema.ResourceData, dto map[string]any) error { + return converters.Flatten(converters.ServiceUserConfig, name, d, dto) } diff --git a/internal/sdkprovider/service/cassandra/cassandra.go b/internal/sdkprovider/service/cassandra/cassandra.go index a141c1e19..14751a955 100644 --- a/internal/sdkprovider/service/cassandra/cassandra.go +++ b/internal/sdkprovider/service/cassandra/cassandra.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func cassandraSchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeCassandra) s[schemautil.ServiceTypeCassandra] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -19,8 +18,6 @@ func cassandraSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - s[schemautil.ServiceTypeCassandra+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeCassandra) - return s } diff --git a/internal/sdkprovider/service/clickhouse/clickhouse.go b/internal/sdkprovider/service/clickhouse/clickhouse.go index b7ab4d006..5a9c5d05f 100644 --- a/internal/sdkprovider/service/clickhouse/clickhouse.go +++ b/internal/sdkprovider/service/clickhouse/clickhouse.go @@ -5,11 +5,10 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/aiven/terraform-provider-aiven/internal/schemautil" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func clickhouseSchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeClickhouse) s[schemautil.ServiceTypeClickhouse] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -18,7 +17,6 @@ func clickhouseSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - s[schemautil.ServiceTypeClickhouse+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeClickhouse) s["service_integrations"] = &schema.Schema{ Type: schema.TypeList, Optional: true, diff --git a/internal/sdkprovider/service/dragonfly/dragonfly.go b/internal/sdkprovider/service/dragonfly/dragonfly.go index 015d53f47..73b5ca7ae 100644 --- a/internal/sdkprovider/service/dragonfly/dragonfly.go +++ b/internal/sdkprovider/service/dragonfly/dragonfly.go @@ -5,11 +5,10 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/aiven/terraform-provider-aiven/internal/schemautil" - "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/dist" ) func dragonflySchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeDragonfly) s[schemautil.ServiceTypeDragonfly] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -18,8 +17,6 @@ func dragonflySchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - s[schemautil.ServiceTypeDragonfly+"_user_config"] = dist.ServiceTypeDragonfly() - return s } diff --git a/internal/sdkprovider/service/flink/flink.go b/internal/sdkprovider/service/flink/flink.go index d40d3b601..d903cfb7f 100644 --- a/internal/sdkprovider/service/flink/flink.go +++ b/internal/sdkprovider/service/flink/flink.go @@ -10,11 +10,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenFlinkSchema() map[string]*schema.Schema { - aivenFlinkSchema := schemautil.ServiceCommonSchema() + aivenFlinkSchema := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeFlink) aivenFlinkSchema[schemautil.ServiceTypeFlink] = &schema.Schema{ Type: schema.TypeList, MaxItems: 1, @@ -35,8 +34,6 @@ func aivenFlinkSchema() map[string]*schema.Schema { }, }, } - aivenFlinkSchema[schemautil.ServiceTypeFlink+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeFlink) - return aivenFlinkSchema } diff --git a/internal/sdkprovider/service/grafana/grafana.go b/internal/sdkprovider/service/grafana/grafana.go index befe69c77..adeb56820 100644 --- a/internal/sdkprovider/service/grafana/grafana.go +++ b/internal/sdkprovider/service/grafana/grafana.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func grafanaSchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeGrafana) s[schemautil.ServiceTypeGrafana] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -19,7 +18,6 @@ func grafanaSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - s[schemautil.ServiceTypeGrafana+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeGrafana) return s } diff --git a/internal/sdkprovider/service/influxdb/influxdb.go b/internal/sdkprovider/service/influxdb/influxdb.go index 6e4a7dc46..5d4ca56a0 100644 --- a/internal/sdkprovider/service/influxdb/influxdb.go +++ b/internal/sdkprovider/service/influxdb/influxdb.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func influxDBSchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeInfluxDB) s[schemautil.ServiceTypeInfluxDB] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -25,8 +24,6 @@ func influxDBSchema() map[string]*schema.Schema { }, }, } - s[schemautil.ServiceTypeInfluxDB+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeInfluxDB) - return s } diff --git a/internal/sdkprovider/service/kafka/kafka.go b/internal/sdkprovider/service/kafka/kafka.go index 9fc738555..2f52ac6a6 100644 --- a/internal/sdkprovider/service/kafka/kafka.go +++ b/internal/sdkprovider/service/kafka/kafka.go @@ -11,11 +11,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenKafkaSchema() map[string]*schema.Schema { - aivenKafkaSchema := schemautil.ServiceCommonSchema() + aivenKafkaSchema := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeKafka) aivenKafkaSchema["karapace"] = &schema.Schema{ Type: schema.TypeBool, Optional: true, @@ -70,7 +69,6 @@ func aivenKafkaSchema() map[string]*schema.Schema { }, }, } - aivenKafkaSchema[schemautil.ServiceTypeKafka+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeKafka) return aivenKafkaSchema } diff --git a/internal/sdkprovider/service/kafka/kafka_connect.go b/internal/sdkprovider/service/kafka/kafka_connect.go index 90ed59498..b164e16a3 100644 --- a/internal/sdkprovider/service/kafka/kafka_connect.go +++ b/internal/sdkprovider/service/kafka/kafka_connect.go @@ -6,12 +6,11 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenKafkaConnectSchema() map[string]*schema.Schema { - kafkaConnectSchema := schemautil.ServiceCommonSchema() - kafkaConnectSchema[schemautil.ServiceTypeKafkaConnect] = &schema.Schema{ + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeKafkaConnect) + s[schemautil.ServiceTypeKafkaConnect] = &schema.Schema{ Type: schema.TypeList, Computed: true, Description: "Kafka Connect server provided values", @@ -19,9 +18,7 @@ func aivenKafkaConnectSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - kafkaConnectSchema[schemautil.ServiceTypeKafkaConnect+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeKafkaConnect) - - return kafkaConnectSchema + return s } func ResourceKafkaConnect() *schema.Resource { diff --git a/internal/sdkprovider/service/kafka/kafka_mirrormaker.go b/internal/sdkprovider/service/kafka/kafka_mirrormaker.go index 589241239..6489a5f75 100644 --- a/internal/sdkprovider/service/kafka/kafka_mirrormaker.go +++ b/internal/sdkprovider/service/kafka/kafka_mirrormaker.go @@ -6,12 +6,11 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenKafkaMirrormakerSchema() map[string]*schema.Schema { - kafkaMMSchema := schemautil.ServiceCommonSchema() - kafkaMMSchema[schemautil.ServiceTypeKafkaMirrormaker] = &schema.Schema{ + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeKafkaMirrormaker) + s[schemautil.ServiceTypeKafkaMirrormaker] = &schema.Schema{ Type: schema.TypeList, Computed: true, Description: "Kafka MirrorMaker 2 server provided values", @@ -19,9 +18,7 @@ func aivenKafkaMirrormakerSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - kafkaMMSchema[schemautil.ServiceTypeKafkaMirrormaker+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeKafkaMirrormaker) - - return kafkaMMSchema + return s } func ResourceKafkaMirrormaker() *schema.Resource { return &schema.Resource{ diff --git a/internal/sdkprovider/service/m3db/m3aggregator.go b/internal/sdkprovider/service/m3db/m3aggregator.go index 6e0593a34..d149e1e00 100644 --- a/internal/sdkprovider/service/m3db/m3aggregator.go +++ b/internal/sdkprovider/service/m3db/m3aggregator.go @@ -6,12 +6,11 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenM3AggregatorSchema() map[string]*schema.Schema { - schemaM3 := schemautil.ServiceCommonSchema() - schemaM3[schemautil.ServiceTypeM3Aggregator] = &schema.Schema{ + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeM3Aggregator) + s[schemautil.ServiceTypeM3Aggregator] = &schema.Schema{ Type: schema.TypeList, Computed: true, Description: "M3 aggregator specific server provided values", @@ -19,9 +18,7 @@ func aivenM3AggregatorSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - schemaM3[schemautil.ServiceTypeM3Aggregator+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeM3Aggregator) - - return schemaM3 + return s } func ResourceM3Aggregator() *schema.Resource { return &schema.Resource{ diff --git a/internal/sdkprovider/service/m3db/m3db.go b/internal/sdkprovider/service/m3db/m3db.go index e4ae79567..6aeec941f 100644 --- a/internal/sdkprovider/service/m3db/m3db.go +++ b/internal/sdkprovider/service/m3db/m3db.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenM3DBSchema() map[string]*schema.Schema { - schemaM3 := schemautil.ServiceCommonSchema() + schemaM3 := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeM3) schemaM3[schemautil.ServiceTypeM3] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -19,8 +18,6 @@ func aivenM3DBSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - schemaM3[schemautil.ServiceTypeM3+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeM3) - return schemaM3 } func ResourceM3DB() *schema.Resource { diff --git a/internal/sdkprovider/service/mysql/mysql.go b/internal/sdkprovider/service/mysql/mysql.go index 11f3a0c7d..a6fdde84f 100644 --- a/internal/sdkprovider/service/mysql/mysql.go +++ b/internal/sdkprovider/service/mysql/mysql.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenMySQLSchema() map[string]*schema.Schema { - schemaMySQL := schemautil.ServiceCommonSchema() + schemaMySQL := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeMySQL) schemaMySQL[schemautil.ServiceTypeMySQL] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -19,8 +18,6 @@ func aivenMySQLSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - schemaMySQL[schemautil.ServiceTypeMySQL+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeMySQL) - return schemaMySQL } func ResourceMySQL() *schema.Resource { diff --git a/internal/sdkprovider/service/opensearch/opensearch.go b/internal/sdkprovider/service/opensearch/opensearch.go index 2478b8538..6f3ebdd1f 100644 --- a/internal/sdkprovider/service/opensearch/opensearch.go +++ b/internal/sdkprovider/service/opensearch/opensearch.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func opensearchSchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeOpenSearch) s[schemautil.ServiceTypeOpenSearch] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -26,8 +25,6 @@ func opensearchSchema() map[string]*schema.Schema { }, }, } - s[schemautil.ServiceTypeOpenSearch+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeOpenSearch) - return s } diff --git a/internal/sdkprovider/service/pg/pg.go b/internal/sdkprovider/service/pg/pg.go index a6d85cd19..48a38e546 100644 --- a/internal/sdkprovider/service/pg/pg.go +++ b/internal/sdkprovider/service/pg/pg.go @@ -13,12 +13,11 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func aivenPGSchema() map[string]*schema.Schema { - schemaPG := schemautil.ServiceCommonSchema() - schemaPG[schemautil.ServiceTypePG] = &schema.Schema{ + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypePG) + s[schemautil.ServiceTypePG] = &schema.Schema{ Type: schema.TypeList, MaxItems: 1, Computed: true, @@ -78,9 +77,7 @@ func aivenPGSchema() map[string]*schema.Schema { }, }, } - schemaPG[schemautil.ServiceTypePG+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypePG) - - return schemaPG + return s } func ResourcePG() *schema.Resource { diff --git a/internal/sdkprovider/service/redis/redis.go b/internal/sdkprovider/service/redis/redis.go index 985de4efd..2fc88af86 100644 --- a/internal/sdkprovider/service/redis/redis.go +++ b/internal/sdkprovider/service/redis/redis.go @@ -6,11 +6,10 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/schemautil" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" - "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" ) func redisSchema() map[string]*schema.Schema { - s := schemautil.ServiceCommonSchema() + s := schemautil.ServiceCommonSchemaWithUserConfig(schemautil.ServiceTypeRedis) s[schemautil.ServiceTypeRedis] = &schema.Schema{ Type: schema.TypeList, Computed: true, @@ -19,8 +18,6 @@ func redisSchema() map[string]*schema.Schema { Schema: map[string]*schema.Schema{}, }, } - s[schemautil.ServiceTypeRedis+"_user_config"] = service.GetUserConfig(schemautil.ServiceTypeRedis) - return s } diff --git a/internal/sdkprovider/service/serviceintegration/service_integration.go b/internal/sdkprovider/service/serviceintegration/service_integration.go index 51d313a93..7818f94d7 100644 --- a/internal/sdkprovider/service/serviceintegration/service_integration.go +++ b/internal/sdkprovider/service/serviceintegration/service_integration.go @@ -82,7 +82,7 @@ func aivenServiceIntegrationSchema() map[string]*schema.Schema { // Adds user configs for _, k := range serviceintegration.UserConfigTypes() { - s[k+"_user_config"] = serviceintegration.GetUserConfig(k) + converters.SetUserConfig(converters.ServiceIntegrationUserConfig, k, s) } return s } @@ -144,7 +144,7 @@ func resourceServiceIntegrationCreate(ctx context.Context, d *schema.ResourceDat } if hasIntegrationConfig(integrationType) { - uc, err := converters.Expand(integrationType, serviceintegration.GetUserConfig(integrationType), d) + uc, err := converters.Expand(converters.ServiceIntegrationUserConfig, integrationType, d) if err != nil { return diag.FromErr(err) } @@ -359,16 +359,10 @@ func resourceServiceIntegrationCopyAPIResponseToTerraform( } if hasIntegrationConfig(integrationType) { - userConfig, err := converters.Flatten(integrationType, serviceintegration.GetUserConfig(integrationType), d, res.UserConfig) + err := converters.Flatten(converters.ServiceIntegrationUserConfig, integrationType, d, res.UserConfig) if err != nil { return err } - if len(userConfig) > 0 { - err := d.Set(integrationType+"_user_config", userConfig) - if err != nil { - return err - } - } } return nil diff --git a/internal/sdkprovider/service/serviceintegration/service_integration_endpoint.go b/internal/sdkprovider/service/serviceintegration/service_integration_endpoint.go index eee32f757..b7ec9bc88 100644 --- a/internal/sdkprovider/service/serviceintegration/service_integration_endpoint.go +++ b/internal/sdkprovider/service/serviceintegration/service_integration_endpoint.go @@ -13,8 +13,6 @@ import ( "github.com/aiven/terraform-provider-aiven/internal/common" "github.com/aiven/terraform-provider-aiven/internal/schemautil" - "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig" - "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/apiconvert" "github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig/stateupgrader" "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/converters" "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/serviceintegrationendpoint" @@ -24,15 +22,6 @@ func hasEndpointConfig(kind string) bool { return slices.Contains(serviceintegrationendpoint.UserConfigTypes(), kind) } -func endpointUserConfigKey(kind string) string { - switch kind { - case "external_google_cloud_bigquery", "external_postgresql": - // legacy fields - return kind - } - return kind + "_user_config" -} - func aivenServiceIntegrationEndpointSchema() map[string]*schema.Schema { s := map[string]*schema.Schema{ "project": { @@ -65,7 +54,7 @@ func aivenServiceIntegrationEndpointSchema() map[string]*schema.Schema { // Adds user configs for _, k := range serviceintegrationendpoint.UserConfigTypes() { - s[endpointUserConfigKey(k)] = serviceintegrationendpoint.GetUserConfig(k) + converters.SetUserConfig(converters.ServiceIntegrationEndpointUserConfig, k, s) } return s } @@ -96,14 +85,17 @@ func resourceServiceIntegrationEndpointCreate(ctx context.Context, d *schema.Res req := aiven.CreateServiceIntegrationEndpointRequest{ EndpointName: d.Get("endpoint_name").(string), EndpointType: endpointType, + UserConfig: make(map[string]interface{}), } if hasEndpointConfig(endpointType) { - uc, err := converters.Expand(endpointType, serviceintegrationendpoint.GetUserConfig(endpointType), d) + uc, err := converters.Expand(converters.ServiceIntegrationEndpointUserConfig, endpointType, d) if err != nil { return diag.FromErr(err) } - req.UserConfig = uc + if uc != nil { + req.UserConfig = uc + } } endpoint, err := client.ServiceIntegrationEndpoints.Create(ctx, projectName, req) @@ -147,20 +139,21 @@ func resourceServiceIntegrationEndpointUpdate(ctx context.Context, d *schema.Res } endpointType := d.Get("endpoint_type").(string) + req := aiven.UpdateServiceIntegrationEndpointRequest{ + UserConfig: make(map[string]interface{}), + } - userConfig, err := apiconvert.ToAPI(userconfig.IntegrationEndpointTypes, endpointType, d) - if err != nil { - return diag.FromErr(err) + if hasEndpointConfig(endpointType) { + uc, err := converters.Expand(converters.ServiceIntegrationEndpointUserConfig, endpointType, d) + if err != nil { + return diag.FromErr(err) + } + if uc != nil { + req.UserConfig = uc + } } - _, err = client.ServiceIntegrationEndpoints.Update( - ctx, - projectName, - endpointID, - aiven.UpdateServiceIntegrationEndpointRequest{ - UserConfig: userConfig, - }, - ) + _, err = client.ServiceIntegrationEndpoints.Update(ctx, projectName, endpointID, req) if err != nil { return diag.FromErr(err) } @@ -213,15 +206,10 @@ func copyServiceIntegrationEndpointPropertiesFromAPIResponseToTerraform( } if hasEndpointConfig(endpointType) { - userConfig, err := converters.Flatten(endpointType, serviceintegrationendpoint.GetUserConfig(endpointType), d, endpoint.UserConfig) + err := converters.Flatten(converters.ServiceIntegrationEndpointUserConfig, endpointType, d, endpoint.UserConfig) if err != nil { return err } - if len(userConfig) > 0 { - if err := d.Set(endpointUserConfigKey(endpointType), userConfig); err != nil { - return err - } - } } return nil } diff --git a/internal/sdkprovider/service/serviceintegration/service_integration_endpoint_test.go b/internal/sdkprovider/service/serviceintegration/service_integration_endpoint_test.go index 6ed61c6b0..ce29d3973 100644 --- a/internal/sdkprovider/service/serviceintegration/service_integration_endpoint_test.go +++ b/internal/sdkprovider/service/serviceintegration/service_integration_endpoint_test.go @@ -283,3 +283,51 @@ func testAccCheckAivenServiceEndpointIntegrationAttributes(n string) resource.Te return nil } } + +func TestAccAivenServiceIntegrationEndpointExternalPostgresql(t *testing.T) { + resourceName := "aiven_service_integration_endpoint.pg" + rName := acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acc.TestAccPreCheck(t) }, + ProtoV6ProviderFactories: acc.TestProtoV6ProviderFactories, + CheckDestroy: testAccCheckAivenServiceIntegraitonEndpointResourceDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAivenServiceIntegrationEndpointExternalPostgresql(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAivenServiceEndpointIntegrationAttributes(resourceName), + resource.TestCheckResourceAttr(resourceName, "project", os.Getenv("AIVEN_PROJECT_NAME")), + resource.TestCheckResourceAttr(resourceName, "endpoint_type", "external_postgresql"), + resource.TestCheckResourceAttr(resourceName, "external_postgresql.0.port", "1234"), + resource.TestCheckResourceAttr(resourceName, "external_postgresql.0.ssl_mode", "disable"), + ), + }, + }, + }) +} + +func testAccAivenServiceIntegrationEndpointExternalPostgresql(name string) string { + return fmt.Sprintf(` +resource "aiven_pg" "pg" { + project = %q + cloud_name = "google-europe-west1" + plan = "startup-4" + service_name = "test-acc-sr-pg-%s" +} + + +resource "aiven_service_integration_endpoint" "pg" { + project = aiven_pg.pg.project + endpoint_name = "test-acc-external-postgresql-%s" + endpoint_type = "external_postgresql" + + external_postgresql { + username = aiven_pg.pg.service_username + password = aiven_pg.pg.service_password + host = aiven_pg.pg.service_host + port = 1234 + ssl_mode = "disable" + } +} +`, os.Getenv("AIVEN_PROJECT_NAME"), name, name) +} diff --git a/internal/sdkprovider/userconfig/converters/converters.go b/internal/sdkprovider/userconfig/converters/converters.go index 49f677bf8..343a777fc 100644 --- a/internal/sdkprovider/userconfig/converters/converters.go +++ b/internal/sdkprovider/userconfig/converters/converters.go @@ -21,6 +21,10 @@ import ( "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/service" + "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/serviceintegration" + "github.com/aiven/terraform-provider-aiven/internal/sdkprovider/userconfig/serviceintegrationendpoint" ) const ( @@ -28,14 +32,61 @@ const ( AllowIPFilterPurge = "AIVEN_ALLOW_IP_FILTER_PURGE" ) -// Expand expands schema.ResourceData into a DTO map. +type userConfigType string + +const ( + ServiceUserConfig userConfigType = "service" + ServiceIntegrationUserConfig userConfigType = "service integration" + ServiceIntegrationEndpointUserConfig userConfigType = "service integration endpoint" +) + +// userConfigKey provides a single source of truth for a field naming +func userConfigKey(kind userConfigType, name string) string { + switch kind { + case ServiceIntegrationEndpointUserConfig: + switch name { + case "external_google_cloud_bigquery", "external_postgresql": + // legacy fields + return name + } + } + return name + userConfigSuffix +} + +// getUserConfig returns user config for the given kind and name +func getUserConfig(kind userConfigType, name string) *schema.Schema { + switch kind { + case ServiceUserConfig: + return service.GetUserConfig(name) + case ServiceIntegrationUserConfig: + return serviceintegration.GetUserConfig(name) + case ServiceIntegrationEndpointUserConfig: + return serviceintegrationendpoint.GetUserConfig(name) + } + panic(fmt.Sprintf("unknown user config name %q with kind %q", name, kind)) +} + +// SetUserConfig sets user config schema for given kind and name +func SetUserConfig(kind userConfigType, name string, s map[string]*schema.Schema) { + s[userConfigKey(kind, name)] = getUserConfig(kind, name) +} + +func Expand(kind userConfigType, name string, d *schema.ResourceData) (map[string]any, error) { + m, err := expand(kind, name, d) + if err != nil { + return nil, fmt.Errorf("error converting user config options for %s type %q to API format: %w", kind, name, err) + } + return m, nil +} + +// expand expands schema.ResourceData into a DTO map. // It takes schema.Schema to know how to turn a TF item into json. -func Expand(kind string, s *schema.Schema, d *schema.ResourceData) (map[string]any, error) { - key := kind + userConfigSuffix +func expand(kind userConfigType, name string, d *schema.ResourceData) (map[string]any, error) { + key := userConfigKey(kind, name) state := &stateCompose{ key: key, path: key + ".0", // starts from root user config - schema: s, + schema: getUserConfig(kind, name), resource: d, } @@ -74,7 +125,7 @@ type stateCompose struct { key string // state attribute name or schema.ResourceData key path string // schema.ResourceData path, i.e., foo.0.bar.0.baz to get the value schema *schema.Schema // tf schema - config cty.Value // tf file values + config cty.Value // tf file values, it knows if resource value is null resource *schema.ResourceData // tf resource that has both tf state and data that is received from the API } @@ -231,9 +282,18 @@ func expandAttr(state *stateCompose) (any, error) { return items, nil } -// Flatten flattens DTO into a terraform compatible object -func Flatten(kind string, s *schema.Schema, d *schema.ResourceData, dto map[string]any) ([]map[string]any, error) { - prefix := fmt.Sprintf("%s%s.0.", kind, userConfigSuffix) +func Flatten(kind userConfigType, name string, d *schema.ResourceData, dto map[string]any) error { + err := flatten(kind, name, d, dto) + if err != nil { + return fmt.Errorf("error converting user config options for %s type %q from API format: %w", kind, name, err) + } + return nil +} + +// flatten flattens DTO into a terraform compatible object and sets value to the field +func flatten(kind userConfigType, name string, d *schema.ResourceData, dto map[string]any) error { + key := userConfigKey(kind, name) + prefix := fmt.Sprintf("%s.0.", key) // Renames ip_filter field if _, ok := dto["ip_filter"]; ok { @@ -254,12 +314,14 @@ func Flatten(kind string, s *schema.Schema, d *schema.ResourceData, dto map[stri } } + s := getUserConfig(kind, name) r := s.Elem.(*schema.Resource) tfo, err := flattenObj(r.Schema, dto) if tfo == nil || err != nil { - return nil, err + return err } - return []map[string]any{tfo}, nil + + return d.Set(key, []map[string]any{tfo}) } func flattenObj(s map[string]*schema.Schema, dto map[string]any) (map[string]any, error) {