diff --git a/docs/resources/storage_integration.md b/docs/resources/storage_integration.md index 2905735bf2..23e69ec9b6 100644 --- a/docs/resources/storage_integration.md +++ b/docs/resources/storage_integration.md @@ -42,7 +42,7 @@ resource "snowflake_storage_integration" "integration" { - `name` (String) - `storage_allowed_locations` (List of String) Explicitly limits external stages that use the integration to reference one or more storage locations. -- `storage_provider` (String) +- `storage_provider` (String) Specifies the storage provider for the integration. Valid options are: `S3` | `S3GOV` | `S3CHINA` | `GCS` | `AZURE` ### Optional diff --git a/pkg/acceptance/helpers/storage_integration_client.go b/pkg/acceptance/helpers/storage_integration_client.go index 32041df07d..71203ce559 100644 --- a/pkg/acceptance/helpers/storage_integration_client.go +++ b/pkg/acceptance/helpers/storage_integration_client.go @@ -54,10 +54,10 @@ func (c *StorageIntegrationClient) CreateS3(t *testing.T, awsBucketUrl, awsRoleA id := c.ids.RandomAccountObjectIdentifier() req := sdk.NewCreateStorageIntegrationRequest(id, true, s3AllowedLocations). - WithIfNotExists(sdk.Bool(true)). - WithS3StorageProviderParams(sdk.NewS3StorageParamsRequest(awsRoleArn)). + WithIfNotExists(true). + WithS3StorageProviderParams(*sdk.NewS3StorageParamsRequest(sdk.RegularS3Protocol, awsRoleArn)). WithStorageBlockedLocations(s3BlockedLocations). - WithComment(sdk.String("some comment")) + WithComment("some comment") err := c.client().Create(ctx, req) require.NoError(t, err) @@ -73,7 +73,7 @@ func (c *StorageIntegrationClient) DropFunc(t *testing.T, id sdk.AccountObjectId ctx := context.Background() return func() { - err := c.client().Drop(ctx, sdk.NewDropStorageIntegrationRequest(id).WithIfExists(sdk.Bool(true))) + err := c.client().Drop(ctx, sdk.NewDropStorageIntegrationRequest(id).WithIfExists(true)) require.NoError(t, err) } } diff --git a/pkg/resources/storage_integration.go b/pkg/resources/storage_integration.go index c8a1be8cee..85a40729d3 100644 --- a/pkg/resources/storage_integration.go +++ b/pkg/resources/storage_integration.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "slices" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" @@ -52,12 +53,12 @@ var storageIntegrationSchema = map[string]*schema.Schema{ Optional: true, Description: "Explicitly prohibits external stages that use the integration from referencing one or more storage locations.", }, - // TODO (SNOW-1015282): Remove S3gov option before going into V1 "storage_provider": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice([]string{"S3", "S3gov", "GCS", "AZURE", "S3GOV"}, false), + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateDiagFunc: StringInSlice(sdk.AllStorageProviders, true), + Description: fmt.Sprintf("Specifies the storage provider for the integration. Valid options are: %s", possibleValuesListed(sdk.AllStorageProviders)), }, "storage_aws_external_id": { Type: schema.TypeString, @@ -140,7 +141,7 @@ func CreateStorageIntegration(d *schema.ResourceData, meta any) error { req := sdk.NewCreateStorageIntegrationRequest(name, enabled, storageAllowedLocations) if v, ok := d.GetOk("comment"); ok { - req.WithComment(sdk.String(v.(string))) + req.WithComment(v.(string)) } if _, ok := d.GetOk("storage_blocked_locations"); ok { @@ -154,28 +155,33 @@ func CreateStorageIntegration(d *schema.ResourceData, meta any) error { req.WithStorageBlockedLocations(storageBlockedLocations) } - storageProvider := d.Get("storage_provider").(string) + storageProvider := strings.ToUpper(d.Get("storage_provider").(string)) + + switch { + case slices.Contains(sdk.AllS3Protocols, sdk.S3Protocol(storageProvider)): + s3Protocol, err := sdk.ToS3Protocol(storageProvider) + if err != nil { + return err + } - switch storageProvider { - case "S3", "S3GOV", "S3gov": v, ok := d.GetOk("storage_aws_role_arn") if !ok { return fmt.Errorf("if you use the S3 storage provider you must specify a storage_aws_role_arn") } - s3Params := sdk.NewS3StorageParamsRequest(v.(string)) + s3Params := sdk.NewS3StorageParamsRequest(s3Protocol, v.(string)) if _, ok := d.GetOk("storage_aws_object_acl"); ok { - s3Params.WithStorageAwsObjectAcl(sdk.String(d.Get("storage_aws_object_acl").(string))) + s3Params.WithStorageAwsObjectAcl(d.Get("storage_aws_object_acl").(string)) } - req.WithS3StorageProviderParams(s3Params) - case "AZURE": + req.WithS3StorageProviderParams(*s3Params) + case storageProvider == "AZURE": v, ok := d.GetOk("azure_tenant_id") if !ok { return fmt.Errorf("if you use the Azure storage provider you must specify an azure_tenant_id") } - req.WithAzureStorageProviderParams(sdk.NewAzureStorageParamsRequest(sdk.String(v.(string)))) - case "GCS": - req.WithGCSStorageProviderParams(sdk.NewGCSStorageParamsRequest()) + req.WithAzureStorageProviderParams(*sdk.NewAzureStorageParamsRequest(sdk.String(v.(string)))) + case storageProvider == "GCS": + req.WithGCSStorageProviderParams(*sdk.NewGCSStorageParamsRequest()) default: return fmt.Errorf("unexpected provider %v", storageProvider) } @@ -295,7 +301,7 @@ func UpdateStorageIntegration(d *schema.ResourceData, meta any) error { if d.HasChange("comment") { runSetStatement = true - setReq.WithComment(sdk.String(d.Get("comment").(string))) + setReq.WithComment(d.Get("comment").(string)) } if d.HasChange("enabled") { @@ -320,7 +326,7 @@ func UpdateStorageIntegration(d *schema.ResourceData, meta any) error { v := d.Get("storage_blocked_locations").([]interface{}) if len(v) == 0 { if err := client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id). - WithUnset(sdk.NewStorageIntegrationUnsetRequest().WithStorageBlockedLocations(sdk.Bool(true)))); err != nil { + WithUnset(*sdk.NewStorageIntegrationUnsetRequest().WithStorageBlockedLocations(true))); err != nil { return fmt.Errorf("error unsetting storage_blocked_locations, err = %w", err) } } else { @@ -342,25 +348,25 @@ func UpdateStorageIntegration(d *schema.ResourceData, meta any) error { if d.HasChange("storage_aws_object_acl") { if v, ok := d.GetOk("storage_aws_object_acl"); ok { - s3SetParams.WithStorageAwsObjectAcl(sdk.String(v.(string))) + s3SetParams.WithStorageAwsObjectAcl(v.(string)) } else { if err := client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id). - WithUnset(sdk.NewStorageIntegrationUnsetRequest().WithStorageAwsObjectAcl(sdk.Bool(true)))); err != nil { + WithUnset(*sdk.NewStorageIntegrationUnsetRequest().WithStorageAwsObjectAcl(true))); err != nil { return fmt.Errorf("error unsetting storage_aws_object_acl, err = %w", err) } } } - setReq.WithS3Params(s3SetParams) + setReq.WithS3Params(*s3SetParams) } if d.HasChange("azure_tenant_id") { runSetStatement = true - setReq.WithAzureParams(sdk.NewSetAzureStorageParamsRequest(d.Get("azure_tenant_id").(string))) + setReq.WithAzureParams(*sdk.NewSetAzureStorageParamsRequest(d.Get("azure_tenant_id").(string))) } if runSetStatement { - if err := client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id).WithSet(setReq)); err != nil { + if err := client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id).WithSet(*setReq)); err != nil { return fmt.Errorf("error updating storage integration, err = %w", err) } } diff --git a/pkg/sdk/storage_integration_def.go b/pkg/sdk/storage_integration_def.go index bd41ad54b1..04e24c37da 100644 --- a/pkg/sdk/storage_integration_def.go +++ b/pkg/sdk/storage_integration_def.go @@ -1,9 +1,36 @@ package sdk -import g "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/poc/generator" +import ( + "fmt" + "strings" + + g "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/poc/generator" +) //go:generate go run ./poc/main.go +type S3Protocol string + +const ( + RegularS3Protocol S3Protocol = "S3" + GovS3Protocol S3Protocol = "S3GOV" + ChinaS3Protocol S3Protocol = "S3CHINA" +) + +var ( + AllS3Protocols = []S3Protocol{RegularS3Protocol, GovS3Protocol, ChinaS3Protocol} + AllStorageProviders = append(AsStringList(AllS3Protocols), "GCS", "AZURE") +) + +func ToS3Protocol(s string) (S3Protocol, error) { + switch protocol := S3Protocol(strings.ToUpper(s)); protocol { + case RegularS3Protocol, GovS3Protocol, ChinaS3Protocol: + return protocol, nil + default: + return "", fmt.Errorf("invalid S3 protocol: %s", s) + } +} + var StorageLocationDef = g.NewQueryStruct("StorageLocation").Text("Path", g.KeywordOptions().SingleQuotes().Required()) var StorageIntegrationDef = g.NewInterface( @@ -23,7 +50,7 @@ var StorageIntegrationDef = g.NewInterface( OptionalQueryStructField( "S3StorageProviderParams", g.NewQueryStruct("S3StorageParams"). - PredefinedQueryStructField("storageProvider", "string", g.StaticOptions().SQL("STORAGE_PROVIDER = 'S3'")). + PredefinedQueryStructField("Protocol", g.KindOfT[S3Protocol](), g.ParameterOptions().SQL("STORAGE_PROVIDER").SingleQuotes().Required()). TextAssignment("STORAGE_AWS_ROLE_ARN", g.ParameterOptions().SingleQuotes().Required()). OptionalTextAssignment("STORAGE_AWS_OBJECT_ACL", g.ParameterOptions().SingleQuotes()), g.KeywordOptions(), @@ -73,7 +100,7 @@ var StorageIntegrationDef = g.NewInterface( TextAssignment("AZURE_TENANT_ID", g.ParameterOptions().SingleQuotes().Required()), g.KeywordOptions(), ). - BooleanAssignment("ENABLED", g.ParameterOptions()). + OptionalBooleanAssignment("ENABLED", g.ParameterOptions()). ListAssignment("STORAGE_ALLOWED_LOCATIONS", "StorageLocation", g.ParameterOptions().Parentheses()). ListAssignment("STORAGE_BLOCKED_LOCATIONS", "StorageLocation", g.ParameterOptions().Parentheses()). OptionalComment(), diff --git a/pkg/sdk/storage_integration_dto_builders_gen.go b/pkg/sdk/storage_integration_dto_builders_gen.go index e9fedd8c01..f462b01cb1 100644 --- a/pkg/sdk/storage_integration_dto_builders_gen.go +++ b/pkg/sdk/storage_integration_dto_builders_gen.go @@ -16,28 +16,28 @@ func NewCreateStorageIntegrationRequest( return &s } -func (s *CreateStorageIntegrationRequest) WithOrReplace(OrReplace *bool) *CreateStorageIntegrationRequest { - s.OrReplace = OrReplace +func (s *CreateStorageIntegrationRequest) WithOrReplace(OrReplace bool) *CreateStorageIntegrationRequest { + s.OrReplace = &OrReplace return s } -func (s *CreateStorageIntegrationRequest) WithIfNotExists(IfNotExists *bool) *CreateStorageIntegrationRequest { - s.IfNotExists = IfNotExists +func (s *CreateStorageIntegrationRequest) WithIfNotExists(IfNotExists bool) *CreateStorageIntegrationRequest { + s.IfNotExists = &IfNotExists return s } -func (s *CreateStorageIntegrationRequest) WithS3StorageProviderParams(S3StorageProviderParams *S3StorageParamsRequest) *CreateStorageIntegrationRequest { - s.S3StorageProviderParams = S3StorageProviderParams +func (s *CreateStorageIntegrationRequest) WithS3StorageProviderParams(S3StorageProviderParams S3StorageParamsRequest) *CreateStorageIntegrationRequest { + s.S3StorageProviderParams = &S3StorageProviderParams return s } -func (s *CreateStorageIntegrationRequest) WithGCSStorageProviderParams(GCSStorageProviderParams *GCSStorageParamsRequest) *CreateStorageIntegrationRequest { - s.GCSStorageProviderParams = GCSStorageProviderParams +func (s *CreateStorageIntegrationRequest) WithGCSStorageProviderParams(GCSStorageProviderParams GCSStorageParamsRequest) *CreateStorageIntegrationRequest { + s.GCSStorageProviderParams = &GCSStorageProviderParams return s } -func (s *CreateStorageIntegrationRequest) WithAzureStorageProviderParams(AzureStorageProviderParams *AzureStorageParamsRequest) *CreateStorageIntegrationRequest { - s.AzureStorageProviderParams = AzureStorageProviderParams +func (s *CreateStorageIntegrationRequest) WithAzureStorageProviderParams(AzureStorageProviderParams AzureStorageParamsRequest) *CreateStorageIntegrationRequest { + s.AzureStorageProviderParams = &AzureStorageProviderParams return s } @@ -46,21 +46,23 @@ func (s *CreateStorageIntegrationRequest) WithStorageBlockedLocations(StorageBlo return s } -func (s *CreateStorageIntegrationRequest) WithComment(Comment *string) *CreateStorageIntegrationRequest { - s.Comment = Comment +func (s *CreateStorageIntegrationRequest) WithComment(Comment string) *CreateStorageIntegrationRequest { + s.Comment = &Comment return s } func NewS3StorageParamsRequest( + Protocol S3Protocol, StorageAwsRoleArn string, ) *S3StorageParamsRequest { s := S3StorageParamsRequest{} + s.Protocol = Protocol s.StorageAwsRoleArn = StorageAwsRoleArn return &s } -func (s *S3StorageParamsRequest) WithStorageAwsObjectAcl(StorageAwsObjectAcl *string) *S3StorageParamsRequest { - s.StorageAwsObjectAcl = StorageAwsObjectAcl +func (s *S3StorageParamsRequest) WithStorageAwsObjectAcl(StorageAwsObjectAcl string) *S3StorageParamsRequest { + s.StorageAwsObjectAcl = &StorageAwsObjectAcl return s } @@ -84,18 +86,18 @@ func NewAlterStorageIntegrationRequest( return &s } -func (s *AlterStorageIntegrationRequest) WithIfExists(IfExists *bool) *AlterStorageIntegrationRequest { - s.IfExists = IfExists +func (s *AlterStorageIntegrationRequest) WithIfExists(IfExists bool) *AlterStorageIntegrationRequest { + s.IfExists = &IfExists return s } -func (s *AlterStorageIntegrationRequest) WithSet(Set *StorageIntegrationSetRequest) *AlterStorageIntegrationRequest { - s.Set = Set +func (s *AlterStorageIntegrationRequest) WithSet(Set StorageIntegrationSetRequest) *AlterStorageIntegrationRequest { + s.Set = &Set return s } -func (s *AlterStorageIntegrationRequest) WithUnset(Unset *StorageIntegrationUnsetRequest) *AlterStorageIntegrationRequest { - s.Unset = Unset +func (s *AlterStorageIntegrationRequest) WithUnset(Unset StorageIntegrationUnsetRequest) *AlterStorageIntegrationRequest { + s.Unset = &Unset return s } @@ -113,13 +115,13 @@ func NewStorageIntegrationSetRequest() *StorageIntegrationSetRequest { return &StorageIntegrationSetRequest{} } -func (s *StorageIntegrationSetRequest) WithS3Params(S3Params *SetS3StorageParamsRequest) *StorageIntegrationSetRequest { - s.S3Params = S3Params +func (s *StorageIntegrationSetRequest) WithS3Params(S3Params SetS3StorageParamsRequest) *StorageIntegrationSetRequest { + s.S3Params = &S3Params return s } -func (s *StorageIntegrationSetRequest) WithAzureParams(AzureParams *SetAzureStorageParamsRequest) *StorageIntegrationSetRequest { - s.AzureParams = AzureParams +func (s *StorageIntegrationSetRequest) WithAzureParams(AzureParams SetAzureStorageParamsRequest) *StorageIntegrationSetRequest { + s.AzureParams = &AzureParams return s } @@ -138,8 +140,8 @@ func (s *StorageIntegrationSetRequest) WithStorageBlockedLocations(StorageBlocke return s } -func (s *StorageIntegrationSetRequest) WithComment(Comment *string) *StorageIntegrationSetRequest { - s.Comment = Comment +func (s *StorageIntegrationSetRequest) WithComment(Comment string) *StorageIntegrationSetRequest { + s.Comment = &Comment return s } @@ -151,8 +153,8 @@ func NewSetS3StorageParamsRequest( return &s } -func (s *SetS3StorageParamsRequest) WithStorageAwsObjectAcl(StorageAwsObjectAcl *string) *SetS3StorageParamsRequest { - s.StorageAwsObjectAcl = StorageAwsObjectAcl +func (s *SetS3StorageParamsRequest) WithStorageAwsObjectAcl(StorageAwsObjectAcl string) *SetS3StorageParamsRequest { + s.StorageAwsObjectAcl = &StorageAwsObjectAcl return s } @@ -168,23 +170,23 @@ func NewStorageIntegrationUnsetRequest() *StorageIntegrationUnsetRequest { return &StorageIntegrationUnsetRequest{} } -func (s *StorageIntegrationUnsetRequest) WithStorageAwsObjectAcl(StorageAwsObjectAcl *bool) *StorageIntegrationUnsetRequest { - s.StorageAwsObjectAcl = StorageAwsObjectAcl +func (s *StorageIntegrationUnsetRequest) WithStorageAwsObjectAcl(StorageAwsObjectAcl bool) *StorageIntegrationUnsetRequest { + s.StorageAwsObjectAcl = &StorageAwsObjectAcl return s } -func (s *StorageIntegrationUnsetRequest) WithEnabled(Enabled *bool) *StorageIntegrationUnsetRequest { - s.Enabled = Enabled +func (s *StorageIntegrationUnsetRequest) WithEnabled(Enabled bool) *StorageIntegrationUnsetRequest { + s.Enabled = &Enabled return s } -func (s *StorageIntegrationUnsetRequest) WithStorageBlockedLocations(StorageBlockedLocations *bool) *StorageIntegrationUnsetRequest { - s.StorageBlockedLocations = StorageBlockedLocations +func (s *StorageIntegrationUnsetRequest) WithStorageBlockedLocations(StorageBlockedLocations bool) *StorageIntegrationUnsetRequest { + s.StorageBlockedLocations = &StorageBlockedLocations return s } -func (s *StorageIntegrationUnsetRequest) WithComment(Comment *bool) *StorageIntegrationUnsetRequest { - s.Comment = Comment +func (s *StorageIntegrationUnsetRequest) WithComment(Comment bool) *StorageIntegrationUnsetRequest { + s.Comment = &Comment return s } @@ -196,8 +198,8 @@ func NewDropStorageIntegrationRequest( return &s } -func (s *DropStorageIntegrationRequest) WithIfExists(IfExists *bool) *DropStorageIntegrationRequest { - s.IfExists = IfExists +func (s *DropStorageIntegrationRequest) WithIfExists(IfExists bool) *DropStorageIntegrationRequest { + s.IfExists = &IfExists return s } @@ -205,8 +207,8 @@ func NewShowStorageIntegrationRequest() *ShowStorageIntegrationRequest { return &ShowStorageIntegrationRequest{} } -func (s *ShowStorageIntegrationRequest) WithLike(Like *Like) *ShowStorageIntegrationRequest { - s.Like = Like +func (s *ShowStorageIntegrationRequest) WithLike(Like Like) *ShowStorageIntegrationRequest { + s.Like = &Like return s } diff --git a/pkg/sdk/storage_integration_dto_gen.go b/pkg/sdk/storage_integration_dto_gen.go index 7612817825..27e0856970 100644 --- a/pkg/sdk/storage_integration_dto_gen.go +++ b/pkg/sdk/storage_integration_dto_gen.go @@ -24,7 +24,8 @@ type CreateStorageIntegrationRequest struct { } type S3StorageParamsRequest struct { - StorageAwsRoleArn string // required + Protocol S3Protocol // required + StorageAwsRoleArn string // required StorageAwsObjectAcl *string } diff --git a/pkg/sdk/storage_integration_gen.go b/pkg/sdk/storage_integration_gen.go index 82b02c4547..0aaa8eaf85 100644 --- a/pkg/sdk/storage_integration_gen.go +++ b/pkg/sdk/storage_integration_gen.go @@ -37,9 +37,9 @@ type StorageLocation struct { } type S3StorageParams struct { - storageProvider string `ddl:"static" sql:"STORAGE_PROVIDER = 'S3'"` - StorageAwsRoleArn string `ddl:"parameter,single_quotes" sql:"STORAGE_AWS_ROLE_ARN"` - StorageAwsObjectAcl *string `ddl:"parameter,single_quotes" sql:"STORAGE_AWS_OBJECT_ACL"` + Protocol S3Protocol `ddl:"parameter,single_quotes" sql:"STORAGE_PROVIDER"` + StorageAwsRoleArn string `ddl:"parameter,single_quotes" sql:"STORAGE_AWS_ROLE_ARN"` + StorageAwsObjectAcl *string `ddl:"parameter,single_quotes" sql:"STORAGE_AWS_OBJECT_ACL"` } type GCSStorageParams struct { diff --git a/pkg/sdk/storage_integration_gen_test.go b/pkg/sdk/storage_integration_gen_test.go index 2863dc49e0..61c74ddac2 100644 --- a/pkg/sdk/storage_integration_gen_test.go +++ b/pkg/sdk/storage_integration_gen_test.go @@ -1,6 +1,11 @@ package sdk -import "testing" +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) func TestStorageIntegrations_Create(t *testing.T) { id := randomAccountObjectIdentifier() @@ -10,6 +15,7 @@ func TestStorageIntegrations_Create(t *testing.T) { return &CreateStorageIntegrationOptions{ name: id, S3StorageProviderParams: &S3StorageParams{ + Protocol: RegularS3Protocol, StorageAwsRoleArn: "arn:aws:iam::001234567890:role/role", }, Enabled: true, @@ -52,10 +58,23 @@ func TestStorageIntegrations_Create(t *testing.T) { assertOptsValidAndSQLEquals(t, opts, `CREATE STORAGE INTEGRATION %s TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3' STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::001234567890:role/role' ENABLED = true STORAGE_ALLOWED_LOCATIONS = ('allowed-loc-1', 'allowed-loc-2')`, id.FullyQualifiedName()) }) + t.Run("basic - s3 gov protocol", func(t *testing.T) { + opts := defaultOpts() + opts.S3StorageProviderParams.Protocol = GovS3Protocol + assertOptsValidAndSQLEquals(t, opts, `CREATE STORAGE INTEGRATION %s TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3GOV' STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::001234567890:role/role' ENABLED = true STORAGE_ALLOWED_LOCATIONS = ('allowed-loc-1', 'allowed-loc-2')`, id.FullyQualifiedName()) + }) + + t.Run("basic - s3 china protocol", func(t *testing.T) { + opts := defaultOpts() + opts.S3StorageProviderParams.Protocol = ChinaS3Protocol + assertOptsValidAndSQLEquals(t, opts, `CREATE STORAGE INTEGRATION %s TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3CHINA' STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::001234567890:role/role' ENABLED = true STORAGE_ALLOWED_LOCATIONS = ('allowed-loc-1', 'allowed-loc-2')`, id.FullyQualifiedName()) + }) + t.Run("all options - s3", func(t *testing.T) { opts := defaultOpts() opts.IfNotExists = Bool(true) opts.S3StorageProviderParams = &S3StorageParams{ + Protocol: RegularS3Protocol, StorageAwsRoleArn: "arn:aws:iam::001234567890:role/role", StorageAwsObjectAcl: String("bucket-owner-full-control"), } @@ -283,3 +302,38 @@ func TestStorageIntegrations_Describe(t *testing.T) { assertOptsValidAndSQLEquals(t, opts, "DESCRIBE STORAGE INTEGRATION %s", id.FullyQualifiedName()) }) } + +func TestToS3Protocol(t *testing.T) { + testCases := []struct { + Name string + Input string + Expected S3Protocol + Error string + }{ + {Input: "S3", Expected: RegularS3Protocol}, + {Input: "s3", Expected: RegularS3Protocol}, + {Input: "S3gov", Expected: GovS3Protocol}, + {Input: "S3GOV", Expected: GovS3Protocol}, + {Input: "S3ChInA", Expected: ChinaS3Protocol}, + {Input: "S3CHINA", Expected: ChinaS3Protocol}, + {Name: "validation: incorrect s3 protocol", Input: "incorrect", Error: "invalid S3 protocol: incorrect"}, + {Name: "validation: empty input", Input: "", Error: "invalid S3 protocol: "}, + } + + for _, testCase := range testCases { + name := testCase.Name + if name == "" { + name = fmt.Sprintf("%v s3 protocol", testCase.Input) + } + t.Run(name, func(t *testing.T) { + value, err := ToS3Protocol(testCase.Input) + if testCase.Error != "" { + assert.Empty(t, value) + assert.ErrorContains(t, err, testCase.Error) + } else { + assert.NoError(t, err) + assert.Equal(t, testCase.Expected, value) + } + }) + } +} diff --git a/pkg/sdk/storage_integration_impl_gen.go b/pkg/sdk/storage_integration_impl_gen.go index 1361bfdfad..9ac54949d8 100644 --- a/pkg/sdk/storage_integration_impl_gen.go +++ b/pkg/sdk/storage_integration_impl_gen.go @@ -38,7 +38,7 @@ func (v *storageIntegrations) Show(ctx context.Context, request *ShowStorageInte } func (v *storageIntegrations) ShowByID(ctx context.Context, id AccountObjectIdentifier) (*StorageIntegration, error) { - storageIntegrations, err := v.Show(ctx, NewShowStorageIntegrationRequest().WithLike(&Like{ + storageIntegrations, err := v.Show(ctx, NewShowStorageIntegrationRequest().WithLike(Like{ Pattern: String(id.Name()), })) if err != nil { @@ -71,6 +71,7 @@ func (r *CreateStorageIntegrationRequest) toOpts() *CreateStorageIntegrationOpti } if r.S3StorageProviderParams != nil { opts.S3StorageProviderParams = &S3StorageParams{ + Protocol: r.S3StorageProviderParams.Protocol, StorageAwsRoleArn: r.S3StorageProviderParams.StorageAwsRoleArn, StorageAwsObjectAcl: r.S3StorageProviderParams.StorageAwsObjectAcl, } diff --git a/pkg/sdk/testint/storage_integration_gen_integration_test.go b/pkg/sdk/testint/storage_integration_gen_integration_test.go index 5fb1839705..1ff3aab9d9 100644 --- a/pkg/sdk/testint/storage_integration_gen_integration_test.go +++ b/pkg/sdk/testint/storage_integration_gen_integration_test.go @@ -151,15 +151,15 @@ func TestInt_StorageIntegrations(t *testing.T) { gcsBlockedLocations := blockedLocations(gcsBucketUrl) azureBlockedLocations := blockedLocations(azureBucketUrl) - createS3StorageIntegration := func(t *testing.T) sdk.AccountObjectIdentifier { + createS3StorageIntegration := func(t *testing.T, protocol sdk.S3Protocol) sdk.AccountObjectIdentifier { t.Helper() id := testClientHelper().Ids.RandomAccountObjectIdentifier() req := sdk.NewCreateStorageIntegrationRequest(id, true, s3AllowedLocations). - WithIfNotExists(sdk.Bool(true)). - WithS3StorageProviderParams(sdk.NewS3StorageParamsRequest(awsRoleARN)). + WithIfNotExists(true). + WithS3StorageProviderParams(*sdk.NewS3StorageParamsRequest(protocol, awsRoleARN)). WithStorageBlockedLocations(s3BlockedLocations). - WithComment(sdk.String("some comment")) + WithComment("some comment") err := client.StorageIntegrations.Create(ctx, req) require.NoError(t, err) @@ -177,10 +177,10 @@ func TestInt_StorageIntegrations(t *testing.T) { id := testClientHelper().Ids.RandomAccountObjectIdentifier() req := sdk.NewCreateStorageIntegrationRequest(id, true, gcsAllowedLocations). - WithIfNotExists(sdk.Bool(true)). - WithGCSStorageProviderParams(sdk.NewGCSStorageParamsRequest()). + WithIfNotExists(true). + WithGCSStorageProviderParams(*sdk.NewGCSStorageParamsRequest()). WithStorageBlockedLocations(gcsBlockedLocations). - WithComment(sdk.String("some comment")) + WithComment("some comment") err := client.StorageIntegrations.Create(ctx, req) require.NoError(t, err) @@ -198,10 +198,10 @@ func TestInt_StorageIntegrations(t *testing.T) { id := testClientHelper().Ids.RandomAccountObjectIdentifier() req := sdk.NewCreateStorageIntegrationRequest(id, true, azureAllowedLocations). - WithIfNotExists(sdk.Bool(true)). - WithAzureStorageProviderParams(sdk.NewAzureStorageParamsRequest(sdk.String(azureTenantId))). + WithIfNotExists(true). + WithAzureStorageProviderParams(*sdk.NewAzureStorageParamsRequest(sdk.String(azureTenantId))). WithStorageBlockedLocations(azureBlockedLocations). - WithComment(sdk.String("some comment")) + WithComment("some comment") err := client.StorageIntegrations.Create(ctx, req) require.NoError(t, err) @@ -215,7 +215,17 @@ func TestInt_StorageIntegrations(t *testing.T) { } t.Run("Create - S3", func(t *testing.T) { - id := createS3StorageIntegration(t) + id := createS3StorageIntegration(t, sdk.RegularS3Protocol) + + storageIntegration, err := client.StorageIntegrations.ShowByID(ctx, id) + require.NoError(t, err) + + assertStorageIntegrationShowResult(t, storageIntegration, id, "some comment") + }) + + t.Run("Create - S3GOV", func(t *testing.T) { + t.Skip("TODO(SNOW-1820099): Setup GOV accounts to be able to run this test on CI") + id := createS3StorageIntegration(t, sdk.GovS3Protocol) storageIntegration, err := client.StorageIntegrations.ShowByID(ctx, id) require.NoError(t, err) @@ -242,18 +252,18 @@ func TestInt_StorageIntegrations(t *testing.T) { }) t.Run("Alter - set - S3", func(t *testing.T) { - id := createS3StorageIntegration(t) + id := createS3StorageIntegration(t, sdk.RegularS3Protocol) changedS3AllowedLocations := append([]sdk.StorageLocation{{Path: awsBucketUrl + "/allowed-location3"}}, s3AllowedLocations...) changedS3BlockedLocations := append([]sdk.StorageLocation{{Path: awsBucketUrl + "/blocked-location3"}}, s3BlockedLocations...) req := sdk.NewAlterStorageIntegrationRequest(id). WithSet( - sdk.NewStorageIntegrationSetRequest(). - WithS3Params(sdk.NewSetS3StorageParamsRequest(awsRoleARN)). + *sdk.NewStorageIntegrationSetRequest(). + WithS3Params(*sdk.NewSetS3StorageParamsRequest(awsRoleARN)). WithEnabled(true). WithStorageAllowedLocations(changedS3AllowedLocations). WithStorageBlockedLocations(changedS3BlockedLocations). - WithComment(sdk.String("changed comment")), + WithComment("changed comment"), ) err := client.StorageIntegrations.Alter(ctx, req) require.NoError(t, err) @@ -271,12 +281,12 @@ func TestInt_StorageIntegrations(t *testing.T) { changedAzureBlockedLocations := append([]sdk.StorageLocation{{Path: azureBucketUrl + "/blocked-location3"}}, azureBlockedLocations...) req := sdk.NewAlterStorageIntegrationRequest(id). WithSet( - sdk.NewStorageIntegrationSetRequest(). - WithAzureParams(sdk.NewSetAzureStorageParamsRequest(azureTenantId)). + *sdk.NewStorageIntegrationSetRequest(). + WithAzureParams(*sdk.NewSetAzureStorageParamsRequest(azureTenantId)). WithEnabled(true). WithStorageAllowedLocations(changedAzureAllowedLocations). WithStorageBlockedLocations(changedAzureBlockedLocations). - WithComment(sdk.String("changed comment")), + WithComment("changed comment"), ) err := client.StorageIntegrations.Alter(ctx, req) require.NoError(t, err) @@ -288,15 +298,15 @@ func TestInt_StorageIntegrations(t *testing.T) { }) t.Run("Alter - unset", func(t *testing.T) { - id := createS3StorageIntegration(t) + id := createS3StorageIntegration(t, sdk.RegularS3Protocol) req := sdk.NewAlterStorageIntegrationRequest(id). WithUnset( - sdk.NewStorageIntegrationUnsetRequest(). - WithStorageAwsObjectAcl(sdk.Bool(true)). - WithEnabled(sdk.Bool(true)). - WithStorageBlockedLocations(sdk.Bool(true)). - WithComment(sdk.Bool(true)), + *sdk.NewStorageIntegrationUnsetRequest(). + WithStorageAwsObjectAcl(true). + WithEnabled(true). + WithStorageBlockedLocations(true). + WithComment(true), ) err := client.StorageIntegrations.Alter(ctx, req) require.NoError(t, err) @@ -308,7 +318,7 @@ func TestInt_StorageIntegrations(t *testing.T) { }) t.Run("Describe - S3", func(t *testing.T) { - id := createS3StorageIntegration(t) + id := createS3StorageIntegration(t, sdk.RegularS3Protocol) desc, err := client.StorageIntegrations.Describe(ctx, id) require.NoError(t, err)