Skip to content

Commit

Permalink
feat: Added Row Access Policy Resources (Snowflake-Labs#624)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisIsidora authored and daniepett committed Feb 9, 2022
1 parent c0593a6 commit 1b9a5a7
Show file tree
Hide file tree
Showing 20 changed files with 1,239 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
data "snowflake_row_access_policies" "current" {
database = "MYDB"
schema = "MYSCHEMA"
}
2 changes: 2 additions & 0 deletions examples/resources/snowflake_row_access_policy/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# format is database name | schema name | policy name
terraform import snowflake_row_access_policy.example 'dbName|schemaName|policyName'
10 changes: 10 additions & 0 deletions examples/resources/snowflake_row_access_policy/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "snowflake_row_access_policy" "example_row_access_policy" {
name = "EXAMPLE_ROW_ACCESS_POLICY"
database = "EXAMPLE_DB"
schema = "EXAMPLE_SCHEMA"
signature = {
A = "VARCHAR",
B = "VARCHAR"
}
row_access_expression = "case when current_role() in ('ANALYST') then true else false end"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# format is database name | schema name | row access policy name | privilege | true/false for with_grant_option
terraform import snowflake_row_access_policy_grant.example 'dbName|schemaName|rowAccessPolicyName|SELECT|false'
13 changes: 13 additions & 0 deletions examples/resources/snowflake_row_access_policy_grant/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "snowflake_row_access_policy_grant" "grant" {
database_name = "db"
schema_name = "schema"
row_access_policy_name = "row_access_policy"

privilege = "APPLY"
roles = [
"role1",
"role2",
]

with_grant_option = false
}
90 changes: 90 additions & 0 deletions pkg/datasources/row_access_policies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package datasources

import (
"database/sql"
"fmt"
"log"

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

var rowAccessPoliciesSchema = map[string]*schema.Schema{
"database": {
Type: schema.TypeString,
Required: true,
Description: "The database from which to return the schemas from.",
},
"schema": {
Type: schema.TypeString,
Required: true,
Description: "The schema from which to return the row access policyfrom.",
},
"row_access_policies": {
Type: schema.TypeList,
Computed: true,
Description: "The row access policy in the schema",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"database": {
Type: schema.TypeString,
Computed: true,
},
"schema": {
Type: schema.TypeString,
Computed: true,
},
"comment": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
},
},
}

func RowAccessPolicies() *schema.Resource {
return &schema.Resource{
Read: ReadRowAccessPolicies,
Schema: rowAccessPoliciesSchema,
}
}

func ReadRowAccessPolicies(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
databaseName := d.Get("database").(string)
schemaName := d.Get("schema").(string)

currentRowAccessPolicies, err := snowflake.ListRowAccessPolicies(databaseName, schemaName, db)
if err == sql.ErrNoRows {
// If not found, mark resource to be removed from statefile during apply or refresh
log.Printf("[DEBUG] row access policy in schema (%s) not found", d.Id())
d.SetId("")
return nil
} else if err != nil {
log.Printf("[DEBUG] unable to parse row access policy in schema (%s)", d.Id())
d.SetId("")
return nil
}

rowAccessPolicies := []map[string]interface{}{}

for _, rowAccessPolicy := range currentRowAccessPolicies {
rowAccessPolicyMap := map[string]interface{}{}

rowAccessPolicyMap["name"] = rowAccessPolicy.Name.String
rowAccessPolicyMap["database"] = rowAccessPolicy.DatabaseName.String
rowAccessPolicyMap["schema"] = rowAccessPolicy.SchemaName.String
rowAccessPolicyMap["comment"] = rowAccessPolicy.Comment.String

rowAccessPolicies = append(rowAccessPolicies, rowAccessPolicyMap)
}

d.SetId(fmt.Sprintf(`%v|%v`, databaseName, schemaName))
return d.Set("row_access_policies", rowAccessPolicies)
}
63 changes: 63 additions & 0 deletions pkg/datasources/row_access_policies_acceptance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
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 TestAccRowAccessPolicies(t *testing.T) {
databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
schemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
rowAccessPolicyName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
Steps: []resource.TestStep{
{
Config: rowAccessPolicies(databaseName, schemaName, rowAccessPolicyName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.snowflake_row_access_policies.v", "database", databaseName),
resource.TestCheckResourceAttr("data.snowflake_row_access_policies.v", "schema", schemaName),
resource.TestCheckResourceAttrSet("data.snowflake_row_access_policies.v", "row_access_policies.#"),
resource.TestCheckResourceAttr("data.snowflake_row_access_policies.v", "row_access_policies.#", "1"),
resource.TestCheckResourceAttr("data.snowflake_row_access_policies.v", "row_access_policies.0.name", rowAccessPolicyName),
),
},
},
})
}

func rowAccessPolicies(databaseName string, schemaName string, rowAccessPolicyName string) string {
return fmt.Sprintf(`
resource snowflake_database "test" {
name = "%v"
}
resource snowflake_schema "test"{
name = "%v"
database = snowflake_database.test.name
}
resource "snowflake_row_access_policy" "test" {
name = "%v"
database = snowflake_database.test.name
schema = snowflake_schema.test.name
signature = {
N = "VARCHAR"
V = "VARCHAR",
}
row_access_expression = "case when current_role() in ('ANALYST') then true else false end"
comment = "Terraform acceptance test"
}
data snowflake_row_access_policies "v" {
database = snowflake_row_access_policy.test.database
schema = snowflake_row_access_policy.test.schema
depends_on = [snowflake_row_access_policy.test]
}
`, databaseName, schemaName, rowAccessPolicyName)
}
3 changes: 3 additions & 0 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ func GetGrantResources() resources.TerraformGrantResources {
"snowflake_pipe_grant": resources.PipeGrant(),
"snowflake_procedure_grant": resources.ProcedureGrant(),
"snowflake_resource_monitor_grant": resources.ResourceMonitorGrant(),
"snowflake_row_access_policy_grant": resources.RowAccessPolicyGrant(),
"snowflake_schema_grant": resources.SchemaGrant(),
"snowflake_sequence_grant": resources.SequenceGrant(),
"snowflake_stage_grant": resources.StageGrant(),
Expand Down Expand Up @@ -169,6 +170,7 @@ func getResources() map[string]*schema.Resource {
"snowflake_resource_monitor": resources.ResourceMonitor(),
"snowflake_role": resources.Role(),
"snowflake_role_grants": resources.RoleGrants(),
"snowflake_row_access_policy": resources.RowAccessPolicy(),
"snowflake_schema": resources.Schema(),
"snowflake_scim_integration": resources.SCIMIntegration(),
"snowflake_sequence": resources.Sequence(),
Expand Down Expand Up @@ -215,6 +217,7 @@ func getDataSources() map[string]*schema.Resource {
"snowflake_warehouses": datasources.Warehouses(),
"snowflake_resource_monitors": datasources.ResourceMonitors(),
"snowflake_storage_integrations": datasources.StorageIntegrations(),
"snowflake_row_access_policies": datasources.RowAccessPolicies(),
}

return dataSources
Expand Down
16 changes: 16 additions & 0 deletions pkg/resources/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,19 @@ func taskGrant(t *testing.T, id string, params map[string]interface{}) *schema.R
d.SetId(id)
return d
}

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

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

0 comments on commit 1b9a5a7

Please sign in to comment.