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

fix: schema name is optional for future function_grant #1485

Merged
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
4 changes: 2 additions & 2 deletions docs/resources/function_grant.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ resource "snowflake_function_grant" "grant" {
### Required

- `database_name` (String) The name of the database containing the current or future functions on which to grant privileges.
- `schema_name` (String) The name of the schema containing the current or future functions on which to grant privileges.
- `roles` (Set of String) Grants privilege to these roles.

### Optional

Expand All @@ -54,7 +54,7 @@ resource "snowflake_function_grant" "grant" {
- `on_future` (Boolean) When this is set to true and a schema_name is provided, apply this grant on all future functions in the given schema. When this is true and no schema_name is provided apply this grant on all future functions in the given database. The function_name, arguments, return_type, and shares fields must be unset in order to use on_future.
- `privilege` (String) The privilege to grant on the current or future function. Must be one of `USAGE` or `OWNERSHIP`.
- `return_type` (String) The return type of the function (must be present if function_name is present)
- `roles` (Set of String) Grants privilege to these roles.
- `schema_name` (String) The name of the schema containing the current or future functions on which to grant privileges.
- `shares` (Set of String) Grants privilege to these shares (only valid if on_future is false).
- `with_grant_option` (Boolean) When this is set to true, allows the recipient role to grant the privileges to other roles.

Expand Down
83 changes: 43 additions & 40 deletions pkg/resources/function_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ var validFunctionPrivileges = NewPrivilegeSet(
)

var functionGrantSchema = map[string]*schema.Schema{
"function_name": {
Type: schema.TypeString,
Optional: true,
Description: "The name of the function on which to grant privileges immediately (only valid if on_future is false).",
ForceNew: true,
},
"arguments": {
Type: schema.TypeList,
Elem: &schema.Resource{
Expand All @@ -41,16 +35,17 @@ var functionGrantSchema = map[string]*schema.Schema{
Description: "List of the arguments for the function (must be present if function has arguments and function_name is present)",
ForceNew: true,
},
"return_type": {
Type: schema.TypeString,
"enable_multiple_grants": {
Type: schema.TypeBool,
Optional: true,
Description: "The return type of the function (must be present if function_name is present)",
Description: "When this is set to true, multiple grants of the same type can be created. This will cause Terraform to not revoke grants applied to roles and objects outside Terraform.",
Default: false,
ForceNew: true,
},
"schema_name": {
"function_name": {
Type: schema.TypeString,
Required: true,
Description: "The name of the schema containing the current or future functions on which to grant privileges.",
Optional: true,
Description: "The name of the function on which to grant privileges immediately (only valid if on_future is false).",
ForceNew: true,
},
"database_name": {
Expand All @@ -59,6 +54,13 @@ var functionGrantSchema = map[string]*schema.Schema{
Description: "The name of the database containing the current or future functions on which to grant privileges.",
ForceNew: true,
},
"on_future": {
Type: schema.TypeBool,
Optional: true,
Description: "When this is set to true and a schema_name is provided, apply this grant on all future functions in the given schema. When this is true and no schema_name is provided apply this grant on all future functions in the given database. The function_name, arguments, return_type, and shares fields must be unset in order to use on_future.",
Default: false,
ForceNew: true,
},
"privilege": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -67,39 +69,37 @@ var functionGrantSchema = map[string]*schema.Schema{
ValidateFunc: validation.StringInSlice(validFunctionPrivileges.ToList(), true),
ForceNew: true,
},
"return_type": {
Type: schema.TypeString,
Optional: true,
Description: "The return type of the function (must be present if function_name is present)",
ForceNew: true,
},
"roles": {
Type: schema.TypeSet,
Required: true,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "Grants privilege to these roles.",
},
"schema_name": {
Type: schema.TypeString,
Optional: true,
Description: "The name of the schema containing the current or future functions on which to grant privileges.",
ForceNew: true,
},
"shares": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "Grants privilege to these shares (only valid if on_future is false).",
},
"on_future": {
Type: schema.TypeBool,
Optional: true,
Description: "When this is set to true and a schema_name is provided, apply this grant on all future functions in the given schema. When this is true and no schema_name is provided apply this grant on all future functions in the given database. The function_name, arguments, return_type, and shares fields must be unset in order to use on_future.",
Default: false,
ForceNew: true,
},
"with_grant_option": {
Type: schema.TypeBool,
Optional: true,
Description: "When this is set to true, allows the recipient role to grant the privileges to other roles.",
Default: false,
ForceNew: true,
},
"enable_multiple_grants": {
Type: schema.TypeBool,
Optional: true,
Description: "When this is set to true, multiple grants of the same type can be created. This will cause Terraform to not revoke grants applied to roles and objects outside Terraform.",
Default: false,
ForceNew: true,
},
}

// FunctionGrant returns a pointer to the resource representing a function grant.
Expand Down Expand Up @@ -140,17 +140,20 @@ func CreateFunctionGrant(d *schema.ResourceData, meta interface{}) error {
dbName := d.Get("database_name").(string)
schemaName := d.Get("schema_name").(string)
priv := d.Get("privilege").(string)
futureFunctions := d.Get("on_future").(bool)
onFuture := d.Get("on_future").(bool)
grantOption := d.Get("with_grant_option").(bool)
arguments = d.Get("arguments").([]interface{})
roles := expandStringList(d.Get("roles").(*schema.Set).List())

if (functionName == "") && !futureFunctions {
if (functionName == "") && !onFuture {
return errors.New("function_name must be set unless on_future is true")
}
if (functionName != "") && futureFunctions {
if (functionName != "") && onFuture {
return errors.New("function_name must be empty if on_future is true")
}
if (schemaName == "") && !onFuture {
return errors.New("schema_name must be set unless on_future is true")
}

if functionName != "" {
functionSignature, _, argumentTypes = formatCallableObjectName(functionName, returnType, arguments)
Expand All @@ -159,7 +162,7 @@ func CreateFunctionGrant(d *schema.ResourceData, meta interface{}) error {
}

var builder snowflake.GrantBuilder
if futureFunctions {
if onFuture {
builder = snowflake.FutureFunctionGrant(dbName, schemaName)
} else {
builder = snowflake.FunctionGrant(dbName, schemaName, functionName, argumentTypes)
Expand Down Expand Up @@ -209,9 +212,9 @@ func ReadFunctionGrant(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("schema_name", schemaName); err != nil {
return err
}
futureFunctionsEnabled := false
onFuture := false
if functionSignature == "" {
futureFunctionsEnabled = true
onFuture = true
} else {
functionSignatureMap, err := parseCallableObjectName(functionSignature)
if err != nil {
Expand All @@ -231,7 +234,7 @@ func ReadFunctionGrant(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("return_type", returnType); err != nil {
return err
}
if err := d.Set("on_future", futureFunctionsEnabled); err != nil {
if err := d.Set("on_future", onFuture); err != nil {
return err
}
if err := d.Set("privilege", priv); err != nil {
Expand All @@ -242,13 +245,13 @@ func ReadFunctionGrant(d *schema.ResourceData, meta interface{}) error {
}

var builder snowflake.GrantBuilder
if futureFunctionsEnabled {
if onFuture {
builder = snowflake.FutureFunctionGrant(dbName, schemaName)
} else {
builder = snowflake.FunctionGrant(dbName, schemaName, functionName, argumentTypes)
}

return readGenericGrant(d, meta, functionGrantSchema, builder, futureFunctionsEnabled, validFunctionPrivileges)
return readGenericGrant(d, meta, functionGrantSchema, builder, onFuture, validFunctionPrivileges)
}

// DeleteFunctionGrant implements schema.DeleteFunc.
Expand All @@ -260,10 +263,10 @@ func DeleteFunctionGrant(d *schema.ResourceData, meta interface{}) error {
dbName := grantID.ResourceName
schemaName := grantID.SchemaName

futureFunctions := (grantID.ObjectName == "")
onFuture := (grantID.ObjectName == "")

var builder snowflake.GrantBuilder
if futureFunctions {
if onFuture {
builder = snowflake.FutureFunctionGrant(dbName, schemaName)
} else {
functionSignatureMap, err := parseCallableObjectName(grantID.ObjectName)
Expand Down Expand Up @@ -303,11 +306,11 @@ func UpdateFunctionGrant(d *schema.ResourceData, meta interface{}) error {
dbName := grantID.ResourceName
schemaName := grantID.SchemaName
functionName := grantID.ObjectName
futureFunctions := (functionName == "")
onFuture := (functionName == "")

// create the builder
var builder snowflake.GrantBuilder
if futureFunctions {
if onFuture {
builder = snowflake.FutureFunctionGrant(dbName, schemaName)
} else {
functionSignatureMap, err := parseCallableObjectName(grantID.ObjectName)
Expand Down