Skip to content

Commit

Permalink
feat: forbid using additional_disk_space if autoscaler integratio…
Browse files Browse the repository at this point in the history
…n is enabled

Autoscaler and additional disk space conflict with each other. If the service
hits its storage threshold, autoscaler integration will bump the service disk
space. This would invalidate `additional_disk_space` set on the service resource
so we disallow setting the field if autoscaler integration is enabled.

Additionally adds tests for autoscaler integration.
  • Loading branch information
rriski committed Oct 28, 2024
1 parent b5b9706 commit 8cb63b3
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 10 deletions.
28 changes: 19 additions & 9 deletions internal/schemautil/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const (
ServiceTypeValkey = "valkey"
)

var ErrAutoscalerConflict = errors.New("autoscaler integration is enabled, additional_disk_space cannot be set")

var TechEmailsResourceSchema = &schema.Resource{
Schema: map[string]*schema.Schema{
"email": {
Expand Down Expand Up @@ -514,6 +516,17 @@ func ResourceServiceUpdate(ctx context.Context, d *schema.ResourceData, m interf
return diag.FromErr(err)
}

// Note: Only service_integrations are needed here, but no specific API exists yet.
s, err := avnGen.ServiceGet(ctx, projectName, serviceName, service.ServiceGetIncludeSecrets(true))
if err != nil {
return diag.Errorf("unable to GET service %s: %s", d.Id(), err)
}

autoscalerIntegrations := getIntegrationsForTerraform(s.ServiceIntegrations, service.IntegrationTypeAutoscaler)
if _, ok := d.GetOk("additional_disk_space"); ok && len(autoscalerIntegrations) > 0 {
return diag.FromErr(ErrAutoscalerConflict)
}

cloud := d.Get("cloud_name").(string)
plan := d.Get("plan").(string)
powered := true
Expand Down Expand Up @@ -604,18 +617,18 @@ func getTechnicalEmailsForTerraform(s *service.ServiceGetOut) *schema.Set {
return schema.NewSet(schema.HashResource(TechEmailsResourceSchema), techEmails)
}

func getReadReplicaIntegrationsForTerraform(integrations []service.ServiceIntegrationOut) ([]map[string]interface{}, error) {
var readReplicaIntegrations []map[string]interface{}
func getIntegrationsForTerraform(integrations []service.ServiceIntegrationOut, integrationType service.IntegrationType) []map[string]interface{} {
var filteredIntegrations []map[string]interface{}
for _, integration := range integrations {
if integration.IntegrationType == "read_replica" {
if integration.IntegrationType == integrationType {
integrationMap := map[string]interface{}{
"integration_type": integration.IntegrationType,
"source_service_name": integration.SourceService,
}
readReplicaIntegrations = append(readReplicaIntegrations, integrationMap)
filteredIntegrations = append(filteredIntegrations, integrationMap)
}
}
return readReplicaIntegrations, nil
return filteredIntegrations
}

func ResourceServiceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
Expand Down Expand Up @@ -781,10 +794,7 @@ func copyServicePropertiesFromAPIResponseToTerraform(
}

// Handle read_replica service integrations
readReplicaIntegrations, err := getReadReplicaIntegrationsForTerraform(s.ServiceIntegrations)
if err != nil {
return err
}
readReplicaIntegrations := getIntegrationsForTerraform(s.ServiceIntegrations, service.IntegrationTypeReadReplica)
if err := d.Set("service_integrations", readReplicaIntegrations); err != nil {
return err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ resource "aiven_service_integration" "bar" {
cluster_alias = "source"
}
}`

}

func testAccCheckAivenServiceIntegrationResourceDestroy(s *terraform.State) error {
Expand Down Expand Up @@ -690,3 +689,75 @@ func TestAccAivenServiceIntegration_clickhouse_postgres_user_config_creates(t *t
},
})
}

func testAccServiceIntegrationAutoscaler(prefix string, includeDiskSpace bool) string {
additionalDiskSpace := ""
if includeDiskSpace {
additionalDiskSpace = `additional_disk_space = "30GiB"`
}

return fmt.Sprintf(`
data "aiven_project" "project" {
project = %[1]q
}
resource "aiven_pg" "test_pg" {
project = data.aiven_project.project.project
cloud_name = "google-europe-north1"
service_name = "%[2]s-pg"
plan = "startup-4"
%[3]s
}
resource "aiven_service_integration_endpoint" "test_endpoint" {
project = data.aiven_project.project.project
endpoint_name = "%[2]s-autoscaler"
endpoint_type = "autoscaler"
autoscaler_user_config {
autoscaling {
cap_gb = 200
type = "autoscale_disk"
}
}
}
resource "aiven_service_integration" "test_autoscaler" {
project = data.aiven_project.project.project
integration_type = "autoscaler"
source_service_name = aiven_pg.test_pg.service_name
destination_endpoint_id = aiven_service_integration_endpoint.test_endpoint.id
}
`, os.Getenv("AIVEN_PROJECT_NAME"), prefix, additionalDiskSpace)
}

func TestAccAivenServiceIntegration_autoscaler(t *testing.T) {
project := os.Getenv("AIVEN_PROJECT_NAME")
prefix := "test-acc-" + acctest.RandString(7)
resourceName := "aiven_service_integration.test_autoscaler"
endpointResourceName := "aiven_service_integration_endpoint.test_endpoint"
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { /* Add necessary pre-checks here */ },
ProtoV6ProviderFactories: acc.TestProtoV6ProviderFactories,
CheckDestroy: testAccCheckAivenServiceIntegrationResourceDestroy,
Steps: []resource.TestStep{
{
Config: testAccServiceIntegrationAutoscaler(prefix, false),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "integration_type", "autoscaler"),
resource.TestCheckResourceAttr(resourceName, "project", project),
resource.TestCheckResourceAttr(resourceName, "source_service_name", fmt.Sprintf("%s-pg", prefix)),
resource.TestCheckResourceAttrSet(resourceName, "destination_endpoint_id"),
resource.TestCheckResourceAttr(endpointResourceName, "project", project),
resource.TestCheckResourceAttr(endpointResourceName, "endpoint_name", fmt.Sprintf("%s-autoscaler", prefix)),
resource.TestCheckResourceAttr(endpointResourceName, "endpoint_type", "autoscaler"),
resource.TestCheckResourceAttr(endpointResourceName, "autoscaler_user_config.0.autoscaling.0.cap_gb", "200"),
),
},
{
Config: testAccServiceIntegrationAutoscaler(prefix, true),
ExpectError: regexp.MustCompile(schemautil.ErrAutoscalerConflict.Error()),
},
},
})
}

0 comments on commit 8cb63b3

Please sign in to comment.