From 87187e01021e727c7a266103fd0f3a93a34344ba Mon Sep 17 00:00:00 2001
From: Petro Protsakh
Date: Wed, 2 Jul 2025 14:50:09 +0300
Subject: [PATCH 1/2] SCALRCORE-28930 Add support for AWS default tags in
provider configurations
---
provider_configuration.go | 179 ++++++++++++++++++---------------
provider_configuration_test.go | 111 ++++++++++++++++++++
type_helpers.go | 5 +
3 files changed, 212 insertions(+), 83 deletions(-)
diff --git a/provider_configuration.go b/provider_configuration.go
index 7fca7f9..80bca8f 100644
--- a/provider_configuration.go
+++ b/provider_configuration.go
@@ -19,6 +19,13 @@ type ProviderConfigurations interface {
Update(ctx context.Context, configurationID string, options ProviderConfigurationUpdateOptions) (*ProviderConfiguration, error)
}
+type AwsDefaultTagsStrategy string
+
+const (
+ AwsDefaultTagsStrategySkip AwsDefaultTagsStrategy = "skip"
+ AwsDefaultTagsStrategyUpdate AwsDefaultTagsStrategy = "update"
+)
+
// providerConfigurations implements ProviderConfigurations.
type providerConfigurations struct {
client *Client
@@ -32,34 +39,36 @@ type ProviderConfigurationsList struct {
// ProviderConfiguration represents a Scalr provider configuration.
type ProviderConfiguration struct {
- ID string `jsonapi:"primary,provider-configurations"`
- Name string `jsonapi:"attr,name"`
- ProviderName string `jsonapi:"attr,provider-name"`
- ExportShellVariables bool `jsonapi:"attr,export-shell-variables"`
- IsShared bool `jsonapi:"attr,is-shared"`
- IsCustom bool `jsonapi:"attr,is-custom"`
- AwsAccessKey string `jsonapi:"attr,aws-access-key"`
- AwsSecretKey string `jsonapi:"attr,aws-secret-key"`
- AwsAccountType string `jsonapi:"attr,aws-account-type"`
- AwsCredentialsType string `jsonapi:"attr,aws-credentials-type"`
- AwsTrustedEntityType string `jsonapi:"attr,aws-trusted-entity-type"`
- AwsRoleArn string `jsonapi:"attr,aws-role-arn"`
- AwsExternalId string `jsonapi:"attr,aws-external-id"`
- AwsAudience string `jsonapi:"attr,aws-audience"`
- AzurermClientId string `jsonapi:"attr,azurerm-client-id"`
- AzurermClientSecret string `jsonapi:"attr,azurerm-client-secret"`
- AzurermSubscriptionId string `jsonapi:"attr,azurerm-subscription-id"`
- AzurermTenantId string `jsonapi:"attr,azurerm-tenant-id"`
- AzurermAuthType string `jsonapi:"attr,azurerm-auth-type"`
- AzurermAudience string `jsonapi:"attr,azurerm-audience"`
- GoogleAuthType string `jsonapi:"attr,google-auth-type"`
- GoogleServiceAccountEmail string `jsonapi:"attr,google-service-account-email"`
- GoogleWorkloadProviderName string `jsonapi:"attr,google-workload-provider-name"`
- GoogleProject string `jsonapi:"attr,google-project"`
- GoogleCredentials string `jsonapi:"attr,google-credentials"`
- GoogleUseDefaultProject bool `jsonapi:"attr,google-use-default-project"`
- ScalrHostname string `jsonapi:"attr,scalr-hostname"`
- ScalrToken string `jsonapi:"attr,scalr-token"`
+ ID string `jsonapi:"primary,provider-configurations"`
+ Name string `jsonapi:"attr,name"`
+ ProviderName string `jsonapi:"attr,provider-name"`
+ ExportShellVariables bool `jsonapi:"attr,export-shell-variables"`
+ IsShared bool `jsonapi:"attr,is-shared"`
+ IsCustom bool `jsonapi:"attr,is-custom"`
+ AwsAccessKey string `jsonapi:"attr,aws-access-key"`
+ AwsSecretKey string `jsonapi:"attr,aws-secret-key"`
+ AwsAccountType string `jsonapi:"attr,aws-account-type"`
+ AwsCredentialsType string `jsonapi:"attr,aws-credentials-type"`
+ AwsTrustedEntityType string `jsonapi:"attr,aws-trusted-entity-type"`
+ AwsRoleArn string `jsonapi:"attr,aws-role-arn"`
+ AwsExternalId string `jsonapi:"attr,aws-external-id"`
+ AwsAudience string `jsonapi:"attr,aws-audience"`
+ AwsDefaultTags *map[string]string `jsonapi:"attr,aws-default-tags"`
+ AwsDefaultTagsStrategy AwsDefaultTagsStrategy `jsonapi:"attr,aws-default-tags-strategy"`
+ AzurermClientId string `jsonapi:"attr,azurerm-client-id"`
+ AzurermClientSecret string `jsonapi:"attr,azurerm-client-secret"`
+ AzurermSubscriptionId string `jsonapi:"attr,azurerm-subscription-id"`
+ AzurermTenantId string `jsonapi:"attr,azurerm-tenant-id"`
+ AzurermAuthType string `jsonapi:"attr,azurerm-auth-type"`
+ AzurermAudience string `jsonapi:"attr,azurerm-audience"`
+ GoogleAuthType string `jsonapi:"attr,google-auth-type"`
+ GoogleServiceAccountEmail string `jsonapi:"attr,google-service-account-email"`
+ GoogleWorkloadProviderName string `jsonapi:"attr,google-workload-provider-name"`
+ GoogleProject string `jsonapi:"attr,google-project"`
+ GoogleCredentials string `jsonapi:"attr,google-credentials"`
+ GoogleUseDefaultProject bool `jsonapi:"attr,google-use-default-project"`
+ ScalrHostname string `jsonapi:"attr,scalr-hostname"`
+ ScalrToken string `jsonapi:"attr,scalr-token"`
Account *Account `jsonapi:"relation,account"`
Parameters []*ProviderConfigurationParameter `jsonapi:"relation,parameters"`
@@ -102,34 +111,36 @@ func (s *providerConfigurations) List(ctx context.Context, options ProviderConfi
// ProviderConfigurationCreateOptions represents the options for creating a new provider configuration.
type ProviderConfigurationCreateOptions struct {
- ID string `jsonapi:"primary,provider-configurations"`
- Name *string `jsonapi:"attr,name"`
- ProviderName *string `jsonapi:"attr,provider-name"`
- ExportShellVariables *bool `jsonapi:"attr,export-shell-variables,omitempty"`
- IsShared *bool `jsonapi:"attr,is-shared,omitempty"`
- IsCustom *bool `jsonapi:"attr,is-custom,omitempty"`
- AwsAccessKey *string `jsonapi:"attr,aws-access-key,omitempty"`
- AwsSecretKey *string `jsonapi:"attr,aws-secret-key,omitempty"`
- AwsAccountType *string `jsonapi:"attr,aws-account-type"`
- AwsCredentialsType *string `jsonapi:"attr,aws-credentials-type"`
- AwsTrustedEntityType *string `jsonapi:"attr,aws-trusted-entity-type"`
- AwsAudience *string `jsonapi:"attr,aws-audience"`
- AwsRoleArn *string `jsonapi:"attr,aws-role-arn"`
- AwsExternalId *string `jsonapi:"attr,aws-external-id"`
- AzurermClientId *string `jsonapi:"attr,azurerm-client-id,omitempty"`
- AzurermClientSecret *string `jsonapi:"attr,azurerm-client-secret,omitempty"`
- AzurermSubscriptionId *string `jsonapi:"attr,azurerm-subscription-id,omitempty"`
- AzurermTenantId *string `jsonapi:"attr,azurerm-tenant-id,omitempty"`
- AzurermAuthType *string `jsonapi:"attr,azurerm-auth-type,omitempty"`
- AzurermAudience *string `jsonapi:"attr,azurerm-audience,omitempty"`
- GoogleAuthType *string `jsonapi:"attr,google-auth-type,omitempty"`
- GoogleServiceAccountEmail *string `jsonapi:"attr,google-service-account-email,omitempty"`
- GoogleWorkloadProviderName *string `jsonapi:"attr,google-workload-provider-name,omitempty"`
- GoogleProject *string `jsonapi:"attr,google-project,omitempty"`
- GoogleCredentials *string `jsonapi:"attr,google-credentials,omitempty"`
- GoogleUseDefaultProject *bool `jsonapi:"attr,google-use-default-project,omitempty"`
- ScalrHostname *string `jsonapi:"attr,scalr-hostname,omitempty"`
- ScalrToken *string `jsonapi:"attr,scalr-token,omitempty"`
+ ID string `jsonapi:"primary,provider-configurations"`
+ Name *string `jsonapi:"attr,name"`
+ ProviderName *string `jsonapi:"attr,provider-name"`
+ ExportShellVariables *bool `jsonapi:"attr,export-shell-variables,omitempty"`
+ IsShared *bool `jsonapi:"attr,is-shared,omitempty"`
+ IsCustom *bool `jsonapi:"attr,is-custom,omitempty"`
+ AwsAccessKey *string `jsonapi:"attr,aws-access-key,omitempty"`
+ AwsSecretKey *string `jsonapi:"attr,aws-secret-key,omitempty"`
+ AwsAccountType *string `jsonapi:"attr,aws-account-type"`
+ AwsCredentialsType *string `jsonapi:"attr,aws-credentials-type"`
+ AwsTrustedEntityType *string `jsonapi:"attr,aws-trusted-entity-type"`
+ AwsAudience *string `jsonapi:"attr,aws-audience"`
+ AwsRoleArn *string `jsonapi:"attr,aws-role-arn"`
+ AwsExternalId *string `jsonapi:"attr,aws-external-id"`
+ AwsDefaultTags *map[string]string `jsonapi:"attr,aws-default-tags,omitempty"`
+ AwsDefaultTagsStrategy *AwsDefaultTagsStrategy `jsonapi:"attr,aws-default-tags-strategy,omitempty"`
+ AzurermClientId *string `jsonapi:"attr,azurerm-client-id,omitempty"`
+ AzurermClientSecret *string `jsonapi:"attr,azurerm-client-secret,omitempty"`
+ AzurermSubscriptionId *string `jsonapi:"attr,azurerm-subscription-id,omitempty"`
+ AzurermTenantId *string `jsonapi:"attr,azurerm-tenant-id,omitempty"`
+ AzurermAuthType *string `jsonapi:"attr,azurerm-auth-type,omitempty"`
+ AzurermAudience *string `jsonapi:"attr,azurerm-audience,omitempty"`
+ GoogleAuthType *string `jsonapi:"attr,google-auth-type,omitempty"`
+ GoogleServiceAccountEmail *string `jsonapi:"attr,google-service-account-email,omitempty"`
+ GoogleWorkloadProviderName *string `jsonapi:"attr,google-workload-provider-name,omitempty"`
+ GoogleProject *string `jsonapi:"attr,google-project,omitempty"`
+ GoogleCredentials *string `jsonapi:"attr,google-credentials,omitempty"`
+ GoogleUseDefaultProject *bool `jsonapi:"attr,google-use-default-project,omitempty"`
+ ScalrHostname *string `jsonapi:"attr,scalr-hostname,omitempty"`
+ ScalrToken *string `jsonapi:"attr,scalr-token,omitempty"`
Account *Account `jsonapi:"relation,account,omitempty"`
Environments []*Environment `jsonapi:"relation,environments,omitempty"`
@@ -183,33 +194,35 @@ func (s *providerConfigurations) Read(ctx context.Context, configurationID strin
type ProviderConfigurationUpdateOptions struct {
ID string `jsonapi:"primary,provider-configurations"`
- Name *string `jsonapi:"attr,name"`
- IsShared *bool `jsonapi:"attr,is-shared,omitempty"`
- Environments []*Environment `jsonapi:"relation,environments"`
- ExportShellVariables *bool `jsonapi:"attr,export-shell-variables"`
- AwsAccessKey *string `jsonapi:"attr,aws-access-key"`
- AwsSecretKey *string `jsonapi:"attr,aws-secret-key"`
- AwsAccountType *string `jsonapi:"attr,aws-account-type"`
- AwsCredentialsType *string `jsonapi:"attr,aws-credentials-type"`
- AwsTrustedEntityType *string `jsonapi:"attr,aws-trusted-entity-type"`
- AwsRoleArn *string `jsonapi:"attr,aws-role-arn"`
- AwsExternalId *string `jsonapi:"attr,aws-external-id"`
- AwsAudience *string `jsonapi:"attr,aws-audience"`
- AzurermAuthType *string `jsonapi:"attr,azurerm-auth-type"`
- AzurermAudience *string `jsonapi:"attr,azurerm-audience"`
- AzurermClientId *string `jsonapi:"attr,azurerm-client-id"`
- AzurermClientSecret *string `jsonapi:"attr,azurerm-client-secret"`
- AzurermSubscriptionId *string `jsonapi:"attr,azurerm-subscription-id"`
- AzurermTenantId *string `jsonapi:"attr,azurerm-tenant-id"`
- GoogleAuthType *string `jsonapi:"attr,google-auth-type"`
- GoogleServiceAccountEmail *string `jsonapi:"attr,google-service-account-email"`
- GoogleWorkloadProviderName *string `jsonapi:"attr,google-workload-provider-name"`
- GoogleProject *string `jsonapi:"attr,google-project"`
- GoogleCredentials *string `jsonapi:"attr,google-credentials"`
- GoogleUseDefaultProject *bool `jsonapi:"attr,google-use-default-project,omitempty"`
- ScalrHostname *string `jsonapi:"attr,scalr-hostname"`
- ScalrToken *string `jsonapi:"attr,scalr-token"`
- Owners []*Team `jsonapi:"relation,owners"`
+ Name *string `jsonapi:"attr,name"`
+ IsShared *bool `jsonapi:"attr,is-shared,omitempty"`
+ Environments []*Environment `jsonapi:"relation,environments"`
+ ExportShellVariables *bool `jsonapi:"attr,export-shell-variables"`
+ AwsAccessKey *string `jsonapi:"attr,aws-access-key"`
+ AwsSecretKey *string `jsonapi:"attr,aws-secret-key"`
+ AwsAccountType *string `jsonapi:"attr,aws-account-type"`
+ AwsCredentialsType *string `jsonapi:"attr,aws-credentials-type"`
+ AwsTrustedEntityType *string `jsonapi:"attr,aws-trusted-entity-type"`
+ AwsRoleArn *string `jsonapi:"attr,aws-role-arn"`
+ AwsExternalId *string `jsonapi:"attr,aws-external-id"`
+ AwsAudience *string `jsonapi:"attr,aws-audience"`
+ AwsDefaultTags *map[string]string `jsonapi:"attr,aws-default-tags"`
+ AwsDefaultTagsStrategy *AwsDefaultTagsStrategy `jsonapi:"attr,aws-default-tags-strategy,omitempty"`
+ AzurermAuthType *string `jsonapi:"attr,azurerm-auth-type"`
+ AzurermAudience *string `jsonapi:"attr,azurerm-audience"`
+ AzurermClientId *string `jsonapi:"attr,azurerm-client-id"`
+ AzurermClientSecret *string `jsonapi:"attr,azurerm-client-secret"`
+ AzurermSubscriptionId *string `jsonapi:"attr,azurerm-subscription-id"`
+ AzurermTenantId *string `jsonapi:"attr,azurerm-tenant-id"`
+ GoogleAuthType *string `jsonapi:"attr,google-auth-type"`
+ GoogleServiceAccountEmail *string `jsonapi:"attr,google-service-account-email"`
+ GoogleWorkloadProviderName *string `jsonapi:"attr,google-workload-provider-name"`
+ GoogleProject *string `jsonapi:"attr,google-project"`
+ GoogleCredentials *string `jsonapi:"attr,google-credentials"`
+ GoogleUseDefaultProject *bool `jsonapi:"attr,google-use-default-project,omitempty"`
+ ScalrHostname *string `jsonapi:"attr,scalr-hostname"`
+ ScalrToken *string `jsonapi:"attr,scalr-token"`
+ Owners []*Team `jsonapi:"relation,owners"`
}
// Update an existing provider configuration.
diff --git a/provider_configuration_test.go b/provider_configuration_test.go
index a5c66cf..3d82c34 100644
--- a/provider_configuration_test.go
+++ b/provider_configuration_test.go
@@ -228,6 +228,38 @@ func TestProviderConfigurationCreateAws(t *testing.T) {
})
}
+func TestProviderConfigurationCreateAwsWithTags(t *testing.T) {
+ client := testClient(t)
+ ctx := context.Background()
+
+ accessKeyId, secretAccessKey, _, _ := getAwsTestingCreds(t)
+
+ t.Run("success aws with tags", func(t *testing.T) {
+ options := ProviderConfigurationCreateOptions{
+ Account: &Account{ID: defaultAccountID},
+ Name: String("tst-" + randomString(t)),
+ ProviderName: String("aws"),
+ AwsAccessKey: String(accessKeyId),
+ AwsSecretKey: String(secretAccessKey),
+ AwsAccountType: String("regular"),
+ AwsCredentialsType: String("access_keys"),
+ AwsDefaultTagsStrategy: AwsDefaultTagsStrategyPtr(AwsDefaultTagsStrategyUpdate),
+ AwsDefaultTags: &map[string]string{"Tag1": "Value1", "Tag2": "Value2"},
+ }
+ pcfg, err := client.ProviderConfigurations.Create(ctx, options)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer client.ProviderConfigurations.Delete(ctx, pcfg.ID)
+
+ pcfg, err = client.ProviderConfigurations.Read(ctx, pcfg.ID)
+ require.NoError(t, err)
+
+ assert.Equal(t, *options.AwsDefaultTagsStrategy, pcfg.AwsDefaultTagsStrategy)
+ assert.Equal(t, *options.AwsDefaultTags, *pcfg.AwsDefaultTags)
+ })
+}
+
func TestProviderConfigurationCreateGoogle(t *testing.T) {
client := testClient(t)
ctx := context.Background()
@@ -514,6 +546,85 @@ func TestProviderConfigurationUpdateAws(t *testing.T) {
})
}
+func TestProviderConfigurationUpdateAwsWithTags(t *testing.T) {
+ client := testClient(t)
+ ctx := context.Background()
+
+ accessKeyId, secretAccessKey, _, _ := getAwsTestingCreds(t)
+ name := String("tst-" + randomString(t))
+
+ t.Run("success aws update tags", func(t *testing.T) {
+ options := ProviderConfigurationCreateOptions{
+ Account: &Account{ID: defaultAccountID},
+ Name: name,
+ ExportShellVariables: Bool(false),
+ ProviderName: String("aws"),
+ AwsAccessKey: String(accessKeyId),
+ AwsSecretKey: String(secretAccessKey),
+ AwsAccountType: String("regular"),
+ AwsCredentialsType: String("access_keys"),
+ AwsDefaultTagsStrategy: AwsDefaultTagsStrategyPtr(AwsDefaultTagsStrategyUpdate),
+ AwsDefaultTags: &map[string]string{"Tag1": "Value1", "Tag2": "Value2"},
+ }
+ pcfg, err := client.ProviderConfigurations.Create(ctx, options)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer client.ProviderConfigurations.Delete(ctx, pcfg.ID)
+
+ updateOptions := ProviderConfigurationUpdateOptions{
+ Name: name,
+ ExportShellVariables: Bool(false),
+ AwsAccessKey: String(accessKeyId),
+ AwsSecretKey: String(secretAccessKey),
+ AwsAccountType: String("regular"),
+ AwsCredentialsType: String("access_keys"),
+ AwsDefaultTagsStrategy: AwsDefaultTagsStrategyPtr(AwsDefaultTagsStrategySkip),
+ AwsDefaultTags: &map[string]string{"Tag1": "NewValue1", "NewTag2": "Value2"},
+ }
+ updatedPcfg, err := client.ProviderConfigurations.Update(
+ ctx, pcfg.ID, updateOptions,
+ )
+ require.NoError(t, err)
+ assert.Equal(t, *updateOptions.AwsDefaultTagsStrategy, updatedPcfg.AwsDefaultTagsStrategy)
+ assert.Equal(t, *updateOptions.AwsDefaultTags, *updatedPcfg.AwsDefaultTags)
+ })
+
+ t.Run("success aws remove tags", func(t *testing.T) {
+ options := ProviderConfigurationCreateOptions{
+ Account: &Account{ID: defaultAccountID},
+ Name: name,
+ ExportShellVariables: Bool(false),
+ ProviderName: String("aws"),
+ AwsAccessKey: String(accessKeyId),
+ AwsSecretKey: String(secretAccessKey),
+ AwsAccountType: String("regular"),
+ AwsCredentialsType: String("access_keys"),
+ AwsDefaultTagsStrategy: AwsDefaultTagsStrategyPtr(AwsDefaultTagsStrategyUpdate),
+ AwsDefaultTags: &map[string]string{"Tag1": "Value1", "Tag2": "Value2"},
+ }
+ pcfg, err := client.ProviderConfigurations.Create(ctx, options)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer client.ProviderConfigurations.Delete(ctx, pcfg.ID)
+
+ updateOptions := ProviderConfigurationUpdateOptions{
+ Name: name,
+ ExportShellVariables: Bool(false),
+ AwsAccessKey: String(accessKeyId),
+ AwsSecretKey: String(secretAccessKey),
+ AwsAccountType: String("regular"),
+ AwsCredentialsType: String("access_keys"),
+ }
+ updatedPcfg, err := client.ProviderConfigurations.Update(
+ ctx, pcfg.ID, updateOptions,
+ )
+ require.NoError(t, err)
+ assert.Nil(t, updatedPcfg.AwsDefaultTags)
+ })
+}
+
func TestProviderConfigurationUpdateGoogle(t *testing.T) {
client := testClient(t)
ctx := context.Background()
diff --git a/type_helpers.go b/type_helpers.go
index 383bdc0..a3e74b6 100644
--- a/type_helpers.go
+++ b/type_helpers.go
@@ -49,3 +49,8 @@ func ServiceAccountStatusPtr(v ServiceAccountStatus) *ServiceAccountStatus {
func WorkspaceIaCPlatformPtr(v WorkspaceIaCPlatform) *WorkspaceIaCPlatform {
return &v
}
+
+// AwsDefaultTagsStrategyPtr returns a pointer to the given AwsDefaultTagsStrategy
+func AwsDefaultTagsStrategyPtr(v AwsDefaultTagsStrategy) *AwsDefaultTagsStrategy {
+ return &v
+}
From 2b40cb959a679d050c9ddb0cd1655e9b6aa8e4f9 Mon Sep 17 00:00:00 2001
From: Petro Protsakh
Date: Wed, 2 Jul 2025 18:44:39 +0300
Subject: [PATCH 2/2] SCALRCORE-28930 Add support for AWS default tags in
provider configurations
---
provider_configuration.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/provider_configuration.go b/provider_configuration.go
index 80bca8f..e15cf85 100644
--- a/provider_configuration.go
+++ b/provider_configuration.go
@@ -207,7 +207,7 @@ type ProviderConfigurationUpdateOptions struct {
AwsExternalId *string `jsonapi:"attr,aws-external-id"`
AwsAudience *string `jsonapi:"attr,aws-audience"`
AwsDefaultTags *map[string]string `jsonapi:"attr,aws-default-tags"`
- AwsDefaultTagsStrategy *AwsDefaultTagsStrategy `jsonapi:"attr,aws-default-tags-strategy,omitempty"`
+ AwsDefaultTagsStrategy *AwsDefaultTagsStrategy `jsonapi:"attr,aws-default-tags-strategy"`
AzurermAuthType *string `jsonapi:"attr,azurerm-auth-type"`
AzurermAudience *string `jsonapi:"attr,azurerm-audience"`
AzurermClientId *string `jsonapi:"attr,azurerm-client-id"`