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

feat: Row access policy resource v1 #3063

Merged
merged 11 commits into from
Sep 13, 2024
4 changes: 2 additions & 2 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Please rename these fields in your configuration files. State will be migrated a
#### *(breaking change)* Adjusted behavior of arguments/signature
Now, arguments are stored as a list, instead of a map. Please adjust that in your configs. State is migrated automatically. Also, this means that order of the items matters and may be adjusted.

Argument names are now case sensitive.
Argument names are now case sensitive. All policies created previously in the provider have upper case argument names. If you used lower case before, please adjust your configs.

#### *(breaking change)* Adjusted behavior on changing name
Previously, after changing `name` field, the resource was recreated. Now, the object is renamed with `RENAME TO`.
Expand All @@ -31,7 +31,7 @@ Now, similarly to handling statements in other resources, we replace blank chara

#### *(breaking change)* Identifiers related changes
sfc-gh-asawicki marked this conversation as resolved.
Show resolved Hide resolved
During [identifiers rework](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/ROADMAP.md#identifiers-rework) we decided to
migrate resource ids from pipe-separated to regular Snowflake identifiers (e.g. `<database_name>|<schema_name>` -> `"<database_name>"."<schema_name>"`).
migrate resource ids from pipe-separated to regular Snowflake identifiers (e.g. `<database_name>|<schema_name>` -> `"<database_name>"."<schema_name>"`). Importing resources also needs to be adjusted (see [example](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/row_access_policy#import)).

Also, we added diff suppress function that prevents Terraform from showing differences, when only quoting is different.

Expand Down
10 changes: 9 additions & 1 deletion docs/resources/row_access_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ resource "snowflake_row_access_policy" "example_row_access_policy" {
name = "ARG1"
type = "VARCHAR"
}
argument {
name = "ARG2"
type = "NUMBER"
}
argument {
name = "ARG3"
type = "TIMESTAMP_NTZ"
}
body = "case when current_role() in ('ANALYST') then true else false end"
comment = "comment"
}
Expand Down Expand Up @@ -91,5 +99,5 @@ Read-Only:
Import is supported using the following syntax:

```shell
terraform import snowflake_row_access_policy.example '"<database_name>"."<schema_name>"."<view_name>"'
terraform import snowflake_row_access_policy.example '"<database_name>"."<schema_name>"."<row_access_policy_name>"'
```
2 changes: 1 addition & 1 deletion examples/resources/snowflake_row_access_policy/import.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
terraform import snowflake_row_access_policy.example '"<database_name>"."<schema_name>"."<view_name>"'
terraform import snowflake_row_access_policy.example '"<database_name>"."<schema_name>"."<row_access_policy_name>"'
8 changes: 8 additions & 0 deletions examples/resources/snowflake_row_access_policy/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ resource "snowflake_row_access_policy" "example_row_access_policy" {
name = "ARG1"
type = "VARCHAR"
}
argument {
name = "ARG2"
type = "NUMBER"
}
argument {
name = "ARG3"
type = "TIMESTAMP_NTZ"
}
body = "case when current_role() in ('ANALYST') then true else false end"
comment = "comment"
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ var allResourceSchemaDefs = []ResourceSchemaDef{
name: "ResourceMonitor",
schema: resources.ResourceMonitor().Schema,
},
{
name: "RowAccessPolicy",
schema: resources.RowAccessPolicy().Schema,
},
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package resourceassert

import (
"fmt"
"strconv"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
)

func (r *RowAccessPolicyResourceAssert) HasArguments(args []sdk.RowAccessPolicyArgument) *RowAccessPolicyResourceAssert {
r.AddAssertion(assert.ValueSet("argument.#", strconv.FormatInt(int64(len(args)), 10)))
for i, v := range args {
r.AddAssertion(assert.ValueSet(fmt.Sprintf("argument.%d.name", i), v.Name))
r.AddAssertion(assert.ValueSet(fmt.Sprintf("argument.%d.type", i), v.Type))
}
return r
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package model

import (
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-testing/config"
tfconfig "github.com/hashicorp/terraform-plugin-testing/config"
)

func (r *RowAccessPolicyModel) WithArgument(argument []sdk.RowAccessPolicyArgument) *RowAccessPolicyModel {
maps := make([]config.Variable, len(argument))
for i, v := range argument {
maps[i] = config.MapVariable(map[string]config.Variable{
sfc-gh-jcieslak marked this conversation as resolved.
Show resolved Hide resolved
"name": config.StringVariable(v.Name),
"type": config.StringVariable(v.Type),
})
}
r.Argument = tfconfig.SetVariable(maps...)
return r
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions pkg/acceptance/helpers/row_access_policy_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ func (c *RowAccessPolicyClient) CreateRowAccessPolicyWithDataType(t *testing.T,
return rowAccessPolicy, c.DropRowAccessPolicyFunc(t, id)
}

func (c *RowAccessPolicyClient) CreateOrReplaceRowAccessPolicy(t *testing.T, req sdk.CreateRowAccessPolicyRequest) (*sdk.RowAccessPolicy, func()) {
t.Helper()
ctx := context.Background()

err := c.client().Create(ctx, req.WithOrReplace(sdk.Pointer(true)))
require.NoError(t, err)

rowAccessPolicy, err := c.client().ShowByID(ctx, req.GetName())
require.NoError(t, err)

return rowAccessPolicy, c.DropRowAccessPolicyFunc(t, req.GetName())
}

func (c *RowAccessPolicyClient) Alter(t *testing.T, req sdk.AlterRowAccessPolicyRequest) {
t.Helper()
ctx := context.Background()
Expand Down
62 changes: 52 additions & 10 deletions pkg/resources/row_access_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ var rowAccessPolicySchema = map[string]*schema.Schema{
},
// TODO(SNOW-1596962): Fully support VECTOR data type sdk.ParseFunctionArgumentsFromString could be a base for another function that takes argument names into consideration.
"type": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: func(key, oldValue, newValue string, _ *schema.ResourceData) bool {
return NormalizeAndCompare(sdk.ToDataType)(key, oldValue, newValue, nil)
},
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: NormalizeAndCompare(sdk.ToDataType),
ValidateDiagFunc: sdkValidation(sdk.ToDataType),
Description: "The argument type",
ForceNew: true,
Expand Down Expand Up @@ -106,12 +104,12 @@ func RowAccessPolicy() *schema.Resource {

Schema: rowAccessPolicySchema,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: ImportRowAccessPolicy,
},

CustomizeDiff: customdiff.All(
ComputedIfAnyAttributeChanged(rowAccessPolicySchema, ShowOutputAttributeName, "comment"),
ComputedIfAnyAttributeChanged(rowAccessPolicySchema, DescribeOutputAttributeName, "body"),
ComputedIfAnyAttributeChanged(rowAccessPolicySchema, ShowOutputAttributeName, "comment", "name"),
ComputedIfAnyAttributeChanged(rowAccessPolicySchema, DescribeOutputAttributeName, "body", "name", "signature"),
ComputedIfAnyAttributeChanged(rowAccessPolicySchema, FullyQualifiedNameAttributeName, "name"),
sfc-gh-jcieslak marked this conversation as resolved.
Show resolved Hide resolved
),

Expand All @@ -126,6 +124,47 @@ func RowAccessPolicy() *schema.Resource {
}
}

func ImportRowAccessPolicy(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
log.Printf("[DEBUG] Starting row access policy import")
client := meta.(*provider.Context).Client
id, err := sdk.ParseSchemaObjectIdentifier(d.Id())
if err != nil {
return nil, err
}

policy, err := client.RowAccessPolicies.ShowByID(ctx, id)
if err != nil {
return nil, err
}
if err := d.Set("name", id.Name()); err != nil {
return nil, err
}
if err := d.Set("database", id.DatabaseName()); err != nil {
return nil, err
}
if err := d.Set("schema", id.SchemaName()); err != nil {
return nil, err
}
if err := d.Set("comment", policy.Comment); err != nil {
return nil, err
}
policyDescription, err := client.RowAccessPolicies.Describe(ctx, id)
if err != nil {
return nil, err
}
if err := d.Set("body", policyDescription.Body); err != nil {
return nil, err
}
args, err := policyDescription.Arguments()
if err != nil {
return nil, err
}
if err := d.Set("argument", schemas.RowAccessPolicyArgumentsToSchema(args)); err != nil {
return nil, err
}
return []*schema.ResourceData{d}, nil
}

func CreateRowAccessPolicy(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
client := meta.(*provider.Context).Client

Expand Down Expand Up @@ -205,8 +244,11 @@ func ReadRowAccessPolicy(ctx context.Context, d *schema.ResourceData, meta any)
if err := d.Set("body", rowAccessPolicyDescription.Body); err != nil {
return diag.FromErr(err)
}

if err := d.Set("argument", rowAccessPolicyDescription.Arguments()); err != nil {
args, err := rowAccessPolicyDescription.Arguments()
if err != nil {
return diag.FromErr(err)
}
if err := d.Set("argument", schemas.RowAccessPolicyArgumentsToSchema(args)); err != nil {
return diag.FromErr(err)
}
if err = d.Set(ShowOutputAttributeName, []map[string]any{schemas.RowAccessPolicyToSchema(rowAccessPolicy)}); err != nil {
Expand Down
Loading
Loading