Skip to content

Commit

Permalink
feat: add autoscaler service integration support (#1878)
Browse files Browse the repository at this point in the history
Co-authored-by: Murad Biashimov <[email protected]>
  • Loading branch information
rriski and byashimov authored Oct 31, 2024
1 parent 31bcb06 commit 2b880be
Show file tree
Hide file tree
Showing 43 changed files with 390 additions and 553 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ nav_order: 1
# Changelog

<!-- Always keep the following header in place: -->
<!-- ## [MAJOR.MINOR.PATCH] - YYYY-MM-DD -->
## [MAJOR.MINOR.PATCH] - YYYY-MM-DD

- Add support for `autoscaler` service integration

## [4.28.0] - 2024-10-21

Expand Down
18 changes: 18 additions & 0 deletions docs/data-sources/service_integration_endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ data "aiven_service_integration_endpoint" "myendpoint" {

### Read-Only

- `autoscaler_user_config` (List of Object) Autoscaler user configurable settings (see [below for nested schema](#nestedatt--autoscaler_user_config))
- `datadog_user_config` (List of Object) Datadog user configurable settings (see [below for nested schema](#nestedatt--datadog_user_config))
- `endpoint_config` (Map of String) Integration endpoint specific backend configuration
- `endpoint_type` (String) Type of the service integration endpoint. The possible values are `autoscaler`, `datadog`, `external_aws_cloudwatch_logs`, `external_aws_cloudwatch_metrics`, `external_aws_s3`, `external_clickhouse`, `external_elasticsearch_logs`, `external_google_cloud_bigquery`, `external_google_cloud_logging`, `external_kafka`, `external_mysql`, `external_opensearch_logs`, `external_postgresql`, `external_prometheus`, `external_redis`, `external_schema_registry`, `external_sumologic_logs`, `jolokia`, `prometheus` and `rsyslog`.
Expand All @@ -50,6 +51,23 @@ data "aiven_service_integration_endpoint" "myendpoint" {
- `prometheus_user_config` (List of Object) Prometheus user configurable settings (see [below for nested schema](#nestedatt--prometheus_user_config))
- `rsyslog_user_config` (List of Object) Rsyslog user configurable settings (see [below for nested schema](#nestedatt--rsyslog_user_config))

<a id="nestedatt--autoscaler_user_config"></a>
### Nested Schema for `autoscaler_user_config`

Read-Only:

- `autoscaling` (List of Object) (see [below for nested schema](#nestedobjatt--autoscaler_user_config--autoscaling))

<a id="nestedobjatt--autoscaler_user_config--autoscaling"></a>
### Nested Schema for `autoscaler_user_config.autoscaling`

Read-Only:

- `cap_gb` (Number)
- `type` (String)



<a id="nestedatt--datadog_user_config"></a>
### Nested Schema for `datadog_user_config`

Expand Down
18 changes: 18 additions & 0 deletions docs/resources/service_integration_endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The Service Integration Endpoint resource allows the creation and management of

### Optional

- `autoscaler_user_config` (Block List, Max: 1) Autoscaler user configurable settings (see [below for nested schema](#nestedblock--autoscaler_user_config))
- `datadog_user_config` (Block List, Max: 1) Datadog user configurable settings (see [below for nested schema](#nestedblock--datadog_user_config))
- `external_aws_cloudwatch_logs_user_config` (Block List, Max: 1) ExternalAwsCloudwatchLogs user configurable settings (see [below for nested schema](#nestedblock--external_aws_cloudwatch_logs_user_config))
- `external_aws_cloudwatch_metrics_user_config` (Block List, Max: 1) ExternalAwsCloudwatchMetrics user configurable settings (see [below for nested schema](#nestedblock--external_aws_cloudwatch_metrics_user_config))
Expand All @@ -47,6 +48,23 @@ The Service Integration Endpoint resource allows the creation and management of
- `endpoint_config` (Map of String) Integration endpoint specific backend configuration
- `id` (String) The ID of this resource.

<a id="nestedblock--autoscaler_user_config"></a>
### Nested Schema for `autoscaler_user_config`

Required:

- `autoscaling` (Block List, Min: 1, Max: 64) Configure autoscaling thresholds for a service (see [below for nested schema](#nestedblock--autoscaler_user_config--autoscaling))

<a id="nestedblock--autoscaler_user_config--autoscaling"></a>
### Nested Schema for `autoscaler_user_config.autoscaling`

Required:

- `cap_gb` (Number) The maximum total disk size (in gb) to allow autoscaler to scale up to. Example: `300`.
- `type` (String) Enum: `autoscale_disk`. Type of autoscale event.



<a id="nestedblock--datadog_user_config"></a>
### Nested Schema for `datadog_user_config`

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ require (
github.com/samber/lo v1.47.0
github.com/stoewer/go-strcase v1.3.0
github.com/stretchr/testify v1.9.0
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
golang.org/x/tools v0.26.0
gopkg.in/yaml.v3 v3.0.1
)
Expand Down Expand Up @@ -59,7 +59,7 @@ require (
cloud.google.com/go v0.112.0 // indirect
cloud.google.com/go/storage v1.36.0 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/aiven/go-api-schemas v1.94.0
github.com/aiven/go-api-schemas v1.95.0
github.com/aws/aws-sdk-go v1.44.122 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/aiven/aiven-go-client/v2 v2.30.0 h1:dj1nRuO1XglnwH2IwKmqEl3SGaqKebDoxnd+SRjxQRg=
github.com/aiven/aiven-go-client/v2 v2.30.0/go.mod h1:Eyxa+fNgayObmUBW94uJuEkyOe1646cEpjFzhm/NETY=
github.com/aiven/go-api-schemas v1.94.0 h1:kbszL56VLORPZ2jXmQBP6FJpihcmiLGdH051G8zBRd0=
github.com/aiven/go-api-schemas v1.94.0/go.mod h1:qS3E/3R+aKQbHsqXzNHqlXATY1kbVNzhiJvk2IDmADI=
github.com/aiven/go-api-schemas v1.95.0 h1:3xGqlX1dwixNDZkUEpm4sn+qjwq8yb0usKubCx3icVA=
github.com/aiven/go-api-schemas v1.95.0/go.mod h1:ATdCq7aRp+URkFI4W4mVZaNZgoN5FRicXKH3c2fpgW4=
github.com/aiven/go-client-codegen v0.45.0 h1:5+5eCN42Qb0QegJSYDw7WCi3z1IHemFyRxzJBN2TnaQ=
github.com/aiven/go-client-codegen v0.45.0/go.mod h1:FfbH32Xb+Hx5zeKTIug1Y8SfMeB+AKNRzxgrzkts2oA=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
Expand Down Expand Up @@ -639,8 +639,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw=
golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down
111 changes: 103 additions & 8 deletions internal/schemautil/custom_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,63 @@ package schemautil

import (
"context"
"errors"
"fmt"
"strings"

"github.com/aiven/aiven-go-client/v2"
avngen "github.com/aiven/go-client-codegen"
"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/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"golang.org/x/exp/slices"
)

func ServiceIntegrationShouldNotBeEmpty(_ context.Context, _, new, _ interface{}) bool {
return len(new.([]interface{})) != 0
}
"github.com/aiven/terraform-provider-aiven/internal/common"
)

func DiskSpaceShouldNotBeEmpty(_ context.Context, _, new, _ interface{}) bool {
return new.(string) != ""
func CustomizeDiffGenericService(serviceType string) schema.CustomizeDiffFunc {
return customdiff.Sequence(
SetServiceTypeIfEmpty(serviceType),
CustomizeDiffDisallowMultipleManyToOneKeys,
customdiff.IfValueChange("tag",
ShouldNotBeEmpty,
CustomizeDiffCheckUniqueTag,
),
customdiff.IfValueChange("disk_space",
ShouldNotBeEmpty,
CustomizeDiffCheckDiskSpace,
),
customdiff.IfValueChange("additional_disk_space",
ShouldNotBeEmpty,
customdiff.Sequence(
CustomizeDiffCheckDiskSpace,
CustomizeDiffAdditionalDiskSpace,
),
),
customdiff.IfValueChange("service_integrations",
ShouldNotBeEmpty,
CustomizeDiffServiceIntegrationAfterCreation,
),
customdiff.Sequence(
CustomizeDiffCheckPlanAndStaticIpsCannotBeModifiedTogether,
CustomizeDiffCheckStaticIPDisassociation,
),
)
}

func TagsShouldNotBeEmpty(_ context.Context, _, new, _ interface{}) bool {
return len(new.(*schema.Set).List()) != 0
func ShouldNotBeEmpty(_ context.Context, _, new, _ interface{}) bool {
switch t := new.(type) {
case string:
return t != ""
case []interface{}:
return len(t) != 0
case *schema.Set:
return t.Len() != 0
default:
panic(fmt.Sprintf("unexpected type: %T", t))
}
}

func CustomizeDiffServiceIntegrationAfterCreation(_ context.Context, d *schema.ResourceDiff, _ interface{}) error {
Expand Down Expand Up @@ -225,3 +262,61 @@ func checkForMultipleValues(v cty.Value) error {

return nil
}

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

// CustomizeDiffAdditionalDiskSpace
// 1. checks that additional_disk_space is not set if autoscaler is enabled
// 2. outputs a diff for a computed field, which otherwise would be suppressed when removed
func CustomizeDiffAdditionalDiskSpace(ctx context.Context, diff *schema.ResourceDiff, _ interface{}) error {
client, err := common.GenClient()
if err != nil {
return err
}

s, err := client.ServiceGet(ctx, diff.Get("project").(string), diff.Get("service_name").(string))
if avngen.IsNotFound(err) {
// The service does not exist, so we cannot check if autoscaler is enabled
return nil
}

if err != nil {
return err
}

isAutoscalerEnabled := false
for _, i := range s.ServiceIntegrations {
if i.IntegrationType == service.IntegrationTypeAutoscaler {
isAutoscalerEnabled = true
break
}
}

k := "additional_disk_space"

// There are three possible sources of additional_disk_space value:
// 1. It is explicitly set in config file
// 2. Computed: disk_space - plan.disk_space = additional_disk_space
// 3. Computed: autoscaler is enabled, so additional_disk_space is managed by the autoscaler
if HasConfigValue(diff, k) || HasConfigValue(diff, "disk_space") {
if isAutoscalerEnabled {
// Autoscaler is enabled, so we cannot set additional_disk_space
return ErrAutoscalerConflict
}

// It is in the config file, lets TF handle it
return nil
}

if isAutoscalerEnabled {
// If the autoscaler is enabled, we don't need to manage the field,
// it will change its value automatically
return nil
}

// It is not set but has a value (ShouldNotBeEmpty proves it has).
// That means the value is being removed.
// We must output a diff for the computed field,
// which otherwise will be suppressed by TF
return diff.SetNew(k, "0B")
}
7 changes: 7 additions & 0 deletions internal/schemautil/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@ 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/diag"
)

// ResourceStateOrResourceDiff either *schema.ResourceState or *schema.ResourceDiff
type ResourceStateOrResourceDiff interface {
GetRawConfig() cty.Value
GetOk(key string) (interface{}, bool)
Get(key string) interface{}
}

func HasConfigValue(d ResourceStateOrResourceDiff, key string) bool {
c := d.GetRawConfig()
return !(c.IsNull() || c.AsValueMap()[key].IsNull())
}

// PlanParameters service plan aparameters
type PlanParameters struct {
DiskSizeMBDefault int
Expand Down
Loading

0 comments on commit 2b880be

Please sign in to comment.