Skip to content

Commit

Permalink
[refactor] Grants: Wrap grants with their valid privilges for cztack …
Browse files Browse the repository at this point in the history
…codegen (#333)

I don't think this PR is breaking the deps check. Going to go ahead and merge to avoid conflicts/rebase/etc headaches and will figure out the mods in a follow-up
  • Loading branch information
Eduardo Lopez committed Dec 9, 2020
1 parent 82e82eb commit ffe977a
Show file tree
Hide file tree
Showing 27 changed files with 233 additions and 168 deletions.
7 changes: 2 additions & 5 deletions docs/index.md
Expand Up @@ -32,19 +32,16 @@ provider snowflake {

## Schema

### Required

- **account** (String, Required)
- **username** (String, Required)

### Optional

- **account** (String, Optional)
- **browser_auth** (Boolean, Optional)
- **oauth_access_token** (String, Optional)
- **password** (String, Optional)
- **private_key_path** (String, Optional)
- **region** (String, Optional)
- **role** (String, Optional)
- **username** (String, Optional)


## Authentication
Expand Down
2 changes: 1 addition & 1 deletion docs/resources/account_grant.md
Expand Up @@ -24,7 +24,7 @@ resource snowflake_account_grant grant {
### Optional

- **id** (String, Optional) The ID of this resource.
- **privilege** (String, Optional) The privilege to grant on the schema.
- **privilege** (String, Optional) The privilege to grant on the account.
- **roles** (Set of String, Optional) Grants privilege to these roles.
- **with_grant_option** (Boolean, Optional) When this is set to true, allows the recipient role to grant the privileges to other roles.

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -15,5 +15,5 @@ require (
github.com/snowflakedb/gosnowflake v1.3.12
github.com/stretchr/testify v1.6.1
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49
golang.org/x/tools v0.0.0-20201208225042-ef0c635082b3
)
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -937,8 +937,8 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200713011307-fd294ab11aed/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49 h1:K1QAOVIWIvmQ66F1Z3AEa9Wzp0bj+xU3YzLkvROk2Ds=
golang.org/x/tools v0.0.0-20201208211828-de58e7c01d49/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208225042-ef0c635082b3 h1:ZCTyS0mmKNKnJH/wbIdBVEe+mhkxEgV6lDU9G4ZYH6M=
golang.org/x/tools v0.0.0-20201208225042-ef0c635082b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
73 changes: 44 additions & 29 deletions pkg/provider/provider.go
Expand Up @@ -67,42 +67,57 @@ func Provider() *schema.Provider {
DefaultFunc: schema.EnvDefaultFunc("SNOWFLAKE_REGION", "us-west-2"),
},
},
ResourcesMap: map[string]*schema.Resource{
"snowflake_account_grant": resources.AccountGrant(),
"snowflake_database": resources.Database(),
"snowflake_database_grant": resources.DatabaseGrant(),
"snowflake_integration_grant": resources.IntegrationGrant(),
"snowflake_managed_account": resources.ManagedAccount(),
"snowflake_network_policy": resources.NetworkPolicy(),
"snowflake_network_policy_attachment": resources.NetworkPolicyAttachment(),
"snowflake_pipe": resources.Pipe(),
"snowflake_resource_monitor": resources.ResourceMonitor(),
"snowflake_resource_monitor_grant": resources.ResourceMonitorGrant(),
"snowflake_role": resources.Role(),
"snowflake_role_grants": resources.RoleGrants(),
"snowflake_schema": resources.Schema(),
"snowflake_schema_grant": resources.SchemaGrant(),
"snowflake_share": resources.Share(),
"snowflake_stage": resources.Stage(),
"snowflake_stage_grant": resources.StageGrant(),
"snowflake_storage_integration": resources.StorageIntegration(),
"snowflake_stream": resources.Stream(),
"snowflake_user": resources.User(),
"snowflake_view": resources.View(),
"snowflake_view_grant": resources.ViewGrant(),
"snowflake_task": resources.Task(),
"snowflake_table": resources.Table(),
"snowflake_table_grant": resources.TableGrant(),
"snowflake_warehouse": resources.Warehouse(),
"snowflake_warehouse_grant": resources.WarehouseGrant(),
},
ResourcesMap: getResources(),
DataSourcesMap: map[string]*schema.Resource{
"snowflake_system_get_aws_sns_iam_policy": datasources.SystemGetAWSSNSIAMPolicy(),
},
ConfigureFunc: ConfigureProvider,
}
}

