Skip to content

Commit

Permalink
[feature] future grants (#151)
Browse files Browse the repository at this point in the history
Attempt to add more `on_future` functionality recently added to snowflake:

## Additions

- Ability to add future grants on schemas in a database

## Changes

- Ability to add future grants on tables/views in a database
  • Loading branch information
henriblancke committed Apr 3, 2020
1 parent 54e1451 commit 174b215
Show file tree
Hide file tree
Showing 10 changed files with 350 additions and 73 deletions.
51 changes: 26 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,14 @@ These resources do not enforce exclusive attachment of a grant, it is the user's

#### properties

| NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT |
|---------------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|---------|
| database_name | string | The name of the database containing the schema on which to grant privileges. | false | true | false | <nil> |
| privilege | string | The privilege to grant on the schema. Note that if "OWNERSHIP" is specified, ensure that the role that terraform is using is granted access. | true | false | false | "USAGE" |
| roles | set | Grants privilege to these roles. | true | false | false | <nil> |
| schema_name | string | The name of the schema on which to grant privileges. | false | true | false | <nil> |
| shares | set | Grants privilege to these shares. | true | false | false | <nil> |
| NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT |
|---------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|---------|
| database_name | string | The name of the database containing the schema on which to grant privileges. | false | true | false | <nil> |
| on_future | bool | When this is set to true, apply this grant on all future schemas in the given database. The schema_name and shares fields must be unset in order to use on_future. | true | false | false | false |
| privilege | string | 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. | true | false | false | "USAGE" |
| roles | set | Grants privilege to these roles. | true | false | false | <nil> |
| schema_name | string | The name of the schema on which to grant privileges. | true | false | false | <nil> |
| shares | set | Grants privilege to these shares (only valid if on_future is unset). | true | false | false | <nil> |

### snowflake_share

Expand Down Expand Up @@ -318,15 +319,15 @@ These resources do not enforce exclusive attachment of a grant, it is the user's

#### properties

| NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT |
|---------------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|----------|
| database_name | string | The name of the database containing the current or future tables on which to grant privileges. | false | true | false | <nil> |
| on_future | bool | When this is set to true, apply this grant on all future tables in the given schema. The table_name and shares fields must be unset in order to use on_future. | true | false | false | false |
| privilege | string | The privilege to grant on the current or future table. | true | false | false | "SELECT" |
| roles | set | Grants privilege to these roles. | true | false | false | <nil> |
| schema_name | string | The name of the schema containing the current or future tables on which to grant privileges. | true | false | false | "PUBLIC" |
| shares | set | Grants privilege to these shares (only valid if on_future is unset). | true | false | false | <nil> |
| table_name | string | The name of the table on which to grant privileges immediately (only valid if on_future is unset). | true | false | false | <nil> |
| NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT |
|---------------|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|----------|
| database_name | string | The name of the database containing the current or future tables on which to grant privileges. | false | true | false | <nil> |
| on_future | bool | When this is set to true and a schema_name is provided, apply this grant on all future tables in the given schema. When this is true and no schema_name is provided apply this grant on all future tables in the given database. The table_name and shares fields must be unset in order to use on_future. | true | false | false | false |
| privilege | string | The privilege to grant on the current or future table. | true | false | false | "SELECT" |
| roles | set | Grants privilege to these roles. | true | false | false | <nil> |
| schema_name | string | The name of the schema containing the current or future tables on which to grant privileges. | true | false | false | <nil> |
| shares | set | Grants privilege to these shares (only valid if on_future is unset). | true | false | false | <nil> |
| table_name | string | The name of the table on which to grant privileges immediately (only valid if on_future is unset). | true | false | false | <nil> |

### snowflake_user

Expand Down Expand Up @@ -370,15 +371,15 @@ These resources do not enforce exclusive attachment of a grant, it is the user's

#### properties

| NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT |
|---------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|----------|
| database_name | string | The name of the database containing the current or future views on which to grant privileges. | false | true | false | <nil> |
| on_future | bool | When this is set to true, apply this grant on all future views in the given schema. The view_name and shares fields must be unset in order to use on_future. | true | false | false | false |
| privilege | string | The privilege to grant on the current or future view. | true | false | false | "SELECT" |
| roles | set | Grants privilege to these roles. | true | false | false | <nil> |
| schema_name | string | The name of the schema containing the current or future views on which to grant privileges. | true | false | false | "PUBLIC" |
| shares | set | Grants privilege to these shares (only valid if on_future is unset). | true | false | false | <nil> |
| view_name | string | The name of the view on which to grant privileges immediately (only valid if on_future is unset). | true | false | false | <nil> |
| NAME | TYPE | DESCRIPTION | OPTIONAL | REQUIRED | COMPUTED | DEFAULT |
|---------------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-----------|----------|----------|
| database_name | string | The name of the database containing the current or future views on which to grant privileges. | false | true | false | <nil> |
| on_future | bool | When this is set to true and a schema_name is provided, apply this grant on all future views in the given schema. When this is true and no schema_name is provided apply this grant on all future views in the given database. The view_name and shares fields must be unset in order to use on_future. | true | false | false | false |
| privilege | string | The privilege to grant on the current or future view. | true | false | false | "SELECT" |
| roles | set | Grants privilege to these roles. | true | false | false | <nil> |
| schema_name | string | The name of the schema containing the current or future views on which to grant privileges. | true | false | false | <nil> |
| shares | set | Grants privilege to these shares (only valid if on_future is unset). | true | false | false | <nil> |
| view_name | string | The name of the view on which to grant privileges immediately (only valid if on_future is unset). | true | false | false | <nil> |

### snowflake_warehouse

Expand Down
75 changes: 63 additions & 12 deletions pkg/resources/schema_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resources
import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/pkg/errors"

"github.com/chanzuckerberg/terraform-provider-snowflake/pkg/snowflake"
)
Expand Down Expand Up @@ -33,7 +34,7 @@ var validSchemaPrivileges = newPrivilegeSet(
var schemaGrantSchema = map[string]*schema.Schema{
"schema_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
Optional: true,
Description: "The name of the schema on which to grant privileges.",
ForceNew: true,
},
Expand All @@ -46,7 +47,7 @@ var schemaGrantSchema = map[string]*schema.Schema{
"privilege": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "The privilege to grant on the schema. Note that if \"OWNERSHIP\" is specified, ensure that the role that terraform is using is granted access.",
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),
ForceNew: true,
Expand All @@ -62,12 +63,20 @@ var schemaGrantSchema = map[string]*schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "Grants privilege to these shares.",
Description: "Grants privilege to these shares (only valid if on_future is unset).",
ForceNew: true,
},
"on_future": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Description: "When this is set to true, apply this grant on all future schemas in the given database. The schema_name and shares fields must be unset in order to use on_future.",
Default: false,
ForceNew: true,
ConflictsWith: []string{"schema_name", "shares"},
},
}

