diff --git a/docs/index.md b/docs/index.md index b6f2e40be0..b40f88bb5b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -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 diff --git a/docs/resources/account_grant.md b/docs/resources/account_grant.md index 6b9c0e0158..ef636fc0fe 100644 --- a/docs/resources/account_grant.md +++ b/docs/resources/account_grant.md @@ -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. diff --git a/go.mod b/go.mod index 8c650f0698..d8e3e4efc5 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index f4476ed2c3..0fb1d1f258 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 0629d6322a..004fa5943a 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -67,35 +67,7 @@ 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(), }, @@ -103,6 +75,49 @@ func Provider() *schema.Provider { } } +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) diff --git a/pkg/provider/provider_helper.go b/pkg/provider/provider_helper.go new file mode 100644 index 0000000000..2c69d7f823 --- /dev/null +++ b/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 +} diff --git a/pkg/resources/account_grant.go b/pkg/resources/account_grant.go index a433d85d5e..4242bdad5a 100644 --- a/pkg/resources/account_grant.go +++ b/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( @@ -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": { @@ -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, } } diff --git a/pkg/resources/account_grant_test.go b/pkg/resources/account_grant_test.go index 6d63bb77e1..9931283b1f 100644 --- a/pkg/resources/account_grant_test.go +++ b/pkg/resources/account_grant_test.go @@ -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) } @@ -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) { diff --git a/pkg/resources/database_grant.go b/pkg/resources/database_grant.go index 0f117a5e7f..c9278b1407 100644 --- a/pkg/resources/database_grant.go +++ b/pkg/resources/database_grant.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) -var ValidDatabasePrivileges = NewPrivilegeSet( +var validDatabasePrivileges = NewPrivilegeSet( privilegeCreateSchema, privilegeImportedPrivileges, privilegeModify, @@ -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": { @@ -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, } } @@ -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 diff --git a/pkg/resources/database_grant_test.go b/pkg/resources/database_grant_test.go index 4bad5e55fe..f5316514f8 100644 --- a/pkg/resources/database_grant_test.go +++ b/pkg/resources/database_grant_test.go @@ -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) } @@ -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) { diff --git a/pkg/resources/grant_helpers.go b/pkg/resources/grant_helpers.go index c8b2aa0bda..526d4837c1 100644 --- a/pkg/resources/grant_helpers.go +++ b/pkg/resources/grant_helpers.go @@ -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 = '|' ) diff --git a/pkg/resources/helpers_test.go b/pkg/resources/helpers_test.go index 9fd496c186..fbf58375ba 100644 --- a/pkg/resources/helpers_test.go +++ b/pkg/resources/helpers_test.go @@ -19,7 +19,7 @@ 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 @@ -27,7 +27,7 @@ func databaseGrant(t *testing.T, id string, params map[string]interface{}) *sche 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 @@ -35,7 +35,7 @@ func schemaGrant(t *testing.T, id string, params map[string]interface{}) *schema 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 @@ -43,7 +43,7 @@ func stageGrant(t *testing.T, id string, params map[string]interface{}) *schema. 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 @@ -51,7 +51,7 @@ func tableGrant(t *testing.T, id string, params map[string]interface{}) *schema. 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 @@ -59,7 +59,7 @@ func viewGrant(t *testing.T, id string, params map[string]interface{}) *schema.R 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 @@ -67,7 +67,7 @@ func resourceMonitorGrant(t *testing.T, id string, params map[string]interface{} 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 @@ -75,7 +75,7 @@ func integrationGrant(t *testing.T, id string, params map[string]interface{}) *s 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 diff --git a/pkg/resources/integration_grant.go b/pkg/resources/integration_grant.go index e299626cf8..6438bc2db5 100644 --- a/pkg/resources/integration_grant.go +++ b/pkg/resources/integration_grant.go @@ -22,7 +22,7 @@ var integrationGrantSchema = map[string]*schema.Schema{ Optional: true, Description: "The privilege to grant on the integration.", Default: "USAGE", - ValidateFunc: validation.StringInSlice(validIntegrationPrivileges.toList(), true), + ValidateFunc: validation.StringInSlice(validIntegrationPrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -42,13 +42,16 @@ var integrationGrantSchema = map[string]*schema.Schema{ } // IntegrationGrant returns a pointer to the resource representing a integration grant -func IntegrationGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateIntegrationGrant, - Read: ReadIntegrationGrant, - Delete: DeleteIntegrationGrant, +func IntegrationGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateIntegrationGrant, + Read: ReadIntegrationGrant, + Delete: DeleteIntegrationGrant, - Schema: integrationGrantSchema, + Schema: integrationGrantSchema, + }, + ValidPrivs: validIntegrationPrivileges, } } diff --git a/pkg/resources/integration_grant_test.go b/pkg/resources/integration_grant_test.go index 9952927627..2e74f29c2b 100644 --- a/pkg/resources/integration_grant_test.go +++ b/pkg/resources/integration_grant_test.go @@ -17,7 +17,7 @@ import ( func TestIntegrationGrant(t *testing.T) { r := require.New(t) - err := resources.IntegrationGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.IntegrationGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -30,7 +30,7 @@ func TestIntegrationGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.IntegrationGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.IntegrationGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { diff --git a/pkg/resources/privileges.go b/pkg/resources/privileges.go index a156ef0b7c..f670d5ac8c 100644 --- a/pkg/resources/privileges.go +++ b/pkg/resources/privileges.go @@ -59,7 +59,7 @@ func NewPrivilegeSet(privileges ...Privilege) PrivilegeSet { return ps } -func (ps PrivilegeSet) toList() []string { +func (ps PrivilegeSet) ToList() []string { privs := []string{} for p := range ps { privs = append(privs, string(p)) diff --git a/pkg/resources/resource_monitor_grant.go b/pkg/resources/resource_monitor_grant.go index 117e749f43..2de898708a 100644 --- a/pkg/resources/resource_monitor_grant.go +++ b/pkg/resources/resource_monitor_grant.go @@ -23,7 +23,7 @@ var resourceMonitorGrantSchema = map[string]*schema.Schema{ Optional: true, Description: "The privilege to grant on the resource monitor.", Default: "MONITOR", - ValidateFunc: validation.StringInSlice(validResourceMonitorPrivileges.toList(), true), + ValidateFunc: validation.StringInSlice(validResourceMonitorPrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -43,13 +43,16 @@ var resourceMonitorGrantSchema = map[string]*schema.Schema{ } // ResourceMonitorGrant returns a pointer to the resource representing a resource monitor grant -func ResourceMonitorGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateResourceMonitorGrant, - Read: ReadResourceMonitorGrant, - Delete: DeleteResourceMonitorGrant, +func ResourceMonitorGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateResourceMonitorGrant, + Read: ReadResourceMonitorGrant, + Delete: DeleteResourceMonitorGrant, - Schema: resourceMonitorGrantSchema, + Schema: resourceMonitorGrantSchema, + }, + ValidPrivs: validResourceMonitorPrivileges, } } diff --git a/pkg/resources/resource_monitor_grant_test.go b/pkg/resources/resource_monitor_grant_test.go index d5c654c69a..b6096f0efa 100644 --- a/pkg/resources/resource_monitor_grant_test.go +++ b/pkg/resources/resource_monitor_grant_test.go @@ -17,7 +17,7 @@ import ( func TestResourceMonitorGrant(t *testing.T) { r := require.New(t) - err := resources.ResourceMonitorGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.ResourceMonitorGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -30,7 +30,7 @@ func TestResourceMonitorGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.ResourceMonitorGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.ResourceMonitorGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { diff --git a/pkg/resources/schema_grant.go b/pkg/resources/schema_grant.go index b8b74e83cd..18b25809bb 100644 --- a/pkg/resources/schema_grant.go +++ b/pkg/resources/schema_grant.go @@ -47,7 +47,7 @@ var schemaGrantSchema = map[string]*schema.Schema{ Optional: true, Description: "The privilege to grant on the current or future schema. Note that if \"OWNERSHIP\" is specified, ensure that the role that terraform is using is granted access.", Default: "USAGE", - ValidateFunc: validation.StringInSlice(validSchemaPrivileges.toList(), true), + ValidateFunc: validation.StringInSlice(validSchemaPrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -82,16 +82,19 @@ var schemaGrantSchema = map[string]*schema.Schema{ } // SchemaGrant returns a pointer to the resource representing a view grant -func SchemaGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateSchemaGrant, - Read: ReadSchemaGrant, - Delete: DeleteSchemaGrant, - - Schema: schemaGrantSchema, - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, +func SchemaGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateSchemaGrant, + Read: ReadSchemaGrant, + Delete: DeleteSchemaGrant, + + Schema: schemaGrantSchema, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, }, + ValidPrivs: validSchemaPrivileges, } } diff --git a/pkg/resources/schema_grant_test.go b/pkg/resources/schema_grant_test.go index 44bea64143..f4db690eb6 100644 --- a/pkg/resources/schema_grant_test.go +++ b/pkg/resources/schema_grant_test.go @@ -16,7 +16,7 @@ import ( func TestSchemaGrant(t *testing.T) { r := require.New(t) - err := resources.SchemaGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.SchemaGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -32,7 +32,7 @@ func TestSchemaGrantCreate(t *testing.T) { "shares": []interface{}{"test-share-1", "test-share-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.SchemaGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.SchemaGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { @@ -110,7 +110,7 @@ func TestFutureSchemaGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.SchemaGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.SchemaGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { diff --git a/pkg/resources/stage_grant.go b/pkg/resources/stage_grant.go index 973dd0a4f3..fcdb517cde 100644 --- a/pkg/resources/stage_grant.go +++ b/pkg/resources/stage_grant.go @@ -7,7 +7,7 @@ import ( "github.com/chanzuckerberg/terraform-provider-snowflake/pkg/snowflake" ) -var ValidStagePrivileges = NewPrivilegeSet( +var validStagePrivileges = NewPrivilegeSet( privilegeOwnership, privilegeUsage, // These privileges are only valid for internal stages @@ -39,7 +39,7 @@ var stageGrantSchema = map[string]*schema.Schema{ Optional: true, Description: "The privilege to grant on the stage.", Default: "USAGE", - ValidateFunc: validation.StringInSlice(ValidStagePrivileges.toList(), true), + ValidateFunc: validation.StringInSlice(validStagePrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -66,16 +66,19 @@ var stageGrantSchema = map[string]*schema.Schema{ } // StageGrant returns a pointer to the resource representing a stage grant -func StageGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateStageGrant, - Read: ReadStageGrant, - Delete: DeleteStageGrant, - - Schema: stageGrantSchema, - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, +func StageGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateStageGrant, + Read: ReadStageGrant, + Delete: DeleteStageGrant, + + Schema: stageGrantSchema, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, }, + ValidPrivs: validStagePrivileges, } } @@ -148,7 +151,7 @@ func ReadStageGrant(d *schema.ResourceData, meta interface{}) error { } builder := snowflake.StageGrant(dbName, schemaName, stageName) - return readGenericGrant(d, meta, stageGrantSchema, builder, false, ValidStagePrivileges) + return readGenericGrant(d, meta, stageGrantSchema, builder, false, validStagePrivileges) } // DeleteStageGrant implements schema.DeleteFunc diff --git a/pkg/resources/stage_grant_test.go b/pkg/resources/stage_grant_test.go index 37efe015ff..21015f8f71 100644 --- a/pkg/resources/stage_grant_test.go +++ b/pkg/resources/stage_grant_test.go @@ -16,7 +16,7 @@ import ( func TestStageGrant(t *testing.T) { r := require.New(t) - err := resources.StageGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.StageGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -33,7 +33,7 @@ func TestStageGrantCreate(t *testing.T) { "shares": []interface{}{"test-share-1", "test-share-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.StageGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.StageGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { diff --git a/pkg/resources/table_grant.go b/pkg/resources/table_grant.go index cc52f375a9..138827026d 100644 --- a/pkg/resources/table_grant.go +++ b/pkg/resources/table_grant.go @@ -40,8 +40,8 @@ var tableGrantSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, Description: "The privilege to grant on the current or future table.", - Default: "SELECT", - ValidateFunc: validation.StringInSlice(validTablePrivileges.toList(), true), + Default: privilegeSelect.String(), + ValidateFunc: validation.StringInSlice(validTablePrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -76,16 +76,19 @@ var tableGrantSchema = map[string]*schema.Schema{ } // TableGrant returns a pointer to the resource representing a Table grant -func TableGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateTableGrant, - Read: ReadTableGrant, - Delete: DeleteTableGrant, - - Schema: tableGrantSchema, - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, +func TableGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateTableGrant, + Read: ReadTableGrant, + Delete: DeleteTableGrant, + + Schema: tableGrantSchema, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, }, + ValidPrivs: validTablePrivileges, } } diff --git a/pkg/resources/table_grant_test.go b/pkg/resources/table_grant_test.go index 0ec2128016..39af8a7b13 100644 --- a/pkg/resources/table_grant_test.go +++ b/pkg/resources/table_grant_test.go @@ -17,7 +17,7 @@ import ( func TestTableGrant(t *testing.T) { r := require.New(t) - err := resources.TableGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.TableGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -33,7 +33,7 @@ func TestTableGrantCreate(t *testing.T) { "shares": []interface{}{"test-share-1", "test-share-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.TableGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.TableGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { @@ -104,7 +104,7 @@ func TestFutureTableGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.TableGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.TableGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { @@ -135,7 +135,7 @@ func TestFutureTableGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": false, } - d = schema.TestResourceDataRaw(t, resources.TableGrant().Schema, in) + d = schema.TestResourceDataRaw(t, resources.TableGrant().Resource.Schema, in) b.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { diff --git a/pkg/resources/view_grant.go b/pkg/resources/view_grant.go index adb57e559f..504dd6f2d1 100644 --- a/pkg/resources/view_grant.go +++ b/pkg/resources/view_grant.go @@ -8,7 +8,7 @@ import ( "github.com/chanzuckerberg/terraform-provider-snowflake/pkg/snowflake" ) -var ValidViewPrivileges = NewPrivilegeSet( +var validViewPrivileges = NewPrivilegeSet( privilegeSelect, ) @@ -35,8 +35,8 @@ var viewGrantSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, Description: "The privilege to grant on the current or future view.", - Default: "SELECT", - ValidateFunc: validation.StringInSlice(ValidViewPrivileges.toList(), true), + Default: privilegeSelect.String(), + ValidateFunc: validation.StringInSlice(validViewPrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -71,16 +71,19 @@ var viewGrantSchema = map[string]*schema.Schema{ } // ViewGrant returns a pointer to the resource representing a view grant -func ViewGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateViewGrant, - Read: ReadViewGrant, - Delete: DeleteViewGrant, - - Schema: viewGrantSchema, - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, +func ViewGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateViewGrant, + Read: ReadViewGrant, + Delete: DeleteViewGrant, + + Schema: viewGrantSchema, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, }, + ValidPrivs: validViewPrivileges, } } @@ -191,7 +194,7 @@ func ReadViewGrant(d *schema.ResourceData, meta interface{}) error { builder = snowflake.ViewGrant(dbName, schemaName, viewName) } - return readGenericGrant(d, meta, viewGrantSchema, builder, futureViewsEnabled, ValidViewPrivileges) + return readGenericGrant(d, meta, viewGrantSchema, builder, futureViewsEnabled, validViewPrivileges) } // DeleteViewGrant implements schema.DeleteFunc diff --git a/pkg/resources/view_grant_test.go b/pkg/resources/view_grant_test.go index b53e96d818..7f35e79254 100644 --- a/pkg/resources/view_grant_test.go +++ b/pkg/resources/view_grant_test.go @@ -15,7 +15,7 @@ import ( func TestViewGrant(t *testing.T) { r := require.New(t) - err := resources.ViewGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.ViewGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -31,7 +31,7 @@ func TestViewGrantCreate(t *testing.T) { "shares": []interface{}{"test-share-1", "test-share-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.ViewGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.ViewGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { @@ -103,7 +103,7 @@ func TestFutureViewGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": true, } - d := schema.TestResourceDataRaw(t, resources.ViewGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.ViewGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { @@ -135,7 +135,7 @@ func TestFutureViewGrantCreate(t *testing.T) { "roles": []interface{}{"test-role-1", "test-role-2"}, "with_grant_option": false, } - d = schema.TestResourceDataRaw(t, resources.ViewGrant().Schema, in) + d = schema.TestResourceDataRaw(t, resources.ViewGrant().Resource.Schema, in) b.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { diff --git a/pkg/resources/warehouse_grant.go b/pkg/resources/warehouse_grant.go index dba5957f04..721ec934bc 100644 --- a/pkg/resources/warehouse_grant.go +++ b/pkg/resources/warehouse_grant.go @@ -24,8 +24,8 @@ var warehouseGrantSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, Description: "The privilege to grant on the warehouse.", - Default: "USAGE", - ValidateFunc: validation.StringInSlice(validWarehousePrivileges.toList(), true), + Default: privilegeUsage.String(), + ValidateFunc: validation.StringInSlice(validWarehousePrivileges.ToList(), true), ForceNew: true, }, "roles": { @@ -45,17 +45,20 @@ var warehouseGrantSchema = map[string]*schema.Schema{ } // WarehouseGrant returns a pointer to the resource representing a warehouse grant -func WarehouseGrant() *schema.Resource { - return &schema.Resource{ - Create: CreateWarehouseGrant, - Read: ReadWarehouseGrant, - Delete: DeleteWarehouseGrant, +func WarehouseGrant() *TerraformGrantResource { + return &TerraformGrantResource{ + Resource: &schema.Resource{ + Create: CreateWarehouseGrant, + Read: ReadWarehouseGrant, + Delete: DeleteWarehouseGrant, - Schema: warehouseGrantSchema, - // FIXME - tests for this don't currently work - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, + Schema: warehouseGrantSchema, + // FIXME - tests for this don't currently work + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, }, + ValidPrivs: validWarehousePrivileges, } } diff --git a/pkg/resources/warehouse_grant_test.go b/pkg/resources/warehouse_grant_test.go index fa6b866b4e..fc7a7c4a68 100644 --- a/pkg/resources/warehouse_grant_test.go +++ b/pkg/resources/warehouse_grant_test.go @@ -6,18 +6,16 @@ import ( "time" sqlmock "github.com/DATA-DOG/go-sqlmock" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/chanzuckerberg/terraform-provider-snowflake/pkg/provider" "github.com/chanzuckerberg/terraform-provider-snowflake/pkg/resources" . "github.com/chanzuckerberg/terraform-provider-snowflake/pkg/testhelpers" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/stretchr/testify/require" ) func TestWarehouseGrant(t *testing.T) { r := require.New(t) - err := resources.WarehouseGrant().InternalValidate(provider.Provider().Schema, true) + err := resources.WarehouseGrant().Resource.InternalValidate(provider.Provider().Schema, true) r.NoError(err) } @@ -29,7 +27,7 @@ func TestWarehouseGrantCreate(t *testing.T) { "privilege": "USAGE", "roles": []interface{}{"test-role-1", "test-role-2"}, } - d := schema.TestResourceDataRaw(t, resources.WarehouseGrant().Schema, in) + d := schema.TestResourceDataRaw(t, resources.WarehouseGrant().Resource.Schema, in) r.NotNil(d) WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) {