Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Improve tags integration tests #3193

Merged
merged 4 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pkg/acceptance/helpers/security_integration_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ func (c *SecurityIntegrationClient) CreateOauthForCustomClients(t *testing.T) (*
return si, c.DropSecurityIntegrationFunc(t, request.GetName())
}

func (c *SecurityIntegrationClient) CreateSaml2(t *testing.T, id sdk.AccountObjectIdentifier) (*sdk.SecurityIntegration, func()) {
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)))
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/sdk/system_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ func (c *systemFunctions) GetTag(ctx context.Context, tagID ObjectIdentifier, ob
// 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, error) {
if !isTagAssociationAllowedObjectTypes(objectType) {
if !canBeAssociatedWithTag(objectType) {
return "", fmt.Errorf("tagging for object type %s is not supported", objectType)
}
if slices.Contains([]ObjectType{ObjectTypeView, ObjectTypeMaterializedView, ObjectTypeExternalTable}, objectType) {
if slices.Contains([]ObjectType{ObjectTypeView, ObjectTypeMaterializedView, ObjectTypeExternalTable, ObjectTypeEventTable}, objectType) {
return ObjectTypeTable, nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/sdk/tag_association_validations.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ var (
TagAssociationAllowedObjectTypesString = make([]string, len(TagAssociationAllowedObjectTypes))
)

func isTagAssociationAllowedObjectTypes(o ObjectType) bool {
func canBeAssociatedWithTag(o ObjectType) bool {
return slices.Contains(TagAssociationAllowedObjectTypes, o)
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/sdk/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type Tags interface {
Undrop(ctx context.Context, request *UndropTagRequest) error
Set(ctx context.Context, request *SetTagRequest) error
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be more consistent with other objects, we could modify the Set method so that inside, you would choose on what object you want to set the tag (I think the Options struct should be more similar to GrantPrivilegesToAccountRoleOptions one where you have on field with sub-fields being: OnAccount, OnObject, OnColumn).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree because in SetOnCurrentAccount we don't use any identifier. We're modifying the current account like ALTER ACCOUNT, where this one uses ALTER <type> <id> which is different.

Unset(ctx context.Context, request *UnsetTagRequest) error
SetOnCurrentAccount(ctx context.Context, request *SetTagOnCurrentAccountRequest) error
UnsetOnCurrentAccount(ctx context.Context, request *UnsetTagOnCurrentAccountRequest) error
}

type setTagOptions struct {
Expand Down
8 changes: 8 additions & 0 deletions pkg/sdk/tags_dto.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions pkg/sdk/tags_dto_builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions pkg/sdk/tags_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
25 changes: 25 additions & 0 deletions pkg/sdk/tags_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sdk

import (
"errors"
"testing"
)

Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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{
Expand Down
13 changes: 13 additions & 0 deletions pkg/sdk/tags_validations.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sdk

import (
"errors"
"fmt"
)

var (
Expand Down Expand Up @@ -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...)
}

Expand All @@ -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...)
}
14 changes: 6 additions & 8 deletions pkg/sdk/testint/authentication_policies_gen_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -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},
Expand All @@ -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()).
Expand All @@ -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},
Expand All @@ -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]")

Expand Down
68 changes: 2 additions & 66 deletions pkg/sdk/testint/databases_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ func TestInt_DatabasesCreateSecondary(t *testing.T) {

func TestInt_DatabasesAlter(t *testing.T) {
client := testClient(t)
secondaryClient := testSecondaryClient(t)
ctx := testContext(t)

assertDatabaseParameterEquals := func(t *testing.T, params []*sdk.Parameter, parameterName sdk.AccountParameter, expected string) {
Expand Down Expand Up @@ -369,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,
},
}

Expand Down
Loading
Loading