Skip to content

Commit

Permalink
feat: add on_account to session and object params (#1685)
Browse files Browse the repository at this point in the history
* add on_account to session and object params

* add on_account to session and object params

* fix parameters data source acc tests

* refactor parameters to remove code duplication

* refactor parameters to remove code duplication
  • Loading branch information
sfc-gh-swinkler authored Apr 3, 2023
1 parent edc7fd6 commit 1329430
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 157 deletions.
2 changes: 2 additions & 0 deletions docs/data-sources/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ data "snowflake_parameters" "p2" {
data "snowflake_parameters" "p3" {
parameter_type = "SESSION"
pattern = "ROWS_PER_RESULTSET"
user = "TEST_USER"
}
```

Expand All @@ -46,6 +47,7 @@ data "snowflake_parameters" "p3" {
- `object_type` (String) If parameter_type is set to "OBJECT" then object_type is the type of object to display object parameters for. Valid values are any object supported by the IN clause of the [SHOW PARAMETERS](https://docs.snowflake.com/en/sql-reference/sql/show-parameters.html#parameters) statement, including: WAREHOUSE | DATABASE | SCHEMA | TASK | TABLE
- `parameter_type` (String) The type of parameter to filter by. Valid values are: "ACCOUNT", "SESSION", "OBJECT".
- `pattern` (String) Allows limiting the list of parameters by name using LIKE clause. Refer to [Limiting the List of Parameters by Name](https://docs.snowflake.com/en/sql-reference/parameters.html#limiting-the-list-of-parameters-by-name)
- `user` (String) If parameter_type is set to "SESSION" then user is the name of the user to display session parameters for.

### Read-Only

Expand Down
6 changes: 4 additions & 2 deletions docs/resources/object_parameter.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ resource "snowflake_object_parameter" "o3" {
// Setting object parameter at account level
resource "snowflake_object_parameter" "o4" {
key = "DATA_RETENTION_TIME_IN_DAYS"
value = "89"
key = "DATA_RETENTION_TIME_IN_DAYS"
value = "89"
on_account = true
}
```

Expand All @@ -81,6 +82,7 @@ resource "snowflake_object_parameter" "o4" {

- `object_identifier` (Block List) Specifies the object identifier for the object parameter. If no value is provided, then the resource will default to setting the object parameter at account level. (see [below for nested schema](#nestedblock--object_identifier))
- `object_type` (String) Type of object to which the parameter applies. Valid values are those in [object types](https://docs.snowflake.com/en/sql-reference/parameters.html#object-types). If no value is provided, then the resource will default to setting the object parameter at account level.
- `on_account` (Boolean) If true, the object parameter will be set on the account level.

### Read-Only

Expand Down
12 changes: 12 additions & 0 deletions docs/resources/session_parameter.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ description: |-
resource "snowflake_session_parameter" "s" {
key = "AUTOCOMMIT"
value = "false"
user = "TEST_USER"
}
resource "snowflake_session_parameter" "s2" {
key = "BINARY_OUTPUT_FORMAT"
value = "BASE64"
on_account = true
}
```

Expand All @@ -27,6 +34,11 @@ resource "snowflake_session_parameter" "s" {
- `key` (String) Name of session parameter. Valid values are those in [session parameters](https://docs.snowflake.com/en/sql-reference/parameters.html#session-parameters).
- `value` (String) Value of session parameter, as a string. Constraints are the same as those for the parameters in Snowflake documentation.

### Optional

- `on_account` (Boolean) If true, the session parameter will be set on the account level.
- `user` (String) The user to set the session parameter for. Required if on_account is false

### Read-Only

- `id` (String) The ID of this resource.
Expand Down
1 change: 1 addition & 0 deletions examples/data-sources/snowflake_parameters/data-source.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ data "snowflake_parameters" "p2" {
data "snowflake_parameters" "p3" {
parameter_type = "SESSION"
pattern = "ROWS_PER_RESULTSET"
user = "TEST_USER"
}
5 changes: 3 additions & 2 deletions examples/resources/snowflake_object_parameter/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ resource "snowflake_object_parameter" "o3" {

// Setting object parameter at account level
resource "snowflake_object_parameter" "o4" {
key = "DATA_RETENTION_TIME_IN_DAYS"
value = "89"
key = "DATA_RETENTION_TIME_IN_DAYS"
value = "89"
on_account = true
}
7 changes: 7 additions & 0 deletions examples/resources/snowflake_session_parameter/resource.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
resource "snowflake_session_parameter" "s" {
key = "AUTOCOMMIT"
value = "false"
user = "TEST_USER"
}

resource "snowflake_session_parameter" "s2" {
key = "BINARY_OUTPUT_FORMAT"
value = "BASE64"
on_account = true
}
47 changes: 20 additions & 27 deletions pkg/datasources/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package datasources
import (
"database/sql"
"errors"
"fmt"
"log"
"strings"

Expand All @@ -15,7 +16,7 @@ var parametersSchema = map[string]*schema.Schema{
"parameter_type": {
Type: schema.TypeString,
Optional: true,
Default: "SESSION",
Default: "ACCOUNT",
Description: "The type of parameter to filter by. Valid values are: \"ACCOUNT\", \"SESSION\", \"OBJECT\".",
ValidateFunc: validation.StringInSlice([]string{"ACCOUNT", "SESSION", "OBJECT"}, true),
},
Expand All @@ -24,6 +25,11 @@ var parametersSchema = map[string]*schema.Schema{
Optional: true,
Description: "Allows limiting the list of parameters by name using LIKE clause. Refer to [Limiting the List of Parameters by Name](https://docs.snowflake.com/en/sql-reference/parameters.html#limiting-the-list-of-parameters-by-name)",
},
"user": {
Type: schema.TypeString,
Optional: true,
Description: "If parameter_type is set to \"SESSION\" then user is the name of the user to display session parameters for.",
},
"object_type": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -90,37 +96,24 @@ func ReadParameters(d *schema.ResourceData, meta interface{}) error {
if ok {
pattern = p.(string)
}
var parameters []snowflake.Parameter
var err error
parameterType := snowflake.ParameterType(strings.ToUpper(d.Get("parameter_type").(string)))
if parameterType == snowflake.ParameterTypeObject {
switch parameterType {
case snowflake.ParameterTypeAccount:
parameters, err = snowflake.ListAccountParameters(db, pattern)
case snowflake.ParameterTypeSession:
user := d.Get("user").(string)
if user == "" {
return fmt.Errorf("user is required when parameter_type is set to SESSION")
}
parameters, err = snowflake.ListSessionParameters(db, pattern, user)
case snowflake.ParameterTypeObject:
oType := d.Get("object_type").(string)
objectType := snowflake.ObjectType(oType)
objectName := d.Get("object_name").(string)
parameters, err := snowflake.ListObjectParameters(db, objectType, objectName, pattern)
if errors.Is(err, sql.ErrNoRows) {
log.Printf("[DEBUG] parameters not found")
d.SetId("")
return nil
} else if err != nil {
log.Printf("[DEBUG] error occurred during read: %v", err.Error())
return err
}
d.SetId("parameters")
params := []map[string]interface{}{}
for _, param := range parameters {
paramMap := map[string]interface{}{}

paramMap["key"] = param.Key.String
paramMap["value"] = param.Value.String
paramMap["default"] = param.Default.String
paramMap["level"] = param.Level.String
paramMap["description"] = param.Description.String
paramMap["type"] = param.PType.String

params = append(params, paramMap)
}
return d.Set("parameters", params)
parameters, err = snowflake.ListObjectParameters(db, objectType, objectName, pattern)
}
parameters, err := snowflake.ListParameters(db, parameterType, pattern)
if errors.Is(err, sql.ErrNoRows) {
log.Printf("[DEBUG] parameters not found")
d.SetId("")
Expand Down
80 changes: 76 additions & 4 deletions pkg/datasources/parameters_acceptance_test.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,100 @@
package datasources_test

import (
"fmt"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAcc_Parameters(t *testing.T) {
func TestAcc_ParametersOnAccount(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: parameters(),
Config: parametersConfigOnAccount(),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.snowflake_parameters.p", "pattern", "AUTOCOMMIT"),
resource.TestCheckResourceAttr("data.snowflake_parameters.p", "parameters.#", "1"),
resource.TestCheckResourceAttr("data.snowflake_parameters.p", "parameters.0.key", "AUTOCOMMIT"),
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.0.value"),
),
},
},
})
}

func TestAcc_ParametersOnSession(t *testing.T) {
userName := "TEST_USER_" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: parametersConfigOnSession(userName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.#"),
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.0.key"),
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.0.value"),
resource.TestCheckResourceAttr("data.snowflake_parameters.p", "user", userName),
),
},
},
})
}

func parameters() string {
return `data "snowflake_parameters" "p" {}`
func TestAcc_ParametersOnObject(t *testing.T) {
dbName := "TEST_DB_" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: parametersConfigOnObject(dbName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.#"),
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.0.key"),
resource.TestCheckResourceAttrSet("data.snowflake_parameters.p", "parameters.0.value"),
resource.TestCheckResourceAttr("data.snowflake_parameters.p", "object_type", "DATABASE"),
resource.TestCheckResourceAttr("data.snowflake_parameters.p", "object_name", dbName),
),
},
},
})
}

func parametersConfigOnAccount() string {
return `data "snowflake_parameters" "p" {
parameter_type = "ACCOUNT"
pattern = "AUTOCOMMIT"
}`
}

func parametersConfigOnSession(user string) string {
s := `
resource "snowflake_user" "u" {
name = "%s"
}
data "snowflake_parameters" "p" {
parameter_type = "SESSION"
user = snowflake_user.u.name
}`
return fmt.Sprintf(s, user)
}

func parametersConfigOnObject(name string) string {
stmt := `
resource "snowflake_database" "d" {
name = "%s"
}
data "snowflake_parameters" "p" {
parameter_type = "OBJECT"
object_type = "DATABASE"
object_name = snowflake_database.d.name
}`
return fmt.Sprintf(stmt, name)
}
4 changes: 2 additions & 2 deletions pkg/resources/account_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func CreateAccountParameter(d *schema.ResourceData, meta interface{}) error {
value = fmt.Sprintf("'%s'", snowflake.EscapeString(value))
}

builder := snowflake.NewParameter(key, value, snowflake.ParameterTypeAccount, db)
builder := snowflake.NewAccountParameter(key, value, db)
err := builder.SetParameter()
if err != nil {
return fmt.Errorf("error creating account parameter err = %w", err)
Expand Down Expand Up @@ -111,7 +111,7 @@ func DeleteAccountParameter(d *schema.ResourceData, meta interface{}) error {
if reflect.TypeOf(parameterDefault.DefaultValue) == typeString {
value = fmt.Sprintf("'%s'", value)
}
builder := snowflake.NewParameter(key, value, snowflake.ParameterTypeAccount, db)
builder := snowflake.NewAccountParameter(key, value, db)
err := builder.SetParameter()
if err != nil {
return fmt.Errorf("error creating account parameter err = %w", err)
Expand Down
39 changes: 26 additions & 13 deletions pkg/resources/object_parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ var objectParameterSchema = map[string]*schema.Schema{
Required: true,
Description: "Value of object parameter, as a string. Constraints are the same as those for the parameters in Snowflake documentation.",
},
"on_account": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "If true, the object parameter will be set on the account level.",
},
"object_type": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -99,7 +105,12 @@ func CreateObjectParameter(d *schema.ResourceData, meta interface{}) error {
value = fmt.Sprintf("'%s'", snowflake.EscapeString(value))
}

builder := snowflake.NewParameter(key, value, snowflake.ParameterTypeObject, db)
builder := snowflake.NewObjectParameter(key, value, db)

onAccount := d.Get("on_account").(bool)
if onAccount {
builder.SetOnAccount(onAccount)
}

var fullyQualifierObjectIdentifier string
if v, ok := d.GetOk("object_identifier"); ok {
Expand All @@ -121,7 +132,7 @@ func CreateObjectParameter(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return fmt.Errorf("error creating object parameter err = %w", err)
}
id := fmt.Sprintf("%v❄️%v❄️%v", key, objectType, fullyQualifierObjectIdentifier)
id := fmt.Sprintf("%v|%v|%v", key, objectType, fullyQualifierObjectIdentifier)
d.SetId(id)
var p *snowflake.Parameter
if fullyQualifierObjectIdentifier != "" {
Expand All @@ -143,9 +154,12 @@ func CreateObjectParameter(d *schema.ResourceData, meta interface{}) error {
func ReadObjectParameter(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
id := d.Id()
parts := strings.Split(id, "❄️")
parts := strings.Split(id, "|")
if len(parts) != 3 {
parts = strings.Split(id, "❄️") // for backwards compatibility
}
if len(parts) != 3 {
return fmt.Errorf("unexpected format of ID (%v), expected key❄️object_type❄️object_identifier", id)
return fmt.Errorf("unexpected format of ID (%v), expected key|object_type|object_identifier", id)
}
key := parts[0]
var p *snowflake.Parameter
Expand Down Expand Up @@ -185,14 +199,20 @@ func DeleteObjectParameter(d *schema.ResourceData, meta interface{}) error {
if reflect.TypeOf(parameterDefault.DefaultValue) == typeString {
value = fmt.Sprintf("'%s'", value)
}
builder := snowflake.NewParameter(key, value, snowflake.ParameterTypeObject, db)
builder := snowflake.NewObjectParameter(key, value, db)

onAccount := d.Get("on_account").(bool)
if onAccount {
builder.SetOnAccount(onAccount)
}

var fullyQualifierObjectIdentifier string
if v, ok := d.GetOk("object_identifier"); ok {
objectDatabase, objectSchema, objectName := expandObjectIdentifier(v.([]interface{}))
fullyQualifierObjectIdentifier = snowflakeValidation.FormatFullyQualifiedObjectID(objectDatabase, objectSchema, objectName)
builder.WithObjectIdentifier(fullyQualifierObjectIdentifier)
}

var objectType snowflake.ObjectType
if v, ok := d.GetOk("object_type"); ok {
objectType = snowflake.ObjectType(v.(string))
Expand All @@ -201,18 +221,11 @@ func DeleteObjectParameter(d *schema.ResourceData, meta interface{}) error {
}
builder.WithObjectType(objectType)
}

err := builder.SetParameter()
if err != nil {
return fmt.Errorf("error deleting object parameter err = %w", err)
}
if fullyQualifierObjectIdentifier != "" {
_, err = snowflake.ShowObjectParameter(db, key, objectType, fullyQualifierObjectIdentifier)
} else {
_, err = snowflake.ShowAccountParameter(db, key)
}
if err != nil {
return fmt.Errorf("error reading object parameter err = %w", err)
}

d.SetId("")
return nil
Expand Down
Loading

0 comments on commit 1329430

Please sign in to comment.