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: Example of granting role to multiple objects #3047

Merged
merged 3 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ role = "<any role, e.g. ACCOUNTADMIN>"
host="<host of your account, e.g. organisation-account_name.snowflakecomputing.com>"
```

We are aware that not everyone has access two multiple accounts, so the majority of tests can be run using just one account. The tests setup however, requires both profiles (`default` and `secondary_test_account`) to be present. You can use the same details for `secondary_test_account` as in the `default` one, if you don't plan to run tests requiring multiple accounts.
We are aware that not everyone has access two multiple accounts, so the majority of tests can be run using just one account. The tests setup however, requires both profiles (`default` and `secondary_test_account`) to be present. You can use the same details for `secondary_test_account` as in the `default` one, if you don't plan to run tests requiring multiple accounts. The warning will be logged when setting up tests with just a single account.

**⚠️ Important ⚠️** Some of the tests require the privileged role (like `ACCOUNTADMIN`). Otherwise, the managed objects may not be created. If you want to use lower role, you have to make sure it has all the necessary privileges added.

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ test: test-client ## run unit and integration tests
go test -v -cover -timeout=45m ./...

test-acceptance: ## run acceptance tests
TF_ACC=1 SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE=true TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX=1 go test -run "^TestAcc_" -v -cover -timeout=60m ./...
TF_ACC=1 SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE=true TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX=1 go test -run "^TestAcc_" -v -cover -timeout=90m ./...

test-integration: ## run SDK integration tests
TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX=1 go test -run "^TestInt_" -v -cover -timeout=45m ./...
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
roles:
"example_role1":
grant_to:
user:
- "example_user1"
role:
"example_role2":
grant_to:
user:
role:
- "example_role3"
"example_role3":
grant_to:
user:
- "example_user1"
- "example_user2"
- "example_user3"
role:
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
terraform {
required_version = ">= 1.3.6"
required_providers {
snowflake = {
source = "snowflake-labs/snowflake"
version = "0.94.1"
}
}
}

resource "snowflake_user" "user1" {
name = "example_user1"
}

resource "snowflake_user" "user2" {
name = "example_user2"
}

resource "snowflake_user" "user3" {
name = "example_user3"
}

resource "snowflake_account_role" "role1" {
name = "example_role1"
}

resource "snowflake_account_role" "role2" {
name = "example_role2"
}

resource "snowflake_account_role" "role3" {
name = "example_role3"
}

locals {
yaml_roles = yamldecode(file("${path.module}/config.yaml"))
grant_to_user = distinct(flatten([
for k, v in local.yaml_roles.roles : v.grant_to.user == null ? [] : [
for u in v.grant_to.user : {
role = k
to_user = u
}
]]))
grant_to_role = distinct(flatten([
for k, v in local.yaml_roles.roles : v.grant_to.role == null ? [] : [
for r in v.grant_to.role : {
role = k
to_role = r
}
]]))
}

output "grant_to_user_output" {
value = local.grant_to_user
}

output "grant_to_role_output" {
value = local.grant_to_role
}

resource "snowflake_grant_account_role" "user_grants" {
depends_on = [
snowflake_user.user1, snowflake_user.user2, snowflake_user.user3, snowflake_account_role.role1,
snowflake_account_role.role2, snowflake_account_role.role3
]
for_each = {for entry in local.grant_to_user : "${entry.role}.${entry.to_user}" => entry}
role_name = each.value.role
user_name = each.value.to_user
}

resource "snowflake_grant_account_role" "role_grants" {
depends_on = [
snowflake_user.user1, snowflake_user.user2, snowflake_user.user3, snowflake_account_role.role1,
snowflake_account_role.role2, snowflake_account_role.role3
]
for_each = {for entry in local.grant_to_role : "${entry.role}.${entry.to_role}" => entry}
role_name = each.value.role
parent_role_name = each.value.to_role
}
28 changes: 16 additions & 12 deletions pkg/sdk/testint/setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,21 +128,21 @@ func (itc *integrationTestContext) initialize() error {
itc.client = c
itc.ctx = context.Background()

db, dbCleanup, err := createDb(itc.client, itc.ctx)
db, dbCleanup, err := createDb(itc.client, itc.ctx, false)
itc.databaseCleanup = dbCleanup
if err != nil {
return err
}
itc.database = db

sc, scCleanup, err := createSc(itc.client, itc.ctx, itc.database)
sc, scCleanup, err := createSc(itc.client, itc.ctx, itc.database, false)
itc.schemaCleanup = scCleanup
if err != nil {
return err
}
itc.schema = sc

wh, whCleanup, err := createWh(itc.client, itc.ctx)
wh, whCleanup, err := createWh(itc.client, itc.ctx, false)
itc.warehouseCleanup = whCleanup
if err != nil {
return err
Expand All @@ -154,28 +154,32 @@ func (itc *integrationTestContext) initialize() error {
return err
}

if config.Account == defaultConfig.Account {
log.Println("[WARN] default and secondary configs are set to the same account; it may cause problems in tests requiring multiple accounts")
}

secondaryClient, err := sdk.NewClient(config)
if err != nil {
return err
}
itc.secondaryClient = secondaryClient
itc.secondaryCtx = context.Background()

secondaryDb, secondaryDbCleanup, err := createDb(itc.secondaryClient, itc.secondaryCtx)
secondaryDb, secondaryDbCleanup, err := createDb(itc.secondaryClient, itc.secondaryCtx, true)
itc.secondaryDatabaseCleanup = secondaryDbCleanup
if err != nil {
return err
}
itc.secondaryDatabase = secondaryDb

secondarySchema, secondarySchemaCleanup, err := createSc(itc.secondaryClient, itc.secondaryCtx, itc.database)
secondarySchema, secondarySchemaCleanup, err := createSc(itc.secondaryClient, itc.secondaryCtx, itc.database, true)
itc.secondarySchemaCleanup = secondarySchemaCleanup
if err != nil {
return err
}
itc.secondarySchema = secondarySchema

secondaryWarehouse, secondaryWarehouseCleanup, err := createWh(itc.secondaryClient, itc.secondaryCtx)
secondaryWarehouse, secondaryWarehouseCleanup, err := createWh(itc.secondaryClient, itc.secondaryCtx, true)
itc.secondaryWarehouseCleanup = secondaryWarehouseCleanup
if err != nil {
return err
Expand Down Expand Up @@ -206,38 +210,38 @@ func (itc *integrationTestContext) initialize() error {
return nil
}

func createDb(client *sdk.Client, ctx context.Context) (*sdk.Database, func(), error) {
func createDb(client *sdk.Client, ctx context.Context, ifNotExists bool) (*sdk.Database, func(), error) {
id := sdk.NewAccountObjectIdentifier(TestDatabaseName)
cleanup := func() {
_ = client.Databases.Drop(ctx, id, &sdk.DropDatabaseOptions{IfExists: sdk.Bool(true)})
}
err := client.Databases.Create(ctx, id, nil)
err := client.Databases.Create(ctx, id, &sdk.CreateDatabaseOptions{IfNotExists: sdk.Bool(ifNotExists)})
if err != nil {
return nil, cleanup, err
}
database, err := client.Databases.ShowByID(ctx, id)
return database, cleanup, err
}

func createSc(client *sdk.Client, ctx context.Context, db *sdk.Database) (*sdk.Schema, func(), error) {
func createSc(client *sdk.Client, ctx context.Context, db *sdk.Database, ifNotExists bool) (*sdk.Schema, func(), error) {
id := sdk.NewDatabaseObjectIdentifier(db.Name, TestSchemaName)
cleanup := func() {
_ = client.Schemas.Drop(ctx, id, &sdk.DropSchemaOptions{IfExists: sdk.Bool(true)})
}
err := client.Schemas.Create(ctx, id, nil)
err := client.Schemas.Create(ctx, id, &sdk.CreateSchemaOptions{IfNotExists: sdk.Bool(ifNotExists)})
if err != nil {
return nil, cleanup, err
}
schema, err := client.Schemas.ShowByID(ctx, sdk.NewDatabaseObjectIdentifier(db.Name, TestSchemaName))
return schema, cleanup, err
}

func createWh(client *sdk.Client, ctx context.Context) (*sdk.Warehouse, func(), error) {
func createWh(client *sdk.Client, ctx context.Context, ifNotExists bool) (*sdk.Warehouse, func(), error) {
id := sdk.NewAccountObjectIdentifier(TestWarehouseName)
cleanup := func() {
_ = client.Warehouses.Drop(ctx, id, &sdk.DropWarehouseOptions{IfExists: sdk.Bool(true)})
}
err := client.Warehouses.Create(ctx, id, nil)
err := client.Warehouses.Create(ctx, id, &sdk.CreateWarehouseOptions{IfNotExists: sdk.Bool(ifNotExists)})
if err != nil {
return nil, cleanup, err
}
Expand Down
Loading