diff --git a/docs/resources/external_volume.md b/docs/resources/external_volume.md
new file mode 100644
index 0000000000..3e9d24c8e9
--- /dev/null
+++ b/docs/resources/external_volume.md
@@ -0,0 +1,74 @@
+---
+page_title: "snowflake_external_volume Resource - terraform-provider-snowflake"
+subcategory: ""
+description: |-
+ Resource used to manage external volume objects. For more information, check external volume documentation https://docs.snowflake.com/en/sql-reference/commands-data-loading#external-volume.
+---
+
+# snowflake_external_volume (Resource)
+
+Resource used to manage external volume objects. For more information, check [external volume documentation](https://docs.snowflake.com/en/sql-reference/commands-data-loading#external-volume).
+
+
+
+
+## Schema
+
+### Required
+
+- `name` (String) Identifier for the external volume; must be unique for your account. Due to technical limitations (read more [here](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/docs/technical-documentation/identifiers_rework_design_decisions.md#known-limitations-and-identifier-recommendations)), avoid using the following characters: `|`, `.`, `(`, `)`, `"`
+- `storage_location` (Block List, Min: 1) List of named cloud storage locations in different regions and, optionally, cloud platforms. Minimum 1 required. Note that not all parameter combinations are valid as they depend on the given storage_provider. Consult [the docs](https://docs.snowflake.com/en/sql-reference/sql/create-external-volume#cloud-provider-parameters-cloudproviderparams) for more details on this. (see [below for nested schema](#nestedblock--storage_location))
+
+### Optional
+
+- `allow_writes` (String) Specifies whether write operations are allowed for the external volume; must be set to TRUE for Iceberg tables that use Snowflake as the catalog. Available options are: "true" or "false". When the value is not set in the configuration the provider will put "default" there which means to use the Snowflake default for this value.
+- `comment` (String) Specifies a comment for the external volume.
+
+### Read-Only
+
+- `describe_output` (List of Object) Outputs the result of `DESCRIBE EXTERNAL VOLUME` for the given external volume. (see [below for nested schema](#nestedatt--describe_output))
+- `fully_qualified_name` (String) Fully qualified name of the resource. For more information, see [object name resolution](https://docs.snowflake.com/en/sql-reference/name-resolution).
+- `id` (String) The ID of this resource.
+- `show_output` (List of Object) Outputs the result of `SHOW EXTERNAL VOLUMES` for the given external volume. (see [below for nested schema](#nestedatt--show_output))
+
+
+### Nested Schema for `storage_location`
+
+Required:
+
+- `storage_base_url` (String) Specifies the base URL for your cloud storage location.
+- `storage_location_name` (String) Name of the storage location. Must be unique for the external volume.
+- `storage_provider` (String) Specifies the cloud storage provider that stores your data files. Valid values are (case-insensitive): `GCS` | `AZURE` | `S3` | `S3GOV`.
+
+Optional:
+
+- `azure_tenant_id` (String) Specifies the ID for your Office 365 tenant that the allowed and blocked storage accounts belong to.
+- `encryption_kms_key_id` (String) Specifies the ID for the KMS-managed key used to encrypt files.
+- `encryption_type` (String) Specifies the encryption type used.
+- `storage_aws_role_arn` (String) Specifies the case-sensitive Amazon Resource Name (ARN) of the AWS identity and access management (IAM) role that grants privileges on the S3 bucket containing your data files.
+
+Read-Only:
+
+- `storage_aws_external_id` (String) External ID that Snowflake uses to establish a trust relationship with AWS.
+
+
+
+### Nested Schema for `describe_output`
+
+Read-Only:
+
+- `default` (String)
+- `name` (String)
+- `parent` (String)
+- `type` (String)
+- `value` (String)
+
+
+
+### Nested Schema for `show_output`
+
+Read-Only:
+
+- `allow_writes` (Boolean)
+- `comment` (String)
+- `name` (String)
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceassert/external_volume_resource_ext.go b/pkg/acceptance/bettertestspoc/assert/resourceassert/external_volume_resource_ext.go
new file mode 100644
index 0000000000..411854a941
--- /dev/null
+++ b/pkg/acceptance/bettertestspoc/assert/resourceassert/external_volume_resource_ext.go
@@ -0,0 +1,12 @@
+package resourceassert
+
+import (
+ "strconv"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+)
+
+func (e *ExternalVolumeResourceAssert) HasStorageLocationLength(len int) *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueSet("storage_location.#", strconv.FormatInt(int64(len), 10)))
+ return e
+}
diff --git a/pkg/acceptance/bettertestspoc/assert/resourceassert/external_volume_resource_gen.go b/pkg/acceptance/bettertestspoc/assert/resourceassert/external_volume_resource_gen.go
new file mode 100644
index 0000000000..2a7a71d6ba
--- /dev/null
+++ b/pkg/acceptance/bettertestspoc/assert/resourceassert/external_volume_resource_gen.go
@@ -0,0 +1,87 @@
+// Code generated by assertions generator; DO NOT EDIT.
+
+package resourceassert
+
+import (
+ "testing"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+)
+
+type ExternalVolumeResourceAssert struct {
+ *assert.ResourceAssert
+}
+
+func ExternalVolumeResource(t *testing.T, name string) *ExternalVolumeResourceAssert {
+ t.Helper()
+
+ return &ExternalVolumeResourceAssert{
+ ResourceAssert: assert.NewResourceAssert(name, "resource"),
+ }
+}
+
+func ImportedExternalVolumeResource(t *testing.T, id string) *ExternalVolumeResourceAssert {
+ t.Helper()
+
+ return &ExternalVolumeResourceAssert{
+ ResourceAssert: assert.NewImportedResourceAssert(id, "imported resource"),
+ }
+}
+
+///////////////////////////////////
+// Attribute value string checks //
+///////////////////////////////////
+
+func (e *ExternalVolumeResourceAssert) HasAllowWritesString(expected string) *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueSet("allow_writes", expected))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasCommentString(expected string) *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueSet("comment", expected))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasFullyQualifiedNameString(expected string) *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueSet("fully_qualified_name", expected))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasNameString(expected string) *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueSet("name", expected))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasStorageLocationString(expected string) *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueSet("storage_location", expected))
+ return e
+}
+
+////////////////////////////
+// Attribute empty checks //
+////////////////////////////
+
+func (e *ExternalVolumeResourceAssert) HasNoAllowWrites() *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueNotSet("allow_writes"))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasNoComment() *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueNotSet("comment"))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasNoFullyQualifiedName() *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueNotSet("fully_qualified_name"))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasNoName() *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueNotSet("name"))
+ return e
+}
+
+func (e *ExternalVolumeResourceAssert) HasNoStorageLocation() *ExternalVolumeResourceAssert {
+ e.AddAssertion(assert.ValueNotSet("storage_location"))
+ return e
+}
diff --git a/pkg/acceptance/check_destroy.go b/pkg/acceptance/check_destroy.go
index 0001f75795..e7102a8b18 100644
--- a/pkg/acceptance/check_destroy.go
+++ b/pkg/acceptance/check_destroy.go
@@ -113,6 +113,9 @@ var showByIdFunctions = map[resources.Resource]showByIdFunc{
resources.ExternalTable: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error {
return runShowById(ctx, id, client.ExternalTables.ShowByID)
},
+ resources.ExternalVolume: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error {
+ return runShowById(ctx, id, client.ExternalVolumes.ShowByID)
+ },
resources.FailoverGroup: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error {
return runShowById(ctx, id, client.FailoverGroups.ShowByID)
},
diff --git a/pkg/acceptance/helpers/external_volume_client.go b/pkg/acceptance/helpers/external_volume_client.go
index 415f7bea0c..621bf364a1 100644
--- a/pkg/acceptance/helpers/external_volume_client.go
+++ b/pkg/acceptance/helpers/external_volume_client.go
@@ -2,7 +2,6 @@ package helpers
import (
"context"
- "fmt"
"testing"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
@@ -21,39 +20,56 @@ func NewExternalVolumeClient(context *TestClientContext, idsGenerator *IdsGenera
}
}
-func (c *ExternalVolumeClient) exec(sql string) error {
- ctx := context.Background()
- _, err := c.context.client.ExecForTests(ctx, sql)
- return err
+func (c *ExternalVolumeClient) client() sdk.ExternalVolumes {
+ return c.context.client.ExternalVolumes
}
-// TODO(SNOW-999142): Use SDK implementation for External Volume once it's available
+// TODO switch to returning *sdk.ExternalVolume
+// need to update existing acceptance tests for this
func (c *ExternalVolumeClient) Create(t *testing.T) (sdk.AccountObjectIdentifier, func()) {
t.Helper()
+ ctx := context.Background()
+
id := c.ids.RandomAccountObjectIdentifier()
- err := c.exec(fmt.Sprintf(`
-create external volume %s
- storage_locations =
- (
- (
- name = 'my-s3-us-west-2'
- storage_provider = 's3'
- storage_base_url = 's3://my_example_bucket/'
- storage_aws_role_arn = 'arn:aws:iam::123456789012:role/myrole'
- encryption=(type='aws_sse_kms' kms_key_id='1234abcd-12ab-34cd-56ef-1234567890ab')
- )
- );
-`, id.FullyQualifiedName()))
+ kmsKeyId := "1234abcd-12ab-34cd-56ef-1234567890ab"
+ storageLocations := []sdk.ExternalVolumeStorageLocation{
+ {
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: "my-s3-us-west-2",
+ StorageProvider: "S3",
+ StorageAwsRoleArn: "arn:aws:iam::123456789012:role/myrole",
+ StorageBaseUrl: "s3://my_example_bucket/",
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: "AWS_SSE_KMS",
+ KmsKeyId: &kmsKeyId,
+ },
+ },
+ },
+ }
+
+ req := sdk.NewCreateExternalVolumeRequest(id, storageLocations)
+ err := c.client().Create(ctx, req)
require.NoError(t, err)
+ _, showErr := c.client().ShowByID(ctx, id)
+ require.NoError(t, showErr)
+
return id, c.DropFunc(t, id)
}
+func (c *ExternalVolumeClient) Alter(t *testing.T, req *sdk.AlterExternalVolumeRequest) {
+ t.Helper()
+ ctx := context.Background()
+ err := c.client().Alter(ctx, req)
+ require.NoError(t, err)
+}
+
func (c *ExternalVolumeClient) DropFunc(t *testing.T, id sdk.AccountObjectIdentifier) func() {
t.Helper()
+ ctx := context.Background()
return func() {
- err := c.exec(fmt.Sprintf(`drop external volume if exists %s`, id.FullyQualifiedName()))
+ err := c.client().Drop(ctx, sdk.NewDropExternalVolumeRequest(id).WithIfExists(true))
require.NoError(t, err)
}
}
diff --git a/pkg/helpers/helpers.go b/pkg/helpers/helpers.go
index 0c94f05585..c36cb1cc79 100644
--- a/pkg/helpers/helpers.go
+++ b/pkg/helpers/helpers.go
@@ -2,6 +2,7 @@ package helpers
import (
"encoding/csv"
+ "encoding/json"
"fmt"
"log"
"path"
@@ -163,6 +164,247 @@ func ConcatSlices[T any](slices ...[]T) []T {
return tmp
}
+// Structs for parsing external volume desribe output
+type S3StorageLocation struct {
+ Name string `json:"NAME"`
+ StorageProvider string `json:"STORAGE_PROVIDER"`
+ StorageBaseUrl string `json:"STORAGE_BASE_URL"`
+ StorageAllowedLocations []string `json:"-"`
+ StorageAwsRoleArn string `json:"STORAGE_AWS_ROLE_ARN"`
+ StroageAwsIamUserArn string `json:"-"`
+ StorageAwsExternalId string `json:"STORAGE_AWS_EXTERNAL_ID"`
+ EncryptionType string `json:"ENCRYPTION_TYPE,omitempty"`
+ EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID,omitempty"`
+}
+
+type GCSStorageLocation struct {
+ Name string `json:"NAME"`
+ StorageProvider string `json:"STORAGE_PROVIDER"`
+ StorageBaseUrl string `json:"STORAGE_BASE_URL"`
+ StorageAllowedLocations []string `json:"-"`
+ StorageGcpServiceAccount string `json:"-"`
+ EncryptionType string `json:"ENCRYPTION_TYPE,omitempty"`
+ EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID,omitempty"`
+}
+
+type AzureStorageLocation struct {
+ Name string `json:"NAME"`
+ StorageProvider string `json:"STORAGE_PROVIDER"`
+ StorageBaseUrl string `json:"STORAGE_BASE_URL"`
+ StorageAllowedLocations []string `json:"-"`
+ AzureTenantId string `json:"AZURE_TENANT_ID"`
+ AzureMultiTenantAppName string `json:"-"`
+ AzureConsentUrl string `json:"-"`
+ EncryptionType string `json:"-"`
+ EncryptionKmsId string `json:"-"`
+}
+
+type StorageLocation struct {
+ Name string `json:"NAME"`
+ StorageProvider string `json:"STORAGE_PROVIDER"`
+ StorageBaseUrl string `json:"STORAGE_BASE_URL"`
+ StorageAwsRoleArn string `json:"STORAGE_AWS_ROLE_ARN,omitempty"`
+ StorageAwsExternalId string `json:"STORAGE_AWS_EXTERNAL_ID,omitempty"`
+ EncryptionType string `json:"ENCRYPTION_TYPE,omitempty"`
+ EncryptionKmsKeyId string `json:"ENCRYPTION_KMS_KEY_ID,omitempty"`
+ AzureTenantId string `json:"AZURE_TENANT_ID,omitempty"`
+}
+
+func storageLocationsEqual(s1 StorageLocation, s2 StorageLocation) bool {
+ return s1.Name == s2.Name &&
+ s1.StorageProvider == s2.StorageProvider &&
+ s1.StorageBaseUrl == s2.StorageBaseUrl &&
+ s1.StorageAwsRoleArn == s2.StorageAwsRoleArn &&
+ s1.StorageAwsExternalId == s2.StorageAwsExternalId &&
+ s1.EncryptionType == s2.EncryptionType &&
+ s1.EncryptionKmsKeyId == s2.EncryptionKmsKeyId &&
+ s1.AzureTenantId == s2.AzureTenantId
+}
+
+func validateParsedExternalVolumeDescribed(p ParsedExternalVolumeDescribed) error {
+ if len(p.StorageLocations) == 0 {
+ return fmt.Errorf("No storage locations could be parsed from the external volume.")
+ }
+ if len(p.AllowWrites) == 0 {
+ return fmt.Errorf("The external volume AllowWrites property could not be parsed.")
+ }
+
+ for _, s := range p.StorageLocations {
+ if len(s.Name) == 0 {
+ return fmt.Errorf("A storage location's Name in this volume could not be parsed.")
+ }
+ if len(s.StorageProvider) == 0 {
+ return fmt.Errorf("A storage location's StorageProvider in this volume could not be parsed.")
+ }
+ if len(s.StorageBaseUrl) == 0 {
+ return fmt.Errorf("A storage location's StorageBaseUrl in this volume could not be parsed.")
+ }
+
+ storageProvider, err := sdk.ToStorageProvider(s.StorageProvider)
+ if err != nil {
+ return err
+ }
+
+ switch storageProvider {
+ case sdk.StorageProviderS3, sdk.StorageProviderS3GOV:
+ if len(s.StorageAwsRoleArn) == 0 {
+ return fmt.Errorf("An S3 storage location's StorageAwsRoleArn in this volume could not be parsed.")
+ }
+ case sdk.StorageProviderAzure:
+ if len(s.AzureTenantId) == 0 {
+ return fmt.Errorf("An Azure storage location's AzureTenantId in this volume could not be parsed.")
+ }
+ }
+ }
+
+ return nil
+}
+
+type ParsedExternalVolumeDescribed struct {
+ StorageLocations []StorageLocation
+ Active string
+ Comment string
+ AllowWrites string
+}
+
+func ParsedExternalVolumesDescribedEqual(p1 ParsedExternalVolumeDescribed, p2 ParsedExternalVolumeDescribed) bool {
+ attributesEqual := p1.Active == p2.Active && p1.Comment == p2.Comment && p1.AllowWrites == p2.AllowWrites
+ if attributesEqual && (len(p1.StorageLocations) == len(p2.StorageLocations)) {
+ for i := range p1.StorageLocations {
+ if !storageLocationsEqual(p1.StorageLocations[i], p2.StorageLocations[i]) {
+ return false
+ }
+ }
+
+ return true
+ }
+ return false
+}
+
+func ParseExternalVolumeDescribed(props []sdk.ExternalVolumeProperty) (ParsedExternalVolumeDescribed, error) {
+ parsedExternalVolumeDescribed := ParsedExternalVolumeDescribed{}
+ var storageLocations []StorageLocation
+ for _, p := range props {
+ switch {
+ case p.Name == "COMMENT":
+ parsedExternalVolumeDescribed.Comment = p.Value
+ case p.Name == "ACTIVE":
+ parsedExternalVolumeDescribed.Active = p.Value
+ case p.Name == "ALLOW_WRITES":
+ parsedExternalVolumeDescribed.AllowWrites = p.Value
+ case strings.Contains(p.Name, "STORAGE_LOCATION_"):
+ switch {
+ case strings.Contains(p.Value, `"STORAGE_PROVIDER":"S3"`):
+ s3StorageLocation := S3StorageLocation{}
+ err := json.Unmarshal([]byte(p.Value), &s3StorageLocation)
+ if err != nil {
+ return ParsedExternalVolumeDescribed{}, err
+ }
+ storageLocation := StorageLocation{
+ Name: s3StorageLocation.Name,
+ StorageProvider: s3StorageLocation.StorageProvider,
+ StorageBaseUrl: s3StorageLocation.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocation.StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageLocation.StorageAwsExternalId,
+ EncryptionType: s3StorageLocation.EncryptionType,
+ EncryptionKmsKeyId: s3StorageLocation.EncryptionKmsId,
+ }
+ storageLocations = append(
+ storageLocations,
+ storageLocation,
+ )
+ case strings.Contains(p.Value, `"STORAGE_PROVIDER":"GCS"`):
+ gcsStorageLocation := GCSStorageLocation{}
+ err := json.Unmarshal([]byte(p.Value), &gcsStorageLocation)
+ if err != nil {
+ return ParsedExternalVolumeDescribed{}, err
+ }
+
+ storageLocation := StorageLocation{
+ Name: gcsStorageLocation.Name,
+ StorageProvider: gcsStorageLocation.StorageProvider,
+ StorageBaseUrl: gcsStorageLocation.StorageBaseUrl,
+ EncryptionType: gcsStorageLocation.EncryptionType,
+ EncryptionKmsKeyId: gcsStorageLocation.EncryptionKmsId,
+ }
+ storageLocations = append(
+ storageLocations,
+ storageLocation,
+ )
+ case strings.Contains(p.Value, `"STORAGE_PROVIDER":"AZURE"`):
+ azureStorageLocation := AzureStorageLocation{}
+ err := json.Unmarshal([]byte(p.Value), &azureStorageLocation)
+ if err != nil {
+ return ParsedExternalVolumeDescribed{}, err
+ }
+
+ storageLocation := StorageLocation{
+ Name: azureStorageLocation.Name,
+ StorageProvider: azureStorageLocation.StorageProvider,
+ StorageBaseUrl: azureStorageLocation.StorageBaseUrl,
+ AzureTenantId: azureStorageLocation.AzureTenantId,
+ }
+ storageLocations = append(
+ storageLocations,
+ storageLocation,
+ )
+ default:
+ return ParsedExternalVolumeDescribed{}, fmt.Errorf("Unrecognized storage provider in storage location property: %s", p.Value)
+ }
+ default:
+ return ParsedExternalVolumeDescribed{}, fmt.Errorf("Unrecognized external volume property: %s", p.Name)
+ }
+ }
+
+ parsedExternalVolumeDescribed.StorageLocations = storageLocations
+ validated := validateParsedExternalVolumeDescribed(parsedExternalVolumeDescribed)
+ if validated != nil {
+ return ParsedExternalVolumeDescribed{}, validated
+ }
+
+ return parsedExternalVolumeDescribed, nil
+}
+
+// Generate input to the ParseExternalVolumeDescribedInput, useful for testing purposes
+func GenerateParseExternalVolumeDescribedInput(comment string, allowWrites string, storageLocations []string, active string) []sdk.ExternalVolumeProperty {
+ storageLocationProperties := make([]sdk.ExternalVolumeProperty, len(storageLocations))
+ allowWritesProperty := sdk.ExternalVolumeProperty{
+ Parent: "",
+ Name: "ALLOW_WRITES",
+ Type: "Boolean",
+ Value: allowWrites,
+ Default: "true",
+ }
+
+ commentProperty := sdk.ExternalVolumeProperty{
+ Parent: "",
+ Name: "COMMENT",
+ Type: "String",
+ Value: comment,
+ Default: "",
+ }
+
+ activeProperty := sdk.ExternalVolumeProperty{
+ Parent: "STORAGE_LOCATIONS",
+ Name: "ACTIVE",
+ Type: "String",
+ Value: active,
+ Default: "",
+ }
+
+ for i, property := range storageLocations {
+ storageLocationProperties[i] = sdk.ExternalVolumeProperty{
+ Parent: "STORAGE_LOCATIONS",
+ Name: fmt.Sprintf("STORAGE_LOCATION_%s", strconv.Itoa(i+1)),
+ Type: "String",
+ Value: property,
+ Default: "",
+ }
+ }
+
+ return append(append([]sdk.ExternalVolumeProperty{allowWritesProperty, commentProperty}, storageLocationProperties...), activeProperty)
+}
+
// TODO(SNOW-1569530): address during identifiers rework follow-up
func ParseRootLocation(location string) (sdk.SchemaObjectIdentifier, string, error) {
location = strings.TrimPrefix(location, "@")
diff --git a/pkg/helpers/helpers_test.go b/pkg/helpers/helpers_test.go
index fac9ae1858..0d1c008502 100644
--- a/pkg/helpers/helpers_test.go
+++ b/pkg/helpers/helpers_test.go
@@ -387,3 +387,1080 @@ func Test_ContainsIdentifierIgnoreQuotes(t *testing.T) {
})
}
}
+
+// External volume helper tests
+
+var (
+ allowWritesTrue = "true"
+ allowWritesFalse = "false"
+ comment = "some comment"
+)
+
+var (
+ azureStorageLocationName = "azureTest"
+ azureStorageProvider = "AZURE"
+ azureStorageBaseUrl = "azure://123456789.blob.core.windows.net/my_example_container"
+ azureTenantId = "123456789"
+)
+
+var azureStorageLocationStandard = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["azure://123456789.blob.core.windows.net/my_example_container"],"AZURE_TENANT_ID":"%s","AZURE_MULTI_TENANT_APP_NAME":"test12","AZURE_CONSENT_URL":"https://login.microsoftonline.com/123456789/oauth2/authorize?client_id=test&response_type=test","ENCRYPTION_TYPE":"NONE","ENCRYPTION_KMS_KEY_ID":""}`,
+ azureStorageLocationName,
+ azureStorageProvider,
+ azureStorageBaseUrl,
+ azureTenantId,
+)
+
+var azureStorageLocationWithExtraFields = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["azure://123456789.blob.core.windows.net/my_example_container"],"AZURE_TENANT_ID":"%s","AZURE_MULTI_TENANT_APP_NAME":"test12","AZURE_CONSENT_URL":"https://login.microsoftonline.com/123456789/oauth2/authorize?client_id=test&response_type=test","ENCRYPTION_TYPE":"NONE","ENCRYPTION_KMS_KEY_ID":"","EXTRA_FIELD_ONE":"testing","EXTRA_FIELD_TWO":"123456"}`,
+ azureStorageLocationName,
+ azureStorageProvider,
+ azureStorageBaseUrl,
+ azureTenantId,
+)
+
+var azureStorageLocationMissingTenantId = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["azure://123456789.blob.core.windows.net/my_example_container"],"AZURE_MULTI_TENANT_APP_NAME":"test12","AZURE_CONSENT_URL":"https://login.microsoftonline.com/123456789/oauth2/authorize?client_id=test&response_type=test","ENCRYPTION_TYPE":"NONE","ENCRYPTION_KMS_KEY_ID":""}`,
+ azureStorageLocationName,
+ azureStorageProvider,
+ azureStorageBaseUrl,
+)
+
+var (
+ gcsStorageLocationName = "gcsTest"
+ gcsStorageProvider = "GCS"
+ gcsStorageBaseUrl = "gcs://my_example_bucket"
+ gcsEncryptionTypeNone = "NONE"
+ gcsEncryptionTypeSseKms = "GCS_SSE_KMS"
+ gcsEncryptionKmsKeyId = "123456789"
+)
+
+var gcsStorageLocationStandard = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["gcs://my_example_bucket/*"],"STORAGE_GCP_SERVICE_ACCOUNT":"test@test.iam.test.com","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":""}`,
+ gcsStorageLocationName,
+ gcsStorageProvider,
+ gcsStorageBaseUrl,
+ gcsEncryptionTypeNone,
+)
+
+var gcsStorageLocationWithExtraFields = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["gcs://my_example_bucket/*"],"STORAGE_GCP_SERVICE_ACCOUNT":"test@test.iam.test.com","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"","EXTRA_FIELD_ONE":"testing","EXTRA_FIELD_TWO":"123456"}`,
+ gcsStorageLocationName,
+ gcsStorageProvider,
+ gcsStorageBaseUrl,
+ gcsEncryptionTypeNone,
+)
+
+var gcsStorageLocationKmsEncryption = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["gcs://my_example_bucket/*"],"STORAGE_GCP_SERVICE_ACCOUNT":"test@test.iam.test.com","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"%s"}`,
+ gcsStorageLocationName,
+ gcsStorageProvider,
+ gcsStorageBaseUrl,
+ gcsEncryptionTypeSseKms,
+ gcsEncryptionKmsKeyId,
+)
+
+var gcsStorageLocationMissingBaseUrl = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_ALLOWED_LOCATIONS":["gcs://my_example_bucket/*"],"STORAGE_GCP_SERVICE_ACCOUNT":"test@test.iam.test.com","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":""}`,
+ gcsStorageLocationName,
+ gcsStorageProvider,
+ gcsEncryptionTypeNone,
+)
+
+var (
+ s3StorageLocationName = "s3Test"
+ s3StorageProvider = "S3"
+ s3StorageBaseUrl = "s3://my_example_bucket"
+ s3StorageAwsRoleArn = "arn:aws:iam::123456789012:role/myrole"
+ s3StorageAwsExternalId = "123456789"
+ s3EncryptionTypeNone = "NONE"
+ s3EncryptionTypeSseS3 = "AWS_SSE_S3"
+ s3EncryptionTypeSseKms = "AWS_SSE_KMS"
+ s3EncryptionKmsKeyId = "123456789"
+)
+
+var s3StorageLocationStandard = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["s3://my_example_bucket/*"],"STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_IAM_USER_ARN":"arn:aws:iam::123456789:user/a11b0000-s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s"}`,
+ s3StorageLocationName,
+ s3StorageProvider,
+ s3StorageBaseUrl,
+ s3StorageAwsRoleArn,
+ s3StorageAwsExternalId,
+ s3EncryptionTypeNone,
+)
+
+var s3StorageLocationWithExtraFields = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["s3://my_example_bucket/*"],"STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_IAM_USER_ARN":"arn:aws:iam::123456789:user/a11b0000-s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"%s","EXTRA_FIELD_ONE":"testing","EXTRA_FIELD_TWO":"123456"}`,
+ s3StorageLocationName,
+ s3StorageProvider,
+ s3StorageBaseUrl,
+ s3StorageAwsRoleArn,
+ s3StorageAwsExternalId,
+ s3EncryptionTypeSseKms,
+ s3EncryptionKmsKeyId,
+)
+
+var s3StorageLocationSseS3Encryption = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["s3://my_example_bucket/*"],"STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_IAM_USER_ARN":"arn:aws:iam::123456789:user/a11b0000-s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s"}`,
+ s3StorageLocationName,
+ s3StorageProvider,
+ s3StorageBaseUrl,
+ s3StorageAwsRoleArn,
+ s3StorageAwsExternalId,
+ s3EncryptionTypeSseS3,
+)
+
+var s3StorageLocationSseKmsEncryption = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["s3://my_example_bucket/*"],"STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_IAM_USER_ARN":"arn:aws:iam::123456789:user/a11b0000-s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s", "ENCRYPTION_KMS_KEY_ID":"%s"}`,
+ s3StorageLocationName,
+ s3StorageProvider,
+ s3StorageBaseUrl,
+ s3StorageAwsRoleArn,
+ s3StorageAwsExternalId,
+ s3EncryptionTypeSseKms,
+ s3EncryptionKmsKeyId,
+)
+
+var s3StorageLocationMissingRoleArn = fmt.Sprintf(
+ `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_ALLOWED_LOCATIONS":["s3://my_example_bucket/*"],"STORAGE_AWS_IAM_USER_ARN":"arn:aws:iam::123456789:user/a11b0000-s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s"}`,
+ s3StorageLocationName,
+ s3StorageProvider,
+ s3StorageBaseUrl,
+ s3StorageAwsExternalId,
+ s3EncryptionTypeNone,
+)
+
+func Test_ParsedExternalVolumesDescribedEqual(t *testing.T) {
+ equalCases := []struct {
+ Name string
+ ParsedVolumeA ParsedExternalVolumeDescribed
+ ParsedVolumeB ParsedExternalVolumeDescribed
+ }{
+ {
+ Name: "All values matching",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ }
+
+ notEqualCases := []struct {
+ Name string
+ ParsedVolumeA ParsedExternalVolumeDescribed
+ ParsedVolumeB ParsedExternalVolumeDescribed
+ }{
+ {
+ Name: "Different Active",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "b",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Comment",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "b",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different AllowWrites",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "b",
+ },
+ },
+ {
+ Name: "Different Storage Location - Name",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "b",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - StorageProvider",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "b",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - StorageBaseUrl",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "b",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - StorageAwsRoleArn",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "b",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - StorageAwsExternalId",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "b",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - EncryptionType",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "b",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - EncryptionKmsKeyId",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "b",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ {
+ Name: "Different Storage Location - AzureTenantId",
+ ParsedVolumeA: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "a",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ ParsedVolumeB: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: "a",
+ StorageProvider: "a",
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: "a",
+ EncryptionType: "a",
+ EncryptionKmsKeyId: "a",
+ AzureTenantId: "b",
+ },
+ },
+ Active: "a",
+ Comment: "a",
+ AllowWrites: "a",
+ },
+ },
+ }
+
+ for _, tc := range equalCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ assert.True(t, ParsedExternalVolumesDescribedEqual(tc.ParsedVolumeA, tc.ParsedVolumeB))
+ })
+ }
+
+ for _, tc := range notEqualCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ assert.False(t, ParsedExternalVolumesDescribedEqual(tc.ParsedVolumeA, tc.ParsedVolumeB))
+ })
+ }
+}
+
+func Test_GenerateParseExternalVolumeDescribedInput(t *testing.T) {
+ cases := []struct {
+ TestName string
+ Comment string
+ AllowWrites string
+ StorageLocations []string
+ Active string
+ ExpectedOutput []sdk.ExternalVolumeProperty
+ }{
+ {
+ TestName: "Generate input",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ StorageLocations: []string{s3StorageLocationStandard},
+ Active: "",
+ ExpectedOutput: []sdk.ExternalVolumeProperty{
+ {
+ Parent: "",
+ Name: "ALLOW_WRITES",
+ Type: "Boolean",
+ Value: allowWritesTrue,
+ Default: "true",
+ },
+ {
+ Parent: "",
+ Name: "COMMENT",
+ Type: "String",
+ Value: comment,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "STORAGE_LOCATION_1",
+ Type: "String",
+ Value: s3StorageLocationStandard,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "ACTIVE",
+ Type: "String",
+ Value: "",
+ Default: "",
+ },
+ },
+ },
+ {
+ TestName: "Generate input - multiple locations and active set",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ StorageLocations: []string{s3StorageLocationStandard, azureStorageLocationStandard, gcsStorageLocationStandard},
+ Active: s3StorageLocationName,
+ ExpectedOutput: []sdk.ExternalVolumeProperty{
+ {
+ Parent: "",
+ Name: "ALLOW_WRITES",
+ Type: "Boolean",
+ Value: allowWritesTrue,
+ Default: "true",
+ },
+ {
+ Parent: "",
+ Name: "COMMENT",
+ Type: "String",
+ Value: comment,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "STORAGE_LOCATION_1",
+ Type: "String",
+ Value: s3StorageLocationStandard,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "STORAGE_LOCATION_2",
+ Type: "String",
+ Value: azureStorageLocationStandard,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "STORAGE_LOCATION_3",
+ Type: "String",
+ Value: gcsStorageLocationStandard,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "ACTIVE",
+ Type: "String",
+ Value: s3StorageLocationName,
+ Default: "",
+ },
+ },
+ },
+ }
+
+ for _, tc := range cases {
+ t.Run(tc.TestName, func(t *testing.T) {
+ generatedInput := GenerateParseExternalVolumeDescribedInput(
+ tc.Comment,
+ tc.AllowWrites,
+ tc.StorageLocations,
+ tc.Active,
+ )
+
+ assert.Equal(t, len(tc.ExpectedOutput), len(generatedInput))
+ for i := range generatedInput {
+ assert.Equal(t, tc.ExpectedOutput[i].Parent, generatedInput[i].Parent)
+ assert.Equal(t, tc.ExpectedOutput[i].Name, generatedInput[i].Name)
+ assert.Equal(t, tc.ExpectedOutput[i].Type, generatedInput[i].Type)
+ assert.Equal(t, tc.ExpectedOutput[i].Value, generatedInput[i].Value)
+ assert.Equal(t, tc.ExpectedOutput[i].Default, generatedInput[i].Default)
+ }
+ })
+ }
+}
+
+func Test_ParseExternalVolumeDescribed(t *testing.T) {
+ validCases := []struct {
+ Name string
+ DescribeOutput []sdk.ExternalVolumeProperty
+ ParsedDescribeOutput ParsedExternalVolumeDescribed
+ }{
+ {
+ Name: "Volume with azure storage location",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesFalse, []string{azureStorageLocationStandard}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: azureStorageLocationName,
+ StorageProvider: azureStorageProvider,
+ StorageBaseUrl: azureStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: "",
+ EncryptionKmsKeyId: "",
+ AzureTenantId: azureTenantId,
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesFalse,
+ },
+ },
+ {
+ Name: "Volume with azure storage location, with extra fields",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesFalse, []string{azureStorageLocationWithExtraFields}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: azureStorageLocationName,
+ StorageProvider: azureStorageProvider,
+ StorageBaseUrl: azureStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: "",
+ EncryptionKmsKeyId: "",
+ AzureTenantId: azureTenantId,
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesFalse,
+ },
+ },
+ {
+ Name: "Volume with gcs storage location",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{gcsStorageLocationStandard}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: gcsStorageLocationName,
+ StorageProvider: gcsStorageProvider,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: gcsEncryptionTypeNone,
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with gcs storage location, with extra fields",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{gcsStorageLocationWithExtraFields}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: gcsStorageLocationName,
+ StorageProvider: gcsStorageProvider,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: gcsEncryptionTypeNone,
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with gcs storage location, sse kms encryption",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{gcsStorageLocationKmsEncryption}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: gcsStorageLocationName,
+ StorageProvider: gcsStorageProvider,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: gcsEncryptionTypeSseKms,
+ EncryptionKmsKeyId: gcsEncryptionKmsKeyId,
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with s3 storage location",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{s3StorageLocationStandard}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: s3StorageLocationName,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageAwsExternalId,
+ EncryptionType: s3EncryptionTypeNone,
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with s3 storage location, with extra fields",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{s3StorageLocationWithExtraFields}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: s3StorageLocationName,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageAwsExternalId,
+ EncryptionType: s3EncryptionTypeSseKms,
+ EncryptionKmsKeyId: s3EncryptionKmsKeyId,
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with s3 storage location, sse s3 encryption",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{s3StorageLocationSseS3Encryption}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: s3StorageLocationName,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageAwsExternalId,
+ EncryptionType: s3EncryptionTypeSseS3,
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with s3 storage location, sse kms encryption",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{s3StorageLocationSseKmsEncryption}, ""),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: s3StorageLocationName,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageAwsExternalId,
+ EncryptionType: s3EncryptionTypeSseKms,
+ EncryptionKmsKeyId: s3EncryptionKmsKeyId,
+ AzureTenantId: "",
+ },
+ },
+ Active: "",
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with multiple storage locations and active set",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(
+ comment,
+ allowWritesTrue,
+ []string{s3StorageLocationStandard, gcsStorageLocationStandard, azureStorageLocationStandard},
+ s3StorageLocationName,
+ ),
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: s3StorageLocationName,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageAwsExternalId,
+ EncryptionType: s3EncryptionTypeNone,
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ {
+ Name: gcsStorageLocationName,
+ StorageProvider: gcsStorageProvider,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: gcsEncryptionTypeNone,
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ {
+ Name: azureStorageLocationName,
+ StorageProvider: azureStorageProvider,
+ StorageBaseUrl: azureStorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: "",
+ EncryptionKmsKeyId: "",
+ AzureTenantId: azureTenantId,
+ },
+ },
+ Active: s3StorageLocationName,
+ Comment: comment,
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ {
+ Name: "Volume with s3 storage location that has no comment set (in this case describe doesn't contain a comment property)",
+ DescribeOutput: []sdk.ExternalVolumeProperty{
+ {
+ Parent: "",
+ Name: "ALLOW_WRITES",
+ Type: "Boolean",
+ Value: allowWritesTrue,
+ Default: "true",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "STORAGE_LOCATION_1",
+ Type: "String",
+ Value: s3StorageLocationSseKmsEncryption,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "ACTIVE",
+ Type: "String",
+ Value: s3StorageLocationName,
+ Default: "",
+ },
+ },
+ ParsedDescribeOutput: ParsedExternalVolumeDescribed{
+ StorageLocations: []StorageLocation{
+ {
+ Name: s3StorageLocationName,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: s3StorageAwsExternalId,
+ EncryptionType: s3EncryptionTypeSseKms,
+ EncryptionKmsKeyId: s3EncryptionKmsKeyId,
+ AzureTenantId: "",
+ },
+ },
+ Active: s3StorageLocationName,
+ Comment: "",
+ AllowWrites: allowWritesTrue,
+ },
+ },
+ }
+
+ invalidCases := []struct {
+ Name string
+ DescribeOutput []sdk.ExternalVolumeProperty
+ }{
+ {
+ Name: "Volume with s3 storage location, missing STORAGE_AWS_ROLE_ARN",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{s3StorageLocationMissingRoleArn}, ""),
+ },
+ {
+ Name: "Volume with azure storage location, missing AZURE_TENANT_ID",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{azureStorageLocationMissingTenantId}, ""),
+ },
+ {
+ Name: "Volume with gcs storage location, missing STORAGE_BASE_URL",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{gcsStorageLocationMissingBaseUrl}, ""),
+ },
+ {
+ Name: "Volume with no storage locations",
+ DescribeOutput: GenerateParseExternalVolumeDescribedInput(comment, allowWritesTrue, []string{}, ""),
+ },
+ {
+ Name: "Volume with no allow writes",
+ DescribeOutput: []sdk.ExternalVolumeProperty{
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "STORAGE_LOCATION_1",
+ Type: "String",
+ Value: s3StorageLocationSseKmsEncryption,
+ Default: "",
+ },
+ {
+ Parent: "STORAGE_LOCATIONS",
+ Name: "ACTIVE",
+ Type: "String",
+ Value: s3StorageLocationName,
+ Default: "",
+ },
+ },
+ },
+ }
+
+ for _, tc := range validCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ parsed, err := ParseExternalVolumeDescribed(tc.DescribeOutput)
+ require.NoError(t, err)
+ assert.True(t, ParsedExternalVolumesDescribedEqual(tc.ParsedDescribeOutput, parsed))
+ })
+ }
+
+ for _, tc := range invalidCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ _, err := ParseExternalVolumeDescribed(tc.DescribeOutput)
+ require.Error(t, err)
+ })
+ }
+}
diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go
index edb760e412..97bd689bfe 100644
--- a/pkg/provider/provider.go
+++ b/pkg/provider/provider.go
@@ -439,6 +439,7 @@ func getResources() map[string]*schema.Resource {
"snowflake_external_function": resources.ExternalFunction(),
"snowflake_external_oauth_integration": resources.ExternalOauthIntegration(),
"snowflake_external_table": resources.ExternalTable(),
+ "snowflake_external_volume": resources.ExternalVolume(),
"snowflake_failover_group": resources.FailoverGroup(),
"snowflake_file_format": resources.FileFormat(),
"snowflake_function": resources.Function(),
diff --git a/pkg/provider/resources/resources.go b/pkg/provider/resources/resources.go
index 219617d4e6..c555e656a1 100644
--- a/pkg/provider/resources/resources.go
+++ b/pkg/provider/resources/resources.go
@@ -19,6 +19,7 @@ const (
ExternalFunction resource = "snowflake_external_function"
ExternalTable resource = "snowflake_external_table"
ExternalOauthSecurityIntegration resource = "snowflake_external_oauth_security_integration"
+ ExternalVolume resource = "snowflake_external_volume"
FailoverGroup resource = "snowflake_failover_group"
FileFormat resource = "snowflake_file_format"
Function resource = "snowflake_function"
diff --git a/pkg/resources/external_volume.go b/pkg/resources/external_volume.go
new file mode 100644
index 0000000000..89c7e6e6d7
--- /dev/null
+++ b/pkg/resources/external_volume.go
@@ -0,0 +1,711 @@
+package resources
+
+import (
+ "context"
+ "errors"
+ "fmt"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/schemas"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+var externalVolumeSchema = map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ ForceNew: true,
+ Required: true,
+ Description: blocklistedCharactersFieldDescription("Identifier for the external volume; must be unique for your account."),
+ DiffSuppressFunc: suppressIdentifierQuoting,
+ },
+ // A list is used as the order of storage locations matter. Storage location position in the list is used to select
+ // the active storage location - https://docs.snowflake.com/en/user-guide/tables-iceberg-storage#active-storage-location
+ // This is also why it has been left as one list with optional cloud dependent parameters, rather than splitting into
+ // one list per cloud provider.
+ "storage_location": {
+ Type: schema.TypeList,
+ Required: true,
+ MinItems: 1,
+ Description: "List of named cloud storage locations in different regions and, optionally, cloud platforms. Minimum 1 required. Note that not all parameter combinations are valid as they depend on the given storage_provider. Consult [the docs](https://docs.snowflake.com/en/sql-reference/sql/create-external-volume#cloud-provider-parameters-cloudproviderparams) for more details on this.",
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "storage_location_name": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "Name of the storage location. Must be unique for the external volume.",
+ },
+ "storage_provider": {
+ Type: schema.TypeString,
+ Required: true,
+ ValidateDiagFunc: sdkValidation(sdk.ToStorageProvider),
+ DiffSuppressFunc: SuppressIfAny(NormalizeAndCompare(sdk.ToStorageProvider)),
+ Description: fmt.Sprintf("Specifies the cloud storage provider that stores your data files. Valid values are (case-insensitive): %s.", possibleValuesListed(sdk.ValidStorageProviderString)),
+ },
+ "storage_base_url": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "Specifies the base URL for your cloud storage location.",
+ },
+ "storage_aws_role_arn": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Specifies the case-sensitive Amazon Resource Name (ARN) of the AWS identity and access management (IAM) role that grants privileges on the S3 bucket containing your data files.",
+ },
+ "storage_aws_external_id": {
+ Type: schema.TypeString,
+ Computed: true,
+ Description: "External ID that Snowflake uses to establish a trust relationship with AWS.",
+ },
+ "encryption_type": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Specifies the encryption type used.",
+ DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool {
+ return oldValue == "NONE" && newValue == ""
+ },
+ },
+ "encryption_kms_key_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Specifies the ID for the KMS-managed key used to encrypt files.",
+ },
+ "azure_tenant_id": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Specifies the ID for your Office 365 tenant that the allowed and blocked storage accounts belong to.",
+ },
+ },
+ },
+ },
+ "comment": {
+ Type: schema.TypeString,
+ Optional: true,
+ Description: "Specifies a comment for the external volume.",
+ },
+ "allow_writes": {
+ Type: schema.TypeString,
+ Optional: true,
+ Default: BooleanDefault,
+ Description: booleanStringFieldDescription("Specifies whether write operations are allowed for the external volume; must be set to TRUE for Iceberg tables that use Snowflake as the catalog."),
+ },
+ ShowOutputAttributeName: {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Outputs the result of `SHOW EXTERNAL VOLUMES` for the given external volume.",
+ Elem: &schema.Resource{
+ Schema: schemas.ShowExternalVolumeSchema,
+ },
+ },
+ DescribeOutputAttributeName: {
+ Type: schema.TypeList,
+ Computed: true,
+ Description: "Outputs the result of `DESCRIBE EXTERNAL VOLUME` for the given external volume.",
+ Elem: &schema.Resource{
+ Schema: schemas.DescribeExternalVolumeSchema,
+ },
+ },
+ FullyQualifiedNameAttributeName: schemas.FullyQualifiedNameSchema,
+}
+
+// ExternalVolume returns a pointer to the resource representing an external volume.
+func ExternalVolume() *schema.Resource {
+ return &schema.Resource{
+ SchemaVersion: 1,
+
+ CreateContext: CreateContextExternalVolume,
+ UpdateContext: UpdateContextExternalVolume,
+ ReadContext: ReadContextExternalVolume(true),
+ DeleteContext: DeleteContextExternalVolume,
+ Description: "Resource used to manage external volume objects. For more information, check [external volume documentation](https://docs.snowflake.com/en/sql-reference/commands-data-loading#external-volume).",
+
+ Schema: externalVolumeSchema,
+ Importer: &schema.ResourceImporter{
+ StateContext: ImportExternalVolume,
+ },
+
+ CustomizeDiff: customdiff.All(
+ ComputedIfAnyAttributeChanged(externalVolumeSchema, ShowOutputAttributeName, "name", "allow_writes", "comment"),
+ ComputedIfAnyAttributeChanged(externalVolumeSchema, FullyQualifiedNameAttributeName, "name"),
+ ComputedIfAnyAttributeChanged(externalVolumeSchema, DescribeOutputAttributeName, "name", "allow_writes", "comment", "storage_location"),
+ ),
+ }
+}
+
+func ImportExternalVolume(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
+ logging.DebugLogger.Printf("[DEBUG] Starting external volume import")
+ client := meta.(*provider.Context).Client
+ id := helpers.DecodeSnowflakeID(d.Id()).(sdk.AccountObjectIdentifier)
+
+ if err := d.Set("name", id.Name()); err != nil {
+ return nil, err
+ }
+
+ externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
+ if err != nil {
+ return nil, err
+ }
+
+ if err = d.Set("allow_writes", booleanStringFromBool(externalVolume.AllowWrites)); err != nil {
+ return nil, err
+ }
+
+ if err = d.Set("comment", externalVolume.Comment); err != nil {
+ return nil, err
+ }
+
+ externalVolumeDescribe, err := client.ExternalVolumes.Describe(ctx, id)
+ if err != nil {
+ return nil, err
+ }
+
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(externalVolumeDescribe)
+ if err != nil {
+ return nil, err
+ }
+
+ storageLocations := make([]map[string]any, len(parsedExternalVolumeDescribed.StorageLocations))
+ for i, storageLocation := range parsedExternalVolumeDescribed.StorageLocations {
+ storageLocations[i] = map[string]any{
+ "storage_location_name": storageLocation.Name,
+ "storage_provider": storageLocation.StorageProvider,
+ "storage_base_url": storageLocation.StorageBaseUrl,
+ "storage_aws_role_arn": storageLocation.StorageAwsRoleArn,
+ "storage_aws_external_id": storageLocation.StorageAwsExternalId,
+ "encryption_type": storageLocation.EncryptionType,
+ "encryption_kms_key_id": storageLocation.EncryptionKmsKeyId,
+ "azure_tenant_id": storageLocation.AzureTenantId,
+ }
+ }
+
+ if err = d.Set("storage_location", storageLocations); err != nil {
+ return nil, err
+ }
+
+ return []*schema.ResourceData{d}, nil
+}
+
+func extractStorageLocations(v any, withAzureEncryptionCheck bool) ([]sdk.ExternalVolumeStorageLocation, error) {
+ _, ok := v.([]any)
+ if v == nil || !ok {
+ return nil, fmt.Errorf("unable to extract storage locations, input is either nil or non expected type (%T): %v", v, v)
+ }
+
+ storageLocations := make([]sdk.ExternalVolumeStorageLocation, len(v.([]any)))
+ for i, storageLocationConfigRaw := range v.([]any) {
+ storageLocationConfig, ok := storageLocationConfigRaw.(map[string]any)
+ if !ok {
+ return nil, fmt.Errorf("unable to extract storage location, non expected type of %T: %v", storageLocationConfigRaw, storageLocationConfigRaw)
+ }
+
+ name, ok := storageLocationConfig["storage_location_name"].(string)
+ if !ok {
+ return nil, fmt.Errorf("unable to extract storage location, missing storage_location_name key in storage location")
+ }
+
+ storageProvider, ok := storageLocationConfig["storage_provider"].(string)
+ if !ok {
+ return nil, fmt.Errorf("unable to extract storage location, missing storage_provider key in storage location")
+ }
+
+ storage_base_url, ok := storageLocationConfig["storage_base_url"].(string)
+ if !ok {
+ return nil, fmt.Errorf("unable to extract storage location, missing storage_base_url key in storage location")
+ }
+
+ storageProviderParsed, err := sdk.ToStorageProvider(storageProvider)
+ if err != nil {
+ return nil, err
+ }
+
+ var storageLocation sdk.ExternalVolumeStorageLocation
+ switch storageProviderParsed {
+ case sdk.StorageProviderS3, sdk.StorageProviderS3GOV:
+ // Test that azure_tenant_id is not given
+ // If given non empty plans will be produced
+ azure_tenant_id, ok := storageLocationConfig["azure_tenant_id"].(string)
+ if ok && len(azure_tenant_id) > 0 {
+ return nil, fmt.Errorf("unable to extract storage location, azure_tenant_id provided for s3 storage location")
+ }
+
+ storage_aws_role_arn, ok := storageLocationConfig["storage_aws_role_arn"].(string)
+ if !ok || len(storage_aws_role_arn) == 0 {
+ return nil, fmt.Errorf("unable to extract storage location, missing storage_aws_role_arn key in an s3 storage location")
+ }
+
+ s3StorageProvider, err := sdk.ToS3StorageProvider(storageProvider)
+ if err != nil {
+ return nil, err
+ }
+
+ s3StorageLocation := &sdk.S3StorageLocationParams{
+ Name: name,
+ StorageProvider: s3StorageProvider,
+ StorageBaseUrl: storage_base_url,
+ StorageAwsRoleArn: storage_aws_role_arn,
+ }
+
+ encryption_type, ok := storageLocationConfig["encryption_type"].(string)
+ if ok && len(encryption_type) > 0 {
+ encryptionTypeParsed, err := sdk.ToS3EncryptionType(encryption_type)
+ if err != nil {
+ return nil, err
+ }
+
+ encryption_kms_key_id, ok := storageLocationConfig["encryption_kms_key_id"].(string)
+ if ok && len(encryption_kms_key_id) > 0 {
+ s3StorageLocation.Encryption = &sdk.ExternalVolumeS3Encryption{
+ Type: encryptionTypeParsed,
+ KmsKeyId: &encryption_kms_key_id,
+ }
+ } else {
+ s3StorageLocation.Encryption = &sdk.ExternalVolumeS3Encryption{
+ Type: encryptionTypeParsed,
+ }
+ }
+ }
+
+ storageLocation = sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: s3StorageLocation,
+ }
+ case sdk.StorageProviderGCS:
+ // Test that azure_tenant_id and storage_aws_role_arn are not given
+ // If given non empty plans will be produced
+ azure_tenant_id, ok := storageLocationConfig["azure_tenant_id"].(string)
+ storage_aws_role_arn, ok := storageLocationConfig["storage_aws_role_arn"].(string)
+ if ok && len(azure_tenant_id) > 0 {
+ return nil, fmt.Errorf("unable to extract storage location, azure_tenant_id provided for gcs storage location")
+ }
+ if ok && len(storage_aws_role_arn) > 0 {
+ return nil, fmt.Errorf("unable to extract storage location, storage_aws_role_arn provided for gcs storage location")
+ }
+
+ gcsStorageLocation := &sdk.GCSStorageLocationParams{
+ Name: name,
+ StorageBaseUrl: storage_base_url,
+ }
+ encryption_type, ok := storageLocationConfig["encryption_type"].(string)
+ if ok && len(encryption_type) > 0 {
+ encryptionTypeParsed, err := sdk.ToGCSEncryptionType(encryption_type)
+ if err != nil {
+ return nil, err
+ }
+ encryption_kms_key_id, ok := storageLocationConfig["encryption_kms_key_id"].(string)
+ if ok && len(encryption_kms_key_id) > 0 {
+ gcsStorageLocation.Encryption = &sdk.ExternalVolumeGCSEncryption{
+ Type: encryptionTypeParsed,
+ KmsKeyId: &encryption_kms_key_id,
+ }
+ } else {
+ gcsStorageLocation.Encryption = &sdk.ExternalVolumeGCSEncryption{
+ Type: encryptionTypeParsed,
+ }
+ }
+ }
+
+ storageLocation = sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: gcsStorageLocation,
+ }
+ case sdk.StorageProviderAzure:
+ // Test that storage_aws_role_arn is not given
+ // If given non empty plans will be produced
+ storage_aws_role_arn, ok := storageLocationConfig["storage_aws_role_arn"].(string)
+ if ok && len(storage_aws_role_arn) > 0 {
+ return nil, fmt.Errorf("unable to extract storage location, storage_aws_role_arn provided for azure storage location")
+ }
+
+ // Encryption fields are set on describe requests, although they are not a valid parameter.
+ // Allowing optional checking of these fields as they will be present in some cases.
+ if withAzureEncryptionCheck {
+ encryption_type, ok := storageLocationConfig["encryption_type"].(string)
+ if ok && len(encryption_type) > 0 {
+ return nil, fmt.Errorf("unable to extract storage location, encryption_type provided for azure storage location")
+ }
+
+ encryption_kms_key_id, ok := storageLocationConfig["encryption_kms_key_id"].(string)
+ if ok && len(encryption_kms_key_id) > 0 {
+ return nil, fmt.Errorf("unable to extract storage location, encryption_kms_key_id provided for azure storage location")
+ }
+ }
+
+ azure_tenant_id, ok := storageLocationConfig["azure_tenant_id"].(string)
+ if !ok || len(azure_tenant_id) == 0 {
+ return nil, fmt.Errorf("unable to extract storage location, missing azure_tenant_id provider key in an azure storage location")
+ }
+
+ storageLocation = sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: name,
+ AzureTenantId: azure_tenant_id,
+ StorageBaseUrl: storage_base_url,
+ },
+ }
+ }
+ storageLocations[i] = storageLocation
+ }
+ return storageLocations, nil
+}
+
+func CreateContextExternalVolume(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
+ client := meta.(*provider.Context).Client
+
+ name := d.Get("name").(string)
+ id := sdk.NewAccountObjectIdentifier(name)
+
+ storageLocations, err := extractStorageLocations(d.Get("storage_location"), true)
+ if err != nil {
+ return diag.FromErr(fmt.Errorf("error creating external volume %v err = %w", id.Name(), err))
+ }
+
+ req := sdk.NewCreateExternalVolumeRequest(id, storageLocations)
+
+ if v, ok := d.GetOk("comment"); ok {
+ req.WithComment(v.(string))
+ }
+
+ if v := d.Get("allow_writes").(string); v != BooleanDefault {
+ parsed, err := booleanStringToBool(v)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ req.WithAllowWrites(parsed)
+ }
+
+ createErr := client.ExternalVolumes.Create(ctx, req)
+ if err != nil {
+ return diag.FromErr(fmt.Errorf("error creating external volume %v err = %w", id.Name(), createErr))
+ }
+
+ d.SetId(helpers.EncodeResourceIdentifier(id))
+ return ReadContextExternalVolume(false)(ctx, d, meta)
+}
+
+func ReadContextExternalVolume(withExternalChangesMarking bool) schema.ReadContextFunc {
+ return func(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
+ client := meta.(*provider.Context).Client
+ id := helpers.DecodeSnowflakeID(d.Id()).(sdk.AccountObjectIdentifier)
+
+ if err := d.Set("name", id.Name()); err != nil {
+ return diag.FromErr(err)
+ }
+
+ externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ if withExternalChangesMarking {
+ if err = handleExternalChangesToObjectInShow(d,
+ showMapping{"allow_writes", "allow_writes", externalVolume.AllowWrites, booleanStringFromBool(externalVolume.AllowWrites), nil},
+ ); err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ if err = setStateToValuesFromConfig(d, externalVolumeSchema, []string{
+ "allow_writes",
+ }); err != nil {
+ return diag.FromErr(err)
+ }
+
+ if err = d.Set("comment", externalVolume.Comment); err != nil {
+ return diag.FromErr(err)
+ }
+
+ externalVolumeDescribe, err := client.ExternalVolumes.Describe(ctx, id)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(externalVolumeDescribe)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ storageLocations := make([]map[string]any, len(parsedExternalVolumeDescribed.StorageLocations))
+ for i, storageLocation := range parsedExternalVolumeDescribed.StorageLocations {
+ storageLocations[i] = map[string]any{
+ "storage_location_name": storageLocation.Name,
+ "storage_provider": storageLocation.StorageProvider,
+ "storage_base_url": storageLocation.StorageBaseUrl,
+ "storage_aws_role_arn": storageLocation.StorageAwsRoleArn,
+ "storage_aws_external_id": storageLocation.StorageAwsExternalId,
+ "encryption_type": storageLocation.EncryptionType,
+ "encryption_kms_key_id": storageLocation.EncryptionKmsKeyId,
+ "azure_tenant_id": storageLocation.AzureTenantId,
+ }
+ }
+
+ if err = d.Set("storage_location", storageLocations); err != nil {
+ return diag.FromErr(err)
+ }
+ if err = d.Set(DescribeOutputAttributeName, schemas.ExternalVolumeDescriptionToSchema(externalVolumeDescribe)); err != nil {
+ return diag.FromErr(err)
+ }
+ if err = d.Set(ShowOutputAttributeName, []map[string]any{schemas.ExternalVolumeToSchema(externalVolume)}); err != nil {
+ return diag.FromErr(err)
+ }
+
+ return nil
+ }
+}
+
+func addStorageLocation(
+ addedLocation sdk.ExternalVolumeStorageLocation,
+ client *sdk.Client,
+ ctx context.Context,
+ id sdk.AccountObjectIdentifier,
+) error {
+ storageProvider, err := GetStorageLocationStorageProvider(addedLocation)
+ if err != nil {
+ return err
+ }
+
+ var newStorageLocationreq *sdk.ExternalVolumeStorageLocationRequest
+ switch storageProvider {
+ case sdk.StorageProviderS3, sdk.StorageProviderS3GOV:
+ addedLocation := addedLocation.S3StorageLocationParams
+ s3ParamsRequest := sdk.NewS3StorageLocationParamsRequest(
+ addedLocation.Name,
+ addedLocation.StorageProvider,
+ addedLocation.StorageAwsRoleArn,
+ addedLocation.StorageBaseUrl,
+ )
+ if addedLocation.Encryption != nil {
+ if addedLocation.Encryption.KmsKeyId != nil {
+ s3ParamsRequest = s3ParamsRequest.WithEncryption(
+ *sdk.NewExternalVolumeS3EncryptionRequest(addedLocation.Encryption.Type).
+ WithKmsKeyId(*addedLocation.Encryption.KmsKeyId),
+ )
+ } else {
+ s3ParamsRequest = s3ParamsRequest.WithEncryption(
+ *sdk.NewExternalVolumeS3EncryptionRequest(addedLocation.Encryption.Type),
+ )
+ }
+ }
+
+ newStorageLocationreq = sdk.NewExternalVolumeStorageLocationRequest().WithS3StorageLocationParams(*s3ParamsRequest)
+ case sdk.StorageProviderGCS:
+ addedLocation := addedLocation.GCSStorageLocationParams
+ gcsParamsRequest := sdk.NewGCSStorageLocationParamsRequest(
+ addedLocation.Name,
+ addedLocation.StorageBaseUrl,
+ )
+
+ if addedLocation.Encryption != nil {
+ if addedLocation.Encryption.KmsKeyId != nil {
+ gcsParamsRequest = gcsParamsRequest.WithEncryption(
+ *sdk.NewExternalVolumeGCSEncryptionRequest(addedLocation.Encryption.Type).
+ WithKmsKeyId(*addedLocation.Encryption.KmsKeyId),
+ )
+ } else {
+ gcsParamsRequest = gcsParamsRequest.WithEncryption(
+ *sdk.NewExternalVolumeGCSEncryptionRequest(addedLocation.Encryption.Type),
+ )
+ }
+ }
+
+ newStorageLocationreq = sdk.NewExternalVolumeStorageLocationRequest().WithGCSStorageLocationParams(*gcsParamsRequest)
+ case sdk.StorageProviderAzure:
+ addedLocation := addedLocation.AzureStorageLocationParams
+ azureParamsRequest := sdk.NewAzureStorageLocationParamsRequest(
+ addedLocation.Name,
+ addedLocation.AzureTenantId,
+ addedLocation.StorageBaseUrl,
+ )
+ newStorageLocationreq = sdk.NewExternalVolumeStorageLocationRequest().WithAzureStorageLocationParams(*azureParamsRequest)
+ }
+
+ if err := client.ExternalVolumes.Alter(ctx, sdk.NewAlterExternalVolumeRequest(id).WithAddStorageLocation(*newStorageLocationreq)); err != nil {
+ return err
+ } else {
+ return nil
+ }
+}
+
+func removeStorageLocation(
+ removedLocation sdk.ExternalVolumeStorageLocation,
+ client *sdk.Client,
+ ctx context.Context,
+ id sdk.AccountObjectIdentifier,
+) error {
+ removedName, err := GetStorageLocationName(removedLocation)
+ if err != nil {
+ return err
+ }
+
+ if err := client.ExternalVolumes.Alter(ctx, sdk.NewAlterExternalVolumeRequest(id).WithRemoveStorageLocation(removedName)); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// Process the removal / addition storage location requests.
+// to avoid creating storage locations with duplicate names.
+// len(removedLocations) should be less than the total number
+// of storage locations the external volume has, else this function will fail.
+func updateStorageLocations(
+ removedLocations []sdk.ExternalVolumeStorageLocation,
+ addedLocations []sdk.ExternalVolumeStorageLocation,
+ client *sdk.Client,
+ ctx context.Context,
+ id sdk.AccountObjectIdentifier,
+) error {
+ for _, removedLocation := range removedLocations {
+ err := removeStorageLocation(removedLocation, client, ctx, id)
+ if err != nil {
+ return err
+ }
+ }
+ for _, addedLocation := range addedLocations {
+ err := addStorageLocation(addedLocation, client, ctx, id)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func UpdateContextExternalVolume(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
+ client := meta.(*provider.Context).Client
+ id, err := sdk.ParseAccountObjectIdentifier(d.Id())
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ set := sdk.NewAlterExternalVolumeSetRequest()
+
+ if d.HasChange("comment") {
+ // not using d.GetOk as that doesn't let comments be reset to the empty string
+ set.WithComment(d.Get("comment").(string))
+ }
+
+ if d.HasChange("allow_writes") {
+ if v := d.Get("allow_writes").(string); v != BooleanDefault {
+ parsed, err := booleanStringToBool(v)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ set.WithAllowWrites(parsed)
+ } else {
+ // no way to unset allow writes - set to false as a default
+ set.WithAllowWrites(false)
+ }
+ }
+
+ if (*set != sdk.AlterExternalVolumeSetRequest{}) {
+ if err := client.ExternalVolumes.Alter(ctx, sdk.NewAlterExternalVolumeRequest(id).WithSet(*set)); err != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ if d.HasChange("storage_location") {
+ old, new := d.GetChange("storage_location")
+ oldLocations, err := extractStorageLocations(old, false)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ newLocations, err := extractStorageLocations(new, false)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ // Storage locations can only be added to the tail of the list, but can be
+ // removed at any position. Given this limitation, to keep the configuration order
+ // matching that on Snowflake the list needs to be partially recreated. For example, if a location
+ // is added in the configuration at index 5 in the list, all existing storage locations from index 5
+ // need to be removed, then the new location can be added, and then the removed locations
+ // can be added back. The storage locations lower than index 5 don't need to be modified.
+ // The removal process could be done without the above recreation, but it handles this case
+ // too so it's used for both actions.
+ longestCommonPrefix, err := LongestCommonPrefix(newLocations, oldLocations)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ var removedLocations []sdk.ExternalVolumeStorageLocation
+ var addedLocations []sdk.ExternalVolumeStorageLocation
+ if longestCommonPrefix == -1 {
+ removedLocations = oldLocations
+ addedLocations = newLocations
+ } else {
+ // Could +1 on the prefix here as the lists until and including this index
+ // are identical, would need to add some more checks for list length to avoid
+ // an array index out of bounds error
+ removedLocations = oldLocations[longestCommonPrefix:]
+ addedLocations = newLocations[longestCommonPrefix:]
+ }
+
+ if len(removedLocations) == len(oldLocations) {
+ // Create a temporary storage location, which is a copy of a storage location currently existing
+ // except with a different name. This is done to avoid recreating the external volume, which
+ // would otherwise be necessary as a minimum of 1 storage location per external volume is required.
+ // The alternative solution of adding volumes before removing them isn't possible as
+ // name must be unique for storage locations
+ if len(removedLocations) > 1 {
+ // To ensure the name of the temporary storage location is unique,
+ // first remove all but 1 storage locations from the list
+ for _, removedStorageLocation := range removedLocations[1:] {
+ err = removeStorageLocation(removedStorageLocation, client, ctx, id)
+ if err != nil {
+ return diag.FromErr(err)
+ }
+ }
+ }
+
+ temp_storage_location, err := CopyStorageLocationWithTempName(removedLocations[0])
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ addTempErr := addStorageLocation(temp_storage_location, client, ctx, id)
+ if addTempErr != nil {
+ return diag.FromErr(addTempErr)
+ }
+
+ updateErr := updateStorageLocations([]sdk.ExternalVolumeStorageLocation{removedLocations[0]}, addedLocations, client, ctx, id)
+ if updateErr != nil {
+ // Try to remove the temp location and then return with error
+ removeErr := removeStorageLocation(temp_storage_location, client, ctx, id)
+ if removeErr != nil {
+ return diag.FromErr(errors.Join(updateErr, removeErr))
+ }
+
+ return diag.FromErr(updateErr)
+ }
+
+ removeErr := removeStorageLocation(temp_storage_location, client, ctx, id)
+ if removeErr != nil {
+ return diag.FromErr(removeErr)
+ }
+ } else {
+ updateErr := updateStorageLocations(removedLocations, addedLocations, client, ctx, id)
+ if updateErr != nil {
+ return diag.FromErr(err)
+ }
+ }
+
+ }
+
+ return ReadContextExternalVolume(false)(ctx, d, meta)
+}
+
+func DeleteContextExternalVolume(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
+ client := meta.(*provider.Context).Client
+ id := helpers.DecodeSnowflakeID(d.Id()).(sdk.AccountObjectIdentifier)
+
+ err := client.ExternalVolumes.Drop(ctx, sdk.NewDropExternalVolumeRequest(id).WithIfExists(true))
+ if err != nil {
+ return diag.FromErr(err)
+ }
+
+ d.SetId("")
+ return nil
+}
diff --git a/pkg/resources/external_volume_acceptance_test.go b/pkg/resources/external_volume_acceptance_test.go
new file mode 100644
index 0000000000..e6a7e4cd79
--- /dev/null
+++ b/pkg/resources/external_volume_acceptance_test.go
@@ -0,0 +1,1928 @@
+package resources_test
+
+// TODO Add test that includes Iceberg table creation, as this impacts the describe output (updates ACTIVE)
+
+import (
+ "regexp"
+ "testing"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
+
+ acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs"
+
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/resourceassert"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources"
+ r "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+ "github.com/hashicorp/terraform-plugin-testing/config"
+ "github.com/hashicorp/terraform-plugin-testing/helper/resource"
+ "github.com/hashicorp/terraform-plugin-testing/tfversion"
+)
+
+var (
+ comment = random.Comment()
+ comment2 = random.Comment()
+ allowWritesTrue = "true"
+ allowWritesFalse = "false"
+)
+
+var (
+ s3StorageLocationName = "s3Test"
+ s3StorageLocationName2 = "s3Test2"
+ s3StorageProvider = "S3"
+ s3StorageBaseUrl = "s3://my_example_bucket"
+ s3StorageBaseUrl2 = "s3://my_example_bucket2"
+ s3StorageAwsRoleArn = "arn:aws:iam::123456789012:role/myrole"
+ s3StorageAwsRoleArn2 = "arn:aws:iam::123456789012:role/myrole2"
+ s3EncryptionTypeNone = "NONE"
+ s3EncryptionTypeSseS3 = "AWS_SSE_S3"
+ s3EncryptionTypeSseKms = "AWS_SSE_KMS"
+ s3EncryptionKmsKeyId = "123456789"
+ s3EncryptionKmsKeyId2 = "987654321"
+)
+
+var (
+ s3StorageLocation = getS3StorageLocation(s3StorageLocationName, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeNone, "")
+ s3StorageLocationUpdatedBaseUrl = getS3StorageLocation(s3StorageLocationName, s3StorageProvider, s3StorageBaseUrl2, s3StorageAwsRoleArn, s3EncryptionTypeNone, "")
+ s3StorageLocationUpdatedRoleArn = getS3StorageLocation(s3StorageLocationName, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn2, s3EncryptionTypeNone, "")
+ s3StorageLocationUpdatedName = getS3StorageLocation(s3StorageLocationName2, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeNone, "")
+ s3StorageLocationSseEncryption = getS3StorageLocation(s3StorageLocationName, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeSseS3, "")
+ s3StorageLocationKmsEncryption = getS3StorageLocation(s3StorageLocationName, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeSseKms, s3EncryptionKmsKeyId)
+ s3StorageLocationKmsEncryptionUpdatedName = getS3StorageLocation(s3StorageLocationName2, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeSseKms, s3EncryptionKmsKeyId)
+ s3StorageLocationKmsEncryptionUpdatedKey = getS3StorageLocation(s3StorageLocationName, s3StorageProvider, s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeSseKms, s3EncryptionKmsKeyId2)
+)
+
+var (
+ gcsStorageLocationName = "gcsTest"
+ gcsStorageLocationName2 = "gcsTest2"
+ gcsStorageProvider = "GCS"
+ gcsStorageBaseUrl = "gcs://my_example_bucket"
+ gcsStorageBaseUrl2 = "gcs://my_example_bucket2"
+ gcsEncryptionTypeNone = "NONE"
+ gcsEncryptionTypeSseKms = "GCS_SSE_KMS"
+ gcsEncryptionKmsKeyId = "123456789"
+ gcsEncryptionKmsKeyId2 = "987654321"
+)
+
+var (
+ gcsStorageLocation = getGcsStorageLocation(gcsStorageLocationName, gcsStorageBaseUrl, gcsEncryptionTypeNone, "")
+ gcsStorageLocationUpdatedName = getGcsStorageLocation(gcsStorageLocationName2, gcsStorageBaseUrl, gcsEncryptionTypeNone, "")
+ gcsStorageLocationUpdatedBaseUrl = getGcsStorageLocation(gcsStorageLocationName, gcsStorageBaseUrl2, gcsEncryptionTypeNone, "")
+ gcsStorageLocationKmsEncryption = getGcsStorageLocation(gcsStorageLocationName, gcsStorageBaseUrl, gcsEncryptionTypeSseKms, gcsEncryptionKmsKeyId)
+ gcsStorageLocationKmsEncryptionUpdatedName = getGcsStorageLocation(gcsStorageLocationName2, gcsStorageBaseUrl, gcsEncryptionTypeSseKms, gcsEncryptionKmsKeyId)
+ gcsStorageLocationKmsEncryptionUpdatedKey = getGcsStorageLocation(gcsStorageLocationName, gcsStorageBaseUrl, gcsEncryptionTypeSseKms, gcsEncryptionKmsKeyId2)
+)
+
+var (
+ azureStorageLocationName = "azureTest"
+ azureStorageLocationName2 = "azureTest2"
+ azureStorageProvider = "AZURE"
+ azureStorageBaseUrl = "azure://123456789.blob.core.windows.net/my_example_container"
+ azureTenantId = "123456789"
+ azureTenantId2 = "987654321"
+)
+
+var (
+ azureStorageLocation = getAzureStorageLocation(azureStorageLocationName, azureStorageBaseUrl, azureTenantId)
+ azureStorageLocationUpdatedTenantId = getAzureStorageLocation(azureStorageLocationName, azureStorageBaseUrl, azureTenantId2)
+ azureStorageLocationUpdatedName = getAzureStorageLocation(azureStorageLocationName2, azureStorageBaseUrl, azureTenantId)
+)
+
+// Note that generators currently don't handle lists of objects, which is required for storage locations
+// Using the old approach of files for this reason
+
+func getS3StorageLocation(
+ locName string,
+ provider string,
+ baseUrl string,
+ roleArn string,
+ encryptionType string,
+ s3EncryptionKmsKeyId string,
+) config.Variable {
+ if encryptionType == "AWS_SSE_KMS" {
+ return config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(locName),
+ "storage_provider": config.StringVariable(provider),
+ "storage_base_url": config.StringVariable(baseUrl),
+ "storage_aws_role_arn": config.StringVariable(roleArn),
+ "encryption_type": config.StringVariable(encryptionType),
+ "encryption_kms_key_id": config.StringVariable(s3EncryptionKmsKeyId),
+ })
+ } else {
+ return config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(locName),
+ "storage_provider": config.StringVariable(provider),
+ "storage_base_url": config.StringVariable(baseUrl),
+ "storage_aws_role_arn": config.StringVariable(roleArn),
+ "encryption_type": config.StringVariable(encryptionType),
+ })
+ }
+}
+
+func getGcsStorageLocation(
+ locName string,
+ baseUrl string,
+ encryptionType string,
+ gcsEncryptionKmsKeyId string,
+) config.Variable {
+ if encryptionType == "GCS_SSE_KMS" {
+ return config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(locName),
+ "storage_provider": config.StringVariable(gcsStorageProvider),
+ "storage_base_url": config.StringVariable(baseUrl),
+ "encryption_type": config.StringVariable(encryptionType),
+ "encryption_kms_key_id": config.StringVariable(gcsEncryptionKmsKeyId),
+ })
+ } else {
+ return config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(locName),
+ "storage_provider": config.StringVariable(gcsStorageProvider),
+ "storage_base_url": config.StringVariable(baseUrl),
+ "encryption_type": config.StringVariable(encryptionType),
+ })
+ }
+}
+
+func getAzureStorageLocation(
+ locName string,
+ baseUrl string,
+ azureTenantId string,
+) config.Variable {
+ return config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(locName),
+ "storage_provider": config.StringVariable(azureStorageProvider),
+ "storage_base_url": config.StringVariable(baseUrl),
+ "azure_tenant_id": config.StringVariable(azureTenantId),
+ })
+}
+
+func externalVolume(storageLocations config.Variable, name string, comment string, allowWrites string) config.Variables {
+ return config.Variables{
+ "name": config.StringVariable(name),
+ "comment": config.StringVariable(comment),
+ "allow_writes": config.StringVariable(allowWrites),
+ "storage_location": storageLocations,
+ }
+}
+
+func externalVolumeMultiple(s3StorageLocations config.Variable, gcsStorageLocations config.Variable, azureStorageLocations config.Variable, name string, comment string, allowWrites string) config.Variables {
+ return config.Variables{
+ "name": config.StringVariable(name),
+ "comment": config.StringVariable(comment),
+ "allow_writes": config.StringVariable(allowWrites),
+ "s3_storage_locations": s3StorageLocations,
+ "gcs_storage_locations": gcsStorageLocations,
+ "azure_storage_locations": azureStorageLocations,
+ }
+}
+
+// Test volume with s3 storage locations
+func TestAcc_External_Volume_S3(t *testing.T) {
+ _ = testenvs.GetOrSkipTest(t, testenvs.EnableAcceptance)
+ id := acc.TestClient().Ids.RandomAccountObjectIdentifier()
+ externalVolumeName := id.Name()
+ resourceId := helpers.EncodeResourceIdentifier(id)
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: acc.CheckDestroy(t, resources.ExternalVolume),
+ Steps: []resource.TestStep{
+ // without optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, "", ""),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString("").
+ HasAllowWritesString(r.BooleanDefault).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "3")),
+ ),
+ },
+ // import - without optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, "", ""),
+ ResourceName: "snowflake_external_volume.test",
+ ImportStateCheck: assert.AssertThatImport(t,
+ resourceassert.ImportedExternalVolumeResource(t, resourceId).
+ HasNameString(externalVolumeName).
+ HasStorageLocationLength(1),
+ ),
+ },
+ // set external volume optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // import - with external volume optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // add second storage location without s3 optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // import - 2 storage locations without all s3 optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // update comment and change back to 1 storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment2, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // update allowWrites
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // add none encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // add AWS_SSE_S3 encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationSseEncryption), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeSseS3)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // add AWS_SSE_KMS encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationKmsEncryption), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", s3EncryptionKmsKeyId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // update kms key
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationKmsEncryptionUpdatedKey), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", s3EncryptionKmsKeyId2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // import - all optional s3 storage location optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationKmsEncryption), externalVolumeName, comment2, allowWritesFalse),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // add second storage location with all s3 optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationKmsEncryptionUpdatedKey, s3StorageLocationKmsEncryptionUpdatedName), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", s3EncryptionKmsKeyId2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", s3EncryptionKmsKeyId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // import - 2 s3 storage locations, with all s3 optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationKmsEncryptionUpdatedKey, s3StorageLocationKmsEncryptionUpdatedName), externalVolumeName, comment2, allowWritesFalse),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // change back to AWS_SSE_S3 encryption with 1 s3 storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationSseEncryption), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeSseS3)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // change back to none encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete-add-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // change back to no encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // remove allow writes and comment from config
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, "", ""),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString("").
+ HasAllowWritesString(r.BooleanDefault).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "3")),
+ ),
+ },
+ },
+ })
+}
+
+// Test volume with gcs storage locations
+func TestAcc_External_Volume_GCS(t *testing.T) {
+ _ = testenvs.GetOrSkipTest(t, testenvs.EnableAcceptance)
+ id := acc.TestClient().Ids.RandomAccountObjectIdentifier()
+ externalVolumeName := id.Name()
+ resourceId := helpers.EncodeResourceIdentifier(id)
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: acc.CheckDestroy(t, resources.ExternalVolume),
+ Steps: []resource.TestStep{
+ // without optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, "", ""),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString("").
+ HasAllowWritesString(r.BooleanDefault).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "3")),
+ ),
+ },
+ // import - without optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, "", ""),
+ ResourceName: "snowflake_external_volume.test",
+ ImportStateCheck: assert.AssertThatImport(t,
+ resourceassert.ImportedExternalVolumeResource(t, resourceId).
+ HasNameString(externalVolumeName).
+ HasStorageLocationLength(1),
+ ),
+ },
+ // set external volume optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // import - with external volume optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // add second storage location without gcs optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation, gcsStorageLocationUpdatedName), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // import - 2 storage locations without all gcs optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation, gcsStorageLocationUpdatedName), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // update comment and change back to 1 storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment2, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // update allowWrites
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // add none encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // add GCS_SSE_KMS encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationKmsEncryption), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", gcsEncryptionKmsKeyId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // update kms key
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationKmsEncryptionUpdatedKey), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", gcsEncryptionKmsKeyId2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // import - all gcs storage location optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationKmsEncryption), externalVolumeName, comment2, allowWritesFalse),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // add second storage location with all gcs optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationKmsEncryptionUpdatedKey, gcsStorageLocationKmsEncryptionUpdatedName), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", gcsEncryptionKmsKeyId2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeSseKms)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", gcsEncryptionKmsKeyId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // import - 2 gcs storage locations, with all gcs optionals set
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationKmsEncryptionUpdatedKey, gcsStorageLocationKmsEncryptionUpdatedName), externalVolumeName, comment2, allowWritesFalse),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // change back to none encryption with 1 gcs storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete-add-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // change back to no encryption
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // remove allow writes and comment from config
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocation), externalVolumeName, "", ""),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString("").
+ HasAllowWritesString(r.BooleanDefault).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "3")),
+ ),
+ },
+ },
+ })
+}
+
+// Test volume with azure storage locations
+func TestAcc_External_Volume_Azure(t *testing.T) {
+ _ = testenvs.GetOrSkipTest(t, testenvs.EnableAcceptance)
+ id := acc.TestClient().Ids.RandomAccountObjectIdentifier()
+ externalVolumeName := id.Name()
+ resourceId := helpers.EncodeResourceIdentifier(id)
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: acc.CheckDestroy(t, resources.ExternalVolume),
+ Steps: []resource.TestStep{
+ // without optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, "", ""),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString("").
+ HasAllowWritesString(r.BooleanDefault).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "3")),
+ ),
+ },
+ // import - without optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, "", ""),
+ ResourceName: "snowflake_external_volume.test",
+ ImportStateCheck: assert.AssertThatImport(t,
+ resourceassert.ImportedExternalVolumeResource(t, resourceId).
+ HasNameString(externalVolumeName).
+ HasStorageLocationLength(1),
+ ),
+ },
+ // set external volume optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // import - with external volume optionals
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // add second storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation, azureStorageLocationUpdatedName), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", azureStorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // import - 2 storage locations
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // update comment and change back to 1 storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, comment2, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // update allowWrites
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, comment2, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment2).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "4")),
+ ),
+ },
+ // remove allow writes and comment from config
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, "", ""),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString("").
+ HasAllowWritesString(r.BooleanDefault).
+ HasStorageLocationLength(1),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "3")),
+ ),
+ },
+ },
+ })
+}
+
+// Test volume with multiple storage locations that span multiple providers
+// Test adding/removing storage locations at different positions in the storage_location list
+func TestAcc_External_Volume_Multiple(t *testing.T) {
+ _ = testenvs.GetOrSkipTest(t, testenvs.EnableAcceptance)
+ id := acc.TestClient().Ids.RandomAccountObjectIdentifier()
+ externalVolumeName := id.Name()
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: acc.CheckDestroy(t, resources.ExternalVolume),
+ Steps: []resource.TestStep{
+ // one location of each provider
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // import
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ ResourceName: "snowflake_external_volume.complete",
+ ImportState: true,
+ ImportStateVerify: true,
+ },
+ // change the s3 base url at position 0
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocationUpdatedBaseUrl), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // change back the s3 base url at position 0
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // add new s3 storage location to position 0
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocationUpdatedName, s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(4),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "7")),
+ ),
+ },
+ // remove s3 storage location at position 0
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // change the encryption type of the gcs storage location at position 1
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocationUpdatedBaseUrl), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // change back the encryption type of the gcs storage location at position 1
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // add new s3 storage location to position 1
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(4),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "7")),
+ ),
+ },
+ // remove s3 storage location at position 1
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // change the tenant id of the azure storage location at position 2
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocationUpdatedTenantId), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // change back the tenant id of the azure storage location at position 2
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // add new gcs storage location to position 2
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation, gcsStorageLocationUpdatedName), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(4),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", gcsStorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "7")),
+ ),
+ },
+ // remove gcs storage location at position 2
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ // add new azure storage location to position 3
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation, azureStorageLocationUpdatedName), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(4),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_location_name", azureStorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.3.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "7")),
+ ),
+ },
+ // remove azure storage location from position 3
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/multiple/complete"),
+ ConfigVariables: externalVolumeMultiple(config.ListVariable(s3StorageLocation), config.ListVariable(gcsStorageLocation), config.ListVariable(azureStorageLocation), externalVolumeName, comment, allowWritesTrue),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesTrue).
+ HasStorageLocationLength(3),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", gcsStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", gcsStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", gcsStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", gcsEncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_location_name", azureStorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_provider", azureStorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.storage_base_url", azureStorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.2.azure_tenant_id", azureTenantId)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesTrue)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "6")),
+ ),
+ },
+ },
+ })
+}
+
+// Test that drifts are detected and fixed
+func TestAcc_External_Volume_External_Changes(t *testing.T) {
+ _ = testenvs.GetOrSkipTest(t, testenvs.EnableAcceptance)
+ id := acc.TestClient().Ids.RandomAccountObjectIdentifier()
+ externalVolumeName := id.Name()
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: acc.CheckDestroy(t, resources.ExternalVolume),
+ Steps: []resource.TestStep{
+ // create volume with 2 s3 storage locations
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // externally remove storage location
+ {
+ PreConfig: func() {
+ acc.TestClient().ExternalVolume.Alter(t, sdk.NewAlterExternalVolumeRequest(id).WithRemoveStorageLocation(s3StorageLocationName))
+ },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // externally add storage location
+ {
+ PreConfig: func() {
+ acc.TestClient().ExternalVolume.Alter(
+ t,
+ sdk.NewAlterExternalVolumeRequest(id).WithAddStorageLocation(
+ *sdk.NewExternalVolumeStorageLocationRequest().WithS3StorageLocationParams(
+ *sdk.NewS3StorageLocationParamsRequest(
+ "externally-added-s3-storage-location",
+ "s3",
+ "arn:aws:iam::123456789012:role/externally-added-role",
+ "s3://externally-added-bucket",
+ ),
+ ),
+ ),
+ )
+ },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // externally drop external volume
+ {
+ PreConfig: func() {
+ acc.TestClient().ExternalVolume.DropFunc(t, id)
+ },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // externally update comment
+ {
+ PreConfig: func() {
+ acc.TestClient().ExternalVolume.Alter(t, sdk.NewAlterExternalVolumeRequest(id).WithSet(
+ *sdk.NewAlterExternalVolumeSetRequest().WithComment(comment2),
+ ))
+ },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ // externally update allow writes
+ {
+ PreConfig: func() {
+ acc.TestClient().ExternalVolume.Alter(t, sdk.NewAlterExternalVolumeRequest(id).WithSet(
+ *sdk.NewAlterExternalVolumeSetRequest().WithAllowWrites(true),
+ ))
+ },
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/complete"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation, s3StorageLocationUpdatedName), externalVolumeName, comment, allowWritesFalse),
+ Check: assert.AssertThat(t,
+ resourceassert.ExternalVolumeResource(t, "snowflake_external_volume.complete").
+ HasNameString(externalVolumeName).
+ HasCommentString(comment).
+ HasAllowWritesString(allowWritesFalse).
+ HasStorageLocationLength(2),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_location_name", s3StorageLocationName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.0.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_location_name", s3StorageLocationName2)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_provider", s3StorageProvider)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_base_url", s3StorageBaseUrl)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.storage_aws_role_arn", s3StorageAwsRoleArn)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_type", s3EncryptionTypeNone)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "storage_location.1.encryption_kms_key_id", "")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.#", "1")),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.name", externalVolumeName)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.allow_writes", allowWritesFalse)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "show_output.0.comment", comment)),
+ assert.Check(resource.TestCheckResourceAttr("snowflake_external_volume.complete", "describe_output.#", "5")),
+ ),
+ },
+ },
+ })
+}
+
+// Test invalid parameter combinations throw errors
+func TestAcc_External_Volume_Invalid_Cases(t *testing.T) {
+ id := acc.TestClient().Ids.RandomAccountObjectIdentifier()
+ externalVolumeName := id.Name()
+ s3StorageLocationInvalidStorageProvider := getS3StorageLocation(s3StorageLocationName, "invalid-storage-provider", s3StorageBaseUrl, s3StorageAwsRoleArn, s3EncryptionTypeNone, "")
+ s3StorageLocationWithAzureTenantId := config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(s3StorageLocationName),
+ "storage_provider": config.StringVariable(s3StorageProvider),
+ "storage_base_url": config.StringVariable(s3StorageBaseUrl),
+ "storage_aws_role_arn": config.StringVariable(s3StorageAwsRoleArn),
+ "encryption_type": config.StringVariable(s3EncryptionTypeSseKms),
+ "encryption_kms_key_id": config.StringVariable(s3EncryptionKmsKeyId),
+ "azure_tenant_id": config.StringVariable(azureTenantId),
+ })
+ gcsStorageLocationAllParams := config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(gcsStorageLocationName),
+ "storage_provider": config.StringVariable(gcsStorageProvider),
+ "storage_base_url": config.StringVariable(gcsStorageBaseUrl),
+ "storage_aws_role_arn": config.StringVariable(s3StorageAwsRoleArn),
+ "encryption_type": config.StringVariable(gcsEncryptionTypeSseKms),
+ "encryption_kms_key_id": config.StringVariable(gcsEncryptionKmsKeyId),
+ "azure_tenant_id": config.StringVariable(azureTenantId),
+ })
+ azureStorageLocationAllParams := config.MapVariable(map[string]config.Variable{
+ "storage_location_name": config.StringVariable(azureStorageLocationName),
+ "storage_provider": config.StringVariable(azureStorageProvider),
+ "storage_base_url": config.StringVariable(azureStorageBaseUrl),
+ "storage_aws_role_arn": config.StringVariable(s3StorageAwsRoleArn),
+ "encryption_type": config.StringVariable(s3EncryptionTypeSseKms),
+ "encryption_kms_key_id": config.StringVariable(s3EncryptionKmsKeyId),
+ "azure_tenant_id": config.StringVariable(azureTenantId),
+ })
+
+ resource.Test(t, resource.TestCase{
+ ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
+ PreCheck: func() { acc.TestAccPreCheck(t) },
+ TerraformVersionChecks: []tfversion.TerraformVersionCheck{
+ tfversion.RequireAbove(tfversion.Version1_5_0),
+ },
+ CheckDestroy: acc.CheckDestroy(t, resources.Warehouse),
+ Steps: []resource.TestStep{
+ // invalid storage provider test
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationInvalidStorageProvider), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("invalid storage provider: invalid-storage-provider"),
+ },
+ // no storage locations test
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/basic"),
+ ConfigVariables: externalVolume(config.ListVariable(), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("At least 1 \"storage_location\" blocks are required"),
+ },
+ // aws storage location doesn't specify storage_aws_role_arn
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/no-role-arn"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocation), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, missing storage_aws_role_arn key in an s3 storage location"),
+ },
+ // azure storage location doesn't specify azure_tenant_id
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/no-tenant-id"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocation), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, missing azure_tenant_id provider key in an azure storage location"),
+ },
+ // azure_tenant_id specified for s3 storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/s3/with-azure-tenant-id"),
+ ConfigVariables: externalVolume(config.ListVariable(s3StorageLocationWithAzureTenantId), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, azure_tenant_id provided for s3 storage location"),
+ },
+ // storage_aws_role_arn specified for gcs storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationAllParams), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, storage_aws_role_arn provided for gcs storage location"),
+ },
+ // azure_tenant_id specified for gcs storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/gcs/with-azure-tenant-id"),
+ ConfigVariables: externalVolume(config.ListVariable(gcsStorageLocationAllParams), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, azure_tenant_id provided for gcs storage location"),
+ },
+ // storage_aws_role_arn specified for azure storage location
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/with-storage-aws-role-arn"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocationAllParams), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, storage_aws_role_arn provided for azure storage location"),
+ },
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/with-encryption-type"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocationAllParams), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, encryption_type provided for azure storage location"),
+ },
+ {
+ ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ExternalVolume/azure/with-encryption-kms-key-id"),
+ ConfigVariables: externalVolume(config.ListVariable(azureStorageLocationAllParams), externalVolumeName, "", ""),
+ ExpectError: regexp.MustCompile("unable to extract storage location, encryption_kms_key_id provided for azure storage location"),
+ },
+ },
+ })
+}
diff --git a/pkg/resources/helpers.go b/pkg/resources/helpers.go
index a7c78d2532..8a11630652 100644
--- a/pkg/resources/helpers.go
+++ b/pkg/resources/helpers.go
@@ -330,3 +330,183 @@ func ListDiff[T comparable](beforeList []T, afterList []T) (added []T, removed [
return added, removed
}
+
+func StorageLocationsEqual(s1 sdk.ExternalVolumeStorageLocation, s2 sdk.ExternalVolumeStorageLocation) (bool, error) {
+ s1StorageProvider, err := GetStorageLocationStorageProvider(s1)
+ if err != nil {
+ return false, err
+ }
+
+ s2StorageProvider, err := GetStorageLocationStorageProvider(s2)
+ if err != nil {
+ return false, err
+ }
+
+ if s1StorageProvider != s2StorageProvider {
+ return false, nil
+ }
+
+ switch s1StorageProvider {
+ case sdk.StorageProviderS3, sdk.StorageProviderS3GOV:
+ externalIdsEqual := s1.S3StorageLocationParams.StorageAwsExternalId == nil && s2.S3StorageLocationParams.StorageAwsExternalId == nil ||
+ (s1.S3StorageLocationParams.StorageAwsExternalId != nil && s2.S3StorageLocationParams.StorageAwsExternalId != nil &&
+ *s1.S3StorageLocationParams.StorageAwsExternalId == *s2.S3StorageLocationParams.StorageAwsExternalId)
+
+ if externalIdsEqual &&
+ s1.S3StorageLocationParams.Name == s2.S3StorageLocationParams.Name &&
+ s1.S3StorageLocationParams.StorageProvider == s2.S3StorageLocationParams.StorageProvider &&
+ s1.S3StorageLocationParams.StorageAwsRoleArn == s2.S3StorageLocationParams.StorageAwsRoleArn &&
+ s1.S3StorageLocationParams.StorageBaseUrl == s2.S3StorageLocationParams.StorageBaseUrl {
+
+ if s1.S3StorageLocationParams.Encryption == nil && s2.S3StorageLocationParams.Encryption == nil {
+ return true, nil
+ } else if s1.S3StorageLocationParams.Encryption != nil && s2.S3StorageLocationParams.Encryption != nil {
+ typeEqual := s1.S3StorageLocationParams.Encryption.Type == s2.S3StorageLocationParams.Encryption.Type
+ kmsKeyIdEqual := s1.S3StorageLocationParams.Encryption.KmsKeyId == nil && s2.S3StorageLocationParams.Encryption.KmsKeyId == nil ||
+ (s1.S3StorageLocationParams.Encryption.KmsKeyId != nil && s2.S3StorageLocationParams.Encryption.KmsKeyId != nil &&
+ *s1.S3StorageLocationParams.Encryption.KmsKeyId == *s2.S3StorageLocationParams.Encryption.KmsKeyId)
+ return typeEqual && kmsKeyIdEqual, nil
+ }
+ }
+ case sdk.StorageProviderGCS:
+ if s1.GCSStorageLocationParams.Name == s2.GCSStorageLocationParams.Name &&
+ s1.GCSStorageLocationParams.StorageBaseUrl == s2.GCSStorageLocationParams.StorageBaseUrl {
+
+ if s1.GCSStorageLocationParams.Encryption == nil && s2.GCSStorageLocationParams.Encryption == nil {
+ return true, nil
+ } else if s1.GCSStorageLocationParams.Encryption != nil && s2.GCSStorageLocationParams.Encryption != nil {
+ typeEqual := s1.GCSStorageLocationParams.Encryption.Type == s2.GCSStorageLocationParams.Encryption.Type
+ kmsKeyIdEqual := s1.GCSStorageLocationParams.Encryption.KmsKeyId == nil && s2.GCSStorageLocationParams.Encryption.KmsKeyId == nil ||
+ (s1.GCSStorageLocationParams.Encryption.KmsKeyId != nil && s2.GCSStorageLocationParams.Encryption.KmsKeyId != nil &&
+ *s1.GCSStorageLocationParams.Encryption.KmsKeyId == *s2.GCSStorageLocationParams.Encryption.KmsKeyId)
+ return typeEqual && kmsKeyIdEqual, nil
+ }
+ }
+ case sdk.StorageProviderAzure:
+ return s1.AzureStorageLocationParams.Name == s2.AzureStorageLocationParams.Name &&
+ s1.AzureStorageLocationParams.AzureTenantId == s2.AzureStorageLocationParams.AzureTenantId &&
+ s1.AzureStorageLocationParams.StorageBaseUrl == s2.AzureStorageLocationParams.StorageBaseUrl, nil
+ }
+
+ return false, nil
+}
+
+// Returns a copy of the given storage location with a 'temp_' prefix on the Name field
+func CopyStorageLocationWithTempName(
+ storageLocation sdk.ExternalVolumeStorageLocation,
+) (sdk.ExternalVolumeStorageLocation, error) {
+ storageProvider, err := GetStorageLocationStorageProvider(storageLocation)
+ if err != nil {
+ return sdk.ExternalVolumeStorageLocation{}, err
+ }
+
+ currName, err := GetStorageLocationName(storageLocation)
+ if err != nil {
+ return sdk.ExternalVolumeStorageLocation{}, err
+ }
+
+ newName := fmt.Sprintf("temp_%s", currName)
+ var tempNameStorageLocation sdk.ExternalVolumeStorageLocation
+ switch storageProvider {
+ case sdk.StorageProviderS3, sdk.StorageProviderS3GOV:
+ tempNameStorageLocation = sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: newName,
+ StorageProvider: storageLocation.S3StorageLocationParams.StorageProvider,
+ StorageBaseUrl: storageLocation.S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: storageLocation.S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: storageLocation.S3StorageLocationParams.StorageAwsExternalId,
+ Encryption: storageLocation.S3StorageLocationParams.Encryption,
+ },
+ }
+ case sdk.StorageProviderGCS:
+ tempNameStorageLocation = sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: newName,
+ StorageBaseUrl: storageLocation.GCSStorageLocationParams.StorageBaseUrl,
+ Encryption: storageLocation.GCSStorageLocationParams.Encryption,
+ },
+ }
+ case sdk.StorageProviderAzure:
+ tempNameStorageLocation = sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: newName,
+ StorageBaseUrl: storageLocation.AzureStorageLocationParams.StorageBaseUrl,
+ AzureTenantId: storageLocation.AzureStorageLocationParams.AzureTenantId,
+ },
+ }
+ }
+
+ return tempNameStorageLocation, nil
+}
+
+func GetStorageLocationName(s sdk.ExternalVolumeStorageLocation) (string, error) {
+ if s.S3StorageLocationParams != nil && (*s.S3StorageLocationParams != sdk.S3StorageLocationParams{}) {
+ if len(s.S3StorageLocationParams.Name) == 0 {
+ return "", fmt.Errorf("Invalid S3 storage location - no name set")
+ }
+
+ return s.S3StorageLocationParams.Name, nil
+ } else if s.GCSStorageLocationParams != nil && (*s.GCSStorageLocationParams != sdk.GCSStorageLocationParams{}) {
+ if len(s.GCSStorageLocationParams.Name) == 0 {
+ return "", fmt.Errorf("Invalid GCS storage location - no name set")
+ }
+
+ return s.GCSStorageLocationParams.Name, nil
+ } else if s.AzureStorageLocationParams != nil && (*s.AzureStorageLocationParams != sdk.AzureStorageLocationParams{}) {
+ if len(s.AzureStorageLocationParams.Name) == 0 {
+ return "", fmt.Errorf("Invalid Azure storage location - no name set")
+ }
+
+ return s.AzureStorageLocationParams.Name, nil
+ } else {
+ return "", fmt.Errorf("Invalid storage location")
+ }
+}
+
+func GetStorageLocationStorageProvider(s sdk.ExternalVolumeStorageLocation) (sdk.StorageProvider, error) {
+ if s.S3StorageLocationParams != nil && (*s.S3StorageLocationParams != sdk.S3StorageLocationParams{}) {
+ return sdk.ToStorageProvider(string(s.S3StorageLocationParams.StorageProvider))
+ } else if s.GCSStorageLocationParams != nil && (*s.GCSStorageLocationParams != sdk.GCSStorageLocationParams{}) {
+ return sdk.StorageProviderGCS, nil
+ } else if s.AzureStorageLocationParams != nil && (*s.AzureStorageLocationParams != sdk.AzureStorageLocationParams{}) {
+ return sdk.StorageProviderAzure, nil
+ } else {
+ return "", fmt.Errorf("Invalid storage location")
+ }
+}
+
+// Returns the index of the last matching elements in the list
+// e.g. [1,2,3] [1,3,2] -> 0, [1,2,3] [1,2,4] -> 1
+// -1 is returned if there are no common prefixes in the list
+func LongestCommonPrefix(a []sdk.ExternalVolumeStorageLocation, b []sdk.ExternalVolumeStorageLocation) (int, error) {
+ longestCommonPrefix := 0
+
+ if len(a) == 0 || len(b) == 0 {
+ return -1, nil
+ }
+
+ first_elements_equal, err := StorageLocationsEqual(a[0], b[0])
+ if err != nil {
+ return -1, err
+ }
+
+ if !first_elements_equal {
+ return -1, nil
+ }
+
+ for i := 1; i < min(len(a), len(b)); i++ {
+ storageLocationsAreEqual, err := StorageLocationsEqual(a[i], b[i])
+ if err != nil {
+ return -1, err
+ }
+
+ if !storageLocationsAreEqual {
+ break
+ }
+
+ longestCommonPrefix = i
+ }
+
+ return longestCommonPrefix, nil
+}
diff --git a/pkg/resources/helpers_test.go b/pkg/resources/helpers_test.go
index c143d40f03..f4255c07af 100644
--- a/pkg/resources/helpers_test.go
+++ b/pkg/resources/helpers_test.go
@@ -403,3 +403,1769 @@ func Test_DataTypeIssue3007DiffSuppressFunc(t *testing.T) {
})
}
}
+
+// External volume helper tests
+
+var s3StorageLocationA = sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+}
+
+var s3StorageLocationB = sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName2,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+}
+
+var azureStorageLocationA = sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+}
+
+var azureStorageLocationB = sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName2,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+}
+
+var gcsStorageLocationA = sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+}
+
+var gcsStorageLocationB = sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName2,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+}
+
+var gcsStorageLocationC = sdk.GCSStorageLocationParams{
+ Name: "test",
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+}
+
+var s3GovStorageLocationA = sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+}
+
+func Test_GetStorageLocationName(t *testing.T) {
+ testCases := []struct {
+ Name string
+ StorageLocation sdk.ExternalVolumeStorageLocation
+ ExpectedName string
+ }{
+ {
+ Name: "S3 storage location name succesfully read",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &s3StorageLocationA},
+ ExpectedName: s3StorageLocationA.Name,
+ },
+ {
+ Name: "S3GOV storage location name succesfully read",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &s3GovStorageLocationA},
+ ExpectedName: s3GovStorageLocationA.Name,
+ },
+ {
+ Name: "GCS storage location name succesfully read",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{GCSStorageLocationParams: &gcsStorageLocationA},
+ ExpectedName: gcsStorageLocationA.Name,
+ },
+ {
+ Name: "Azure storage location name succesfully read",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{AzureStorageLocationParams: &azureStorageLocationA},
+ ExpectedName: azureStorageLocationA.Name,
+ },
+ }
+
+ invalidTestCases := []struct {
+ Name string
+ StorageLocation sdk.ExternalVolumeStorageLocation
+ }{
+ {
+ Name: "Empty S3 storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &sdk.S3StorageLocationParams{}},
+ },
+ {
+ Name: "Empty GCS storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{GCSStorageLocationParams: &sdk.GCSStorageLocationParams{}},
+ },
+ {
+ Name: "Empty Azure storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{AzureStorageLocationParams: &sdk.AzureStorageLocationParams{}},
+ },
+ {
+ Name: "Empty storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ name, err := resources.GetStorageLocationName(tc.StorageLocation)
+ require.NoError(t, err)
+ assert.Equal(t, tc.ExpectedName, name)
+ })
+ }
+ for _, tc := range invalidTestCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ _, err := resources.GetStorageLocationName(tc.StorageLocation)
+ require.Error(t, err)
+ })
+ }
+}
+
+func Test_GetStorageLocationStorageProvider(t *testing.T) {
+ testCases := []struct {
+ Name string
+ StorageLocation sdk.ExternalVolumeStorageLocation
+ ExpectedStorageProvider sdk.StorageProvider
+ }{
+ {
+ Name: "S3 storage provider",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &s3StorageLocationA},
+ ExpectedStorageProvider: sdk.StorageProviderS3,
+ },
+ {
+ Name: "S3GOV storage provider",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &s3GovStorageLocationA},
+ ExpectedStorageProvider: sdk.StorageProviderS3GOV,
+ },
+ {
+ Name: "GCS storage provider",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{GCSStorageLocationParams: &gcsStorageLocationA},
+ ExpectedStorageProvider: sdk.StorageProviderGCS,
+ },
+ {
+ Name: "Azure storage provider",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{AzureStorageLocationParams: &azureStorageLocationA},
+ ExpectedStorageProvider: sdk.StorageProviderAzure,
+ },
+ }
+
+ invalidTestCases := []struct {
+ Name string
+ StorageLocation sdk.ExternalVolumeStorageLocation
+ }{
+ {
+ Name: "Empty S3 storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &sdk.S3StorageLocationParams{}},
+ },
+ {
+ Name: "Empty GCS storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{GCSStorageLocationParams: &sdk.GCSStorageLocationParams{}},
+ },
+ {
+ Name: "Empty Azure storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{AzureStorageLocationParams: &sdk.AzureStorageLocationParams{}},
+ },
+ {
+ Name: "Empty storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ storageProvider, err := resources.GetStorageLocationStorageProvider(tc.StorageLocation)
+ require.NoError(t, err)
+ assert.Equal(t, tc.ExpectedStorageProvider, storageProvider)
+ })
+ }
+ for _, tc := range invalidTestCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ _, err := resources.GetStorageLocationName(tc.StorageLocation)
+ require.Error(t, err)
+ })
+ }
+}
+
+var s3StorageAwsExternalId = "1234567890"
+
+func Test_CopyStorageLocationWithTempName(t *testing.T) {
+ t.Run("S3 storage location", func(t *testing.T) {
+ storageLocationInput := sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &s3StorageLocationA}
+ copiedStorageLocation, err := resources.CopyStorageLocationWithTempName(storageLocationInput)
+ require.NoError(t, err)
+ assert.Equal(t, copiedStorageLocation.S3StorageLocationParams.Name, fmt.Sprintf("temp_%s", s3StorageLocationA.Name))
+ assert.Equal(t, copiedStorageLocation.S3StorageLocationParams.StorageProvider, s3StorageLocationA.StorageProvider)
+ assert.Equal(t, copiedStorageLocation.S3StorageLocationParams.StorageBaseUrl, s3StorageLocationA.StorageBaseUrl)
+ assert.Equal(t, copiedStorageLocation.S3StorageLocationParams.StorageAwsRoleArn, s3StorageLocationA.StorageAwsRoleArn)
+ assert.Equal(t, copiedStorageLocation.S3StorageLocationParams.StorageAwsExternalId, s3StorageLocationA.StorageAwsExternalId)
+ assert.Equal(t, copiedStorageLocation.S3StorageLocationParams.Encryption.Type, s3StorageLocationA.Encryption.Type)
+ assert.Equal(t, *copiedStorageLocation.S3StorageLocationParams.Encryption.KmsKeyId, *s3StorageLocationA.Encryption.KmsKeyId)
+ })
+
+ t.Run("GCS storage location", func(t *testing.T) {
+ storageLocationInput := sdk.ExternalVolumeStorageLocation{GCSStorageLocationParams: &gcsStorageLocationA}
+ copiedStorageLocation, err := resources.CopyStorageLocationWithTempName(storageLocationInput)
+ require.NoError(t, err)
+ assert.Equal(t, copiedStorageLocation.GCSStorageLocationParams.Name, fmt.Sprintf("temp_%s", gcsStorageLocationA.Name))
+ assert.Equal(t, copiedStorageLocation.GCSStorageLocationParams.StorageBaseUrl, gcsStorageLocationA.StorageBaseUrl)
+ assert.Equal(t, copiedStorageLocation.GCSStorageLocationParams.Encryption.Type, gcsStorageLocationA.Encryption.Type)
+ assert.Equal(t, *copiedStorageLocation.GCSStorageLocationParams.Encryption.KmsKeyId, *gcsStorageLocationA.Encryption.KmsKeyId)
+ })
+
+ t.Run("Azure storage location", func(t *testing.T) {
+ storageLocationInput := sdk.ExternalVolumeStorageLocation{AzureStorageLocationParams: &azureStorageLocationA}
+ copiedStorageLocation, err := resources.CopyStorageLocationWithTempName(storageLocationInput)
+ require.NoError(t, err)
+ assert.Equal(t, copiedStorageLocation.AzureStorageLocationParams.Name, fmt.Sprintf("temp_%s", azureStorageLocationA.Name))
+ assert.Equal(t, copiedStorageLocation.AzureStorageLocationParams.StorageBaseUrl, azureStorageLocationA.StorageBaseUrl)
+ assert.Equal(t, copiedStorageLocation.AzureStorageLocationParams.AzureTenantId, azureStorageLocationA.AzureTenantId)
+ })
+
+ invalidTestCases := []struct {
+ Name string
+ StorageLocation sdk.ExternalVolumeStorageLocation
+ }{
+ {
+ Name: "Empty S3 storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{S3StorageLocationParams: &sdk.S3StorageLocationParams{}},
+ },
+ {
+ Name: "Empty GCS storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{GCSStorageLocationParams: &sdk.GCSStorageLocationParams{}},
+ },
+ {
+ Name: "Empty Azure storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{AzureStorageLocationParams: &sdk.AzureStorageLocationParams{}},
+ },
+ {
+ Name: "Empty storage location",
+ StorageLocation: sdk.ExternalVolumeStorageLocation{},
+ },
+ }
+
+ for _, tc := range invalidTestCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ _, err := resources.CopyStorageLocationWithTempName(tc.StorageLocation)
+ require.Error(t, err)
+ })
+ }
+}
+
+func Test_LongestCommonPrefix(t *testing.T) {
+ testCases := []struct {
+ Name string
+ ListA []sdk.ExternalVolumeStorageLocation
+ ListB []sdk.ExternalVolumeStorageLocation
+ ExpectedOutput int
+ }{
+ {
+ Name: "Two empty lists",
+ ListA: []sdk.ExternalVolumeStorageLocation{},
+ ListB: []sdk.ExternalVolumeStorageLocation{},
+ ExpectedOutput: -1,
+ },
+ {
+ Name: "First list empty",
+ ListA: []sdk.ExternalVolumeStorageLocation{},
+ ListB: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ExpectedOutput: -1,
+ },
+ {
+ Name: "Second list empty",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{},
+ ExpectedOutput: -1,
+ },
+ {
+ Name: "Lists with no common prefix - length 1",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationB}},
+ ExpectedOutput: -1,
+ },
+ {
+ Name: "Lists with no common prefix - length 2",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}, {AzureStorageLocationParams: &azureStorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationB}, {AzureStorageLocationParams: &azureStorageLocationB}},
+ ExpectedOutput: -1,
+ },
+ {
+ Name: "Identical lists - length 1",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ExpectedOutput: 0,
+ },
+ {
+ Name: "Identical lists - length 2",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}, {AzureStorageLocationParams: &azureStorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}, {AzureStorageLocationParams: &azureStorageLocationA}},
+ ExpectedOutput: 1,
+ },
+ {
+ Name: "Identical lists - length 3",
+ ListA: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {S3StorageLocationParams: &s3GovStorageLocationA},
+ },
+ ListB: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {S3StorageLocationParams: &s3GovStorageLocationA},
+ },
+ ExpectedOutput: 2,
+ },
+ {
+ Name: "Lists with a common prefix - length 3, matching up to and including index 1",
+ ListA: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationA},
+ },
+ ListB: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationB},
+ },
+ ExpectedOutput: 1,
+ },
+ {
+ Name: "Lists with a common prefix - length 4, matching up to and including index 2",
+ ListA: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationB},
+ },
+ ListB: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationC},
+ },
+ ExpectedOutput: 2,
+ },
+ {
+ Name: "Lists with a common prefix - length 4, matching up to and including index 1",
+ ListA: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationC},
+ },
+ ListB: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationB},
+ {GCSStorageLocationParams: &gcsStorageLocationC},
+ },
+ ExpectedOutput: 1,
+ },
+ {
+ Name: "Lists with a common prefix - different lengths, matching up to and including index 1 (last index of shorter list)",
+ ListA: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationA},
+ },
+ ListB: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ },
+ ExpectedOutput: 1,
+ },
+ {
+ Name: "Lists with a common prefix - different lengths, matching up to and including index 2",
+ ListA: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {S3StorageLocationParams: &s3StorageLocationB},
+ {GCSStorageLocationParams: &gcsStorageLocationA},
+ {GCSStorageLocationParams: &gcsStorageLocationB},
+ {AzureStorageLocationParams: &azureStorageLocationB},
+ },
+ ListB: []sdk.ExternalVolumeStorageLocation{
+ {S3StorageLocationParams: &s3StorageLocationA},
+ {AzureStorageLocationParams: &azureStorageLocationA},
+ {S3StorageLocationParams: &s3StorageLocationB},
+ {GCSStorageLocationParams: &gcsStorageLocationB},
+ {AzureStorageLocationParams: &azureStorageLocationB},
+ },
+ ExpectedOutput: 2,
+ },
+ }
+
+ invalidTestCases := []struct {
+ Name string
+ ListA []sdk.ExternalVolumeStorageLocation
+ ListB []sdk.ExternalVolumeStorageLocation
+ }{
+ {
+ Name: "Empty S3 storage location",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &sdk.S3StorageLocationParams{}}},
+ },
+ {
+ Name: "Empty GCS storage location",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{GCSStorageLocationParams: &sdk.GCSStorageLocationParams{}}},
+ },
+ {
+ Name: "Empty Azure storage location",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{AzureStorageLocationParams: &sdk.AzureStorageLocationParams{}}},
+ },
+ {
+ Name: "Empty storage location",
+ ListA: []sdk.ExternalVolumeStorageLocation{{S3StorageLocationParams: &s3StorageLocationA}},
+ ListB: []sdk.ExternalVolumeStorageLocation{{}},
+ },
+ }
+
+ for _, tc := range invalidTestCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ _, err := resources.LongestCommonPrefix(tc.ListA, tc.ListB)
+ require.Error(t, err)
+ })
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ longestCommonPrefix, err := resources.LongestCommonPrefix(tc.ListA, tc.ListB)
+ require.NoError(t, err)
+ assert.Equal(t, tc.ExpectedOutput, longestCommonPrefix)
+ })
+ }
+}
+
+func Test_StorageLocationsEqual(t *testing.T) {
+ equalCases := []struct {
+ Name string
+ StorageLocationA sdk.ExternalVolumeStorageLocation
+ StorageLocationB sdk.ExternalVolumeStorageLocation
+ }{
+ {
+ Name: "S3 storage location",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - sse s3 encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - none encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionNone,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionNone,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - no encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - no StorageAwsExternalId",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ },
+ {
+ Name: "S3Gov storage location",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3Gov storage location - sse s3 encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3Gov storage location - none encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionNone,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionNone,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3Gov storage location - no encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ },
+ {
+ Name: "S3Gov storage location - no StorageAwsExternalId",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ },
+ {
+ Name: "GCS storage location",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - no kms key id",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeNone,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeNone,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - no encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ },
+ },
+ },
+ {
+ Name: "Azure storage location",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ }
+
+ notEqualCases := []struct {
+ Name string
+ StorageLocationA sdk.ExternalVolumeStorageLocation
+ StorageLocationB sdk.ExternalVolumeStorageLocation
+ }{
+ // Types that don't match
+ {
+ Name: "S3/S3Gov storage locations",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3/GCS storage locations",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3/Azure storage locations",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ {
+ Name: "S3Gov/GCS storage locations",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3Gov/Azure storage locations",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ {
+ Name: "GCS/Azure storage locations",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ // Types that match, but some have optional fields and others don't
+ {
+ Name: "S3 storage location - missing kms key id",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - missing encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - missing StorageAwsExternalId",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - missing kms key id",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - missing encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseS3,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - missing StorageAwsExternalId",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - missing kms key id",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeNone,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeNone,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - missing encryption",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeNone,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ },
+ },
+ },
+ // Types and fields match, but values not equal
+ {
+ Name: "S3 storage location - names don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: "a",
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - base urls don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - role arns",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - external ids don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageLocationName,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - encryption types don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionNone,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3 storage location - kms key ids don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3StorageLocationName,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - names don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: "a",
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - base urls don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: "a",
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - role arns",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: "a",
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - external ids don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageLocationName,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - encryption types don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionNone,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "S3GOV storage location - kms key ids don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3StorageLocationName,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3GOV,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - names don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: "a",
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - base urls don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: "a",
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - encryption types don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeNone,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "GCS storage location - encryption kms ids don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsStorageLocationName,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "Azure storage location - names don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: "a",
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ {
+ Name: "Azure storage location - base urls don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: "a",
+ AzureTenantId: azureTenantId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ {
+ Name: "Azure storage location - tenant ids don't match",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: "a",
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ }
+
+ invalidTestCases := []struct {
+ Name string
+ StorageLocationA sdk.ExternalVolumeStorageLocation
+ StorageLocationB sdk.ExternalVolumeStorageLocation
+ }{
+ {
+ Name: "Empty S3 storage location as argument 1",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{},
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "Empty S3 storage location as argument 2",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ StorageAwsExternalId: &s3StorageAwsExternalId,
+ Encryption: &sdk.ExternalVolumeS3Encryption{
+ Type: sdk.S3EncryptionTypeSseKms,
+ KmsKeyId: &s3EncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{},
+ },
+ },
+ {
+ Name: "Empty GCS storage location as argument 1",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{},
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ },
+ {
+ Name: "Empty GCS storage location as argument 2",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{
+ Name: gcsStorageLocationName,
+ StorageBaseUrl: gcsStorageBaseUrl,
+ Encryption: &sdk.ExternalVolumeGCSEncryption{
+ Type: sdk.GCSEncryptionTypeSseKms,
+ KmsKeyId: &gcsEncryptionKmsKeyId,
+ },
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ GCSStorageLocationParams: &sdk.GCSStorageLocationParams{},
+ },
+ },
+ {
+ Name: "Empty Azure storage location as argument 1",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{},
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ },
+ {
+ Name: "Empty Azure storage location as argument 2",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{
+ Name: azureStorageLocationName,
+ StorageBaseUrl: azureStorageBaseUrl,
+ AzureTenantId: azureTenantId,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ AzureStorageLocationParams: &sdk.AzureStorageLocationParams{},
+ },
+ },
+ {
+ Name: "Empty storage location as argument 1",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{},
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ },
+ {
+ Name: "Empty storage location as argument 2",
+ StorageLocationA: sdk.ExternalVolumeStorageLocation{
+ S3StorageLocationParams: &sdk.S3StorageLocationParams{
+ Name: s3StorageLocationName,
+ StorageProvider: sdk.S3StorageProviderS3,
+ StorageBaseUrl: s3StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageAwsRoleArn,
+ },
+ },
+ StorageLocationB: sdk.ExternalVolumeStorageLocation{},
+ },
+ }
+
+ for _, tc := range equalCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ storageLocationsEqual, err := resources.StorageLocationsEqual(tc.StorageLocationA, tc.StorageLocationB)
+ require.NoError(t, err)
+ assert.True(t, storageLocationsEqual)
+ })
+ }
+
+ for _, tc := range notEqualCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ storageLocationsEqual, err := resources.StorageLocationsEqual(tc.StorageLocationA, tc.StorageLocationB)
+ require.NoError(t, err)
+ assert.False(t, storageLocationsEqual)
+ })
+ }
+
+ for _, tc := range invalidTestCases {
+ t.Run(tc.Name, func(t *testing.T) {
+ _, err := resources.StorageLocationsEqual(tc.StorageLocationA, tc.StorageLocationB)
+ require.Error(t, err)
+ })
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/basic/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/basic/test.tf
new file mode 100644
index 0000000000..e0f7a42a41
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/basic/test.tf
@@ -0,0 +1,12 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/basic/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/basic/variables.tf
new file mode 100644
index 0000000000..a704fdd13a
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/basic/variables.tf
@@ -0,0 +1,6 @@
+variable "name" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/complete/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/complete/test.tf
new file mode 100644
index 0000000000..2744f4180f
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/complete/test.tf
@@ -0,0 +1,14 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/complete/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/complete/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/complete/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/no-tenant-id/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/no-tenant-id/test.tf
new file mode 100644
index 0000000000..e7b761012e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/no-tenant-id/test.tf
@@ -0,0 +1,11 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/no-tenant-id/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/no-tenant-id/variables.tf
new file mode 100644
index 0000000000..a704fdd13a
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/no-tenant-id/variables.tf
@@ -0,0 +1,6 @@
+variable "name" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-kms-key-id/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-kms-key-id/test.tf
new file mode 100644
index 0000000000..9c73c53a6e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-kms-key-id/test.tf
@@ -0,0 +1,15 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ encryption_kms_key_id = storage_location.value["encryption_kms_key_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-kms-key-id/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-kms-key-id/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-kms-key-id/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-type/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-type/test.tf
new file mode 100644
index 0000000000..dabc182639
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-type/test.tf
@@ -0,0 +1,15 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ encryption_type = storage_location.value["encryption_type"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-type/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-type/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-encryption-type/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-storage-aws-role-arn/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-storage-aws-role-arn/test.tf
new file mode 100644
index 0000000000..e61ce6e150
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-storage-aws-role-arn/test.tf
@@ -0,0 +1,15 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-storage-aws-role-arn/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-storage-aws-role-arn/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/azure/with-storage-aws-role-arn/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/basic/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/basic/test.tf
new file mode 100644
index 0000000000..e7b761012e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/basic/test.tf
@@ -0,0 +1,11 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/basic/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/basic/variables.tf
new file mode 100644
index 0000000000..a704fdd13a
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/basic/variables.tf
@@ -0,0 +1,6 @@
+variable "name" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-encryption-type/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-encryption-type/test.tf
new file mode 100644
index 0000000000..4e061d603a
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-encryption-type/test.tf
@@ -0,0 +1,14 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ encryption_type = storage_location.value["encryption_type"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-encryption-type/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-encryption-type/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-encryption-type/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type/test.tf
new file mode 100644
index 0000000000..6ae64ecfa3
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type/test.tf
@@ -0,0 +1,15 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ encryption_type = storage_location.value["encryption_type"]
+ encryption_kms_key_id = storage_location.value["encryption_kms_key_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete-add-kms-encryption-type/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete/test.tf
new file mode 100644
index 0000000000..85042d7b39
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete/test.tf
@@ -0,0 +1,13 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/complete/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-azure-tenant-id/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-azure-tenant-id/test.tf
new file mode 100644
index 0000000000..1fd261f47c
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-azure-tenant-id/test.tf
@@ -0,0 +1,16 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ encryption_type = storage_location.value["encryption_type"]
+ encryption_kms_key_id = storage_location.value["encryption_kms_key_id"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-azure-tenant-id/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-azure-tenant-id/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-azure-tenant-id/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn/test.tf
new file mode 100644
index 0000000000..713a8e9bf0
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn/test.tf
@@ -0,0 +1,16 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ encryption_type = storage_location.value["encryption_type"]
+ encryption_kms_key_id = storage_location.value["encryption_kms_key_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/gcs/with-storage-aws-role-arn/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/multiple/complete/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/multiple/complete/test.tf
new file mode 100644
index 0000000000..25c33e59ad
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/multiple/complete/test.tf
@@ -0,0 +1,31 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.s3_storage_locations
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ }
+ }
+ dynamic "storage_location" {
+ for_each = var.gcs_storage_locations
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ }
+ }
+ dynamic "storage_location" {
+ for_each = var.azure_storage_locations
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/multiple/complete/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/multiple/complete/variables.tf
new file mode 100644
index 0000000000..de24426a29
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/multiple/complete/variables.tf
@@ -0,0 +1,18 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "s3_storage_locations" {
+ type = list(map(string))
+}
+variable "gcs_storage_locations" {
+ type = list(map(string))
+}
+variable "azure_storage_locations" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/basic/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/basic/test.tf
new file mode 100644
index 0000000000..ec5f3d0d87
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/basic/test.tf
@@ -0,0 +1,12 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/basic/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/basic/variables.tf
new file mode 100644
index 0000000000..a704fdd13a
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/basic/variables.tf
@@ -0,0 +1,6 @@
+variable "name" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-encryption-type/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-encryption-type/test.tf
new file mode 100644
index 0000000000..7c043f8d3d
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-encryption-type/test.tf
@@ -0,0 +1,15 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ encryption_type = storage_location.value["encryption_type"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-encryption-type/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-encryption-type/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-encryption-type/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type/test.tf
new file mode 100644
index 0000000000..713a8e9bf0
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type/test.tf
@@ -0,0 +1,16 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ encryption_type = storage_location.value["encryption_type"]
+ encryption_kms_key_id = storage_location.value["encryption_kms_key_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete-add-kms-encryption-type/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete/test.tf
new file mode 100644
index 0000000000..89c7b847f0
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete/test.tf
@@ -0,0 +1,14 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/complete/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/no-role-arn/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/no-role-arn/test.tf
new file mode 100644
index 0000000000..e7b761012e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/no-role-arn/test.tf
@@ -0,0 +1,11 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/no-role-arn/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/no-role-arn/variables.tf
new file mode 100644
index 0000000000..a704fdd13a
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/no-role-arn/variables.tf
@@ -0,0 +1,6 @@
+variable "name" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/with-azure-tenant-id/test.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/with-azure-tenant-id/test.tf
new file mode 100644
index 0000000000..9c6a49d6a7
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/with-azure-tenant-id/test.tf
@@ -0,0 +1,17 @@
+resource "snowflake_external_volume" "complete" {
+ name = var.name
+ comment = var.comment
+ allow_writes = var.allow_writes
+ dynamic "storage_location" {
+ for_each = var.storage_location
+ content {
+ storage_location_name = storage_location.value["storage_location_name"]
+ storage_provider = storage_location.value["storage_provider"]
+ storage_base_url = storage_location.value["storage_base_url"]
+ storage_aws_role_arn = storage_location.value["storage_aws_role_arn"]
+ encryption_type = storage_location.value["encryption_type"]
+ encryption_kms_key_id = storage_location.value["encryption_kms_key_id"]
+ azure_tenant_id = storage_location.value["azure_tenant_id"]
+ }
+ }
+}
diff --git a/pkg/resources/testdata/TestAcc_ExternalVolume/s3/with-azure-tenant-id/variables.tf b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/with-azure-tenant-id/variables.tf
new file mode 100644
index 0000000000..e3491d338e
--- /dev/null
+++ b/pkg/resources/testdata/TestAcc_ExternalVolume/s3/with-azure-tenant-id/variables.tf
@@ -0,0 +1,12 @@
+variable "name" {
+ type = string
+}
+variable "comment" {
+ type = string
+}
+variable "allow_writes" {
+ type = string
+}
+variable "storage_location" {
+ type = list(map(string))
+}
diff --git a/pkg/schemas/external_volume.go b/pkg/schemas/external_volume.go
new file mode 100644
index 0000000000..0a6d9184b1
--- /dev/null
+++ b/pkg/schemas/external_volume.go
@@ -0,0 +1,47 @@
+package schemas
+
+import (
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+var DescribeExternalVolumeSchema = map[string]*schema.Schema{
+ "parent": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "type": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "value": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "default": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+}
+
+var _ = ShowExternalVolumeSchema
+
+func ExternalVolumeDescriptionToSchema(description []sdk.ExternalVolumeProperty) []map[string]any {
+ result := make([]map[string]any, len(description))
+ for i, row := range description {
+ result[i] = map[string]any{
+ "parent": row.Parent,
+ "name": row.Name,
+ "type": row.Type,
+ "value": row.Value,
+ "default": row.Default,
+ }
+ }
+ return result
+}
+
+var _ = ExternalVolumeDescriptionToSchema
diff --git a/pkg/schemas/external_volume_gen.go b/pkg/schemas/external_volume_gen.go
new file mode 100644
index 0000000000..1a9f112980
--- /dev/null
+++ b/pkg/schemas/external_volume_gen.go
@@ -0,0 +1,36 @@
+// Code generated by sdk-to-schema generator; DO NOT EDIT.
+
+package schemas
+
+import (
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
+)
+
+// ShowExternalVolumeSchema represents output of SHOW query for the single ExternalVolume.
+var ShowExternalVolumeSchema = map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+ "allow_writes": {
+ Type: schema.TypeBool,
+ Computed: true,
+ },
+ "comment": {
+ Type: schema.TypeString,
+ Computed: true,
+ },
+}
+
+var _ = ShowExternalVolumeSchema
+
+func ExternalVolumeToSchema(externalVolume *sdk.ExternalVolume) map[string]any {
+ externalVolumeSchema := make(map[string]any)
+ externalVolumeSchema["name"] = externalVolume.Name
+ externalVolumeSchema["allow_writes"] = externalVolume.AllowWrites
+ externalVolumeSchema["comment"] = externalVolume.Comment
+ return externalVolumeSchema
+}
+
+var _ = ExternalVolumeToSchema
diff --git a/pkg/schemas/gen/sdk_show_result_structs.go b/pkg/schemas/gen/sdk_show_result_structs.go
index ea2e977160..0d1ac4ff31 100644
--- a/pkg/schemas/gen/sdk_show_result_structs.go
+++ b/pkg/schemas/gen/sdk_show_result_structs.go
@@ -51,6 +51,7 @@ var SdkShowResultStructs = []any{
sdk.User{},
sdk.View{},
sdk.Warehouse{},
+ sdk.ExternalVolume{},
}
// TODO [SNOW-1501905]: currently all this structs have the "Show" added to the schema, while these are not show outputs
diff --git a/pkg/sdk/external_volumes_def.go b/pkg/sdk/external_volumes_def.go
index fb4f610be9..5cfee4ddf7 100644
--- a/pkg/sdk/external_volumes_def.go
+++ b/pkg/sdk/external_volumes_def.go
@@ -1,12 +1,18 @@
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 (
- S3EncryptionType string
+ StorageProvider string
S3StorageProvider string
+ S3EncryptionType string
GCSEncryptionType string
)
@@ -18,8 +24,62 @@ var (
GCSEncryptionTypeNone GCSEncryptionType = "NONE"
S3StorageProviderS3 S3StorageProvider = "S3"
S3StorageProviderS3GOV S3StorageProvider = "S3GOV"
+ StorageProviderGCS StorageProvider = "GCS"
+ StorageProviderAzure StorageProvider = "AZURE"
+ StorageProviderS3 StorageProvider = "S3"
+ StorageProviderS3GOV StorageProvider = "S3GOV"
)
+func ToS3EncryptionType(s string) (S3EncryptionType, error) {
+ switch strings.ToUpper(s) {
+ case string(S3EncryptionTypeSseS3):
+ return S3EncryptionTypeSseS3, nil
+ case string(S3EncryptionTypeSseKms):
+ return S3EncryptionTypeSseKms, nil
+ case string(S3EncryptionNone):
+ return S3EncryptionNone, nil
+ default:
+ return "", fmt.Errorf("invalid s3 encryption type: %s", s)
+ }
+}
+
+func ToGCSEncryptionType(s string) (GCSEncryptionType, error) {
+ switch strings.ToUpper(s) {
+ case string(GCSEncryptionTypeSseKms):
+ return GCSEncryptionTypeSseKms, nil
+ case string(GCSEncryptionTypeNone):
+ return GCSEncryptionTypeNone, nil
+ default:
+ return "", fmt.Errorf("invalid gcs encryption type: %s", s)
+ }
+}
+
+func ToStorageProvider(s string) (StorageProvider, error) {
+ switch strings.ToUpper(s) {
+ case string(StorageProviderGCS):
+ return StorageProviderGCS, nil
+ case string(StorageProviderAzure):
+ return StorageProviderAzure, nil
+ case string(StorageProviderS3):
+ return StorageProviderS3, nil
+ case string(StorageProviderS3GOV):
+ return StorageProviderS3GOV, nil
+ default:
+ return "", fmt.Errorf("invalid storage provider: %s", s)
+ }
+}
+
+func ToS3StorageProvider(s string) (S3StorageProvider, error) {
+ switch strings.ToUpper(s) {
+ case string(S3StorageProviderS3):
+ return S3StorageProviderS3, nil
+ case string(S3StorageProviderS3GOV):
+ return S3StorageProviderS3GOV, nil
+ default:
+ return "", fmt.Errorf("invalid s3 storage provider: %s", s)
+ }
+}
+
var externalS3StorageLocationDef = g.NewQueryStruct("S3StorageLocationParams").
TextAssignment("NAME", g.ParameterOptions().SingleQuotes().Required()).
Assignment("STORAGE_PROVIDER", g.KindOfT[S3StorageProvider](), g.ParameterOptions().SingleQuotes().Required()).
@@ -36,7 +96,7 @@ var externalS3StorageLocationDef = g.NewQueryStruct("S3StorageLocationParams").
var externalGCSStorageLocationDef = g.NewQueryStruct("GCSStorageLocationParams").
TextAssignment("NAME", g.ParameterOptions().SingleQuotes().Required()).
- PredefinedQueryStructField("StorageProviderGcs", "string", g.StaticOptions().SQL("STORAGE_PROVIDER = 'GCS'")).
+ PredefinedQueryStructField("StorageProviderGcs", "string", g.StaticOptions().SQL(fmt.Sprintf("STORAGE_PROVIDER = '%s'", StorageProviderGCS))).
TextAssignment("STORAGE_BASE_URL", g.ParameterOptions().SingleQuotes().Required()).
OptionalQueryStructField(
"Encryption",
@@ -48,7 +108,7 @@ var externalGCSStorageLocationDef = g.NewQueryStruct("GCSStorageLocationParams")
var externalAzureStorageLocationDef = g.NewQueryStruct("AzureStorageLocationParams").
TextAssignment("NAME", g.ParameterOptions().SingleQuotes().Required()).
- PredefinedQueryStructField("StorageProviderAzure", "string", g.StaticOptions().SQL("STORAGE_PROVIDER = 'AZURE'")).
+ PredefinedQueryStructField("StorageProviderAzure", "string", g.StaticOptions().SQL(fmt.Sprintf("STORAGE_PROVIDER = '%s'", StorageProviderAzure))).
TextAssignment("AZURE_TENANT_ID", g.ParameterOptions().SingleQuotes().Required()).
TextAssignment("STORAGE_BASE_URL", g.ParameterOptions().SingleQuotes().Required())
@@ -148,11 +208,11 @@ var ExternalVolumesDef = g.NewInterface(
"https://docs.snowflake.com/en/sql-reference/sql/show-external-volumes",
g.DbStruct("externalVolumeShowRow").
Text("name").
- Text("allow_writes").
- Text("comment"),
+ Bool("allow_writes").
+ OptionalText("comment"),
g.PlainStruct("ExternalVolume").
Text("Name").
- Text("AllowWrites").
+ Bool("AllowWrites").
Text("Comment"),
g.NewQueryStruct("ShowExternalVolumes").
Show().
diff --git a/pkg/sdk/external_volumes_gen.go b/pkg/sdk/external_volumes_gen.go
index 726e3ab819..a2361d0354 100644
--- a/pkg/sdk/external_volumes_gen.go
+++ b/pkg/sdk/external_volumes_gen.go
@@ -1,6 +1,9 @@
package sdk
-import "context"
+import (
+ "context"
+ "database/sql"
+)
type ExternalVolumes interface {
Create(ctx context.Context, request *CreateExternalVolumeRequest) error
@@ -107,12 +110,12 @@ type ShowExternalVolumeOptions struct {
Like *Like `ddl:"keyword" sql:"LIKE"`
}
type externalVolumeShowRow struct {
- Name string `db:"name"`
- AllowWrites string `db:"allow_writes"`
- Comment string `db:"comment"`
+ Name string `db:"name"`
+ AllowWrites bool `db:"allow_writes"`
+ Comment sql.NullString `db:"comment"`
}
type ExternalVolume struct {
Name string
- AllowWrites string
+ AllowWrites bool
Comment string
}
diff --git a/pkg/sdk/external_volumes_gen_test.go b/pkg/sdk/external_volumes_gen_test.go
index 4278e47db6..fd2e5fc1a5 100644
--- a/pkg/sdk/external_volumes_gen_test.go
+++ b/pkg/sdk/external_volumes_gen_test.go
@@ -1,6 +1,10 @@
package sdk
-import "testing"
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
// Storage location structs for testing
var s3StorageLocationParams = &S3StorageLocationParams{
@@ -439,3 +443,143 @@ func TestExternalVolumes_Show(t *testing.T) {
assertOptsValidAndSQLEquals(t, opts, "SHOW EXTERNAL VOLUMES LIKE '%s'", id.Name())
})
}
+
+func Test_ExternalVolumes_ToS3EncryptionType(t *testing.T) {
+ type test struct {
+ input string
+ want S3EncryptionType
+ }
+
+ valid := []test{
+ {input: "aws_sse_s3", want: S3EncryptionTypeSseS3},
+ {input: "AWS_SSE_S3", want: S3EncryptionTypeSseS3},
+ {input: "AWS_SSE_KMS", want: S3EncryptionTypeSseKms},
+ {input: "NONE", want: S3EncryptionNone},
+ }
+
+ invalid := []test{
+ {input: ""},
+ {input: "foo"},
+ }
+
+ for _, tc := range valid {
+ t.Run(tc.input, func(t *testing.T) {
+ got, err := ToS3EncryptionType(tc.input)
+ require.NoError(t, err)
+ require.Equal(t, tc.want, got)
+ })
+ }
+
+ for _, tc := range invalid {
+ t.Run(tc.input, func(t *testing.T) {
+ _, err := ToS3EncryptionType(tc.input)
+ require.Error(t, err)
+ })
+ }
+}
+
+func Test_ExternalVolumes_ToStorageProvider(t *testing.T) {
+ type test struct {
+ input string
+ want StorageProvider
+ }
+
+ valid := []test{
+ {input: "s3", want: StorageProviderS3},
+ {input: "S3", want: StorageProviderS3},
+ {input: "s3gov", want: StorageProviderS3GOV},
+ {input: "S3GOV", want: StorageProviderS3GOV},
+ {input: "gcs", want: StorageProviderGCS},
+ {input: "GCS", want: StorageProviderGCS},
+ {input: "azure", want: StorageProviderAzure},
+ {input: "AZURE", want: StorageProviderAzure},
+ }
+
+ invalid := []test{
+ {input: ""},
+ {input: "foo"},
+ }
+
+ for _, tc := range valid {
+ t.Run(tc.input, func(t *testing.T) {
+ got, err := ToStorageProvider(tc.input)
+ require.NoError(t, err)
+ require.Equal(t, tc.want, got)
+ })
+ }
+
+ for _, tc := range invalid {
+ t.Run(tc.input, func(t *testing.T) {
+ _, err := ToStorageProvider(tc.input)
+ require.Error(t, err)
+ })
+ }
+}
+
+func Test_ExternalVolumes_ToS3StorageProvider(t *testing.T) {
+ type test struct {
+ input string
+ want S3StorageProvider
+ }
+
+ valid := []test{
+ {input: "s3", want: S3StorageProviderS3},
+ {input: "S3", want: S3StorageProviderS3},
+ {input: "s3gov", want: S3StorageProviderS3GOV},
+ {input: "S3GOV", want: S3StorageProviderS3GOV},
+ }
+
+ invalid := []test{
+ {input: ""},
+ {input: "foo"},
+ }
+
+ for _, tc := range valid {
+ t.Run(tc.input, func(t *testing.T) {
+ got, err := ToS3StorageProvider(tc.input)
+ require.NoError(t, err)
+ require.Equal(t, tc.want, got)
+ })
+ }
+
+ for _, tc := range invalid {
+ t.Run(tc.input, func(t *testing.T) {
+ _, err := ToS3StorageProvider(tc.input)
+ require.Error(t, err)
+ })
+ }
+}
+
+func Test_ExternalVolumes_ToGCSEncryptionType(t *testing.T) {
+ type test struct {
+ input string
+ want GCSEncryptionType
+ }
+
+ valid := []test{
+ {input: "gcs_sse_kms", want: GCSEncryptionTypeSseKms},
+ {input: "GCS_SSE_KMS", want: GCSEncryptionTypeSseKms},
+ {input: "NONE", want: GCSEncryptionTypeNone},
+ {input: "none", want: GCSEncryptionTypeNone},
+ }
+
+ invalid := []test{
+ {input: ""},
+ {input: "foo"},
+ }
+
+ for _, tc := range valid {
+ t.Run(tc.input, func(t *testing.T) {
+ got, err := ToGCSEncryptionType(tc.input)
+ require.NoError(t, err)
+ require.Equal(t, tc.want, got)
+ })
+ }
+
+ for _, tc := range invalid {
+ t.Run(tc.input, func(t *testing.T) {
+ _, err := ToGCSEncryptionType(tc.input)
+ require.Error(t, err)
+ })
+ }
+}
diff --git a/pkg/sdk/external_volumes_impl_gen.go b/pkg/sdk/external_volumes_impl_gen.go
index 5b7de50826..7e6a8567fa 100644
--- a/pkg/sdk/external_volumes_impl_gen.go
+++ b/pkg/sdk/external_volumes_impl_gen.go
@@ -160,9 +160,14 @@ func (r *ShowExternalVolumeRequest) toOpts() *ShowExternalVolumeOptions {
}
func (r externalVolumeShowRow) convert() *ExternalVolume {
- return &ExternalVolume{
+ externalVolume := ExternalVolume{
Name: r.Name,
AllowWrites: r.AllowWrites,
- Comment: r.Comment,
}
+
+ if r.Comment.Valid {
+ externalVolume.Comment = r.Comment.String
+ }
+
+ return &externalVolume
}
diff --git a/pkg/sdk/external_volumes_validations_gen.go b/pkg/sdk/external_volumes_validations_gen.go
index 3d4d5eb03d..6e8bb874de 100644
--- a/pkg/sdk/external_volumes_validations_gen.go
+++ b/pkg/sdk/external_volumes_validations_gen.go
@@ -10,6 +10,13 @@ var (
_ validatable = new(ShowExternalVolumeOptions)
)
+var ValidStorageProviderString = []string{
+ string(StorageProviderGCS),
+ string(StorageProviderAzure),
+ string(StorageProviderS3),
+ string(StorageProviderS3GOV),
+}
+
func (opts *CreateExternalVolumeOptions) validate() error {
if opts == nil {
return ErrNilOptions
diff --git a/pkg/sdk/testint/external_volumes_gen_integration_test.go b/pkg/sdk/testint/external_volumes_gen_integration_test.go
index 2c1c14056b..38fa11985f 100644
--- a/pkg/sdk/testint/external_volumes_gen_integration_test.go
+++ b/pkg/sdk/testint/external_volumes_gen_integration_test.go
@@ -1,13 +1,11 @@
package testint
import (
- "encoding/json"
- "fmt"
"strconv"
- "strings"
"testing"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs"
+ "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -31,144 +29,8 @@ func TestInt_ExternalVolumes(t *testing.T) {
assertExternalVolumeShowResult := func(t *testing.T, s *sdk.ExternalVolume, name sdk.AccountObjectIdentifier, allowWrites bool, comment string) {
t.Helper()
assert.Equal(t, name.Name(), s.Name)
- assert.Equal(t, strconv.FormatBool(allowWrites), s.AllowWrites)
- assert.Equal(t, comment, s.Comment)
- }
-
- // Structs for trimProperties function
- type ExternalVolumePropNameValue struct {
- Name string
- Value string
- }
-
- type S3StorageLocation struct {
- Name string `json:"NAME"`
- StorageProvider string `json:"STORAGE_PROVIDER"`
- StorageBaseUrl string `json:"STORAGE_BASE_URL"`
- StorageAllowedLocations []string `json:"STORAGE_ALLOWED_LOCATIONS"`
- StorageAwsRoleArn string `json:"STORAGE_AWS_ROLE_ARN"`
- StroageAwsIamUserArn string `json:"STORAGE_AWS_IAM_USER_ARN"`
- StorageAwsExternalId string `json:"STORAGE_AWS_EXTERNAL_ID"`
- EncryptionType string `json:"ENCRYPTION_TYPE"`
- EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID"`
- }
-
- type S3StorageLocationTrimmed struct {
- Name string `json:"NAME"`
- StorageProvider string `json:"STORAGE_PROVIDER"`
- StorageBaseUrl string `json:"STORAGE_BASE_URL"`
- StorageAwsRoleArn string `json:"STORAGE_AWS_ROLE_ARN"`
- StorageAwsExternalId string `json:"STORAGE_AWS_EXTERNAL_ID"`
- EncryptionType string `json:"ENCRYPTION_TYPE,omitempty"`
- EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID,omitempty"`
- }
-
- type GCSStorageLocation struct {
- Name string `json:"NAME"`
- StorageProvider string `json:"STORAGE_PROVIDER"`
- StorageBaseUrl string `json:"STORAGE_BASE_URL"`
- StorageAllowedLocations []string `json:"STORAGE_ALLOWED_LOCATIONS"`
- StorageGcpServiceAccount string `json:"STORAGE_GCP_SERVICE_ACCOUNT"`
- EncryptionType string `json:"ENCRYPTION_TYPE"`
- EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID"`
- }
-
- type GCSStorageLocationTrimmed struct {
- Name string `json:"NAME"`
- StorageProvider string `json:"STORAGE_PROVIDER"`
- StorageBaseUrl string `json:"STORAGE_BASE_URL"`
- EncryptionType string `json:"ENCRYPTION_TYPE,omitempty"`
- EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID,omitempty"`
- }
-
- type AzureStorageLocation struct {
- Name string `json:"NAME"`
- StorageProvider string `json:"STORAGE_PROVIDER"`
- StorageBaseUrl string `json:"STORAGE_BASE_URL"`
- StorageAllowedLocations []string `json:"STORAGE_ALLOWED_LOCATIONS"`
- AzureTenantId string `json:"AZURE_TENANT_ID"`
- AzureMultiTenantAppName string `json:"AZURE_MULTI_TENANT_APP_NAME"`
- AzureConsentUrl string `json:"AZURE_CONSENT_URL"`
- EncryptionType string `json:"ENCRYPTION_TYPE"`
- EncryptionKmsId string `json:"ENCRYPTION_KMS_KEY_ID"`
- }
-
- type AzureStorageLocationTrimmed struct {
- Name string `json:"NAME"`
- StorageProvider string `json:"STORAGE_PROVIDER"`
- StorageBaseUrl string `json:"STORAGE_BASE_URL"`
- AzureTenantId string `json:"AZURE_TENANT_ID"`
- }
-
- // Enforce only property names and values in tests, not parent_property, type and property_default
- // In addition the storage location properties are trimmed to only contain values that we set
- trimProperties := func(t *testing.T, props []sdk.ExternalVolumeProperty) []ExternalVolumePropNameValue {
- t.Helper()
- var externalVolumePropNameValue []ExternalVolumePropNameValue
- for _, p := range props {
- if strings.Contains(p.Name, "STORAGE_LOCATION_") {
- switch {
- case strings.Contains(p.Value, `"STORAGE_PROVIDER":"S3"`):
- s3StorageLocation := S3StorageLocation{}
- err := json.Unmarshal([]byte(p.Value), &s3StorageLocation)
- require.NoError(t, err)
- s3StorageLocationTrimmed := S3StorageLocationTrimmed{
- Name: s3StorageLocation.Name,
- StorageProvider: s3StorageLocation.StorageProvider,
- StorageBaseUrl: s3StorageLocation.StorageBaseUrl,
- StorageAwsRoleArn: s3StorageLocation.StorageAwsRoleArn,
- StorageAwsExternalId: s3StorageLocation.StorageAwsExternalId,
- EncryptionType: s3StorageLocation.EncryptionType,
- EncryptionKmsId: s3StorageLocation.EncryptionKmsId,
- }
- s3StorageLocationTrimmedMarshaled, err := json.Marshal(s3StorageLocationTrimmed)
- require.NoError(t, err)
- externalVolumePropNameValue = append(
- externalVolumePropNameValue,
- ExternalVolumePropNameValue{Name: p.Name, Value: string(s3StorageLocationTrimmedMarshaled)},
- )
- case strings.Contains(p.Value, `"STORAGE_PROVIDER":"GCS"`):
- gcsStorageLocation := GCSStorageLocation{}
- err := json.Unmarshal([]byte(p.Value), &gcsStorageLocation)
- require.NoError(t, err)
- gcsStorageLocationTrimmed := GCSStorageLocationTrimmed{
- Name: gcsStorageLocation.Name,
- StorageProvider: gcsStorageLocation.StorageProvider,
- StorageBaseUrl: gcsStorageLocation.StorageBaseUrl,
- EncryptionType: gcsStorageLocation.EncryptionType,
- EncryptionKmsId: gcsStorageLocation.EncryptionKmsId,
- }
- gcsStorageLocationTrimmedMarshaled, err := json.Marshal(gcsStorageLocationTrimmed)
- require.NoError(t, err)
- externalVolumePropNameValue = append(
- externalVolumePropNameValue,
- ExternalVolumePropNameValue{Name: p.Name, Value: string(gcsStorageLocationTrimmedMarshaled)},
- )
- case strings.Contains(p.Value, `"STORAGE_PROVIDER":"AZURE"`):
- azureStorageLocation := AzureStorageLocation{}
- err := json.Unmarshal([]byte(p.Value), &azureStorageLocation)
- require.NoError(t, err)
- azureStorageLocationTrimmed := AzureStorageLocationTrimmed{
- Name: azureStorageLocation.Name,
- StorageProvider: azureStorageLocation.StorageProvider,
- StorageBaseUrl: azureStorageLocation.StorageBaseUrl,
- AzureTenantId: azureStorageLocation.AzureTenantId,
- }
- azureStorageLocationTrimmedMarshaled, err := json.Marshal(azureStorageLocationTrimmed)
- require.NoError(t, err)
- externalVolumePropNameValue = append(
- externalVolumePropNameValue,
- ExternalVolumePropNameValue{Name: p.Name, Value: string(azureStorageLocationTrimmedMarshaled)},
- )
- default:
- panic("Unrecognized storage provider in storage location property")
- }
- } else {
- externalVolumePropNameValue = append(externalVolumePropNameValue, ExternalVolumePropNameValue{Name: p.Name, Value: p.Value})
- }
- }
-
- return externalVolumePropNameValue
+ assert.Equal(t, allowWrites, s.AllowWrites)
+ assert.Equal(t, s.Comment, comment)
}
// Storage location structs for testing
@@ -261,14 +123,17 @@ func TestInt_ExternalVolumes(t *testing.T) {
},
}
- createExternalVolume := func(t *testing.T, storageLocations []sdk.ExternalVolumeStorageLocation, allowWrites bool, comment string) sdk.AccountObjectIdentifier {
+ createExternalVolume := func(t *testing.T, storageLocations []sdk.ExternalVolumeStorageLocation, allowWrites bool, comment *string) sdk.AccountObjectIdentifier {
t.Helper()
id := testClientHelper().Ids.RandomAccountObjectIdentifier()
req := sdk.NewCreateExternalVolumeRequest(id, storageLocations).
WithIfNotExists(true).
- WithAllowWrites(allowWrites).
- WithComment(comment)
+ WithAllowWrites(allowWrites)
+
+ if comment != nil {
+ req = req.WithComment(*comment)
+ }
err := client.ExternalVolumes.Create(ctx, req)
require.NoError(t, err)
@@ -284,7 +149,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - S3 Storage Location", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, s3StorageLocations, allowWrites, comment)
+ id := createExternalVolume(t, s3StorageLocations, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -292,10 +157,31 @@ func TestInt_ExternalVolumes(t *testing.T) {
assertExternalVolumeShowResult(t, externalVolume, id, allowWrites, comment)
})
+ t.Run("Create - S3 Storage Location empty Comment", func(t *testing.T) {
+ allowWrites := true
+ emptyComment := ""
+ id := createExternalVolume(t, s3StorageLocations, allowWrites, &emptyComment)
+
+ externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
+ require.NoError(t, err)
+
+ assertExternalVolumeShowResult(t, externalVolume, id, allowWrites, emptyComment)
+ })
+
+ t.Run("Create - S3 Storage Location No Comment", func(t *testing.T) {
+ allowWrites := true
+ id := createExternalVolume(t, s3StorageLocations, allowWrites, nil)
+
+ externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
+ require.NoError(t, err)
+
+ assertExternalVolumeShowResult(t, externalVolume, id, allowWrites, "")
+ })
+
t.Run("Create - S3 Storage Location None Encryption", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, s3StorageLocationsNoneEncryption, allowWrites, comment)
+ id := createExternalVolume(t, s3StorageLocationsNoneEncryption, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -306,7 +192,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - S3 Storage Location No Encryption", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, s3StorageLocationsNoEncryption, allowWrites, comment)
+ id := createExternalVolume(t, s3StorageLocationsNoEncryption, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -317,7 +203,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - GCS Storage Location", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, gcsStorageLocations, allowWrites, comment)
+ id := createExternalVolume(t, gcsStorageLocations, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -328,7 +214,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - GCS Storage Location None Encryption", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, gcsStorageLocationsNoneEncryption, allowWrites, comment)
+ id := createExternalVolume(t, gcsStorageLocationsNoneEncryption, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -339,7 +225,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - GCS Storage Location No Encryption", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, gcsStorageLocationsNoEncryption, allowWrites, comment)
+ id := createExternalVolume(t, gcsStorageLocationsNoEncryption, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -350,7 +236,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - Azure Storage Location", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, azureStorageLocations, allowWrites, comment)
+ id := createExternalVolume(t, azureStorageLocations, allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -361,7 +247,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Create - Multiple Storage Locations", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, append(append(s3StorageLocations, gcsStorageLocationsNoneEncryption...), azureStorageLocations...), allowWrites, comment)
+ id := createExternalVolume(t, append(append(s3StorageLocations, gcsStorageLocationsNoneEncryption...), azureStorageLocations...), allowWrites, &comment)
externalVolume, err := client.ExternalVolumes.ShowByID(ctx, id)
require.NoError(t, err)
@@ -372,7 +258,7 @@ func TestInt_ExternalVolumes(t *testing.T) {
t.Run("Alter - remove storage location", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, append(s3StorageLocationsNoneEncryption, gcsStorageLocationsNoneEncryption...), allowWrites, comment)
+ id := createExternalVolume(t, append(s3StorageLocationsNoneEncryption, gcsStorageLocationsNoneEncryption...), allowWrites, &comment)
req := sdk.NewAlterExternalVolumeRequest(id).WithRemoveStorageLocation(gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Name)
@@ -382,36 +268,37 @@ func TestInt_ExternalVolumes(t *testing.T) {
props, err := client.ExternalVolumes.Describe(ctx, id)
require.NoError(t, err)
- trimmedProperties := trimProperties(t, props)
- assert.Equal(t, 4, len(trimmedProperties))
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "COMMENT", Value: comment})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ALLOW_WRITES", Value: strconv.FormatBool(allowWrites)})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ACTIVE", Value: ""})
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_1",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s"}`,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Name,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Encryption.Type,
- ),
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(props)
+ require.NoError(t, err)
+ expectedParsedExternalVolumeDescribed := helpers.ParsedExternalVolumeDescribed{
+ StorageLocations: []helpers.StorageLocation{
+ {
+ Name: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: string(s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
},
- )
+ Active: "",
+ Comment: comment,
+ AllowWrites: strconv.FormatBool(allowWrites),
+ }
+
+ assert.True(t, helpers.ParsedExternalVolumesDescribedEqual(parsedExternalVolumeDescribed, expectedParsedExternalVolumeDescribed))
})
t.Run("Alter - set comment", func(t *testing.T) {
allowWrites := true
- comment := ""
- id := createExternalVolume(t, s3StorageLocationsNoneEncryption, allowWrites, "some comment")
+ comment1 := "some comment"
+ comment2 := ""
+ id := createExternalVolume(t, s3StorageLocationsNoneEncryption, allowWrites, &comment1)
req := sdk.NewAlterExternalVolumeRequest(id).WithSet(
- *sdk.NewAlterExternalVolumeSetRequest().WithComment(comment),
+ *sdk.NewAlterExternalVolumeSetRequest().WithComment(comment2),
)
err := client.ExternalVolumes.Alter(ctx, req)
@@ -420,32 +307,33 @@ func TestInt_ExternalVolumes(t *testing.T) {
props, err := client.ExternalVolumes.Describe(ctx, id)
require.NoError(t, err)
- trimmedProperties := trimProperties(t, props)
- assert.Equal(t, 3, len(trimmedProperties))
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ALLOW_WRITES", Value: strconv.FormatBool(allowWrites)})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ACTIVE", Value: ""})
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_1",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s"}`,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Name,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Encryption.Type,
- ),
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(props)
+ require.NoError(t, err)
+ expectedParsedExternalVolumeDescribed := helpers.ParsedExternalVolumeDescribed{
+ StorageLocations: []helpers.StorageLocation{
+ {
+ Name: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: string(s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
},
- )
+ Active: "",
+ Comment: comment2,
+ AllowWrites: strconv.FormatBool(allowWrites),
+ }
+
+ assert.True(t, helpers.ParsedExternalVolumesDescribedEqual(parsedExternalVolumeDescribed, expectedParsedExternalVolumeDescribed))
})
t.Run("Alter - set allow writes", func(t *testing.T) {
allowWrites := false
comment := "some comment"
- id := createExternalVolume(t, s3StorageLocations, true, comment)
+ id := createExternalVolume(t, s3StorageLocations, true, &comment)
req := sdk.NewAlterExternalVolumeRequest(id).WithSet(
*sdk.NewAlterExternalVolumeSetRequest().WithAllowWrites(allowWrites),
@@ -457,34 +345,33 @@ func TestInt_ExternalVolumes(t *testing.T) {
props, err := client.ExternalVolumes.Describe(ctx, id)
require.NoError(t, err)
- trimmedProperties := trimProperties(t, props)
- assert.Equal(t, 4, len(trimmedProperties))
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "COMMENT", Value: comment})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ALLOW_WRITES", Value: strconv.FormatBool(allowWrites)})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ACTIVE", Value: ""})
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_1",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"%s"}`,
- s3StorageLocations[0].S3StorageLocationParams.Name,
- s3StorageLocations[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocations[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocations[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocations[0].S3StorageLocationParams.StorageAwsExternalId,
- s3StorageLocations[0].S3StorageLocationParams.Encryption.Type,
- *s3StorageLocations[0].S3StorageLocationParams.Encryption.KmsKeyId,
- ),
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(props)
+ require.NoError(t, err)
+ expectedParsedExternalVolumeDescribed := helpers.ParsedExternalVolumeDescribed{
+ StorageLocations: []helpers.StorageLocation{
+ {
+ Name: s3StorageLocations[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocations[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocations[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocations[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocations[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: string(s3StorageLocations[0].S3StorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: *s3StorageLocations[0].S3StorageLocationParams.Encryption.KmsKeyId,
+ AzureTenantId: "",
+ },
},
- )
+ Active: "",
+ Comment: comment,
+ AllowWrites: strconv.FormatBool(allowWrites),
+ }
+
+ assert.True(t, helpers.ParsedExternalVolumesDescribedEqual(parsedExternalVolumeDescribed, expectedParsedExternalVolumeDescribed))
})
t.Run("Alter - add s3 storage location to external volume", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, gcsStorageLocationsNoneEncryption, allowWrites, comment)
+ id := createExternalVolume(t, gcsStorageLocationsNoneEncryption, allowWrites, &comment)
req := sdk.NewAlterExternalVolumeRequest(id).WithAddStorageLocation(
*sdk.NewExternalVolumeStorageLocationRequest().WithS3StorageLocationParams(
@@ -507,41 +394,37 @@ func TestInt_ExternalVolumes(t *testing.T) {
props, err := client.ExternalVolumes.Describe(ctx, id)
require.NoError(t, err)
- trimmedProperties := trimProperties(t, props)
- assert.Equal(t, 5, len(trimmedProperties))
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "COMMENT", Value: comment})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ALLOW_WRITES", Value: strconv.FormatBool(allowWrites)})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ACTIVE", Value: ""})
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_1",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"GCS","STORAGE_BASE_URL":"%s","ENCRYPTION_TYPE":"%s"}`,
- gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Name,
- gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.StorageBaseUrl,
- gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Encryption.Type,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_2",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"%s"}`,
- s3StorageLocations[0].S3StorageLocationParams.Name,
- s3StorageLocations[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocations[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocations[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocations[0].S3StorageLocationParams.StorageAwsExternalId,
- s3StorageLocations[0].S3StorageLocationParams.Encryption.Type,
- *s3StorageLocations[0].S3StorageLocationParams.Encryption.KmsKeyId,
- ),
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(props)
+ require.NoError(t, err)
+ expectedParsedExternalVolumeDescribed := helpers.ParsedExternalVolumeDescribed{
+ StorageLocations: []helpers.StorageLocation{
+ {
+ Name: gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Name,
+ StorageProvider: string(sdk.StorageProviderGCS),
+ StorageBaseUrl: gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: string(gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ {
+ Name: s3StorageLocations[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocations[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocations[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocations[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocations[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: string(s3StorageLocations[0].S3StorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: *s3StorageLocations[0].S3StorageLocationParams.Encryption.KmsKeyId,
+ AzureTenantId: "",
+ },
},
- )
+ Active: "",
+ Comment: comment,
+ AllowWrites: strconv.FormatBool(allowWrites),
+ }
+
+ assert.True(t, helpers.ParsedExternalVolumesDescribedEqual(parsedExternalVolumeDescribed, expectedParsedExternalVolumeDescribed))
})
t.Run("Describe", func(t *testing.T) {
@@ -551,123 +434,99 @@ func TestInt_ExternalVolumes(t *testing.T) {
t,
append(append(append(append(append(append(s3StorageLocations, gcsStorageLocationsNoneEncryption...), azureStorageLocations...), s3StorageLocationsNoneEncryption...), gcsStorageLocations...), s3StorageLocationsNoEncryption...), gcsStorageLocationsNoEncryption...),
allowWrites,
- comment,
+ &comment,
)
props, err := client.ExternalVolumes.Describe(ctx, id)
require.NoError(t, err)
- trimmedProperties := trimProperties(t, props)
- assert.Equal(t, 10, len(trimmedProperties))
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "COMMENT", Value: comment})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ALLOW_WRITES", Value: strconv.FormatBool(allowWrites)})
- assert.Contains(t, trimmedProperties, ExternalVolumePropNameValue{Name: "ACTIVE", Value: ""})
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_1",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"%s"}`,
- s3StorageLocations[0].S3StorageLocationParams.Name,
- s3StorageLocations[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocations[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocations[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocations[0].S3StorageLocationParams.StorageAwsExternalId,
- s3StorageLocations[0].S3StorageLocationParams.Encryption.Type,
- *s3StorageLocations[0].S3StorageLocationParams.Encryption.KmsKeyId,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_2",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"GCS","STORAGE_BASE_URL":"%s","ENCRYPTION_TYPE":"%s"}`,
- gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Name,
- gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.StorageBaseUrl,
- gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Encryption.Type,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_3",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"AZURE","STORAGE_BASE_URL":"%s","AZURE_TENANT_ID":"%s"}`,
- azureStorageLocations[0].AzureStorageLocationParams.Name,
- azureStorageLocations[0].AzureStorageLocationParams.StorageBaseUrl,
- azureStorageLocations[0].AzureStorageLocationParams.AzureTenantId,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_4",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"%s"}`,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Name,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
- s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Encryption.Type,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_5",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"GCS","STORAGE_BASE_URL":"%s","ENCRYPTION_TYPE":"%s","ENCRYPTION_KMS_KEY_ID":"%s"}`,
- gcsStorageLocations[0].GCSStorageLocationParams.Name,
- gcsStorageLocations[0].GCSStorageLocationParams.StorageBaseUrl,
- gcsStorageLocations[0].GCSStorageLocationParams.Encryption.Type,
- *gcsStorageLocations[0].GCSStorageLocationParams.Encryption.KmsKeyId,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_6",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"%s","STORAGE_BASE_URL":"%s","STORAGE_AWS_ROLE_ARN":"%s","STORAGE_AWS_EXTERNAL_ID":"%s","ENCRYPTION_TYPE":"NONE"}`,
- s3StorageLocationsNoEncryption[0].S3StorageLocationParams.Name,
- s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageProvider,
- s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageBaseUrl,
- s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
- *s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
- ),
- },
- )
- assert.Contains(
- t,
- trimmedProperties,
- ExternalVolumePropNameValue{
- Name: "STORAGE_LOCATION_7",
- Value: fmt.Sprintf(
- `{"NAME":"%s","STORAGE_PROVIDER":"GCS","STORAGE_BASE_URL":"%s","ENCRYPTION_TYPE":"NONE"}`,
- gcsStorageLocationsNoEncryption[0].GCSStorageLocationParams.Name,
- gcsStorageLocationsNoEncryption[0].GCSStorageLocationParams.StorageBaseUrl,
- ),
+ parsedExternalVolumeDescribed, err := helpers.ParseExternalVolumeDescribed(props)
+ require.NoError(t, err)
+ expectedParsedExternalVolumeDescribed := helpers.ParsedExternalVolumeDescribed{
+ StorageLocations: []helpers.StorageLocation{
+ {
+ Name: s3StorageLocations[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocations[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocations[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocations[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocations[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: string(s3StorageLocations[0].S3StorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: *s3StorageLocations[0].S3StorageLocationParams.Encryption.KmsKeyId,
+ AzureTenantId: "",
+ },
+ {
+ Name: gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Name,
+ StorageProvider: string(sdk.StorageProviderGCS),
+ StorageBaseUrl: gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: string(gcsStorageLocationsNoneEncryption[0].GCSStorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ {
+ Name: azureStorageLocations[0].AzureStorageLocationParams.Name,
+ StorageProvider: string(sdk.StorageProviderAzure),
+ StorageBaseUrl: azureStorageLocations[0].AzureStorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: "",
+ EncryptionKmsKeyId: "",
+ AzureTenantId: azureStorageLocations[0].AzureStorageLocationParams.AzureTenantId,
+ },
+ {
+ Name: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: string(s3StorageLocationsNoneEncryption[0].S3StorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ {
+ Name: gcsStorageLocations[0].GCSStorageLocationParams.Name,
+ StorageProvider: string(sdk.StorageProviderGCS),
+ StorageBaseUrl: gcsStorageLocations[0].GCSStorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: string(gcsStorageLocations[0].GCSStorageLocationParams.Encryption.Type),
+ EncryptionKmsKeyId: *gcsStorageLocations[0].GCSStorageLocationParams.Encryption.KmsKeyId,
+ AzureTenantId: "",
+ },
+ {
+ Name: s3StorageLocationsNoEncryption[0].S3StorageLocationParams.Name,
+ StorageProvider: string(s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageProvider),
+ StorageBaseUrl: s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageAwsRoleArn,
+ StorageAwsExternalId: *s3StorageLocationsNoEncryption[0].S3StorageLocationParams.StorageAwsExternalId,
+ EncryptionType: "NONE",
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
+ {
+ Name: gcsStorageLocationsNoEncryption[0].GCSStorageLocationParams.Name,
+ StorageProvider: string(sdk.StorageProviderGCS),
+ StorageBaseUrl: gcsStorageLocationsNoEncryption[0].GCSStorageLocationParams.StorageBaseUrl,
+ StorageAwsRoleArn: "",
+ StorageAwsExternalId: "",
+ EncryptionType: "NONE",
+ EncryptionKmsKeyId: "",
+ AzureTenantId: "",
+ },
},
- )
+ Active: "",
+ Comment: comment,
+ AllowWrites: strconv.FormatBool(allowWrites),
+ }
+
+ assert.True(t, helpers.ParsedExternalVolumesDescribedEqual(parsedExternalVolumeDescribed, expectedParsedExternalVolumeDescribed))
})
t.Run("Show with like", func(t *testing.T) {
allowWrites := true
comment := "some comment"
- id := createExternalVolume(t, s3StorageLocations, allowWrites, comment)
+ id := createExternalVolume(t, s3StorageLocations, allowWrites, &comment)
name := id.Name()
req := sdk.NewShowExternalVolumeRequest().WithLike(sdk.Like{Pattern: &name})