Skip to content

Commit

Permalink
chore: Use service user for ci (#3228)
Browse files Browse the repository at this point in the history
Use service user on CI
- adjust config provider tests
- limit the number of predefined profiles
- create users with limited privileges to test different setups
- extract toml builder (with follow-ups described in TODOs)
- prepare user setups in TestClient (with follow-up improvements
described in TODOs)

Fixes:
- fix the authenticator type merging (special empty value added)

Misc:
- bump sweepers timeout to 10m
- left TODOs to check the behavior of 3-value booleans for each
attribute in driver config
- remove unused asserts
- move some SDK client tests to testint package (TODO left for the rest)
  • Loading branch information
sfc-gh-asawicki authored Nov 28, 2024
1 parent c209a8a commit 2fb50d7
Show file tree
Hide file tree
Showing 24 changed files with 1,022 additions and 509 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:

- name: Create and populate .snowflake/config file
id: create_config
run: mkdir -p $HOME/.snowflake && echo "${{ secrets.SNOWFLAKE_CONFIG_FILE }}" > $HOME/.snowflake/config
run: mkdir -p $HOME/.snowflake && echo "${{ secrets.ASW_TMP_SNOWFLAKE_CONFIG_FILE }}" > $HOME/.snowflake/config

- name: Create and populate .snowflake/config_v097_compatible file
id: create_config_v097_compatible
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ sweep: ## destroy the whole architecture; USE ONLY FOR DEVELOPMENT ACCOUNTS
@echo "Are you sure? [y/n]" >&2
@read -r REPLY; \
if echo "$$REPLY" | grep -qG "^[yY]$$"; then \
TEST_SF_TF_ENABLE_SWEEP=1 go test -timeout 300s -run "^(TestSweepAll|Test_Sweeper_NukeStaleObjects)" ./pkg/sdk -v; \
TEST_SF_TF_ENABLE_SWEEP=1 go test -timeout=10m -run "^(TestSweepAll|Test_Sweeper_NukeStaleObjects)" ./pkg/sdk -v; \
else echo "Aborting..."; \
fi;

Expand Down
23 changes: 0 additions & 23 deletions pkg/acceptance/asserts.go

This file was deleted.

73 changes: 0 additions & 73 deletions pkg/acceptance/asserts_test.go

This file was deleted.

162 changes: 162 additions & 0 deletions pkg/acceptance/helpers/config_toml_creator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package helpers

import (
"fmt"
"testing"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
)

// FullTomlConfigForServiceUser is a temporary function used to test provider configuration
// TODO [SNOW-1827309]: use toml marshaling from "github.com/pelletier/go-toml/v2"
// TODO [SNOW-1827309]: add builders for our toml config struct
func FullTomlConfigForServiceUser(t *testing.T, profile string, userId sdk.AccountObjectIdentifier, roleId sdk.AccountObjectIdentifier, warehouseId sdk.AccountObjectIdentifier, accountIdentifier sdk.AccountIdentifier, privateKey string) string {
t.Helper()

return fmt.Sprintf(`
[%[1]s]
user = '%[2]s'
privatekey = '''%[7]s'''
role = '%[3]s'
organizationname = '%[5]s'
accountname = '%[6]s'
warehouse = '%[4]s'
clientip = '1.2.3.4'
protocol = 'https'
port = 443
oktaurl = 'https://example.com'
clienttimeout = 10
jwtclienttimeout = 20
logintimeout = 30
requesttimeout = 40
jwtexpiretimeout = 50
externalbrowsertimeout = 60
maxretrycount = 1
authenticator = 'SNOWFLAKE_JWT'
insecuremode = true
ocspfailopen = true
token = 'token'
keepsessionalive = true
disabletelemetry = true
validatedefaultparameters = true
clientrequestmfatoken = true
clientstoretemporarycredential = true
tracing = 'warning'
tmpdirpath = '.'
disablequerycontextcache = true
includeretryreason = true
disableconsolelogin = true
[%[1]s.params]
foo = 'bar'
`, profile, userId.Name(), roleId.Name(), warehouseId.Name(), accountIdentifier.OrganizationName(), accountIdentifier.AccountName(), privateKey)
}

// FullInvalidTomlConfigForServiceUser is a temporary function used to test provider configuration
func FullInvalidTomlConfigForServiceUser(t *testing.T, profile string) string {
t.Helper()

privateKey, _, _, _ := random.GenerateRSAKeyPair(t, "")
return fmt.Sprintf(`
[%[1]s]
user = 'invalid'
privatekey = '''%[2]s'''
role = 'invalid'
accountname = 'invalid'
organizationname = 'invalid'
warehouse = 'invalid'
clientip = 'invalid'
protocol = 'invalid'
port = -1
oktaurl = 'invalid'
clienttimeout = -1
jwtclienttimeout = -1
logintimeout = -1
requesttimeout = -1
jwtexpiretimeout = -1
externalbrowsertimeout = -1
maxretrycount = -1
authenticator = 'snowflake'
insecuremode = true
ocspfailopen = true
token = 'token'
keepsessionalive = true
disabletelemetry = true
validatedefaultparameters = false
clientrequestmfatoken = true
clientstoretemporarycredential = true
tracing = 'invalid'
tmpdirpath = '.'
disablequerycontextcache = true
includeretryreason = true
disableconsolelogin = true
[%[1]s.params]
foo = 'bar'`, profile, privateKey)
}

// TomlConfigForServiceUser is a temporary function used to test provider configuration
func TomlConfigForServiceUser(t *testing.T, profile string, userId sdk.AccountObjectIdentifier, roleId sdk.AccountObjectIdentifier, warehouseId sdk.AccountObjectIdentifier, accountIdentifier sdk.AccountIdentifier, privateKey string) string {
t.Helper()

return fmt.Sprintf(`
[%[1]s]
user = '%[2]s'
privatekey = '''%[7]s'''
role = '%[3]s'
organizationname = '%[5]s'
accountname = '%[6]s'
warehouse = '%[4]s'
authenticator = 'SNOWFLAKE_JWT'
`, profile, userId.Name(), roleId.Name(), warehouseId.Name(), accountIdentifier.OrganizationName(), accountIdentifier.AccountName(), privateKey)
}

// TomlConfigForServiceUserWithEncryptedKey is a temporary function used to test provider configuration
func TomlConfigForServiceUserWithEncryptedKey(t *testing.T, profile string, userId sdk.AccountObjectIdentifier, roleId sdk.AccountObjectIdentifier, warehouseId sdk.AccountObjectIdentifier, accountIdentifier sdk.AccountIdentifier, privateKey string, pass string) string {
t.Helper()

return fmt.Sprintf(`
[%[1]s]
user = '%[2]s'
privatekey = '''%[7]s'''
privatekeypassphrase = '%[8]s'
role = '%[3]s'
organizationname = '%[5]s'
accountname = '%[6]s'
warehouse = '%[4]s'
authenticator = 'SNOWFLAKE_JWT'
`, profile, userId.Name(), roleId.Name(), warehouseId.Name(), accountIdentifier.OrganizationName(), accountIdentifier.AccountName(), privateKey, pass)
}

// TomlIncorrectConfigForServiceUser is a temporary function used to test provider configuration
func TomlIncorrectConfigForServiceUser(t *testing.T, profile string, accountIdentifier sdk.AccountIdentifier) string {
t.Helper()

privateKey, _, _, _ := random.GenerateRSAKeyPair(t, "")
return fmt.Sprintf(`
[%[1]s]
user = 'non-existing-user'
privatekey = '''%[4]s'''
role = 'non-existing-role'
organizationname = '%[2]s'
accountname = '%[3]s'
authenticator = 'SNOWFLAKE_JWT'
`, profile, accountIdentifier.OrganizationName(), accountIdentifier.AccountName(), privateKey)
}

// TomlConfigForLegacyServiceUser is a temporary function used to test provider configuration
func TomlConfigForLegacyServiceUser(t *testing.T, profile string, userId sdk.AccountObjectIdentifier, roleId sdk.AccountObjectIdentifier, warehouseId sdk.AccountObjectIdentifier, accountIdentifier sdk.AccountIdentifier, pass string) string {
t.Helper()

return fmt.Sprintf(`
[%[1]s]
user = '%[2]s'
password = '%[7]s'
role = '%[3]s'
organizationname = '%[5]s'
accountname = '%[6]s'
warehouse = '%[4]s'
authenticator = 'SNOWFLAKE'
`, profile, userId.Name(), roleId.Name(), warehouseId.Name(), accountIdentifier.OrganizationName(), accountIdentifier.AccountName(), pass)
}
10 changes: 10 additions & 0 deletions pkg/acceptance/helpers/context_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ func (c *ContextClient) CurrentAccount(t *testing.T) string {
return currentAccount
}

func (c *ContextClient) CurrentAccountId(t *testing.T) sdk.AccountIdentifier {
t.Helper()
ctx := context.Background()

currentSessionDetails, err := c.client().CurrentSessionDetails(ctx)
require.NoError(t, err)

return sdk.NewAccountIdentifier(currentSessionDetails.OrganizationName, currentSessionDetails.AccountName)
}

func (c *ContextClient) CurrentRole(t *testing.T) sdk.AccountObjectIdentifier {
t.Helper()
ctx := context.Background()
Expand Down
66 changes: 66 additions & 0 deletions pkg/acceptance/helpers/grant_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,72 @@ func (c *GrantClient) RevokePrivilegesOnDatabaseFromDatabaseRole(
require.NoError(t, err)
}

func (c *GrantClient) GrantPrivilegesOnDatabaseToAccountRole(
t *testing.T,
accountRoleId sdk.AccountObjectIdentifier,
databaseId sdk.AccountObjectIdentifier,
privileges []sdk.AccountObjectPrivilege,
withGrantOption bool,
) {
t.Helper()
c.grantPrivilegesOnAccountLevelObjectToAccountRole(
t,
accountRoleId,
&sdk.AccountRoleGrantOn{
AccountObject: &sdk.GrantOnAccountObject{
Database: sdk.Pointer(databaseId),
},
},
privileges,
withGrantOption,
)
}

func (c *GrantClient) GrantPrivilegesOnWarehouseToAccountRole(
t *testing.T,
accountRoleId sdk.AccountObjectIdentifier,
warehouseId sdk.AccountObjectIdentifier,
privileges []sdk.AccountObjectPrivilege,
withGrantOption bool,
) {
t.Helper()
c.grantPrivilegesOnAccountLevelObjectToAccountRole(
t,
accountRoleId,
&sdk.AccountRoleGrantOn{
AccountObject: &sdk.GrantOnAccountObject{
Warehouse: sdk.Pointer(warehouseId),
},
},
privileges,
withGrantOption,
)
}

func (c *GrantClient) grantPrivilegesOnAccountLevelObjectToAccountRole(
t *testing.T,
accountRoleId sdk.AccountObjectIdentifier,
accountObjectGrantOn *sdk.AccountRoleGrantOn,
privileges []sdk.AccountObjectPrivilege,
withGrantOption bool,
) {
t.Helper()
ctx := context.Background()

err := c.client().GrantPrivilegesToAccountRole(
ctx,
&sdk.AccountRoleGrantPrivileges{
AccountObjectPrivileges: privileges,
},
accountObjectGrantOn,
accountRoleId,
&sdk.GrantPrivilegesToAccountRoleOptions{
WithGrantOption: sdk.Bool(withGrantOption),
},
)
require.NoError(t, err)
}

func (c *GrantClient) GrantPrivilegesOnDatabaseToDatabaseRole(
t *testing.T,
databaseRoleId sdk.DatabaseObjectIdentifier,
Expand Down
4 changes: 4 additions & 0 deletions pkg/acceptance/helpers/ids_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ func (c *IdsGenerator) WarehouseId() sdk.AccountObjectIdentifier {
return sdk.NewAccountObjectIdentifier(c.context.warehouse)
}

func (c *IdsGenerator) SnowflakeWarehouseId() sdk.AccountObjectIdentifier {
return sdk.NewAccountObjectIdentifier("SNOWFLAKE")
}

func (c *IdsGenerator) AccountIdentifierWithLocator() sdk.AccountIdentifier {
return sdk.NewAccountIdentifierFromAccountLocator(c.context.client.GetAccountLocator())
}
Expand Down
Loading

0 comments on commit 2fb50d7

Please sign in to comment.