// ViewGrant returns a pointer to the resource representing a view grant
// SchemaGrant returns a pointer to the resource representing a view grant
func SchemaGrant() *schema.Resource {
return &schema.Resource{
Create: CreateSchemaGrant,
Expand All @@ -83,10 +92,26 @@ func SchemaGrant() *schema.Resource {

// CreateSchemaGrant implements schema.CreateFunc
func CreateSchemaGrant(data *schema.ResourceData, meta interface{}) error {
schema := data.Get("schema_name").(string)
var schema string
if _, ok := data.GetOk("schema_name"); ok {
schema = data.Get("schema_name").(string)
} else {
schema = ""
}
db := data.Get("database_name").(string)
priv := data.Get("privilege").(string)
builder := snowflake.SchemaGrant(db, schema)
onFuture := data.Get("on_future").(bool)

if (schema == "") && !onFuture {
return errors.New("schema_name must be set unless on_future is true.")
}

var builder snowflake.GrantBuilder
if onFuture {
builder = snowflake.FutureSchemaGrant(db)
} else {
builder = snowflake.SchemaGrant(db, schema)
}

err := createGenericGrant(data, meta, builder)
if err != nil {
Expand All @@ -113,11 +138,22 @@ func ReadSchemaGrant(data *schema.ResourceData, meta interface{}) error {
if err != nil {
return err
}
err = data.Set("database_name", grantID.ResourceName)

dbName := grantID.ResourceName
schemaName := grantID.SchemaName
err = data.Set("database_name", dbName)
if err != nil {
return err
}
err = data.Set("schema_name", grantID.SchemaName)
err = data.Set("schema_name", schemaName)
if err != nil {
return err
}
onFuture := false
if schemaName == "" {
onFuture = true
}
err = data.Set("on_future", onFuture)
if err != nil {
return err
}
Expand All @@ -126,9 +162,13 @@ func ReadSchemaGrant(data *schema.ResourceData, meta interface{}) error {
return err
}

builder := snowflake.SchemaGrant(grantID.ResourceName, grantID.SchemaName)

return readGenericGrant(data, meta, builder, false, validSchemaPrivileges)
var builder snowflake.GrantBuilder
if onFuture {
builder = snowflake.FutureSchemaGrant(dbName)
} else {
builder = snowflake.SchemaGrant(dbName, schemaName)
}
return readGenericGrant(data, meta, builder, onFuture, validSchemaPrivileges)
}

// DeleteSchemaGrant implements schema.DeleteFunc
Expand All @@ -138,7 +178,18 @@ func DeleteSchemaGrant(data *schema.ResourceData, meta interface{}) error {
return err
}

builder := snowflake.SchemaGrant(grantID.ResourceName, grantID.SchemaName)
dbName := grantID.ResourceName
schemaName := grantID.SchemaName
onFuture := false
if schemaName == "" {
onFuture = true
}

var builder snowflake.GrantBuilder
if onFuture {
builder = snowflake.FutureSchemaGrant(dbName)
} else {
builder = snowflake.SchemaGrant(dbName, schemaName)
}
return deleteGenericGrant(data, meta, builder)
}

0 comments on commit 174b215

Please sign in to comment.