func GetGrantResources() resources.TerraformGrantResources {
grants := resources.TerraformGrantResources{
"snowflake_account_grant": resources.AccountGrant(),
"snowflake_database_grant": resources.DatabaseGrant(),
"snowflake_integration_grant": resources.IntegrationGrant(),
"snowflake_resource_monitor_grant": resources.ResourceMonitorGrant(),
"snowflake_schema_grant": resources.SchemaGrant(),
"snowflake_stage_grant": resources.StageGrant(),
"snowflake_table_grant": resources.TableGrant(),
"snowflake_view_grant": resources.ViewGrant(),
"snowflake_warehouse_grant": resources.WarehouseGrant(),
}
return grants
}

func getResources() map[string]*schema.Resource {
others := map[string]*schema.Resource{
"snowflake_database": resources.Database(),
"snowflake_managed_account": resources.ManagedAccount(),
"snowflake_network_policy_attachment": resources.NetworkPolicyAttachment(),
"snowflake_network_policy": resources.NetworkPolicy(),
"snowflake_pipe": resources.Pipe(),
"snowflake_resource_monitor": resources.ResourceMonitor(),
"snowflake_role_grants": resources.RoleGrants(),
"snowflake_role": resources.Role(),
"snowflake_schema": resources.Schema(),
"snowflake_share": resources.Share(),
"snowflake_stage": resources.Stage(),
"snowflake_storage_integration": resources.StorageIntegration(),
"snowflake_stream": resources.Stream(),
"snowflake_table": resources.Table(),
"snowflake_task": resources.Task(),
"snowflake_user": resources.User(),
"snowflake_view": resources.View(),
"snowflake_warehouse": resources.Warehouse(),
}

return mergeSchemas(
others,
GetGrantResources().GetTfSchemas(),
)
}

