diff --git a/pkg/acceptance/helpers/event_table_client..go b/pkg/acceptance/helpers/event_table_client..go new file mode 100644 index 0000000000..0c8e5d529d --- /dev/null +++ b/pkg/acceptance/helpers/event_table_client..go @@ -0,0 +1,49 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/stretchr/testify/require" +) + +type EventTableClient struct { + context *TestClientContext + ids *IdsGenerator +} + +func NewEventTableClient(context *TestClientContext, idsGenerator *IdsGenerator) *EventTableClient { + return &EventTableClient{ + context: context, + ids: idsGenerator, + } +} + +func (c *EventTableClient) client() sdk.EventTables { + return c.context.client.EventTables +} + +func (c *EventTableClient) Create(t *testing.T) (*sdk.EventTable, func()) { + t.Helper() + ctx := context.Background() + + id := c.ids.RandomSchemaObjectIdentifier() + err := c.client().Create(ctx, sdk.NewCreateEventTableRequest(id)) + require.NoError(t, err) + + integration, err := c.client().ShowByID(ctx, id) + require.NoError(t, err) + + return integration, c.DropFunc(t, id) +} + +func (c *EventTableClient) DropFunc(t *testing.T, id sdk.SchemaObjectIdentifier) func() { + t.Helper() + ctx := context.Background() + + return func() { + err := c.client().Drop(ctx, sdk.NewDropEventTableRequest(id).WithIfExists(sdk.Bool(true))) + require.NoError(t, err) + } +} diff --git a/pkg/acceptance/helpers/notification_integration_client.go b/pkg/acceptance/helpers/notification_integration_client.go new file mode 100644 index 0000000000..b453156c07 --- /dev/null +++ b/pkg/acceptance/helpers/notification_integration_client.go @@ -0,0 +1,54 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/stretchr/testify/require" +) + +type NotificationIntegrationClient struct { + context *TestClientContext + ids *IdsGenerator +} + +func NewNotificationIntegrationClient(context *TestClientContext, idsGenerator *IdsGenerator) *NotificationIntegrationClient { + return &NotificationIntegrationClient{ + context: context, + ids: idsGenerator, + } +} + +func (c *NotificationIntegrationClient) client() sdk.NotificationIntegrations { + return c.context.client.NotificationIntegrations +} + +func (c *NotificationIntegrationClient) Create(t *testing.T) (*sdk.NotificationIntegration, func()) { + t.Helper() + ctx := context.Background() + + id := c.ids.RandomAccountObjectIdentifier() + + // TODO [SNOW-1007539]: use email of our service user + request := sdk.NewCreateNotificationIntegrationRequest(id, true). + WithEmailParams(sdk.NewEmailParamsRequest().WithAllowedRecipients([]sdk.NotificationIntegrationAllowedRecipient{{Email: "artur.sawicki@snowflake.com"}})) + + err := c.client().Create(ctx, request) + require.NoError(t, err) + + integration, err := c.client().ShowByID(ctx, id) + require.NoError(t, err) + + return integration, c.DropFunc(t, id) +} + +func (c *NotificationIntegrationClient) DropFunc(t *testing.T, id sdk.AccountObjectIdentifier) func() { + t.Helper() + ctx := context.Background() + + return func() { + err := c.client().Drop(ctx, sdk.NewDropNotificationIntegrationRequest(id).WithIfExists(sdk.Bool(true))) + require.NoError(t, err) + } +} diff --git a/pkg/acceptance/helpers/security_integration_client.go b/pkg/acceptance/helpers/security_integration_client.go index 5931b8fa9d..85115cf084 100644 --- a/pkg/acceptance/helpers/security_integration_client.go +++ b/pkg/acceptance/helpers/security_integration_client.go @@ -25,24 +25,46 @@ func (c *SecurityIntegrationClient) client() sdk.SecurityIntegrations { return c.context.client.SecurityIntegrations } -func (c *SecurityIntegrationClient) UpdateExternalOauth(t *testing.T, request *sdk.AlterExternalOauthSecurityIntegrationRequest) { +func (c *SecurityIntegrationClient) CreateApiAuthenticationWithClientCredentialsFlow(t *testing.T) (*sdk.SecurityIntegration, func()) { t.Helper() ctx := context.Background() - err := c.client().AlterExternalOauth(ctx, request) + id := c.ids.RandomAccountObjectIdentifier() + request := sdk.NewCreateApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest(id, false, "foo", "foo") + err := c.client().CreateApiAuthenticationWithClientCredentialsFlow(ctx, request) + require.NoError(t, err) + + si, err := c.client().ShowByID(ctx, request.GetName()) require.NoError(t, err) + + return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } -func (c *SecurityIntegrationClient) CreateSaml2(t *testing.T, id sdk.AccountObjectIdentifier) (*sdk.SecurityIntegration, func()) { +func (c *SecurityIntegrationClient) CreateApiAuthenticationWithAuthorizationCodeGrantFlow(t *testing.T) (*sdk.SecurityIntegration, func()) { t.Helper() - return c.CreateSaml2WithRequest(t, sdk.NewCreateSaml2SecurityIntegrationRequest(id, c.ids.Alpha(), "https://example.com", "Custom", random.GenerateX509(t))) + ctx := context.Background() + + id := c.ids.RandomAccountObjectIdentifier() + request := sdk.NewCreateApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest(id, false, "foo", "foo") + err := c.client().CreateApiAuthenticationWithAuthorizationCodeGrantFlow(ctx, request) + require.NoError(t, err) + + si, err := c.client().ShowByID(ctx, request.GetName()) + require.NoError(t, err) + + return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } -func (c *SecurityIntegrationClient) CreateSaml2WithRequest(t *testing.T, request *sdk.CreateSaml2SecurityIntegrationRequest) (*sdk.SecurityIntegration, func()) { +func (c *SecurityIntegrationClient) CreateExternalOauth(t *testing.T) (*sdk.SecurityIntegration, func()) { t.Helper() ctx := context.Background() - err := c.client().CreateSaml2(ctx, request) + id := c.ids.RandomAccountObjectIdentifier() + issuer := random.String() + request := sdk.NewCreateExternalOauthSecurityIntegrationRequest(id, false, sdk.ExternalOauthSecurityIntegrationTypeCustom, + issuer, []sdk.TokenUserMappingClaim{{Claim: "foo"}}, sdk.ExternalOauthSecurityIntegrationSnowflakeUserMappingAttributeLoginName, + ).WithExternalOauthJwsKeysUrl([]sdk.JwsKeysUrl{{JwsKeyUrl: "http://example.com"}}) + err := c.client().CreateExternalOauth(ctx, request) require.NoError(t, err) si, err := c.client().ShowByID(ctx, request.GetName()) @@ -51,16 +73,29 @@ func (c *SecurityIntegrationClient) CreateSaml2WithRequest(t *testing.T, request return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } -func (c *SecurityIntegrationClient) CreateScim(t *testing.T) (*sdk.SecurityIntegration, func()) { +func (c *SecurityIntegrationClient) CreateOauthForPartnerApplications(t *testing.T) (*sdk.SecurityIntegration, func()) { t.Helper() - return c.CreateScimWithRequest(t, sdk.NewCreateScimSecurityIntegrationRequest(c.ids.RandomAccountObjectIdentifier(), sdk.ScimSecurityIntegrationScimClientGeneric, sdk.ScimSecurityIntegrationRunAsRoleGenericScimProvisioner)) + ctx := context.Background() + + id := c.ids.RandomAccountObjectIdentifier() + request := sdk.NewCreateOauthForPartnerApplicationsSecurityIntegrationRequest(id, sdk.OauthSecurityIntegrationClientLooker). + WithOauthRedirectUri("http://example.com") + err := c.client().CreateOauthForPartnerApplications(ctx, request) + require.NoError(t, err) + + si, err := c.client().ShowByID(ctx, request.GetName()) + require.NoError(t, err) + + return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } -func (c *SecurityIntegrationClient) CreateApiAuthenticationClientCredentialsWithRequest(t *testing.T, request *sdk.CreateApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest) (*sdk.SecurityIntegration, func()) { +func (c *SecurityIntegrationClient) CreateOauthForCustomClients(t *testing.T) (*sdk.SecurityIntegration, func()) { t.Helper() ctx := context.Background() - err := c.client().CreateApiAuthenticationWithClientCredentialsFlow(ctx, request) + id := c.ids.RandomAccountObjectIdentifier() + request := sdk.NewCreateOauthForCustomClientsSecurityIntegrationRequest(id, sdk.OauthSecurityIntegrationClientTypePublic, "https://example.com") + err := c.client().CreateOauthForCustomClients(ctx, request) require.NoError(t, err) si, err := c.client().ShowByID(ctx, request.GetName()) @@ -69,25 +104,41 @@ func (c *SecurityIntegrationClient) CreateApiAuthenticationClientCredentialsWith return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } -func (c *SecurityIntegrationClient) UpdateSaml2(t *testing.T, request *sdk.AlterSaml2SecurityIntegrationRequest) { +func (c *SecurityIntegrationClient) CreateSaml2(t *testing.T) (*sdk.SecurityIntegration, func()) { + t.Helper() + id := c.ids.RandomAccountObjectIdentifier() + return c.CreateSaml2WithRequest(t, sdk.NewCreateSaml2SecurityIntegrationRequest(id, c.ids.Alpha(), "https://example.com", "Custom", random.GenerateX509(t))) +} + +func (c *SecurityIntegrationClient) CreateSaml2WithRequest(t *testing.T, request *sdk.CreateSaml2SecurityIntegrationRequest) (*sdk.SecurityIntegration, func()) { t.Helper() ctx := context.Background() - err := c.client().AlterSaml2(ctx, request) + err := c.client().CreateSaml2(ctx, request) require.NoError(t, err) + + si, err := c.client().ShowByID(ctx, request.GetName()) + require.NoError(t, err) + + return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } -func (c *SecurityIntegrationClient) UpdateSaml2ForceAuthn(t *testing.T, id sdk.AccountObjectIdentifier, forceAuthn bool) { +func (c *SecurityIntegrationClient) CreateScim(t *testing.T) (*sdk.SecurityIntegration, func()) { t.Helper() - c.UpdateSaml2(t, sdk.NewAlterSaml2SecurityIntegrationRequest(id).WithSet(*sdk.NewSaml2IntegrationSetRequest().WithSaml2ForceAuthn(forceAuthn))) + return c.CreateScimWithRequest(t, sdk.NewCreateScimSecurityIntegrationRequest(c.ids.RandomAccountObjectIdentifier(), sdk.ScimSecurityIntegrationScimClientGeneric, sdk.ScimSecurityIntegrationRunAsRoleGenericScimProvisioner)) } -func (c *SecurityIntegrationClient) UpdateOauthForPartnerApplications(t *testing.T, request *sdk.AlterOauthForPartnerApplicationsSecurityIntegrationRequest) { +func (c *SecurityIntegrationClient) CreateApiAuthenticationClientCredentialsWithRequest(t *testing.T, request *sdk.CreateApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest) (*sdk.SecurityIntegration, func()) { t.Helper() ctx := context.Background() - err := c.client().AlterOauthForPartnerApplications(ctx, request) + err := c.client().CreateApiAuthenticationWithClientCredentialsFlow(ctx, request) + require.NoError(t, err) + + si, err := c.client().ShowByID(ctx, request.GetName()) require.NoError(t, err) + + return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } func (c *SecurityIntegrationClient) CreateScimWithRequest(t *testing.T, request *sdk.CreateScimSecurityIntegrationRequest) (*sdk.SecurityIntegration, func()) { @@ -103,6 +154,35 @@ func (c *SecurityIntegrationClient) CreateScimWithRequest(t *testing.T, request return si, c.DropSecurityIntegrationFunc(t, request.GetName()) } +func (c *SecurityIntegrationClient) UpdateExternalOauth(t *testing.T, request *sdk.AlterExternalOauthSecurityIntegrationRequest) { + t.Helper() + ctx := context.Background() + + err := c.client().AlterExternalOauth(ctx, request) + require.NoError(t, err) +} + +func (c *SecurityIntegrationClient) UpdateSaml2(t *testing.T, request *sdk.AlterSaml2SecurityIntegrationRequest) { + t.Helper() + ctx := context.Background() + + err := c.client().AlterSaml2(ctx, request) + require.NoError(t, err) +} + +func (c *SecurityIntegrationClient) UpdateSaml2ForceAuthn(t *testing.T, id sdk.AccountObjectIdentifier, forceAuthn bool) { + t.Helper() + c.UpdateSaml2(t, sdk.NewAlterSaml2SecurityIntegrationRequest(id).WithSet(*sdk.NewSaml2IntegrationSetRequest().WithSaml2ForceAuthn(forceAuthn))) +} + +func (c *SecurityIntegrationClient) UpdateOauthForPartnerApplications(t *testing.T, request *sdk.AlterOauthForPartnerApplicationsSecurityIntegrationRequest) { + t.Helper() + ctx := context.Background() + + err := c.client().AlterOauthForPartnerApplications(ctx, request) + require.NoError(t, err) +} + func (c *SecurityIntegrationClient) UpdateOauthForClients(t *testing.T, request *sdk.AlterOauthForCustomClientsSecurityIntegrationRequest) { t.Helper() ctx := context.Background() diff --git a/pkg/acceptance/helpers/storage_integration_client.go b/pkg/acceptance/helpers/storage_integration_client.go new file mode 100644 index 0000000000..32041df07d --- /dev/null +++ b/pkg/acceptance/helpers/storage_integration_client.go @@ -0,0 +1,79 @@ +package helpers + +import ( + "context" + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/stretchr/testify/require" +) + +type StorageIntegrationClient struct { + context *TestClientContext + ids *IdsGenerator +} + +func NewStorageIntegrationClient(context *TestClientContext, idsGenerator *IdsGenerator) *StorageIntegrationClient { + return &StorageIntegrationClient{ + context: context, + ids: idsGenerator, + } +} + +func (c *StorageIntegrationClient) client() sdk.StorageIntegrations { + return c.context.client.StorageIntegrations +} + +func (c *StorageIntegrationClient) CreateS3(t *testing.T, awsBucketUrl, awsRoleArn string) (*sdk.StorageIntegration, func()) { + t.Helper() + ctx := context.Background() + + allowedLocations := func(prefix string) []sdk.StorageLocation { + return []sdk.StorageLocation{ + { + Path: prefix + "/allowed-location", + }, + { + Path: prefix + "/allowed-location2", + }, + } + } + s3AllowedLocations := allowedLocations(awsBucketUrl) + + blockedLocations := func(prefix string) []sdk.StorageLocation { + return []sdk.StorageLocation{ + { + Path: prefix + "/blocked-location", + }, + { + Path: prefix + "/blocked-location2", + }, + } + } + s3BlockedLocations := blockedLocations(awsBucketUrl) + + id := c.ids.RandomAccountObjectIdentifier() + req := sdk.NewCreateStorageIntegrationRequest(id, true, s3AllowedLocations). + WithIfNotExists(sdk.Bool(true)). + WithS3StorageProviderParams(sdk.NewS3StorageParamsRequest(awsRoleArn)). + WithStorageBlockedLocations(s3BlockedLocations). + WithComment(sdk.String("some comment")) + + err := c.client().Create(ctx, req) + require.NoError(t, err) + + integration, err := c.client().ShowByID(ctx, id) + require.NoError(t, err) + + return integration, c.DropFunc(t, id) +} + +func (c *StorageIntegrationClient) DropFunc(t *testing.T, id sdk.AccountObjectIdentifier) func() { + t.Helper() + ctx := context.Background() + + return func() { + err := c.client().Drop(ctx, sdk.NewDropStorageIntegrationRequest(id).WithIfExists(sdk.Bool(true))) + require.NoError(t, err) + } +} diff --git a/pkg/acceptance/helpers/test_client.go b/pkg/acceptance/helpers/test_client.go index cf2e559b44..53a9b6cb2d 100644 --- a/pkg/acceptance/helpers/test_client.go +++ b/pkg/acceptance/helpers/test_client.go @@ -27,6 +27,7 @@ type TestClient struct { DataMetricFunctionClient *DataMetricFunctionClient DataMetricFunctionReferences *DataMetricFunctionReferencesClient DynamicTable *DynamicTableClient + EventTable *EventTableClient ExternalAccessIntegration *ExternalAccessIntegrationClient ExternalFunction *ExternalFunctionClient ExternalTable *ExternalTableClient @@ -39,6 +40,7 @@ type TestClient struct { MaterializedView *MaterializedViewClient NetworkPolicy *NetworkPolicyClient NetworkRule *NetworkRuleClient + NotificationIntegration *NotificationIntegrationClient Parameter *ParameterClient PasswordPolicy *PasswordPolicyClient Pipe *PipeClient @@ -54,6 +56,7 @@ type TestClient struct { SessionPolicy *SessionPolicyClient Share *ShareClient Stage *StageClient + StorageIntegration *StorageIntegrationClient Stream *StreamClient Streamlit *StreamlitClient Table *TableClient @@ -96,6 +99,7 @@ func NewTestClient(c *sdk.Client, database string, schema string, warehouse stri DataMetricFunctionClient: NewDataMetricFunctionClient(context, idsGenerator), DataMetricFunctionReferences: NewDataMetricFunctionReferencesClient(context), DynamicTable: NewDynamicTableClient(context, idsGenerator), + EventTable: NewEventTableClient(context, idsGenerator), ExternalAccessIntegration: NewExternalAccessIntegrationClient(context, idsGenerator), ExternalFunction: NewExternalFunctionClient(context, idsGenerator), ExternalTable: NewExternalTableClient(context, idsGenerator), @@ -108,6 +112,7 @@ func NewTestClient(c *sdk.Client, database string, schema string, warehouse stri MaterializedView: NewMaterializedViewClient(context, idsGenerator), NetworkPolicy: NewNetworkPolicyClient(context, idsGenerator), NetworkRule: NewNetworkRuleClient(context, idsGenerator), + NotificationIntegration: NewNotificationIntegrationClient(context, idsGenerator), Parameter: NewParameterClient(context), PasswordPolicy: NewPasswordPolicyClient(context, idsGenerator), Pipe: NewPipeClient(context, idsGenerator), @@ -122,9 +127,10 @@ func NewTestClient(c *sdk.Client, database string, schema string, warehouse stri SecurityIntegration: NewSecurityIntegrationClient(context, idsGenerator), SessionPolicy: NewSessionPolicyClient(context, idsGenerator), Share: NewShareClient(context, idsGenerator), + Stage: NewStageClient(context, idsGenerator), + StorageIntegration: NewStorageIntegrationClient(context, idsGenerator), Stream: NewStreamClient(context, idsGenerator), Streamlit: NewStreamlitClient(context, idsGenerator), - Stage: NewStageClient(context, idsGenerator), Table: NewTableClient(context, idsGenerator), Tag: NewTagClient(context, idsGenerator), Task: NewTaskClient(context, idsGenerator), diff --git a/pkg/sdk/security_integrations_dto_gen.go b/pkg/sdk/security_integrations_dto_gen.go index 43b2d73aae..db894c742b 100644 --- a/pkg/sdk/security_integrations_dto_gen.go +++ b/pkg/sdk/security_integrations_dto_gen.go @@ -61,6 +61,10 @@ type CreateApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationReq Comment *string } +func (r *CreateApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest) GetName() AccountObjectIdentifier { + return r.name +} + type CreateApiAuthenticationWithJwtBearerFlowSecurityIntegrationRequest struct { OrReplace *bool IfNotExists *bool @@ -78,6 +82,10 @@ type CreateApiAuthenticationWithJwtBearerFlowSecurityIntegrationRequest struct { Comment *string } +func (r *CreateApiAuthenticationWithJwtBearerFlowSecurityIntegrationRequest) GetName() AccountObjectIdentifier { + return r.name +} + type CreateExternalOauthSecurityIntegrationRequest struct { OrReplace *bool IfNotExists *bool @@ -99,6 +107,10 @@ type CreateExternalOauthSecurityIntegrationRequest struct { Comment *string } +func (r *CreateExternalOauthSecurityIntegrationRequest) GetName() AccountObjectIdentifier { + return r.name +} + type BlockedRolesListRequest struct { BlockedRolesList []AccountObjectIdentifier // required } diff --git a/pkg/sdk/storage_integration_gen.go b/pkg/sdk/storage_integration_gen.go index 285f35092d..82b02c4547 100644 --- a/pkg/sdk/storage_integration_gen.go +++ b/pkg/sdk/storage_integration_gen.go @@ -121,6 +121,10 @@ type StorageIntegration struct { CreatedOn time.Time } +func (v *StorageIntegration) ID() AccountObjectIdentifier { + return NewAccountObjectIdentifier(v.Name) +} + // DescribeStorageIntegrationOptions is based on https://docs.snowflake.com/en/sql-reference/sql/desc-integration. type DescribeStorageIntegrationOptions struct { describe bool `ddl:"static" sql:"DESCRIBE"` diff --git a/pkg/sdk/system_functions.go b/pkg/sdk/system_functions.go index 4e179ee9ba..6777a013a4 100644 --- a/pkg/sdk/system_functions.go +++ b/pkg/sdk/system_functions.go @@ -27,13 +27,16 @@ type systemFunctions struct { } func (c *systemFunctions) GetTag(ctx context.Context, tagID ObjectIdentifier, objectID ObjectIdentifier, objectType ObjectType) (string, error) { - objectType = normalizeGetTagObjectType(objectType) + objectType, err := normalizeGetTagObjectType(objectType) + if err != nil { + return "", err + } s := &struct { Tag string `db:"TAG"` }{} sql := fmt.Sprintf(`SELECT SYSTEM$GET_TAG('%s', '%s', '%v') AS "TAG"`, tagID.FullyQualifiedName(), objectID.FullyQualifiedName(), objectType) - err := c.client.queryOne(ctx, s, sql) + err = c.client.queryOne(ctx, s, sql) if err != nil { return "", err } @@ -43,15 +46,18 @@ func (c *systemFunctions) GetTag(ctx context.Context, tagID ObjectIdentifier, ob // normalize object types for some values because of errors like below // SQL compilation error: Invalid value VIEW for argument OBJECT_TYPE. Please use object type TABLE for all kinds of table-like objects. // TODO [SNOW-1022645]: discuss how we handle situation like this in the SDK -func normalizeGetTagObjectType(objectType ObjectType) ObjectType { - if slices.Contains([]ObjectType{ObjectTypeView, ObjectTypeMaterializedView, ObjectTypeExternalTable}, objectType) { - return ObjectTypeTable +func normalizeGetTagObjectType(objectType ObjectType) (ObjectType, error) { + if !canBeAssociatedWithTag(objectType) { + return "", fmt.Errorf("tagging for object type %s is not supported", objectType) + } + if slices.Contains([]ObjectType{ObjectTypeView, ObjectTypeMaterializedView, ObjectTypeExternalTable, ObjectTypeEventTable}, objectType) { + return ObjectTypeTable, nil } if slices.Contains([]ObjectType{ObjectTypeExternalFunction}, objectType) { - return ObjectTypeFunction + return ObjectTypeFunction, nil } - return objectType + return objectType, nil } type PipeExecutionState string diff --git a/pkg/sdk/tag_association_validations.go b/pkg/sdk/tag_association_validations.go index b7f5c03b03..cb4c22f818 100644 --- a/pkg/sdk/tag_association_validations.go +++ b/pkg/sdk/tag_association_validations.go @@ -1,5 +1,7 @@ package sdk +import "slices" + var ( // based on https://docs.snowflake.com/en/user-guide/object-tagging.html#supported-objects TagAssociationAllowedObjectTypes = []ObjectType{ @@ -71,6 +73,10 @@ var ( TagAssociationAllowedObjectTypesString = make([]string, len(TagAssociationAllowedObjectTypes)) ) +func canBeAssociatedWithTag(o ObjectType) bool { + return slices.Contains(TagAssociationAllowedObjectTypes, o) +} + func init() { for i, v := range TagAssociationAllowedObjectTypes { TagAssociationAllowedObjectTypesString[i] = v.String() diff --git a/pkg/sdk/tags.go b/pkg/sdk/tags.go index 8e0c87fc29..0fb31322ce 100644 --- a/pkg/sdk/tags.go +++ b/pkg/sdk/tags.go @@ -15,6 +15,8 @@ type Tags interface { Undrop(ctx context.Context, request *UndropTagRequest) error Set(ctx context.Context, request *SetTagRequest) error Unset(ctx context.Context, request *UnsetTagRequest) error + SetOnCurrentAccount(ctx context.Context, request *SetTagOnCurrentAccountRequest) error + UnsetOnCurrentAccount(ctx context.Context, request *UnsetTagOnCurrentAccountRequest) error } type setTagOptions struct { diff --git a/pkg/sdk/tags_dto.go b/pkg/sdk/tags_dto.go index f79a6589a2..4aa1a50df4 100644 --- a/pkg/sdk/tags_dto.go +++ b/pkg/sdk/tags_dto.go @@ -25,6 +25,14 @@ type UnsetTagRequest struct { UnsetTags []ObjectIdentifier } +type SetTagOnCurrentAccountRequest struct { + SetTags []TagAssociation +} + +type UnsetTagOnCurrentAccountRequest struct { + UnsetTags []ObjectIdentifier +} + type CreateTagRequest struct { orReplace *bool ifNotExists *bool diff --git a/pkg/sdk/tags_dto_builders.go b/pkg/sdk/tags_dto_builders.go index b9aaa38e7a..4e8a155989 100644 --- a/pkg/sdk/tags_dto_builders.go +++ b/pkg/sdk/tags_dto_builders.go @@ -24,6 +24,24 @@ func (s *UnsetTagRequest) WithUnsetTags(tags []ObjectIdentifier) *UnsetTagReques return s } +func NewSetTagOnCurrentAccountRequest() *SetTagOnCurrentAccountRequest { + return &SetTagOnCurrentAccountRequest{} +} + +func (s *SetTagOnCurrentAccountRequest) WithSetTags(tags []TagAssociation) *SetTagOnCurrentAccountRequest { + s.SetTags = tags + return s +} + +func NewUnsetTagOnCurrentAccountRequest() *UnsetTagOnCurrentAccountRequest { + return &UnsetTagOnCurrentAccountRequest{} +} + +func (s *UnsetTagOnCurrentAccountRequest) WithUnsetTags(tags []ObjectIdentifier) *UnsetTagOnCurrentAccountRequest { + s.UnsetTags = tags + return s +} + func NewCreateTagRequest(name SchemaObjectIdentifier) *CreateTagRequest { s := CreateTagRequest{} s.name = name diff --git a/pkg/sdk/tags_impl.go b/pkg/sdk/tags_impl.go index 529dc851eb..9813b03803 100644 --- a/pkg/sdk/tags_impl.go +++ b/pkg/sdk/tags_impl.go @@ -57,17 +57,41 @@ func (v *tags) Undrop(ctx context.Context, request *UndropTagRequest) error { } func (v *tags) Set(ctx context.Context, request *SetTagRequest) error { + objectType, err := normalizeGetTagObjectType(request.objectType) + if err != nil { + return err + } + request.objectType = objectType + // TODO [SNOW-1022645]: use query from resource sdk - similarly to https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/0e88e082282adf35f605c323569908a99bd406f9/pkg/acceptance/check_destroy.go#L67 opts := request.toOpts() return validateAndExec(v.client, ctx, opts) } func (v *tags) Unset(ctx context.Context, request *UnsetTagRequest) error { + objectType, err := normalizeGetTagObjectType(request.objectType) + if err != nil { + return err + } + request.objectType = objectType + // TODO [SNOW-1022645]: use query from resource sdk - similarly to https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/0e88e082282adf35f605c323569908a99bd406f9/pkg/acceptance/check_destroy.go#L67 opts := request.toOpts() return validateAndExec(v.client, ctx, opts) } +func (v *tags) SetOnCurrentAccount(ctx context.Context, request *SetTagOnCurrentAccountRequest) error { + return v.client.Accounts.Alter(ctx, &AlterAccountOptions{ + SetTag: request.SetTags, + }) +} + +func (v *tags) UnsetOnCurrentAccount(ctx context.Context, request *UnsetTagOnCurrentAccountRequest) error { + return v.client.Accounts.Alter(ctx, &AlterAccountOptions{ + UnsetTag: request.UnsetTags, + }) +} + func (s *CreateTagRequest) toOpts() *createTagOptions { return &createTagOptions{ OrReplace: s.orReplace, diff --git a/pkg/sdk/tags_test.go b/pkg/sdk/tags_test.go index 5c3e01717a..0979537b27 100644 --- a/pkg/sdk/tags_test.go +++ b/pkg/sdk/tags_test.go @@ -1,6 +1,7 @@ package sdk import ( + "errors" "testing" ) @@ -370,6 +371,18 @@ func TestTagSet(t *testing.T) { assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) }) + t.Run("validation: unsupported object type", func(t *testing.T) { + opts := defaultOpts() + opts.objectType = ObjectTypeSequence + assertOptsInvalidJoinedErrors(t, opts, errors.New("tagging for object type SEQUENCE is not supported")) + }) + + t.Run("validation: unsupported account", func(t *testing.T) { + opts := defaultOpts() + opts.objectType = ObjectTypeAccount + assertOptsInvalidJoinedErrors(t, opts, errors.New("tagging for object type ACCOUNT is not supported - use Tags.SetOnCurrentAccount instead")) + }) + t.Run("set with all optional", func(t *testing.T) { opts := defaultOpts() opts.SetTags = []TagAssociation{ @@ -415,6 +428,18 @@ func TestTagUnset(t *testing.T) { assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) }) + t.Run("validation: unsupported object type", func(t *testing.T) { + opts := defaultOpts() + opts.objectType = ObjectTypeSequence + assertOptsInvalidJoinedErrors(t, opts, errors.New("tagging for object type SEQUENCE is not supported")) + }) + + t.Run("validation: unsupported account", func(t *testing.T) { + opts := defaultOpts() + opts.objectType = ObjectTypeAccount + assertOptsInvalidJoinedErrors(t, opts, errors.New("tagging for object type ACCOUNT is not supported - use Tags.UnsetOnCurrentAccount instead")) + }) + t.Run("unset with all optional", func(t *testing.T) { opts := defaultOpts() opts.UnsetTags = []ObjectIdentifier{ diff --git a/pkg/sdk/tags_validations.go b/pkg/sdk/tags_validations.go index cd0b55cd0a..f6fd74b83b 100644 --- a/pkg/sdk/tags_validations.go +++ b/pkg/sdk/tags_validations.go @@ -2,6 +2,7 @@ package sdk import ( "errors" + "fmt" ) var ( @@ -150,6 +151,12 @@ func (opts *setTagOptions) validate() error { if !ValidObjectIdentifier(opts.objectName) { errs = append(errs, ErrInvalidObjectIdentifier) } + if !canBeAssociatedWithTag(opts.objectType) { + return fmt.Errorf("tagging for object type %s is not supported", opts.objectType) + } + if opts.objectType == ObjectTypeAccount { + return fmt.Errorf("tagging for object type ACCOUNT is not supported - use Tags.SetOnCurrentAccount instead") + } return errors.Join(errs...) } @@ -161,5 +168,11 @@ func (opts *unsetTagOptions) validate() error { if !ValidObjectIdentifier(opts.objectName) { errs = append(errs, ErrInvalidObjectIdentifier) } + if !canBeAssociatedWithTag(opts.objectType) { + return fmt.Errorf("tagging for object type %s is not supported", opts.objectType) + } + if opts.objectType == ObjectTypeAccount { + return fmt.Errorf("tagging for object type ACCOUNT is not supported - use Tags.UnsetOnCurrentAccount instead") + } return errors.Join(errs...) } diff --git a/pkg/sdk/testint/accounts_integration_test.go b/pkg/sdk/testint/accounts_integration_test.go index 232465509c..3192bd27d1 100644 --- a/pkg/sdk/testint/accounts_integration_test.go +++ b/pkg/sdk/testint/accounts_integration_test.go @@ -288,32 +288,4 @@ func TestInt_AccountAlter(t *testing.T) { err = client.Accounts.Alter(ctx, opts) require.NoError(t, err) }) - - t.Run("set and unset tag", func(t *testing.T) { - tagTest1, tagCleanup1 := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup1) - tagTest2, tagCleanup2 := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup2) - - opts := &sdk.AlterAccountOptions{ - SetTag: []sdk.TagAssociation{ - { - Name: tagTest1.ID(), - Value: "abc", - }, - { - Name: tagTest2.ID(), - Value: "123", - }, - }, - } - err := client.Accounts.Alter(ctx, opts) - require.NoError(t, err) - tagValue, err := client.SystemFunctions.GetTag(ctx, tagTest1.ID(), testClientHelper().Ids.AccountIdentifierWithLocator(), sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Equal(t, "abc", tagValue) - tagValue, err = client.SystemFunctions.GetTag(ctx, tagTest2.ID(), testClientHelper().Ids.AccountIdentifierWithLocator(), sdk.ObjectTypeAccount) - require.NoError(t, err) - assert.Equal(t, "123", tagValue) - }) } diff --git a/pkg/sdk/testint/api_integrations_gen_integration_test.go b/pkg/sdk/testint/api_integrations_gen_integration_test.go index 484f5f3e81..b4c04c6e64 100644 --- a/pkg/sdk/testint/api_integrations_gen_integration_test.go +++ b/pkg/sdk/testint/api_integrations_gen_integration_test.go @@ -347,42 +347,6 @@ func TestInt_ApiIntegrations(t *testing.T) { assert.Contains(t, details, sdk.ApiIntegrationProperty{Name: "GOOGLE_AUDIENCE", Type: "String", Value: googleOtherAudience, Default: ""}) }) - t.Run("alter api integration: set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - integration := createAwsApiIntegration(t) - id := integration.ID() - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterApiIntegrationRequest(id).WithSetTags(tags) - - err := client.ApiIntegrations.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterApiIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.ApiIntegrations.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("drop api integration: existing", func(t *testing.T) { request := createApiIntegrationAwsRequest(t) id := request.GetName() diff --git a/pkg/sdk/testint/application_packages_integration_test.go b/pkg/sdk/testint/application_packages_integration_test.go index 196d299974..a9e5e5b2fd 100644 --- a/pkg/sdk/testint/application_packages_integration_test.go +++ b/pkg/sdk/testint/application_packages_integration_test.go @@ -53,31 +53,6 @@ func TestInt_ApplicationPackages(t *testing.T) { return e } - assertApplicationPackage := func(t *testing.T, id sdk.AccountObjectIdentifier) { - t.Helper() - - param, err := client.Parameters.ShowAccountParameter(ctx, sdk.AccountParameterDataRetentionTimeInDays) - require.NoError(t, err) - - defaultDataRetentionTimeInDays, err := strconv.Atoi(param.Value) - require.NoError(t, err) - - e, err := client.ApplicationPackages.ShowByID(ctx, id) - require.NoError(t, err) - - assert.NotEmpty(t, e.CreatedOn) - assert.Equal(t, id.Name(), e.Name) - assert.Equal(t, false, e.IsDefault) - assert.Equal(t, true, e.IsCurrent) - assert.Equal(t, sdk.DistributionInternal, sdk.Distribution(e.Distribution)) - assert.Equal(t, "ACCOUNTADMIN", e.Owner) - assert.Empty(t, e.Comment) - assert.Equal(t, defaultDataRetentionTimeInDays, e.RetentionTime) - assert.Empty(t, e.Options) - assert.Empty(t, e.DroppedOn) - assert.Empty(t, e.ApplicationClass) - } - t.Run("create application package", func(t *testing.T) { id := testClientHelper().Ids.RandomAccountObjectIdentifier() comment := random.Comment() @@ -145,32 +120,6 @@ func TestInt_ApplicationPackages(t *testing.T) { require.Equal(t, sdk.DistributionInternal, sdk.Distribution(o.Distribution)) }) - t.Run("alter application package: set and unset tags", func(t *testing.T) { - e := createApplicationPackageHandle(t) - id := e.ID() - - setTags := []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: "v1", - }, - } - err := client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithSetTags(setTags)) - require.NoError(t, err) - assertApplicationPackage(t, id) - - value, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), id, sdk.ObjectTypeApplicationPackage) - require.NoError(t, err) - assert.Equal(t, "v1", value) - - unsetTags := []sdk.ObjectIdentifier{ - tagTest.ID(), - } - err = client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithUnsetTags(unsetTags)) - require.NoError(t, err) - assertApplicationPackage(t, id) - }) - t.Run("show application package for SQL: with like", func(t *testing.T) { e := createApplicationPackageHandle(t) diff --git a/pkg/sdk/testint/applications_integration_test.go b/pkg/sdk/testint/applications_integration_test.go index 2ee81c8da6..4332983a97 100644 --- a/pkg/sdk/testint/applications_integration_test.go +++ b/pkg/sdk/testint/applications_integration_test.go @@ -236,33 +236,6 @@ func TestInt_Applications(t *testing.T) { require.Equal(t, strconv.FormatBool(false), pairs["debug_mode"]) }) - t.Run("alter application: set and unset tags", func(t *testing.T) { - version, patch := "V001", 0 - _, e, applicationPackage := createApplicationHandle(t, version, patch, false, true, false) - id := e.ID() - - setTags := []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: "v1", - }, - } - err := client.Applications.Alter(ctx, sdk.NewAlterApplicationRequest(id).WithSetTags(setTags)) - require.NoError(t, err) - assertApplication(t, id, applicationPackage.Name, version, patch, "") - - // TODO(SNOW-1746420): adjust after this is fixed on Snowflake side - _, err = client.SystemFunctions.GetTag(ctx, tagTest.ID(), id, sdk.ObjectTypeApplication) - require.ErrorContains(t, err, "391801 (0A000): SQL compilation error: Object tagging not supported for object type APPLICATION") - - unsetTags := []sdk.ObjectIdentifier{ - tagTest.ID(), - } - err = client.Applications.Alter(ctx, sdk.NewAlterApplicationRequest(id).WithUnsetTags(unsetTags)) - require.NoError(t, err) - assertApplication(t, id, applicationPackage.Name, version, patch, "") - }) - t.Run("alter application: upgrade with version and patch", func(t *testing.T) { version, patch := "V001", 0 _, e, applicationPackage := createApplicationHandle(t, version, patch, false, true, true) diff --git a/pkg/sdk/testint/authentication_policies_gen_integration_test.go b/pkg/sdk/testint/authentication_policies_gen_integration_test.go index 67cf9efd92..6de2607031 100644 --- a/pkg/sdk/testint/authentication_policies_gen_integration_test.go +++ b/pkg/sdk/testint/authentication_policies_gen_integration_test.go @@ -58,10 +58,9 @@ func TestInt_AuthenticationPolicies(t *testing.T) { t.Run("Create - complete", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() - saml2Id := testClientHelper().Ids.RandomAccountObjectIdentifier() comment := random.Comment() - _, cleanupSamlIntegration := testClientHelper().SecurityIntegration.CreateSaml2(t, saml2Id) + samlIntegration, cleanupSamlIntegration := testClientHelper().SecurityIntegration.CreateSaml2(t) t.Cleanup(cleanupSamlIntegration) err := client.AuthenticationPolicies.Create(ctx, sdk.NewCreateAuthenticationPolicyRequest(id). @@ -72,7 +71,7 @@ func TestInt_AuthenticationPolicies(t *testing.T) { {Method: sdk.MfaAuthenticationMethodsSaml}, }). WithSecurityIntegrations([]sdk.SecurityIntegrationsOption{ - {Name: saml2Id}, + {Name: samlIntegration.ID()}, }). WithClientTypes([]sdk.ClientTypes{ {ClientType: sdk.ClientTypesDrivers}, @@ -93,19 +92,18 @@ func TestInt_AuthenticationPolicies(t *testing.T) { assertProperty(t, desc, "COMMENT", comment) assertProperty(t, desc, "MFA_ENROLLMENT", "OPTIONAL") assertProperty(t, desc, "MFA_AUTHENTICATION_METHODS", "[PASSWORD, SAML]") - assertProperty(t, desc, "SECURITY_INTEGRATIONS", fmt.Sprintf("[%s]", saml2Id.Name())) + assertProperty(t, desc, "SECURITY_INTEGRATIONS", fmt.Sprintf("[%s]", samlIntegration.ID().Name())) assertProperty(t, desc, "CLIENT_TYPES", "[DRIVERS, SNOWSQL]") assertProperty(t, desc, "AUTHENTICATION_METHODS", "[PASSWORD, SAML]") }) t.Run("Alter - set and unset properties", func(t *testing.T) { - saml2Id := testClientHelper().Ids.RandomAccountObjectIdentifier() comment := random.Comment() authenticationPolicy, cleanupAuthPolicy := testClientHelper().AuthenticationPolicy.Create(t) t.Cleanup(cleanupAuthPolicy) - _, cleanupSamlIntegration := testClientHelper().SecurityIntegration.CreateSaml2(t, saml2Id) + samlIntegration, cleanupSamlIntegration := testClientHelper().SecurityIntegration.CreateSaml2(t) t.Cleanup(cleanupSamlIntegration) err := client.AuthenticationPolicies.Alter(ctx, sdk.NewAlterAuthenticationPolicyRequest(authenticationPolicy.ID()). @@ -117,7 +115,7 @@ func TestInt_AuthenticationPolicies(t *testing.T) { {Method: sdk.MfaAuthenticationMethodsSaml}, }). WithSecurityIntegrations([]sdk.SecurityIntegrationsOption{ - {Name: saml2Id}, + {Name: samlIntegration.ID()}, }). WithClientTypes([]sdk.ClientTypes{ {ClientType: sdk.ClientTypesDrivers}, @@ -136,7 +134,7 @@ func TestInt_AuthenticationPolicies(t *testing.T) { assertProperty(t, desc, "COMMENT", comment) assertProperty(t, desc, "MFA_ENROLLMENT", "REQUIRED") assertProperty(t, desc, "MFA_AUTHENTICATION_METHODS", "[PASSWORD, SAML]") - assertProperty(t, desc, "SECURITY_INTEGRATIONS", fmt.Sprintf("[%s]", saml2Id.Name())) + assertProperty(t, desc, "SECURITY_INTEGRATIONS", fmt.Sprintf("[%s]", samlIntegration.ID().Name())) assertProperty(t, desc, "CLIENT_TYPES", "[DRIVERS, SNOWSQL, SNOWFLAKE_UI]") assertProperty(t, desc, "AUTHENTICATION_METHODS", "[PASSWORD, SAML]") diff --git a/pkg/sdk/testint/database_role_integration_test.go b/pkg/sdk/testint/database_role_integration_test.go index aa0f716150..9d38c2851a 100644 --- a/pkg/sdk/testint/database_role_integration_test.go +++ b/pkg/sdk/testint/database_role_integration_test.go @@ -163,39 +163,6 @@ func TestInt_DatabaseRoles(t *testing.T) { assert.ErrorIs(t, err, sdk.ErrDifferentDatabase) }) - t.Run("alter database_role: set and unset tag", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - databaseRole, cleanupDatabaseRole := testClientHelper().DatabaseRole.CreateDatabaseRole(t) - t.Cleanup(cleanupDatabaseRole) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - - err := client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(databaseRole.ID()).WithSetTags(tags)) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), databaseRole.ID(), sdk.ObjectTypeDatabaseRole) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - err = client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(databaseRole.ID()).WithUnsetTags(unsetTags)) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), databaseRole.ID(), sdk.ObjectTypeDatabaseRole) - require.Error(t, err) - }) - t.Run("show database_role: without like", func(t *testing.T) { role1 := createDatabaseRole(t) role2 := createDatabaseRole(t) diff --git a/pkg/sdk/testint/databases_integration_test.go b/pkg/sdk/testint/databases_integration_test.go index d6b45916b7..8dc2408eee 100644 --- a/pkg/sdk/testint/databases_integration_test.go +++ b/pkg/sdk/testint/databases_integration_test.go @@ -337,12 +337,8 @@ func TestInt_DatabasesCreateSecondary(t *testing.T) { func TestInt_DatabasesAlter(t *testing.T) { client := testClient(t) - secondaryClient := testSecondaryClient(t) ctx := testContext(t) - tagTest, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - assertDatabaseParameterEquals := func(t *testing.T, params []*sdk.Parameter, parameterName sdk.AccountParameter, expected string) { t.Helper() assert.Equal(t, expected, helpers.FindParameter(t, params, parameterName).Value) @@ -372,74 +368,11 @@ func TestInt_DatabasesAlter(t *testing.T) { }, { DatabaseType: "From Share", - CreateFn: func(t *testing.T) (*sdk.Database, func()) { - t.Helper() - - shareTest, shareCleanup := secondaryTestClientHelper().Share.CreateShare(t) - t.Cleanup(shareCleanup) - - sharedDatabase, sharedDatabaseCleanup := secondaryTestClientHelper().Database.CreateDatabase(t) - t.Cleanup(sharedDatabaseCleanup) - - databaseId := sharedDatabase.ID() - - err := secondaryClient.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ - Database: sharedDatabase.ID(), - }, shareTest.ID()) - require.NoError(t, err) - t.Cleanup(func() { - err := secondaryClient.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ - Database: sharedDatabase.ID(), - }, shareTest.ID()) - require.NoError(t, err) - }) - - err = secondaryClient.Shares.Alter(ctx, shareTest.ID(), &sdk.AlterShareOptions{ - IfExists: sdk.Bool(true), - Set: &sdk.ShareSet{ - Accounts: []sdk.AccountIdentifier{ - testClientHelper().Account.GetAccountIdentifier(t), - }, - }, - }) - require.NoError(t, err) - - err = client.Databases.CreateShared(ctx, databaseId, shareTest.ExternalID(), &sdk.CreateSharedDatabaseOptions{}) - require.NoError(t, err) - - database, err := client.Databases.ShowByID(ctx, databaseId) - require.NoError(t, err) - - return database, testClientHelper().Database.DropDatabaseFunc(t, database.ID()) - }, + CreateFn: createDatabaseFromShare, }, { DatabaseType: "Replica", - CreateFn: func(t *testing.T) (*sdk.Database, func()) { - t.Helper() - - sharedDatabase, sharedDatabaseCleanup := secondaryTestClientHelper().Database.CreateDatabase(t) - t.Cleanup(sharedDatabaseCleanup) - - err := secondaryClient.Databases.AlterReplication(ctx, sharedDatabase.ID(), &sdk.AlterDatabaseReplicationOptions{ - EnableReplication: &sdk.EnableReplication{ - ToAccounts: []sdk.AccountIdentifier{ - testClientHelper().Account.GetAccountIdentifier(t), - }, - IgnoreEditionCheck: sdk.Bool(true), - }, - }) - require.NoError(t, err) - - externalDatabaseId := sdk.NewExternalObjectIdentifier(secondaryTestClientHelper().Ids.AccountIdentifierWithLocator(), sharedDatabase.ID()) - err = client.Databases.CreateSecondary(ctx, sharedDatabase.ID(), externalDatabaseId, &sdk.CreateSecondaryDatabaseOptions{}) - require.NoError(t, err) - - database, err := client.Databases.ShowByID(ctx, sharedDatabase.ID()) - require.NoError(t, err) - - return database, testClientHelper().Database.DropDatabaseFunc(t, sharedDatabase.ID()) - }, + CreateFn: createDatabaseReplica, }, } @@ -585,38 +518,6 @@ func TestInt_DatabasesAlter(t *testing.T) { assert.Equal(t, "", database.Comment) }) - t.Run(fmt.Sprintf("Database: %s - setting and unsetting tags", testCase.DatabaseType), func(t *testing.T) { - if testCase.DatabaseType == "Replica" { - t.Skipf("Skipping database test because secondary databases cannot be modified") - } - databaseTest, databaseTestCleanup := testCase.CreateFn(t) - t.Cleanup(databaseTestCleanup) - - err := client.Databases.Alter(ctx, databaseTest.ID(), &sdk.AlterDatabaseOptions{ - SetTag: []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: "v1", - }, - }, - }) - require.NoError(t, err) - - value, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), databaseTest.ID(), sdk.ObjectTypeDatabase) - require.NoError(t, err) - assert.Equal(t, "v1", value) - - err = client.Databases.Alter(ctx, databaseTest.ID(), &sdk.AlterDatabaseOptions{ - UnsetTag: []sdk.ObjectIdentifier{ - tagTest.ID(), - }, - }) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tagTest.ID(), databaseTest.ID(), sdk.ObjectTypeDatabase) - require.Error(t, err) - }) - t.Run(fmt.Sprintf("Database: %s - swap with another database", testCase.DatabaseType), func(t *testing.T) { databaseTest, databaseTestCleanup := testCase.CreateFn(t) t.Cleanup(databaseTestCleanup) diff --git a/pkg/sdk/testint/event_tables_integration_test.go b/pkg/sdk/testint/event_tables_integration_test.go index 806095fe4b..434e0e60c0 100644 --- a/pkg/sdk/testint/event_tables_integration_test.go +++ b/pkg/sdk/testint/event_tables_integration_test.go @@ -147,28 +147,6 @@ func TestInt_EventTables(t *testing.T) { require.NoError(t, err) }) - t.Run("alter event table: set and unset tag", func(t *testing.T) { - dt := createEventTableHandle(t) - id := dt.ID() - - set := []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: "v1", - }, - } - err := client.EventTables.Alter(ctx, sdk.NewAlterEventTableRequest(id).WithSetTags(set)) - require.NoError(t, err) - - value, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), id, sdk.ObjectTypeEventTable) - require.NoError(t, err) - assert.Equal(t, "v1", value) - - unset := []sdk.ObjectIdentifier{tagTest.ID()} - err = client.EventTables.Alter(ctx, sdk.NewAlterEventTableRequest(id).WithUnsetTags(unset)) - require.NoError(t, err) - }) - t.Run("alter event table: rename", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() diff --git a/pkg/sdk/testint/external_functions_integration_test.go b/pkg/sdk/testint/external_functions_integration_test.go index a9858c5742..3d23fd6d6d 100644 --- a/pkg/sdk/testint/external_functions_integration_test.go +++ b/pkg/sdk/testint/external_functions_integration_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -195,33 +194,6 @@ func TestInt_ExternalFunctions(t *testing.T) { assertExternalFunction(t, externalFunction.ID(), true) }) - t.Run("alter external function: set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - externalFunction := createExternalFunction(t) - - id := externalFunction.ID() - setTags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: "v1", - }, - } - err := client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithSetTags(setTags)) - require.NoError(t, err) - - value, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeExternalFunction) - require.NoError(t, err) - assert.Equal(t, "v1", value) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - err = client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithUnsetTags(unsetTags)) - require.NoError(t, err) - }) - t.Run("show external function: with like", func(t *testing.T) { e1 := createExternalFunction(t) e2 := createExternalFunction(t) diff --git a/pkg/sdk/testint/external_tables_integration_test.go b/pkg/sdk/testint/external_tables_integration_test.go index 83832274d9..26f0e0a720 100644 --- a/pkg/sdk/testint/external_tables_integration_test.go +++ b/pkg/sdk/testint/external_tables_integration_test.go @@ -239,50 +239,6 @@ func TestInt_ExternalTables(t *testing.T) { require.NoError(t, err) }) - t.Run("Alter: set tags", func(t *testing.T) { - externalTableID := testClientHelper().Ids.RandomSchemaObjectIdentifier() - err := client.ExternalTables.Create(ctx, minimalCreateExternalTableReq(externalTableID)) - require.NoError(t, err) - - tagValue := "tag-value" - err = client.Tables.Alter( - ctx, - sdk.NewAlterTableRequest(externalTableID). - WithIfExists(sdk.Bool(true)). - WithSetTags([]sdk.TagAssociationRequest{*sdk.NewTagAssociationRequest(tag.ID(), tagValue)})) - require.NoError(t, err) - - tv, err := client.SystemFunctions.GetTag(ctx, tag.ID(), externalTableID, sdk.ObjectTypeExternalTable) - require.NoError(t, err) - assert.Equal(t, tagValue, tv) - }) - - t.Run("Alter: unset tags", func(t *testing.T) { - externalTableID := testClientHelper().Ids.RandomSchemaObjectIdentifier() - err := client.ExternalTables.Create( - ctx, - minimalCreateExternalTableReq(externalTableID). - WithTag([]*sdk.TagAssociationRequest{sdk.NewTagAssociationRequest(tag.ID(), "tag-value")}), - ) - require.NoError(t, err) - tv, err := client.SystemFunctions.GetTag(ctx, tag.ID(), externalTableID, sdk.ObjectTypeExternalTable) - require.NoError(t, err) - assert.Equal(t, "tag-value", tv) - - err = client.Tables.Alter( - ctx, - sdk.NewAlterTableRequest(externalTableID). - WithIfExists(sdk.Bool(true)). - WithUnsetTags([]sdk.ObjectIdentifier{ - tag.ID(), - }), - ) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), externalTableID, sdk.ObjectTypeExternalTable) - require.Error(t, err) - }) - t.Run("Alter: add partitions", func(t *testing.T) { externalTableID := testClientHelper().Ids.RandomSchemaObjectIdentifier() err := client.ExternalTables.CreateWithManualPartitioning(ctx, createExternalTableWithManualPartitioningReq(externalTableID)) diff --git a/pkg/sdk/testint/functions_integration_test.go b/pkg/sdk/testint/functions_integration_test.go index 31e96153ca..1fe0a04bb9 100644 --- a/pkg/sdk/testint/functions_integration_test.go +++ b/pkg/sdk/testint/functions_integration_test.go @@ -189,9 +189,6 @@ func TestInt_OtherFunctions(t *testing.T) { client := testClient(t) ctx := testContext(t) - tagTest, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - assertFunction := func(t *testing.T, id sdk.SchemaObjectIdentifierWithArguments, secure bool, withArguments bool) { t.Helper() @@ -362,32 +359,6 @@ func TestInt_OtherFunctions(t *testing.T) { assertFunction(t, id, false, true) }) - t.Run("alter function: set and unset tags", func(t *testing.T) { - f := createFunctionForSQLHandle(t, true, true) - - id := f.ID() - setTags := []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: "v1", - }, - } - err := client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithSetTags(setTags)) - require.NoError(t, err) - assertFunction(t, id, false, true) - - value, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), id, sdk.ObjectTypeFunction) - require.NoError(t, err) - assert.Equal(t, "v1", value) - - unsetTags := []sdk.ObjectIdentifier{ - tagTest.ID(), - } - err = client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithUnsetTags(unsetTags)) - require.NoError(t, err) - assertFunction(t, id, false, true) - }) - t.Run("show function for SQL: without like", func(t *testing.T) { f1 := createFunctionForSQLHandle(t, true, true) f2 := createFunctionForSQLHandle(t, true, true) diff --git a/pkg/sdk/testint/helpers.go b/pkg/sdk/testint/helpers.go new file mode 100644 index 0000000000..5f5443d945 --- /dev/null +++ b/pkg/sdk/testint/helpers.go @@ -0,0 +1,155 @@ +package testint + +import ( + "context" + "fmt" + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/stretchr/testify/require" +) + +func createDatabaseFromShare(t *testing.T) (*sdk.Database, func()) { + t.Helper() + client := testClient(t) + secondaryClient := testSecondaryClient(t) + ctx := testContext(t) + + shareTest, shareCleanup := secondaryTestClientHelper().Share.CreateShare(t) + t.Cleanup(shareCleanup) + + sharedDatabase, sharedDatabaseCleanup := secondaryTestClientHelper().Database.CreateDatabase(t) + t.Cleanup(sharedDatabaseCleanup) + + databaseId := sharedDatabase.ID() + + err := secondaryClient.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ + Database: sharedDatabase.ID(), + }, shareTest.ID()) + require.NoError(t, err) + t.Cleanup(func() { + err := secondaryClient.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ + Database: sharedDatabase.ID(), + }, shareTest.ID()) + require.NoError(t, err) + }) + + err = secondaryClient.Shares.Alter(ctx, shareTest.ID(), &sdk.AlterShareOptions{ + IfExists: sdk.Bool(true), + Set: &sdk.ShareSet{ + Accounts: []sdk.AccountIdentifier{ + testClientHelper().Account.GetAccountIdentifier(t), + }, + }, + }) + require.NoError(t, err) + + err = client.Databases.CreateShared(ctx, databaseId, shareTest.ExternalID(), &sdk.CreateSharedDatabaseOptions{}) + require.NoError(t, err) + + database, err := client.Databases.ShowByID(ctx, databaseId) + require.NoError(t, err) + + return database, testClientHelper().Database.DropDatabaseFunc(t, database.ID()) +} + +func createDatabaseReplica(t *testing.T) (*sdk.Database, func()) { + t.Helper() + client := testClient(t) + secondaryClient := testSecondaryClient(t) + ctx := testContext(t) + + sharedDatabase, sharedDatabaseCleanup := secondaryTestClientHelper().Database.CreateDatabase(t) + t.Cleanup(sharedDatabaseCleanup) + + err := secondaryClient.Databases.AlterReplication(ctx, sharedDatabase.ID(), &sdk.AlterDatabaseReplicationOptions{ + EnableReplication: &sdk.EnableReplication{ + ToAccounts: []sdk.AccountIdentifier{ + testClientHelper().Account.GetAccountIdentifier(t), + }, + IgnoreEditionCheck: sdk.Bool(true), + }, + }) + require.NoError(t, err) + + externalDatabaseId := sdk.NewExternalObjectIdentifier(secondaryTestClientHelper().Ids.AccountIdentifierWithLocator(), sharedDatabase.ID()) + err = client.Databases.CreateSecondary(ctx, sharedDatabase.ID(), externalDatabaseId, &sdk.CreateSecondaryDatabaseOptions{}) + require.NoError(t, err) + + database, err := client.Databases.ShowByID(ctx, sharedDatabase.ID()) + require.NoError(t, err) + + return database, testClientHelper().Database.DropDatabaseFunc(t, sharedDatabase.ID()) +} + +func createApplicationPackage(t *testing.T) (*sdk.ApplicationPackage, func()) { + t.Helper() + + stage, cleanupStage := testClientHelper().Stage.CreateStage(t) + t.Cleanup(cleanupStage) + + testClientHelper().Stage.PutOnStageWithContent(t, stage.ID(), "manifest.yml", "") + testClientHelper().Stage.PutOnStageWithContent(t, stage.ID(), "setup.sql", "CREATE APPLICATION ROLE IF NOT EXISTS APP_HELLO_SNOWFLAKE;") + + applicationPackage, cleanupApplicationPackage := testClientHelper().ApplicationPackage.CreateApplicationPackage(t) + t.Cleanup(cleanupApplicationPackage) + + testClientHelper().ApplicationPackage.AddApplicationPackageVersion(t, applicationPackage.ID(), stage.ID(), "V01") + + return applicationPackage, cleanupApplicationPackage +} + +func createShare(t *testing.T, ctx context.Context, client *sdk.Client) (*sdk.Share, func()) { + t.Helper() + object, objectCleanup := testClientHelper().Share.CreateShare(t) + t.Cleanup(objectCleanup) + + err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ + Database: testClientHelper().Ids.DatabaseId(), + }, object.ID()) + require.NoError(t, err) + cleanup := func() { + err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ + Database: testClientHelper().Ids.DatabaseId(), + }, object.ID()) + require.NoError(t, err) + } + return object, cleanup +} + +func createPipe(t *testing.T) (*sdk.Pipe, func()) { + t.Helper() + table, tableCleanup := testClientHelper().Table.Create(t) + t.Cleanup(tableCleanup) + + stage, stageCleanup := testClientHelper().Stage.CreateStage(t) + t.Cleanup(stageCleanup) + + return testClientHelper().Pipe.CreatePipe(t, fmt.Sprintf("COPY INTO %s\nFROM @%s", table.ID().FullyQualifiedName(), stage.ID().FullyQualifiedName())) +} + +func createMaterializedView(t *testing.T) (*sdk.MaterializedView, func()) { + t.Helper() + table, tableCleanup := testClientHelper().Table.Create(t) + t.Cleanup(tableCleanup) + query := fmt.Sprintf(`SELECT * FROM %s`, table.ID().FullyQualifiedName()) + return testClientHelper().MaterializedView.CreateMaterializedView(t, query, false) +} + +func createStream(t *testing.T) (*sdk.Stream, func()) { + t.Helper() + table, tableCleanup := testClientHelper().Table.CreateInSchema(t, testClientHelper().Ids.SchemaId()) + t.Cleanup(tableCleanup) + + return testClientHelper().Stream.CreateOnTable(t, table.ID()) +} + +func createExternalTable(t *testing.T) (*sdk.ExternalTable, func()) { + t.Helper() + stageID := testClientHelper().Ids.RandomSchemaObjectIdentifier() + stageLocation := fmt.Sprintf("@%s", stageID.FullyQualifiedName()) + _, stageCleanup := testClientHelper().Stage.CreateStageWithURL(t, stageID) + t.Cleanup(stageCleanup) + + return testClientHelper().ExternalTable.CreateWithLocation(t, stageLocation) +} diff --git a/pkg/sdk/testint/masking_policy_integration_test.go b/pkg/sdk/testint/masking_policy_integration_test.go index e23dc59660..6a645c783a 100644 --- a/pkg/sdk/testint/masking_policy_integration_test.go +++ b/pkg/sdk/testint/masking_policy_integration_test.go @@ -343,40 +343,6 @@ func TestInt_MaskingPolicyAlter(t *testing.T) { require.NoError(t, err) }) - t.Run("setting and unsetting tags", func(t *testing.T) { - maskingPolicy, maskingPolicyCleanup := testClientHelper().MaskingPolicy.CreateMaskingPolicy(t) - id := maskingPolicy.ID() - t.Cleanup(maskingPolicyCleanup) - - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - tag2, tag2Cleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tag2Cleanup) - - tagAssociations := []sdk.TagAssociation{{Name: tag.ID(), Value: "value1"}, {Name: tag2.ID(), Value: "value2"}} - alterOptions := &sdk.AlterMaskingPolicyOptions{ - SetTag: tagAssociations, - } - err := client.MaskingPolicies.Alter(ctx, id, alterOptions) - require.NoError(t, err) - tagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeMaskingPolicy) - require.NoError(t, err) - assert.Equal(t, tagAssociations[0].Value, tagValue) - tag2Value, err := client.SystemFunctions.GetTag(ctx, tag2.ID(), id, sdk.ObjectTypeMaskingPolicy) - require.NoError(t, err) - assert.Equal(t, tagAssociations[1].Value, tag2Value) - - // unset tag - alterOptions = &sdk.AlterMaskingPolicyOptions{ - UnsetTag: []sdk.ObjectIdentifier{tag.ID()}, - } - err = client.MaskingPolicies.Alter(ctx, id, alterOptions) - require.NoError(t, err) - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeMaskingPolicy) - assert.Error(t, err) - }) - t.Run("set body", func(t *testing.T) { maskingPolicy, maskingPolicyCleanup := testClientHelper().MaskingPolicy.CreateMaskingPolicy(t) id := maskingPolicy.ID() diff --git a/pkg/sdk/testint/materialized_views_gen_integration_test.go b/pkg/sdk/testint/materialized_views_gen_integration_test.go index 08c625ad3a..98ba774f94 100644 --- a/pkg/sdk/testint/materialized_views_gen_integration_test.go +++ b/pkg/sdk/testint/materialized_views_gen_integration_test.go @@ -305,44 +305,6 @@ func TestInt_MaterializedViews(t *testing.T) { assert.Equal(t, false, alteredView.IsSecure) }) - // Based on usage notes, set/unset tags is done through VIEW (https://docs.snowflake.com/en/sql-reference/sql/alter-materialized-view#usage-notes). - // TODO [SNOW-1022645]: discuss how we handle situation like this in the SDK - t.Run("alter materialized view: set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - materializedView := createMaterializedView(t) - id := materializedView.ID() - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterViewRequest(id).WithSetTags(tags) - - err := client.Views.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeMaterializedView) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterViewRequest(id).WithUnsetTags(unsetTags) - - err = client.Views.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeMaterializedView) - require.Error(t, err) - }) - t.Run("show materialized view: default", func(t *testing.T) { view1 := createMaterializedView(t) view2 := createMaterializedView(t) diff --git a/pkg/sdk/testint/notification_integrations_gen_integration_test.go b/pkg/sdk/testint/notification_integrations_gen_integration_test.go index 2a706790a9..e813680226 100644 --- a/pkg/sdk/testint/notification_integrations_gen_integration_test.go +++ b/pkg/sdk/testint/notification_integrations_gen_integration_test.go @@ -358,42 +358,6 @@ func TestInt_NotificationIntegrations(t *testing.T) { assert.Contains(t, details, sdk.NotificationIntegrationProperty{Name: "COMMENT", Type: "String", Value: "", Default: ""}) }) - t.Run("alter notification integration: set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - integration := createNotificationIntegrationEmail(t) - id := integration.ID() - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterNotificationIntegrationRequest(id).WithSetTags(tags) - - err := client.NotificationIntegrations.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterNotificationIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.NotificationIntegrations.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("drop notification integration: existing", func(t *testing.T) { request := createNotificationIntegrationEmailRequest(t) id := request.GetName() diff --git a/pkg/sdk/testint/pipes_integration_test.go b/pkg/sdk/testint/pipes_integration_test.go index 2f8701e802..f352d06b26 100644 --- a/pkg/sdk/testint/pipes_integration_test.go +++ b/pkg/sdk/testint/pipes_integration_test.go @@ -281,44 +281,6 @@ func TestInt_PipeAlter(t *testing.T) { assert.Equal(t, "", alteredPipe.Comment) }) - t.Run("set and unset tag", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - pipe, pipeCleanup := testClientHelper().Pipe.CreatePipe(t, pipeCopyStatement) - t.Cleanup(pipeCleanup) - - tagValue := "abc" - alterOptions := &sdk.AlterPipeOptions{ - SetTag: []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - }, - } - - err := itc.client.Pipes.Alter(itc.ctx, pipe.ID(), alterOptions) - require.NoError(t, err) - - returnedTagValue, err := itc.client.SystemFunctions.GetTag(itc.ctx, tag.ID(), pipe.ID(), sdk.ObjectTypePipe) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - alterOptions = &sdk.AlterPipeOptions{ - UnsetTag: []sdk.ObjectIdentifier{ - tag.ID(), - }, - } - - err = itc.client.Pipes.Alter(itc.ctx, pipe.ID(), alterOptions) - require.NoError(t, err) - - _, err = itc.client.SystemFunctions.GetTag(itc.ctx, tag.ID(), pipe.ID(), sdk.ObjectTypePipe) - assert.Error(t, err) - }) - t.Run("refresh with all", func(t *testing.T) { pipe, pipeCleanup := testClientHelper().Pipe.CreatePipe(t, pipeCopyStatement) t.Cleanup(pipeCleanup) diff --git a/pkg/sdk/testint/procedures_integration_test.go b/pkg/sdk/testint/procedures_integration_test.go index 687d80a2db..309a3db9f9 100644 --- a/pkg/sdk/testint/procedures_integration_test.go +++ b/pkg/sdk/testint/procedures_integration_test.go @@ -342,9 +342,6 @@ func TestInt_OtherProcedureFunctions(t *testing.T) { client := testClient(t) ctx := testContext(t) - tagTest, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - assertProcedure := func(t *testing.T, id sdk.SchemaObjectIdentifierWithArguments, secure bool) { t.Helper() @@ -471,32 +468,6 @@ func TestInt_OtherProcedureFunctions(t *testing.T) { assertProcedure(t, id, true) }) - t.Run("alter procedure: set and unset tags", func(t *testing.T) { - f := createProcedureForSQLHandle(t, true) - - id := f.ID() - setTags := []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: "v1", - }, - } - err := client.Procedures.Alter(ctx, sdk.NewAlterProcedureRequest(id).WithSetTags(setTags)) - require.NoError(t, err) - assertProcedure(t, id, true) - - value, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), id, sdk.ObjectTypeProcedure) - require.NoError(t, err) - assert.Equal(t, "v1", value) - - unsetTags := []sdk.ObjectIdentifier{ - tagTest.ID(), - } - err = client.Procedures.Alter(ctx, sdk.NewAlterProcedureRequest(id).WithUnsetTags(unsetTags)) - require.NoError(t, err) - assertProcedure(t, id, true) - }) - t.Run("show procedure for SQL: without like", func(t *testing.T) { f1 := createProcedureForSQLHandle(t, true) f2 := createProcedureForSQLHandle(t, true) diff --git a/pkg/sdk/testint/roles_integration_test.go b/pkg/sdk/testint/roles_integration_test.go index a27422745f..5c173a1ada 100644 --- a/pkg/sdk/testint/roles_integration_test.go +++ b/pkg/sdk/testint/roles_integration_test.go @@ -100,53 +100,6 @@ func TestInt_Roles(t *testing.T) { assert.Equal(t, newName.Name(), r.Name) }) - t.Run("alter set tags", func(t *testing.T) { - role, cleanup := testClientHelper().Role.CreateRole(t) - t.Cleanup(cleanup) - - _, err := client.SystemFunctions.GetTag(ctx, tag.ID(), role.ID(), "ROLE") - require.Error(t, err) - - tagValue := "new-tag-value" - err = client.Roles.Alter(ctx, sdk.NewAlterRoleRequest(role.ID()).WithSetTags([]sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - })) - require.NoError(t, err) - - addedTag, err := client.SystemFunctions.GetTag(ctx, tag.ID(), role.ID(), sdk.ObjectTypeRole) - require.NoError(t, err) - assert.Equal(t, tagValue, addedTag) - - err = client.Roles.Alter(ctx, sdk.NewAlterRoleRequest(role.ID()).WithUnsetTags([]sdk.ObjectIdentifier{tag.ID()})) - require.NoError(t, err) - }) - - t.Run("alter unset tags", func(t *testing.T) { - tagValue := "tag-value" - id := testClientHelper().Ids.RandomAccountObjectIdentifier() - role, cleanup := testClientHelper().Role.CreateRoleWithRequest(t, sdk.NewCreateRoleRequest(id). - WithTag([]sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - })) - t.Cleanup(cleanup) - - value, err := client.SystemFunctions.GetTag(ctx, tag.ID(), role.ID(), sdk.ObjectTypeRole) - require.NoError(t, err) - assert.Equal(t, tagValue, value) - - err = client.Roles.Alter(ctx, sdk.NewAlterRoleRequest(role.ID()).WithUnsetTags([]sdk.ObjectIdentifier{tag.ID()})) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), role.ID(), sdk.ObjectTypeRole) - require.Error(t, err) - }) - t.Run("alter set comment", func(t *testing.T) { role, cleanupRole := testClientHelper().Role.CreateRole(t) t.Cleanup(cleanupRole) diff --git a/pkg/sdk/testint/row_access_policies_gen_integration_test.go b/pkg/sdk/testint/row_access_policies_gen_integration_test.go index 577bf14ef7..4241a7eab1 100644 --- a/pkg/sdk/testint/row_access_policies_gen_integration_test.go +++ b/pkg/sdk/testint/row_access_policies_gen_integration_test.go @@ -168,43 +168,6 @@ func TestInt_RowAccessPolicies(t *testing.T) { assert.Equal(t, "true", alteredRowAccessPolicyDescription.Body) }) - t.Run("alter row access policy: set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - rowAccessPolicy, cleanup := testClientHelper().RowAccessPolicy.CreateRowAccessPolicy(t) - t.Cleanup(cleanup) - id := rowAccessPolicy.ID() - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterRowAccessPolicyRequest(id).WithSetTags(tags) - - err := client.RowAccessPolicies.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeRowAccessPolicy) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterRowAccessPolicyRequest(id).WithUnsetTags(unsetTags) - - err = client.RowAccessPolicies.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeRowAccessPolicy) - require.Error(t, err) - }) - t.Run("show row access policy: default", func(t *testing.T) { rowAccessPolicy1, cleanup1 := testClientHelper().RowAccessPolicy.CreateRowAccessPolicy(t) t.Cleanup(cleanup1) diff --git a/pkg/sdk/testint/schemas_integration_test.go b/pkg/sdk/testint/schemas_integration_test.go index 3b59001862..a1eaa75c3c 100644 --- a/pkg/sdk/testint/schemas_integration_test.go +++ b/pkg/sdk/testint/schemas_integration_test.go @@ -445,60 +445,6 @@ func TestInt_Schemas(t *testing.T) { }) }) - t.Run("alter: set tags", func(t *testing.T) { - schema, cleanupSchema := testClientHelper().Schema.CreateSchema(t) - t.Cleanup(cleanupSchema) - - tag, cleanupTag := testClientHelper().Tag.CreateTagInSchema(t, schema.ID()) - t.Cleanup(cleanupTag) - - tagValue := "tag-value" - err := client.Schemas.Alter(ctx, schema.ID(), &sdk.AlterSchemaOptions{ - SetTag: []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - }, - }) - require.NoError(t, err) - - tv, err := client.SystemFunctions.GetTag(ctx, tag.ID(), schema.ID(), sdk.ObjectTypeSchema) - require.NoError(t, err) - assert.Equal(t, tagValue, tv) - }) - - t.Run("alter: unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - schemaID := testClientHelper().Ids.RandomDatabaseObjectIdentifier() - tagValue := random.String() - err := client.Schemas.Create(ctx, schemaID, &sdk.CreateSchemaOptions{ - Tag: []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - }, - }) - require.NoError(t, err) - t.Cleanup(func() { - err = client.Schemas.Drop(ctx, schemaID, nil) - require.NoError(t, err) - }) - - err = client.Schemas.Alter(ctx, schemaID, &sdk.AlterSchemaOptions{ - UnsetTag: []sdk.ObjectIdentifier{ - tag.ID(), - }, - }) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), schemaID, sdk.ObjectTypeSchema) - require.Error(t, err) - }) - t.Run("alter: enable managed access", func(t *testing.T) { schema, cleanupSchema := testClientHelper().Schema.CreateSchema(t) t.Cleanup(cleanupSchema) diff --git a/pkg/sdk/testint/security_integrations_gen_integration_test.go b/pkg/sdk/testint/security_integrations_gen_integration_test.go index 69e25666b5..29620dcd0a 100644 --- a/pkg/sdk/testint/security_integrations_gen_integration_test.go +++ b/pkg/sdk/testint/security_integrations_gen_integration_test.go @@ -642,41 +642,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { assert.Contains(t, details, sdk.SecurityIntegrationProperty{Name: "COMMENT", Type: "String", Value: "", Default: ""}) }) - t.Run("AlterApiAuthenticationWithClientCredentialsFlow - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id := createApiAuthClientCred(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterApiAuthenticationWithClientCredentialsFlow(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterApiAuthenticationWithClientCredentialsFlow(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("AlterApiAuthenticationWithAuthorizationCodeGrantFlow", func(t *testing.T) { _, id := createApiAuthCodeGrant(t, nil) setRequest := sdk.NewAlterApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest(id). @@ -728,41 +693,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { assert.Contains(t, details, sdk.SecurityIntegrationProperty{Name: "COMMENT", Type: "String", Value: "", Default: ""}) }) - t.Run("AlterApiAuthenticationWithAuthorizationCodeGrantFlow - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id := createApiAuthCodeGrant(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterApiAuthenticationWithAuthorizationCodeGrantFlow(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterApiAuthenticationWithAuthorizationCodeGrantFlow(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("AlterApiAuthenticationWithJwtBearerFlow", func(t *testing.T) { // TODO [SNOW-1452191]: unskip t.Skip("Skip because of the error: Invalid value specified for property 'OAUTH_CLIENT_SECRET'") @@ -817,44 +747,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { assert.Contains(t, details, sdk.SecurityIntegrationProperty{Name: "COMMENT", Type: "String", Value: "", Default: ""}) }) - t.Run("AlterApiAuthenticationWithJwtBearerFlow - set and unset tags", func(t *testing.T) { - // TODO [SNOW-1452191]: unskip - t.Skip("Skip because of the error: Invalid value specified for property 'OAUTH_CLIENT_SECRET'") - - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id := createApiAuthJwtBearer(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterApiAuthenticationWithJwtBearerFlowSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterApiAuthenticationWithJwtBearerFlow(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterApiAuthenticationWithJwtBearerFlowSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterApiAuthenticationWithJwtBearerFlow(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("AlterExternalOauth with other options", func(t *testing.T) { _, id, _ := createExternalOauth(t, func(r *sdk.CreateExternalOauthSecurityIntegrationRequest) { r.WithExternalOauthRsaPublicKey(rsaKey). @@ -915,43 +807,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { assert.Contains(t, details, sdk.SecurityIntegrationProperty{Name: "EXTERNAL_OAUTH_AUDIENCE_LIST", Type: "List", Value: "", Default: "[]"}) }) - t.Run("AlterExternalOauth - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id, _ := createExternalOauth(t, func(r *sdk.CreateExternalOauthSecurityIntegrationRequest) { - r.WithExternalOauthJwsKeysUrl([]sdk.JwsKeysUrl{{JwsKeyUrl: "http://example.com"}}) - }) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterExternalOauthSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterExternalOauth(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterExternalOauthSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterExternalOauth(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("AlterOauthPartner", func(t *testing.T) { _, id := createOauthPartner(t, func(r *sdk.CreateOauthForPartnerApplicationsSecurityIntegrationRequest) { r.WithOauthRedirectUri("http://example.com") @@ -1003,41 +858,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { assert.Contains(t, details, sdk.SecurityIntegrationProperty{Name: "OAUTH_USE_SECONDARY_ROLES", Type: "String", Value: "NONE", Default: "NONE"}) }) - t.Run("AlterOauthPartner - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id := createOauthPartner(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterOauthForPartnerApplicationsSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterOauthForPartnerApplications(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterOauthForPartnerApplicationsSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterOauthForPartnerApplications(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("AlterOauthCustom", func(t *testing.T) { _, id := createOauthCustom(t, nil) @@ -1104,41 +924,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { assert.Contains(t, details, sdk.SecurityIntegrationProperty{Name: "OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP", Type: "String", Value: "", Default: ""}) }) - t.Run("AlterOauthCustom - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id := createOauthCustom(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterOauthForCustomClientsSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterOauthForCustomClients(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterOauthForCustomClientsSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterOauthForCustomClients(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("AlterSAML2Integration", func(t *testing.T) { _, id, issuer := createSAML2Integration(t, nil) @@ -1214,124 +999,6 @@ func TestInt_SecurityIntegrations(t *testing.T) { require.NoError(t, err) }) - t.Run("AlterSAML2Integration - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id, _ := createSAML2Integration(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterSaml2SecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterSaml2(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterSaml2SecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterSaml2(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - - t.Run("AlterSCIMIntegration", func(t *testing.T) { - _, id := createSCIMIntegration(t, nil) - - networkPolicy, networkPolicyCleanup := testClientHelper().NetworkPolicy.CreateNetworkPolicy(t) - t.Cleanup(networkPolicyCleanup) - - setRequest := sdk.NewAlterScimSecurityIntegrationRequest(id). - WithSet( - *sdk.NewScimIntegrationSetRequest(). - WithNetworkPolicy(networkPolicy.ID()). - WithEnabled(false). - WithSyncPassword(false). - WithComment(sdk.StringAllowEmpty{Value: "altered"}), - ) - err := client.SecurityIntegrations.AlterScim(ctx, setRequest) - require.NoError(t, err) - - details, err := client.SecurityIntegrations.Describe(ctx, id) - require.NoError(t, err) - - assertSCIMDescribe(details, "false", networkPolicy.Name, "GENERIC_SCIM_PROVISIONER", "false", "altered") - - unsetRequest := sdk.NewAlterScimSecurityIntegrationRequest(id). - WithUnset( - *sdk.NewScimIntegrationUnsetRequest(). - WithEnabled(true). - WithNetworkPolicy(true). - WithSyncPassword(true), - ) - err = client.SecurityIntegrations.AlterScim(ctx, unsetRequest) - require.NoError(t, err) - - // check setting empty comment because of lacking UNSET COMMENT - // TODO(SNOW-1461780): change this to UNSET - setRequest = sdk.NewAlterScimSecurityIntegrationRequest(id). - WithSet( - *sdk.NewScimIntegrationSetRequest(). - WithComment(sdk.StringAllowEmpty{Value: ""}), - ) - err = client.SecurityIntegrations.AlterScim(ctx, setRequest) - require.NoError(t, err) - - details, err = client.SecurityIntegrations.Describe(ctx, id) - require.NoError(t, err) - - assertSCIMDescribe(details, "false", "", "GENERIC_SCIM_PROVISIONER", "true", "") - }) - - t.Run("AlterSCIMIntegration - set and unset tags", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - _, id := createSCIMIntegration(t, nil) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterScimSecurityIntegrationRequest(id).WithSetTags(tags) - - err := client.SecurityIntegrations.AlterScim(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterScimSecurityIntegrationRequest(id).WithUnsetTags(unsetTags) - - err = client.SecurityIntegrations.AlterScim(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err) - }) - t.Run("Drop", func(t *testing.T) { _, id := createSCIMIntegration(t, nil) diff --git a/pkg/sdk/testint/session_policies_gen_integration_test.go b/pkg/sdk/testint/session_policies_gen_integration_test.go index 6f936e33ff..2c1aaf7678 100644 --- a/pkg/sdk/testint/session_policies_gen_integration_test.go +++ b/pkg/sdk/testint/session_policies_gen_integration_test.go @@ -140,45 +140,6 @@ func TestInt_SessionPolicies(t *testing.T) { assert.Equal(t, "", alteredSessionPolicy.Comment) }) - t.Run("set and unset tag", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - id := testClientHelper().Ids.RandomSchemaObjectIdentifier() - - err := client.SessionPolicies.Create(ctx, sdk.NewCreateSessionPolicyRequest(id)) - require.NoError(t, err) - t.Cleanup(cleanupSessionPolicyProvider(id)) - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterSessionPolicyRequest(id).WithSetTags(tags) - - err = client.SessionPolicies.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeSessionPolicy) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterSessionPolicyRequest(id).WithUnsetTags(unsetTags) - - err = client.SessionPolicies.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeSessionPolicy) - require.Error(t, err) - }) - t.Run("alter session_policy: rename", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() diff --git a/pkg/sdk/testint/shares_integration_test.go b/pkg/sdk/testint/shares_integration_test.go index ad54a6102a..91d6ddd455 100644 --- a/pkg/sdk/testint/shares_integration_test.go +++ b/pkg/sdk/testint/shares_integration_test.go @@ -276,61 +276,6 @@ func TestInt_SharesAlter(t *testing.T) { share = shares[0] assert.Equal(t, "", share.Comment) }) - - t.Run("set and unset tags", func(t *testing.T) { - shareTest, shareCleanup := testClientHelper().Share.CreateShare(t) - t.Cleanup(shareCleanup) - err := client.Grants.GrantPrivilegeToShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ - Database: testClientHelper().Ids.DatabaseId(), - }, shareTest.ID()) - require.NoError(t, err) - t.Cleanup(func() { - err = client.Grants.RevokePrivilegeFromShare(ctx, []sdk.ObjectPrivilege{sdk.ObjectPrivilegeUsage}, &sdk.ShareGrantOn{ - Database: testClientHelper().Ids.DatabaseId(), - }, shareTest.ID()) - require.NoError(t, err) - }) - - tagTest, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - tagTest2, tagCleanup2 := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup2) - tagAssociations := []sdk.TagAssociation{ - { - Name: tagTest.ID(), - Value: random.String(), - }, - { - Name: tagTest2.ID(), - Value: random.String(), - }, - } - err = client.Shares.Alter(ctx, shareTest.ID(), &sdk.AlterShareOptions{ - IfExists: sdk.Bool(true), - SetTag: tagAssociations, - }) - require.NoError(t, err) - tagValue, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), shareTest.ID(), sdk.ObjectTypeShare) - require.NoError(t, err) - assert.Equal(t, tagAssociations[0].Value, tagValue) - tagValue, err = client.SystemFunctions.GetTag(ctx, tagTest2.ID(), shareTest.ID(), sdk.ObjectTypeShare) - require.NoError(t, err) - assert.Equal(t, tagAssociations[1].Value, tagValue) - - // unset tags - err = client.Shares.Alter(ctx, shareTest.ID(), &sdk.AlterShareOptions{ - IfExists: sdk.Bool(true), - UnsetTag: []sdk.ObjectIdentifier{ - tagTest.ID(), - }, - }) - require.NoError(t, err) - _, err = client.SystemFunctions.GetTag(ctx, tagTest.ID(), shareTest.ID(), sdk.ObjectTypeShare) - require.Error(t, err) - tagValue, err = client.SystemFunctions.GetTag(ctx, tagTest2.ID(), shareTest.ID(), sdk.ObjectTypeShare) - require.NoError(t, err) - assert.Equal(t, tagAssociations[1].Value, tagValue) - }) } func TestInt_ShareDescribeProvider(t *testing.T) { diff --git a/pkg/sdk/testint/stages_gen_integration_test.go b/pkg/sdk/testint/stages_gen_integration_test.go index dd70aa4429..5bb3a94198 100644 --- a/pkg/sdk/testint/stages_gen_integration_test.go +++ b/pkg/sdk/testint/stages_gen_integration_test.go @@ -235,42 +235,6 @@ func TestInt_Stages(t *testing.T) { require.NoError(t, err) }) - t.Run("Alter - set unset tags", func(t *testing.T) { - id := testClientHelper().Ids.RandomSchemaObjectIdentifier() - tag, cleanupTag := testClientHelper().Tag.CreateTag(t) - t.Cleanup(cleanupTag) - - err := client.Stages.CreateInternal(ctx, sdk.NewCreateInternalStageRequest(id)) - require.NoError(t, err) - t.Cleanup(func() { - err := client.Stages.Drop(ctx, sdk.NewDropStageRequest(id)) - require.NoError(t, err) - }) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeStage) - require.Error(t, err) - - err = client.Stages.Alter(ctx, sdk.NewAlterStageRequest(id).WithSetTags([]sdk.TagAssociation{ - { - Name: tag.ID(), - Value: "tag value", - }, - })) - require.NoError(t, err) - - value, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeStage) - require.NoError(t, err) - assert.Equal(t, "tag value", value) - - err = client.Stages.Alter(ctx, sdk.NewAlterStageRequest(id).WithUnsetTags([]sdk.ObjectIdentifier{ - tag.ID(), - })) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeStage) - require.Error(t, err) - }) - t.Run("AlterInternalStage", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() diff --git a/pkg/sdk/testint/storage_integration_gen_integration_test.go b/pkg/sdk/testint/storage_integration_gen_integration_test.go index cc3edad74d..5fb1839705 100644 --- a/pkg/sdk/testint/storage_integration_gen_integration_test.go +++ b/pkg/sdk/testint/storage_integration_gen_integration_test.go @@ -307,36 +307,6 @@ func TestInt_StorageIntegrations(t *testing.T) { assertS3StorageIntegrationDescResult(t, props, false, s3AllowedLocations, []sdk.StorageLocation{}, "") }) - t.Run("Alter - set and unset tags", func(t *testing.T) { - id := createS3StorageIntegration(t) - - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - err := client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id). - WithSetTags([]sdk.TagAssociation{ - { - Name: tag.ID(), - Value: "tag-value", - }, - })) - require.NoError(t, err) - - tagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.NoError(t, err) - - assert.Equal(t, "tag-value", tagValue) - - err = client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id). - WithUnsetTags([]sdk.ObjectIdentifier{ - tag.ID(), - })) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeIntegration) - require.Error(t, err, sdk.ErrObjectNotExistOrAuthorized) - }) - t.Run("Describe - S3", func(t *testing.T) { id := createS3StorageIntegration(t) diff --git a/pkg/sdk/testint/streams_gen_integration_test.go b/pkg/sdk/testint/streams_gen_integration_test.go index 2e99ca4f05..f5cd1b4581 100644 --- a/pkg/sdk/testint/streams_gen_integration_test.go +++ b/pkg/sdk/testint/streams_gen_integration_test.go @@ -211,44 +211,6 @@ func TestInt_Streams(t *testing.T) { ) }) - t.Run("Alter tags", func(t *testing.T) { - table, cleanupTable := testClientHelper().Table.CreateInSchema(t, schemaId) - t.Cleanup(cleanupTable) - - id := testClientHelper().Ids.RandomSchemaObjectIdentifier() - req := sdk.NewCreateOnTableStreamRequest(id, table.ID()) - err := client.Streams.CreateOnTable(ctx, req) - require.NoError(t, err) - t.Cleanup(testClientHelper().Stream.DropFunc(t, id)) - - tag, cleanupTag := testClientHelper().Tag.CreateTag(t) - t.Cleanup(cleanupTag) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeStream) - require.Error(t, err) - - err = client.Streams.Alter(ctx, sdk.NewAlterStreamRequest(id).WithSetTags([]sdk.TagAssociation{ - { - Name: tag.ID(), - Value: "tag_value", - }, - })) - require.NoError(t, err) - - tagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeStream) - require.NoError(t, err) - assert.Equal(t, "tag_value", tagValue) - - err = client.Streams.Alter(ctx, sdk.NewAlterStreamRequest(id).WithUnsetTags([]sdk.ObjectIdentifier{tag.ID()})) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeStream) - require.Error(t, err) - - _, err = client.Streams.ShowByID(ctx, id) - require.NoError(t, err) - }) - t.Run("Alter comment", func(t *testing.T) { table, cleanupTable := testClientHelper().Table.CreateInSchema(t, schemaId) t.Cleanup(cleanupTable) diff --git a/pkg/sdk/testint/system_functions_integration_test.go b/pkg/sdk/testint/system_functions_integration_test.go index 4b60bc016b..02208e84c2 100644 --- a/pkg/sdk/testint/system_functions_integration_test.go +++ b/pkg/sdk/testint/system_functions_integration_test.go @@ -45,6 +45,10 @@ func TestInt_GetTag(t *testing.T) { require.Error(t, err) assert.Equal(t, "", s) }) + t.Run("unsupported object type", func(t *testing.T) { + _, err := client.SystemFunctions.GetTag(ctx, tagTest.ID(), testClientHelper().Ids.RandomAccountObjectIdentifier(), sdk.ObjectTypeSequence) + require.ErrorContains(t, err, "tagging for object type SEQUENCE is not supported") + }) } func TestInt_PipeStatus(t *testing.T) { diff --git a/pkg/sdk/testint/tables_integration_test.go b/pkg/sdk/testint/tables_integration_test.go index 7ea659be23..19d7e8732f 100644 --- a/pkg/sdk/testint/tables_integration_test.go +++ b/pkg/sdk/testint/tables_integration_test.go @@ -540,114 +540,6 @@ func TestInt_Table(t *testing.T) { assert.Empty(t, tableDetails[0].PolicyName) }) - t.Run("alter table: set and unset tags", func(t *testing.T) { - id := testClientHelper().Ids.RandomSchemaObjectIdentifier() - columns := []sdk.TableColumnRequest{ - *sdk.NewTableColumnRequest("COLUMN_1", sdk.DataTypeVARCHAR), - *sdk.NewTableColumnRequest("COLUMN_2", sdk.DataTypeVARCHAR), - } - - err := client.Tables.Create(ctx, sdk.NewCreateTableRequest(id, columns)) - require.NoError(t, err) - t.Cleanup(cleanupTableProvider(id)) - - columnTags := []sdk.TagAssociationRequest{ - { - Name: tag1.ID(), - Value: "v1", - }, - { - Name: tag2.ID(), - Value: "v2", - }, - } - - alterRequest := sdk.NewAlterTableRequest(id).WithSetTags(columnTags) - err = client.Tables.Alter(ctx, alterRequest) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag1.ID(), id, sdk.ObjectTypeTable) - require.NoError(t, err) - - assert.Equal(t, "v1", returnedTagValue) - - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag2.ID(), id, sdk.ObjectTypeTable) - require.NoError(t, err) - - assert.Equal(t, "v2", returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag1.ID(), - tag2.ID(), - } - alterRequestUnsetTags := sdk.NewAlterTableRequest(id).WithUnsetTags(unsetTags) - - err = client.Tables.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag1.ID(), id, sdk.ObjectTypeTable) - require.Error(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag2.ID(), id, sdk.ObjectTypeTable) - require.Error(t, err) - }) - - t.Run("alter table: set and unset tags on columns", func(t *testing.T) { - id := testClientHelper().Ids.RandomSchemaObjectIdentifier() - columns := []sdk.TableColumnRequest{ - *sdk.NewTableColumnRequest("COLUMN_1", sdk.DataTypeVARCHAR), - *sdk.NewTableColumnRequest("COLUMN_2", sdk.DataTypeVARCHAR), - } - - err := client.Tables.Create(ctx, sdk.NewCreateTableRequest(id, columns)) - require.NoError(t, err) - t.Cleanup(cleanupTableProvider(id)) - - columnTags := []sdk.TagAssociation{ - { - Name: tag1.ID(), - Value: "v1", - }, - { - Name: tag2.ID(), - Value: "v2", - }, - } - - alterRequestSetTags := sdk.NewAlterTableRequest(id).WithColumnAction(sdk.NewTableColumnActionRequest(). - WithSetTags(sdk.NewTableColumnAlterSetTagsActionRequest("COLUMN_1", columnTags))) - err = client.Tables.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - columnId := sdk.NewTableColumnIdentifier(id.DatabaseName(), id.SchemaName(), id.Name(), "COLUMN_1") - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag1.ID(), columnId, sdk.ObjectTypeColumn) - require.NoError(t, err) - - assert.Equal(t, "v1", returnedTagValue) - - returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag2.ID(), columnId, sdk.ObjectTypeColumn) - require.NoError(t, err) - - assert.Equal(t, "v2", returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag1.ID(), - tag2.ID(), - } - alterRequestUnsetTags := sdk.NewAlterTableRequest(id).WithColumnAction(sdk.NewTableColumnActionRequest(). - WithUnsetTags(sdk.NewTableColumnAlterUnsetTagsActionRequest("COLUMN_1", unsetTags))) - - err = client.Tables.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag1.ID(), id, sdk.ObjectTypeColumn) - require.Error(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag2.ID(), id, sdk.ObjectTypeColumn) - require.Error(t, err) - }) - t.Run("alter table: drop columns", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() columns := []sdk.TableColumnRequest{ diff --git a/pkg/sdk/testint/tags_integration_test.go b/pkg/sdk/testint/tags_integration_test.go index d1fc3ba772..d16d74d661 100644 --- a/pkg/sdk/testint/tags_integration_test.go +++ b/pkg/sdk/testint/tags_integration_test.go @@ -2,11 +2,13 @@ package testint import ( "context" + "fmt" "testing" assertions "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/objectassert" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/collections" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/snowflakeroles" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -281,3 +283,790 @@ func TestInt_TagsShowByID(t *testing.T) { require.Equal(t, id2, e2.ID()) }) } + +type IDProvider[T sdk.AccountObjectIdentifier | sdk.DatabaseObjectIdentifier | sdk.SchemaObjectIdentifier | sdk.TableColumnIdentifier] interface { + ID() T +} + +func TestInt_TagsAssociations(t *testing.T) { + client := testClient(t) + ctx := testContext(t) + + awsBucketUrl := testenvs.GetOrSkipTest(t, testenvs.AwsExternalBucketUrl) + awsRoleARN := testenvs.GetOrSkipTest(t, testenvs.AwsExternalRoleArn) + + tag, tagCleanup := testClientHelper().Tag.CreateTag(t) + t.Cleanup(tagCleanup) + + tagValue := "abc" + tags := []sdk.TagAssociation{ + { + Name: tag.ID(), + Value: tagValue, + }, + } + unsetTags := []sdk.ObjectIdentifier{ + tag.ID(), + } + + testTagSet := func(id sdk.ObjectIdentifier, objectType sdk.ObjectType) { + err := client.Tags.Set(ctx, sdk.NewSetTagRequest(objectType, id).WithSetTags(tags)) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, objectType) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = client.Tags.Unset(ctx, sdk.NewUnsetTagRequest(objectType, id).WithUnsetTags(unsetTags)) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, objectType) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + } + + t.Run("TestInt_TagAssociationForAccount", func(t *testing.T) { + id := testClientHelper().Ids.AccountIdentifierWithLocator() + err := client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{ + SetTag: tags, + }) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{ + UnsetTag: unsetTags, + }) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + + // test tag sdk method + err = client.Tags.SetOnCurrentAccount(ctx, sdk.NewSetTagOnCurrentAccountRequest().WithSetTags(tags)) + require.NoError(t, err) + + returnedTagValue, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = client.Tags.UnsetOnCurrentAccount(ctx, sdk.NewUnsetTagOnCurrentAccountRequest().WithUnsetTags(unsetTags)) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeAccount) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + }) + + accountObjectTestCases := []struct { + name string + objectType sdk.ObjectType + setupObject func() (IDProvider[sdk.AccountObjectIdentifier], func()) + setTags func(sdk.AccountObjectIdentifier, []sdk.TagAssociation) error + unsetTags func(sdk.AccountObjectIdentifier, []sdk.ObjectIdentifier) error + }{ + { + name: "ApplicationPackage", + objectType: sdk.ObjectTypeApplicationPackage, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().ApplicationPackage.CreateApplicationPackage(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "NormalDatabase", + objectType: sdk.ObjectTypeDatabase, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().Database.CreateDatabase(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Databases.Alter(ctx, id, &sdk.AlterDatabaseOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Databases.Alter(ctx, id, &sdk.AlterDatabaseOptions{ + UnsetTag: tags, + }) + }, + }, + { + name: "DatabaseFromShare", + objectType: sdk.ObjectTypeDatabase, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return createDatabaseFromShare(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Databases.Alter(ctx, id, &sdk.AlterDatabaseOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Databases.Alter(ctx, id, &sdk.AlterDatabaseOptions{ + UnsetTag: tags, + }) + }, + }, + // TODO [SNOW-1002023]: Add a test for failover groups; Business Critical Snowflake Edition needed + { + name: "ApiIntegration", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().ApiIntegration.CreateApiIntegration(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.ApiIntegrations.Alter(ctx, sdk.NewAlterApiIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.ApiIntegrations.Alter(ctx, sdk.NewAlterApiIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "NotificationIntegration", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().NotificationIntegration.Create(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.NotificationIntegrations.Alter(ctx, sdk.NewAlterNotificationIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.NotificationIntegrations.Alter(ctx, sdk.NewAlterNotificationIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "StorageIntegration", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().StorageIntegration.CreateS3(t, awsBucketUrl, awsRoleARN) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.StorageIntegrations.Alter(ctx, sdk.NewAlterStorageIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "ApiAuthenticationWithClientCredentialsFlow", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateApiAuthenticationWithClientCredentialsFlow(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterApiAuthenticationWithClientCredentialsFlow(ctx, sdk.NewAlterApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterApiAuthenticationWithClientCredentialsFlow(ctx, sdk.NewAlterApiAuthenticationWithClientCredentialsFlowSecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "ApiAuthenticationWithAuthorizationCodeGrantFlow", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateApiAuthenticationWithAuthorizationCodeGrantFlow(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterApiAuthenticationWithAuthorizationCodeGrantFlow(ctx, sdk.NewAlterApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterApiAuthenticationWithAuthorizationCodeGrantFlow(ctx, sdk.NewAlterApiAuthenticationWithAuthorizationCodeGrantFlowSecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + // TODO [SNOW-1452191]: add a test for jwt bearer integration + { + name: "ExternalOauth", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateExternalOauth(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterExternalOauth(ctx, sdk.NewAlterExternalOauthSecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterExternalOauth(ctx, sdk.NewAlterExternalOauthSecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "OauthForPartnerApplications", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateOauthForPartnerApplications(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterOauthForPartnerApplications(ctx, sdk.NewAlterOauthForPartnerApplicationsSecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterOauthForPartnerApplications(ctx, sdk.NewAlterOauthForPartnerApplicationsSecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "OauthForCustomClients", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateOauthForCustomClients(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterOauthForCustomClients(ctx, sdk.NewAlterOauthForCustomClientsSecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterOauthForCustomClients(ctx, sdk.NewAlterOauthForCustomClientsSecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Saml2", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateSaml2(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterSaml2(ctx, sdk.NewAlterSaml2SecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterSaml2(ctx, sdk.NewAlterSaml2SecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Scim", + objectType: sdk.ObjectTypeIntegration, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().SecurityIntegration.CreateScim(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SecurityIntegrations.AlterScim(ctx, sdk.NewAlterScimSecurityIntegrationRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SecurityIntegrations.AlterScim(ctx, sdk.NewAlterScimSecurityIntegrationRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Role", + objectType: sdk.ObjectTypeRole, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().Role.CreateRole(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Roles.Alter(ctx, sdk.NewAlterRoleRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Roles.Alter(ctx, sdk.NewAlterRoleRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Share", + objectType: sdk.ObjectTypeShare, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return createShare(t, ctx, client) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Shares.Alter(ctx, id, &sdk.AlterShareOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Shares.Alter(ctx, id, &sdk.AlterShareOptions{ + UnsetTag: tags, + }) + }, + }, + { + name: "User", + objectType: sdk.ObjectTypeUser, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().User.CreateUser(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Users.Alter(ctx, id, &sdk.AlterUserOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Users.Alter(ctx, id, &sdk.AlterUserOptions{ + UnsetTag: tags, + }) + }, + }, + { + name: "Warehouse", + objectType: sdk.ObjectTypeWarehouse, + setupObject: func() (IDProvider[sdk.AccountObjectIdentifier], func()) { + return testClientHelper().Warehouse.CreateWarehouse(t) + }, + setTags: func(id sdk.AccountObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Warehouses.Alter(ctx, id, &sdk.AlterWarehouseOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.AccountObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Warehouses.Alter(ctx, id, &sdk.AlterWarehouseOptions{ + UnsetTag: tags, + }) + }, + }, + } + + for _, tc := range accountObjectTestCases { + t.Run(fmt.Sprintf("account object %s", tc.name), func(t *testing.T) { + idProvider, cleanup := tc.setupObject() + t.Cleanup(cleanup) + id := idProvider.ID() + err := tc.setTags(id, tags) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = tc.unsetTags(id, unsetTags) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + + // test object methods + testTagSet(id, tc.objectType) + }) + } + + t.Run("account object Application: invalid operation", func(t *testing.T) { + applicationPackage, applicationPackageCleanup := createApplicationPackage(t) + t.Cleanup(applicationPackageCleanup) + db, dbCleanup := testClientHelper().Application.CreateApplication(t, applicationPackage.ID(), "V01") + t.Cleanup(dbCleanup) + id := db.ID() + + err := client.Applications.Alter(ctx, sdk.NewAlterApplicationRequest(id).WithSetTags(tags)) + require.NoError(t, err) + + // TODO(SNOW-1746420): adjust after this is fixed on Snowflake side + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeApplication) + require.ErrorContains(t, err, "391801 (0A000): SQL compilation error: Object tagging not supported for object type APPLICATION") + + err = client.Applications.Alter(ctx, sdk.NewAlterApplicationRequest(id).WithUnsetTags(unsetTags)) + require.NoError(t, err) + }) + + t.Run("account object database replica: invalid operation", func(t *testing.T) { + db, dbCleanup := createDatabaseReplica(t) + t.Cleanup(dbCleanup) + id := db.ID() + + err := client.Databases.Alter(ctx, id, &sdk.AlterDatabaseOptions{ + SetTag: tags, + }) + require.ErrorContains(t, err, "is a read-only secondary database and cannot be modified.") + }) + + databaseObjectTestCases := []struct { + name string + objectType sdk.ObjectType + setupObject func() (IDProvider[sdk.DatabaseObjectIdentifier], func()) + setTags func(sdk.DatabaseObjectIdentifier, []sdk.TagAssociation) error + unsetTags func(sdk.DatabaseObjectIdentifier, []sdk.ObjectIdentifier) error + }{ + { + name: "DatabaseRole", + objectType: sdk.ObjectTypeDatabaseRole, + setupObject: func() (IDProvider[sdk.DatabaseObjectIdentifier], func()) { + return testClientHelper().DatabaseRole.CreateDatabaseRole(t) + }, + setTags: func(id sdk.DatabaseObjectIdentifier, tags []sdk.TagAssociation) error { + return client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.DatabaseObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.DatabaseRoles.Alter(ctx, sdk.NewAlterDatabaseRoleRequest(id).WithUnsetTags(unsetTags)) + }, + }, + { + name: "Schema", + objectType: sdk.ObjectTypeSchema, + setupObject: func() (IDProvider[sdk.DatabaseObjectIdentifier], func()) { + return testClientHelper().Schema.CreateSchema(t) + }, + setTags: func(id sdk.DatabaseObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Schemas.Alter(ctx, id, &sdk.AlterSchemaOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.DatabaseObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Schemas.Alter(ctx, id, &sdk.AlterSchemaOptions{ + UnsetTag: tags, + }) + }, + }, + } + + for _, tc := range databaseObjectTestCases { + t.Run(fmt.Sprintf("database object %s", tc.name), func(t *testing.T) { + idProvider, cleanup := tc.setupObject() + t.Cleanup(cleanup) + id := idProvider.ID() + err := tc.setTags(id, tags) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = tc.unsetTags(id, unsetTags) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + + // test object methods + testTagSet(id, tc.objectType) + }) + } + + schemaObjectTestCases := []struct { + name string + objectType sdk.ObjectType + setupObject func() (IDProvider[sdk.SchemaObjectIdentifier], func()) + setTags func(sdk.SchemaObjectIdentifier, []sdk.TagAssociation) error + unsetTags func(sdk.SchemaObjectIdentifier, []sdk.ObjectIdentifier) error + }{ + { + name: "ExternalTable", + objectType: sdk.ObjectTypeExternalTable, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return createExternalTable(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + setTags := make([]sdk.TagAssociationRequest, len(tags)) + for i, tag := range tags { + setTags[i] = *sdk.NewTagAssociationRequest(tag.Name, tag.Value) + } + return client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id).WithSetTags(setTags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "MaterializedView", + objectType: sdk.ObjectTypeMaterializedView, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return createMaterializedView(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Views.Alter(ctx, sdk.NewAlterViewRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Views.Alter(ctx, sdk.NewAlterViewRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Pipe", + objectType: sdk.ObjectTypePipe, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return createPipe(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Pipes.Alter(ctx, id, &sdk.AlterPipeOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Pipes.Alter(ctx, id, &sdk.AlterPipeOptions{ + UnsetTag: tags, + }) + }, + }, + { + name: "MaskingPolicy", + objectType: sdk.ObjectTypeMaskingPolicy, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().MaskingPolicy.CreateMaskingPolicy(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.MaskingPolicies.Alter(ctx, id, &sdk.AlterMaskingPolicyOptions{ + SetTag: tags, + }) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.MaskingPolicies.Alter(ctx, id, &sdk.AlterMaskingPolicyOptions{ + UnsetTag: tags, + }) + }, + }, + { + name: "RowAccessPolicy", + objectType: sdk.ObjectTypeRowAccessPolicy, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().RowAccessPolicy.CreateRowAccessPolicy(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.RowAccessPolicies.Alter(ctx, sdk.NewAlterRowAccessPolicyRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.RowAccessPolicies.Alter(ctx, sdk.NewAlterRowAccessPolicyRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "SessionPolicy", + objectType: sdk.ObjectTypeSessionPolicy, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().SessionPolicy.CreateSessionPolicy(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.SessionPolicies.Alter(ctx, sdk.NewAlterSessionPolicyRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.SessionPolicies.Alter(ctx, sdk.NewAlterSessionPolicyRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Stage", + objectType: sdk.ObjectTypeStage, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().Stage.CreateStage(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Stages.Alter(ctx, sdk.NewAlterStageRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Stages.Alter(ctx, sdk.NewAlterStageRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Stream", + objectType: sdk.ObjectTypeStream, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return createStream(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Streams.Alter(ctx, sdk.NewAlterStreamRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Streams.Alter(ctx, sdk.NewAlterStreamRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "EventTable", + objectType: sdk.ObjectTypeEventTable, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().EventTable.Create(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.EventTables.Alter(ctx, sdk.NewAlterEventTableRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.EventTables.Alter(ctx, sdk.NewAlterEventTableRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Table", + objectType: sdk.ObjectTypeTable, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().Table.Create(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + setTags := make([]sdk.TagAssociationRequest, len(tags)) + for i, tag := range tags { + setTags[i] = *sdk.NewTagAssociationRequest(tag.Name, tag.Value) + } + return client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id).WithSetTags(setTags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Task", + objectType: sdk.ObjectTypeTask, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().Task.Create(t) + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Tasks.Alter(ctx, sdk.NewAlterTaskRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Tasks.Alter(ctx, sdk.NewAlterTaskRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "View", + objectType: sdk.ObjectTypeView, + setupObject: func() (IDProvider[sdk.SchemaObjectIdentifier], func()) { + return testClientHelper().View.CreateView(t, "SELECT ROLE_NAME, ROLE_OWNER FROM INFORMATION_SCHEMA.APPLICABLE_ROLES") + }, + setTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.TagAssociation) error { + return client.Views.Alter(ctx, sdk.NewAlterViewRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Views.Alter(ctx, sdk.NewAlterViewRequest(id).WithUnsetTags(tags)) + }, + }, + } + + for _, tc := range schemaObjectTestCases { + t.Run(fmt.Sprintf("schema object %s", tc.name), func(t *testing.T) { + idProvider, cleanup := tc.setupObject() + t.Cleanup(cleanup) + id := idProvider.ID() + err := tc.setTags(id, tags) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = tc.unsetTags(id, unsetTags) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + + // test object methods + testTagSet(id, tc.objectType) + }) + } + + columnTestCases := []struct { + name string + setupObject func() (sdk.TableColumnIdentifier, func()) + setTags func(sdk.TableColumnIdentifier, []sdk.TagAssociation) error + unsetTags func(sdk.TableColumnIdentifier, []sdk.ObjectIdentifier) error + }{ + { + name: "Table", + setupObject: func() (sdk.TableColumnIdentifier, func()) { + object, objectCleanup := testClientHelper().Table.Create(t) + columnId := sdk.NewTableColumnIdentifier(object.ID().DatabaseName(), object.ID().SchemaName(), object.ID().Name(), "ID") + return columnId, objectCleanup + }, + setTags: func(id sdk.TableColumnIdentifier, tags []sdk.TagAssociation) error { + return client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id.SchemaObjectId()).WithColumnAction(sdk.NewTableColumnActionRequest(). + WithSetTags(sdk.NewTableColumnAlterSetTagsActionRequest(id.Name(), tags)))) + }, + unsetTags: func(id sdk.TableColumnIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Tables.Alter(ctx, sdk.NewAlterTableRequest(id.SchemaObjectId()).WithColumnAction(sdk.NewTableColumnActionRequest(). + WithUnsetTags(sdk.NewTableColumnAlterUnsetTagsActionRequest(id.Name(), tags)))) + }, + }, + { + name: "View", + setupObject: func() (sdk.TableColumnIdentifier, func()) { + object, objectCleanup := testClientHelper().View.CreateView(t, "SELECT ROLE_NAME, ROLE_OWNER FROM INFORMATION_SCHEMA.APPLICABLE_ROLES") + t.Cleanup(objectCleanup) + columnId := sdk.NewTableColumnIdentifier(object.ID().DatabaseName(), object.ID().SchemaName(), object.ID().Name(), "ROLE_NAME") + return columnId, objectCleanup + }, + setTags: func(id sdk.TableColumnIdentifier, tags []sdk.TagAssociation) error { + return client.Views.Alter(ctx, sdk.NewAlterViewRequest(id.SchemaObjectId()).WithSetTagsOnColumn( + *sdk.NewViewSetColumnTagsRequest("ROLE_NAME", tags), + )) + }, + unsetTags: func(id sdk.TableColumnIdentifier, tags []sdk.ObjectIdentifier) error { + return client.Views.Alter(ctx, sdk.NewAlterViewRequest(id.SchemaObjectId()).WithUnsetTagsOnColumn( + *sdk.NewViewUnsetColumnTagsRequest("ROLE_NAME", tags), + )) + }, + }, + } + + for _, tc := range columnTestCases { + t.Run(fmt.Sprintf("column in %s", tc.name), func(t *testing.T) { + id, cleanup := tc.setupObject() + t.Cleanup(cleanup) + err := tc.setTags(id, tags) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeColumn) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = tc.unsetTags(id, unsetTags) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeColumn) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + + // test object methods + testTagSet(id, sdk.ObjectTypeColumn) + }) + } + + schemaObjectWithArgumentsTestCases := []struct { + name string + objectType sdk.ObjectType + setupObject func() sdk.SchemaObjectIdentifierWithArguments + setTags func(sdk.SchemaObjectIdentifierWithArguments, []sdk.TagAssociation) error + unsetTags func(sdk.SchemaObjectIdentifierWithArguments, []sdk.ObjectIdentifier) error + }{ + { + name: "Function", + objectType: sdk.ObjectTypeFunction, + setupObject: func() sdk.SchemaObjectIdentifierWithArguments { + // cleanup is set up in the Create function + function := testClientHelper().Function.Create(t, sdk.DataTypeInt) + return function.ID() + }, + setTags: func(id sdk.SchemaObjectIdentifierWithArguments, tags []sdk.TagAssociation) error { + return client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifierWithArguments, tags []sdk.ObjectIdentifier) error { + return client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "ExternalFunction", + objectType: sdk.ObjectTypeExternalFunction, + setupObject: func() sdk.SchemaObjectIdentifierWithArguments { + integration, integrationCleanup := testClientHelper().ApiIntegration.CreateApiIntegration(t) + t.Cleanup(integrationCleanup) + // cleanup is set up in the Create function + function := testClientHelper().ExternalFunction.Create(t, integration.ID(), sdk.DataTypeInt) + return function.ID() + }, + setTags: func(id sdk.SchemaObjectIdentifierWithArguments, tags []sdk.TagAssociation) error { + return client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifierWithArguments, tags []sdk.ObjectIdentifier) error { + return client.Functions.Alter(ctx, sdk.NewAlterFunctionRequest(id).WithUnsetTags(tags)) + }, + }, + { + name: "Procedure", + objectType: sdk.ObjectTypeProcedure, + setupObject: func() sdk.SchemaObjectIdentifierWithArguments { + // cleanup is set up in the Create procedure + procedure := testClientHelper().Procedure.Create(t, sdk.DataTypeInt) + return procedure.ID() + }, + setTags: func(id sdk.SchemaObjectIdentifierWithArguments, tags []sdk.TagAssociation) error { + return client.Procedures.Alter(ctx, sdk.NewAlterProcedureRequest(id).WithSetTags(tags)) + }, + unsetTags: func(id sdk.SchemaObjectIdentifierWithArguments, tags []sdk.ObjectIdentifier) error { + return client.Procedures.Alter(ctx, sdk.NewAlterProcedureRequest(id).WithUnsetTags(tags)) + }, + }, + } + + for _, tc := range schemaObjectWithArgumentsTestCases { + t.Run(fmt.Sprintf("schema object with arguments %s", tc.name), func(t *testing.T) { + id := tc.setupObject() + err := tc.setTags(id, tags) + require.NoError(t, err) + + returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.NoError(t, err) + assert.Equal(t, tagValue, returnedTagValue) + + err = tc.unsetTags(id, unsetTags) + require.NoError(t, err) + + _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, tc.objectType) + require.ErrorContains(t, err, "sql: Scan error on column index 0, name \"TAG\": converting NULL to string is unsupported") + + // test object methods + testTagSet(id, tc.objectType) + }) + } +} diff --git a/pkg/sdk/testint/tasks_gen_integration_test.go b/pkg/sdk/testint/tasks_gen_integration_test.go index 206aa77404..4f61362a27 100644 --- a/pkg/sdk/testint/tasks_gen_integration_test.go +++ b/pkg/sdk/testint/tasks_gen_integration_test.go @@ -725,36 +725,6 @@ func TestInt_Tasks(t *testing.T) { assertions.AssertThat(t, objectparametersassert.TaskParameters(t, task.ID()).HasAllDefaults()) }) - t.Run("alter task: set and unset tag", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - task, taskCleanup := testClientHelper().Task.Create(t) - t.Cleanup(taskCleanup) - - tagValue := "abc" - err := client.Tasks.Alter(ctx, sdk.NewAlterTaskRequest(task.ID()).WithSetTags([]sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - })) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), task.ID(), sdk.ObjectTypeTask) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - err = client.Tasks.Alter(ctx, sdk.NewAlterTaskRequest(task.ID()).WithUnsetTags([]sdk.ObjectIdentifier{ - tag.ID(), - })) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), task.ID(), sdk.ObjectTypeTask) - require.Error(t, err) - }) - t.Run("alter task: resume and suspend", func(t *testing.T) { id := testClientHelper().Ids.RandomSchemaObjectIdentifier() task, taskCleanup := testClientHelper().Task.CreateWithRequest(t, sdk.NewCreateTaskRequest(id, sql).WithSchedule("10 MINUTE")) diff --git a/pkg/sdk/testint/users_integration_test.go b/pkg/sdk/testint/users_integration_test.go index 60906fe118..87dc57819a 100644 --- a/pkg/sdk/testint/users_integration_test.go +++ b/pkg/sdk/testint/users_integration_test.go @@ -44,9 +44,6 @@ func TestInt_Users(t *testing.T) { tag, tagCleanup := testClientHelper().Tag.CreateTag(t) t.Cleanup(tagCleanup) - tag2, tag2Cleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tag2Cleanup) - networkPolicy, networkPolicyCleanup := testClientHelper().NetworkPolicy.CreateNetworkPolicy(t) t.Cleanup(networkPolicyCleanup) @@ -1583,49 +1580,6 @@ func TestInt_Users(t *testing.T) { require.NoError(t, err) }) - t.Run("alter: set and unset tags", func(t *testing.T) { - user, userCleanup := testClientHelper().User.CreateUser(t) - t.Cleanup(userCleanup) - - alterOptions := &sdk.AlterUserOptions{ - SetTag: []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: "val", - }, - { - Name: tag2.ID(), - Value: "val2", - }, - }, - } - err := client.Users.Alter(ctx, user.ID(), alterOptions) - require.NoError(t, err) - - val, err := client.SystemFunctions.GetTag(ctx, tag.ID(), user.ID(), sdk.ObjectTypeUser) - require.NoError(t, err) - require.Equal(t, "val", val) - val2, err := client.SystemFunctions.GetTag(ctx, tag2.ID(), user.ID(), sdk.ObjectTypeUser) - require.NoError(t, err) - require.Equal(t, "val2", val2) - - alterOptions = &sdk.AlterUserOptions{ - UnsetTag: []sdk.ObjectIdentifier{ - tag.ID(), - tag2.ID(), - }, - } - err = client.Users.Alter(ctx, user.ID(), alterOptions) - require.NoError(t, err) - - val, err = client.SystemFunctions.GetTag(ctx, tag.ID(), user.ID(), sdk.ObjectTypeUser) - require.Error(t, err) - require.Equal(t, "", val) - val2, err = client.SystemFunctions.GetTag(ctx, tag2.ID(), user.ID(), sdk.ObjectTypeUser) - require.Error(t, err) - require.Equal(t, "", val2) - }) - t.Run("describe: when user exists", func(t *testing.T) { userDetails, err := client.Users.Describe(ctx, user.ID()) require.NoError(t, err) diff --git a/pkg/sdk/testint/views_gen_integration_test.go b/pkg/sdk/testint/views_gen_integration_test.go index e96b2666a6..7fda5f15ae 100644 --- a/pkg/sdk/testint/views_gen_integration_test.go +++ b/pkg/sdk/testint/views_gen_integration_test.go @@ -353,42 +353,6 @@ func TestInt_Views(t *testing.T) { assert.Equal(t, "OFF", alteredView.ChangeTracking) }) - t.Run("alter view: set and unset tag", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - view := createView(t) - id := view.ID() - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - alterRequestSetTags := sdk.NewAlterViewRequest(id).WithSetTags(tags) - - err := client.Views.Alter(ctx, alterRequestSetTags) - require.NoError(t, err) - - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeView) - require.NoError(t, err) - - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - alterRequestUnsetTags := sdk.NewAlterViewRequest(id).WithUnsetTags(unsetTags) - - err = client.Views.Alter(ctx, alterRequestUnsetTags) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), id, sdk.ObjectTypeView) - require.Error(t, err) - }) - t.Run("alter view: set and unset masking policy on column", func(t *testing.T) { maskingPolicy, maskingPolicyCleanup := testClientHelper().MaskingPolicy.CreateMaskingPolicyIdentity(t, sdk.DataTypeNumber) t.Cleanup(maskingPolicyCleanup) @@ -449,46 +413,6 @@ func TestInt_Views(t *testing.T) { require.Empty(t, references) }) - t.Run("alter view: set and unset tags on column", func(t *testing.T) { - tag, tagCleanup := testClientHelper().Tag.CreateTag(t) - t.Cleanup(tagCleanup) - - view := createView(t) - id := view.ID() - - tagValue := "abc" - tags := []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: tagValue, - }, - } - - alterRequest := sdk.NewAlterViewRequest(id).WithSetTagsOnColumn( - *sdk.NewViewSetColumnTagsRequest("ID", tags), - ) - err := client.Views.Alter(ctx, alterRequest) - require.NoError(t, err) - - columnId := sdk.NewTableColumnIdentifier(id.DatabaseName(), id.SchemaName(), id.Name(), "ID") - returnedTagValue, err := client.SystemFunctions.GetTag(ctx, tag.ID(), columnId, sdk.ObjectTypeColumn) - require.NoError(t, err) - assert.Equal(t, tagValue, returnedTagValue) - - unsetTags := []sdk.ObjectIdentifier{ - tag.ID(), - } - - alterRequest = sdk.NewAlterViewRequest(id).WithUnsetTagsOnColumn( - *sdk.NewViewUnsetColumnTagsRequest("ID", unsetTags), - ) - err = client.Views.Alter(ctx, alterRequest) - require.NoError(t, err) - - _, err = client.SystemFunctions.GetTag(ctx, tag.ID(), columnId, sdk.ObjectTypeColumn) - require.Error(t, err) - }) - t.Run("alter view: add and drop row access policies", func(t *testing.T) { rowAccessPolicy, rowAccessPolicyCleanup := testClientHelper().RowAccessPolicy.CreateRowAccessPolicy(t) t.Cleanup(rowAccessPolicyCleanup) diff --git a/pkg/sdk/testint/warehouses_integration_test.go b/pkg/sdk/testint/warehouses_integration_test.go index f22832f0f3..e2dce5e08c 100644 --- a/pkg/sdk/testint/warehouses_integration_test.go +++ b/pkg/sdk/testint/warehouses_integration_test.go @@ -641,50 +641,6 @@ func TestInt_Warehouses(t *testing.T) { assert.Equal(t, 0, result.Queued) }) - t.Run("alter: set tags and unset tags", func(t *testing.T) { - // new warehouse created on purpose - warehouse, warehouseCleanup := testClientHelper().Warehouse.CreateWarehouse(t) - t.Cleanup(warehouseCleanup) - - alterOptions := &sdk.AlterWarehouseOptions{ - SetTag: []sdk.TagAssociation{ - { - Name: tag.ID(), - Value: "val", - }, - { - Name: tag2.ID(), - Value: "val2", - }, - }, - } - err := client.Warehouses.Alter(ctx, warehouse.ID(), alterOptions) - require.NoError(t, err) - - val, err := client.SystemFunctions.GetTag(ctx, tag.ID(), warehouse.ID(), sdk.ObjectTypeWarehouse) - require.NoError(t, err) - require.Equal(t, "val", val) - val2, err := client.SystemFunctions.GetTag(ctx, tag2.ID(), warehouse.ID(), sdk.ObjectTypeWarehouse) - require.NoError(t, err) - require.Equal(t, "val2", val2) - - alterOptions = &sdk.AlterWarehouseOptions{ - UnsetTag: []sdk.ObjectIdentifier{ - tag.ID(), - tag2.ID(), - }, - } - err = client.Warehouses.Alter(ctx, warehouse.ID(), alterOptions) - require.NoError(t, err) - - val, err = client.SystemFunctions.GetTag(ctx, tag.ID(), warehouse.ID(), sdk.ObjectTypeWarehouse) - require.Error(t, err) - require.Equal(t, "", val) - val2, err = client.SystemFunctions.GetTag(ctx, tag2.ID(), warehouse.ID(), sdk.ObjectTypeWarehouse) - require.Error(t, err) - require.Equal(t, "", val2) - }) - t.Run("describe: when warehouse exists", func(t *testing.T) { result, err := client.Warehouses.Describe(ctx, precreatedWarehouseId) require.NoError(t, err)