func ConfigureProvider(s *schema.ResourceData) (interface{}, error) {
account := s.Get("account").(string)
user := s.Get("username").(string)
Expand Down
13 changes: 13 additions & 0 deletions pkg/provider/provider_helper.go
@@ -0,0 +1,13 @@
package provider

import "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

func mergeSchemas(schemaCollections ...map[string]*schema.Resource) map[string]*schema.Resource {
out := map[string]*schema.Resource{}
for _, schemaCollection := range schemaCollections {
for name, s := range schemaCollection {
out[name] = s
}
}
return out
}
26 changes: 14 additions & 12 deletions pkg/resources/account_grant.go
@@ -1,10 +1,9 @@
package resources

import (
"github.com/chanzuckerberg/terraform-provider-snowflake/pkg/snowflake"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

"github.com/chanzuckerberg/terraform-provider-snowflake/pkg/snowflake"
)

var validAccountPrivileges = NewPrivilegeSet(
Expand All @@ -23,9 +22,9 @@ var accountGrantSchema = map[string]*schema.Schema{
"privilege": {
Type: schema.TypeString,
Optional: true,
Description: "The privilege to grant on the schema.",
Description: "The privilege to grant on the account.",
Default: privilegeMonitorUsage,
ValidateFunc: validation.StringInSlice(validAccountPrivileges.toList(), true),
ValidateFunc: validation.StringInSlice(validAccountPrivileges.ToList(), true),
ForceNew: true,
},
"roles": {
Expand All @@ -44,14 +43,17 @@ var accountGrantSchema = map[string]*schema.Schema{
},
}

// ViewGrant returns a pointer to the resource representing a view grant
func AccountGrant() *schema.Resource {
return &schema.Resource{
Create: CreateAccountGrant,
Read: ReadAccountGrant,
Delete: DeleteAccountGrant,

Schema: accountGrantSchema,
// AccountGrant returns a pointer to the resource representing an account grant
func AccountGrant() *TerraformGrantResource {
return &TerraformGrantResource{
Resource: &schema.Resource{
Create: CreateAccountGrant,
Read: ReadAccountGrant,
Delete: DeleteAccountGrant,

Schema: accountGrantSchema,
},
ValidPrivs: validAccountPrivileges,
}
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/resources/account_grant_test.go
Expand Up @@ -16,7 +16,7 @@ import (
//lintignore:AT003
func TestAccountGrant(t *testing.T) {
r := require.New(t)
err := resources.AccountGrant().InternalValidate(provider.Provider().Schema, true)
err := resources.AccountGrant().Resource.InternalValidate(provider.Provider().Schema, true)
r.NoError(err)
}

Expand All @@ -29,7 +29,7 @@ func TestAccountGrantCreate(t *testing.T) { //lintignore:AT003
"roles": []interface{}{"test-role-1", "test-role-2"},
"with_grant_option": true,
}
d := schema.TestResourceDataRaw(t, resources.AccountGrant().Schema, in)
d := schema.TestResourceDataRaw(t, resources.AccountGrant().Resource.Schema, in)
r.NotNil(d)

WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
Expand Down
25 changes: 14 additions & 11 deletions pkg/resources/database_grant.go
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

var ValidDatabasePrivileges = NewPrivilegeSet(
var validDatabasePrivileges = NewPrivilegeSet(
privilegeCreateSchema,
privilegeImportedPrivileges,
privilegeModify,
Expand All @@ -28,7 +28,7 @@ var databaseGrantSchema = map[string]*schema.Schema{
Optional: true,
Description: "The privilege to grant on the database.",
Default: "USAGE",
ValidateFunc: validation.StringInSlice(ValidDatabasePrivileges.toList(), true),
ValidateFunc: validation.StringInSlice(validDatabasePrivileges.ToList(), true),
ForceNew: true,
},
"roles": {
Expand All @@ -55,16 +55,19 @@ var databaseGrantSchema = map[string]*schema.Schema{
}

// DatabaseGrant returns a pointer to the resource representing a database grant
func DatabaseGrant() *schema.Resource {
return &schema.Resource{
Create: CreateDatabaseGrant,
Read: ReadDatabaseGrant,
Delete: DeleteDatabaseGrant,
func DatabaseGrant() *TerraformGrantResource {
return &TerraformGrantResource{
Resource: &schema.Resource{
Create: CreateDatabaseGrant,
Read: ReadDatabaseGrant,
Delete: DeleteDatabaseGrant,

Schema: databaseGrantSchema,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
Schema: databaseGrantSchema,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
},
ValidPrivs: validDatabasePrivileges,
}
}

Expand Down Expand Up @@ -120,7 +123,7 @@ func ReadDatabaseGrant(d *schema.ResourceData, meta interface{}) error {
}

builder := snowflake.DatabaseGrant(grantID.ResourceName)
return readGenericGrant(d, meta, databaseGrantSchema, builder, false, ValidDatabasePrivileges)
return readGenericGrant(d, meta, databaseGrantSchema, builder, false, validDatabasePrivileges)
}

// DeleteDatabaseGrant implements schema.DeleteFunc
Expand Down
4 changes: 2 additions & 2 deletions pkg/resources/database_grant_test.go
Expand Up @@ -17,7 +17,7 @@ import (

func TestDatabaseGrant(t *testing.T) {
r := require.New(t)
err := resources.DatabaseGrant().InternalValidate(provider.Provider().Schema, true)
err := resources.DatabaseGrant().Resource.InternalValidate(provider.Provider().Schema, true)
r.NoError(err)
}

Expand All @@ -31,7 +31,7 @@ func TestDatabaseGrantCreate(t *testing.T) {
"shares": []interface{}{"test-share-1", "test-share-2"},
"with_grant_option": true,
}
d := schema.TestResourceDataRaw(t, resources.DatabaseGrant().Schema, in)
d := schema.TestResourceDataRaw(t, resources.DatabaseGrant().Resource.Schema, in)
r.NotNil(d)

WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) {
Expand Down
16 changes: 16 additions & 0 deletions pkg/resources/grant_helpers.go
Expand Up @@ -14,6 +14,22 @@ import (
"github.com/jmoiron/sqlx"
)

// TerraformGrantResource augments terraform's *schema.Resource with extra context
type TerraformGrantResource struct {
Resource *schema.Resource
ValidPrivs PrivilegeSet
}

type TerraformGrantResources map[string]*TerraformGrantResource

func (t TerraformGrantResources) GetTfSchemas() map[string]*schema.Resource {
out := map[string]*schema.Resource{}
for name, grant := range t {
out[name] = grant.Resource
}
return out
}

const (
grantIDDelimiter = '|'
)
Expand Down
16 changes: 8 additions & 8 deletions pkg/resources/helpers_test.go
Expand Up @@ -19,63 +19,63 @@ func database(t *testing.T, id string, params map[string]interface{}) *schema.Re

func databaseGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.DatabaseGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.DatabaseGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func schemaGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.SchemaGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.SchemaGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func stageGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.StageGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.StageGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func tableGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.TableGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.TableGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func viewGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.ViewGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.ViewGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func resourceMonitorGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.ResourceMonitorGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.ResourceMonitorGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func integrationGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.IntegrationGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.IntegrationGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
}

func accountGrant(t *testing.T, id string, params map[string]interface{}) *schema.ResourceData {
r := require.New(t)
d := schema.TestResourceDataRaw(t, resources.AccountGrant().Schema, params)
d := schema.TestResourceDataRaw(t, resources.AccountGrant().Resource.Schema, params)
r.NotNil(d)
d.SetId(id)
return d
Expand Down

0 comments on commit ffe977a

Please sign in to comment.