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: View rework part 3 #3023

Merged
merged 17 commits into from
Sep 3, 2024
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
17 changes: 17 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,22 @@ across different versions.
- `comment`
- `owner_role_type`

### snowflake_views data source changes
New filtering options:
- `in`
- `like`
- `starts_with`
- `limit`
- `with_describe`

New output fields
- `show_output`
- `describe_output`

Breaking changes:
- `database` and `schema` are right now under `in` field
- `views` field now organizes output of show under `show_output` field and the output of describe under `describe_output` field.

### snowflake_view resource changes
New fields:
- `row_access_policy`
Expand All @@ -32,6 +48,7 @@ New fields:
- `is_temporary`
- `data_metric_schedule`
- `data_metric_function`
- `column`
- added `show_output` field that holds the response from SHOW VIEWS.
- added `describe_output` field that holds the response from DESCRIBE VIEW. Note that one needs to grant sufficient privileges e.g. with [grant_ownership](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/resources/grant_ownership) on the tables used in this view. Otherwise, this field is not filled.

Expand Down
77 changes: 69 additions & 8 deletions docs/data-sources/views.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
page_title: "snowflake_views Data Source - terraform-provider-snowflake"
subcategory: ""
description: |-

Datasource used to get details of filtered views. Filtering is aligned with the current possibilities for SHOW VIEWS https://docs.snowflake.com/en/sql-reference/sql/show-views query (only like is supported). The results of SHOW and DESCRIBE are encapsulated in one output collection views.
---

# snowflake_views (Data Source)


Datasource used to get details of filtered views. Filtering is aligned with the current possibilities for [SHOW VIEWS](https://docs.snowflake.com/en/sql-reference/sql/show-views) query (only `like` is supported). The results of SHOW and DESCRIBE are encapsulated in one output collection `views`.

## Example Usage

Expand All @@ -21,22 +21,83 @@ data "snowflake_views" "current" {
<!-- schema generated by tfplugindocs -->
## Schema

### Required
### Optional

- `database` (String) The database from which to return the schemas from.
- `schema` (String) The schema from which to return the views from.
- `in` (Block List, Max: 1) IN clause to filter the list of views (see [below for nested schema](#nestedblock--in))
- `like` (String) Filters the output with **case-insensitive** pattern, with support for SQL wildcard characters (`%` and `_`).
- `limit` (Block List, Max: 1) Limits the number of rows returned. If the `limit.from` is set, then the limit wll start from the first element matched by the expression. The expression is only used to match with the first element, later on the elements are not matched by the prefix, but you can enforce a certain pattern with `starts_with` or `like`. (see [below for nested schema](#nestedblock--limit))
- `starts_with` (String) Filters the output with **case-sensitive** characters indicating the beginning of the object name.
- `with_describe` (Boolean) Runs DESC VIEW for each view returned by SHOW VIEWS. The output of describe is saved to the description field. By default this value is set to true.

### Read-Only

- `id` (String) The ID of this resource.
- `views` (List of Object) The views in the schema (see [below for nested schema](#nestedatt--views))
- `views` (List of Object) Holds the aggregated output of all views details queries. (see [below for nested schema](#nestedatt--views))

<a id="nestedblock--in"></a>
### Nested Schema for `in`

Optional:

- `account` (Boolean) Returns records for the entire account.
- `database` (String) Returns records for the current database in use or for a specified database.
- `schema` (String) Returns records for the current schema in use or a specified schema. Use fully qualified name.


<a id="nestedblock--limit"></a>
### Nested Schema for `limit`

Required:

- `rows` (Number) The maximum number of rows to return.

Optional:

- `from` (String) Specifies a **case-sensitive** pattern that is used to match object name. After the first match, the limit on the number of rows will be applied.


<a id="nestedatt--views"></a>
### Nested Schema for `views`

Read-Only:

- `describe_output` (List of Object) (see [below for nested schema](#nestedobjatt--views--describe_output))
- `show_output` (List of Object) (see [below for nested schema](#nestedobjatt--views--show_output))

<a id="nestedobjatt--views--describe_output"></a>
### Nested Schema for `views.describe_output`

Read-Only:

- `check` (String)
- `comment` (String)
- `default` (String)
- `expression` (String)
- `is_nullable` (Boolean)
- `is_primary` (Boolean)
- `is_unique` (Boolean)
- `kind` (String)
- `name` (String)
- `policy_name` (String)
- `privacy_domain` (String)
- `type` (String)


<a id="nestedobjatt--views--show_output"></a>
### Nested Schema for `views.show_output`

Read-Only:

- `change_tracking` (String)
- `comment` (String)
- `database` (String)
- `created_on` (String)
- `database_name` (String)
- `is_materialized` (Boolean)
- `is_secure` (Boolean)
- `kind` (String)
- `name` (String)
- `schema` (String)
- `owner` (String)
- `owner_role_type` (String)
- `reserved` (String)
- `schema_name` (String)
- `text` (String)
54 changes: 52 additions & 2 deletions docs/resources/view.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ resource "snowflake_view" "view" {
select * from foo;
SQL
}
# resource with attached policies and data metric functions
# resource with attached policies, columns and data metric functions
resource "snowflake_view" "test" {
database = "database"
schema = "schema"
Expand All @@ -47,6 +47,20 @@ resource "snowflake_view" "test" {
is_secure = "true"
change_tracking = "true"
is_temporary = "true"
column {
column_name = "id"
comment = "column comment"
}
column {
column_name = "address"
projection_policy {
policy_name = "projection_policy"
}
masking_policy {
policy_name = "masking_policy"
using = ["address"]
}
}
row_access_policy {
policy_name = "row_access_policy"
on = ["id"]
Expand All @@ -63,7 +77,7 @@ resource "snowflake_view" "test" {
using_cron = "15 * * * * UTC"
}
statement = <<-SQL
SELECT id FROM TABLE;
SELECT id, address FROM TABLE;
SQL
}
```
Expand All @@ -84,6 +98,7 @@ SQL

- `aggregation_policy` (Block List, Max: 1) Specifies the aggregation policy to set on a view. (see [below for nested schema](#nestedblock--aggregation_policy))
- `change_tracking` (String) Specifies to enable or disable change tracking on the table. Available options are: "true" or "false". When the value is not set in the configuration the provider will put "default" there which means to use the Snowflake default for this value.
- `column` (Block List) If you want to change the name of a column or add a comment to a column in the new view, include a column list that specifies the column names and (if needed) comments about the columns. (You do not need to specify the data types of the columns.) (see [below for nested schema](#nestedblock--column))
- `comment` (String) Specifies a comment for the view.
- `copy_grants` (Boolean) Retains the access permissions from the original view when a new view is created using the OR REPLACE clause.
- `data_metric_function` (Block Set) Data metric functions used for the view. (see [below for nested schema](#nestedblock--data_metric_function))
Expand Down Expand Up @@ -112,13 +127,48 @@ Optional:
- `entity_key` (Set of String) Defines which columns uniquely identify an entity within the view.


<a id="nestedblock--column"></a>
### Nested Schema for `column`

Required:

- `column_name` (String) Specifies affected column name.

Optional:

- `comment` (String) Specifies a comment for the column.
- `masking_policy` (Block List, Max: 1) (see [below for nested schema](#nestedblock--column--masking_policy))
- `projection_policy` (Block List, Max: 1) (see [below for nested schema](#nestedblock--column--projection_policy))

<a id="nestedblock--column--masking_policy"></a>
### Nested Schema for `column.masking_policy`

Required:

- `policy_name` (String) Specifies the masking policy to set on a column.

Optional:

- `using` (List of String) Specifies the arguments to pass into the conditional masking policy SQL expression. The first column in the list specifies the column for the policy conditions to mask or tokenize the data and must match the column to which the masking policy is set. The additional columns specify the columns to evaluate to determine whether to mask or tokenize the data in each row of the query result when a query is made on the first column. If the USING clause is omitted, Snowflake treats the conditional masking policy as a normal masking policy.


<a id="nestedblock--column--projection_policy"></a>
### Nested Schema for `column.projection_policy`

Required:

- `policy_name` (String) Specifies the projection policy to set on a column.



<a id="nestedblock--data_metric_function"></a>
### Nested Schema for `data_metric_function`

Required:

- `function_name` (String) Identifier of the data metric function to add to the table or view or drop from the table or view. This function identifier must be provided without arguments in parenthesis.
- `on` (Set of String) The table or view columns on which to associate the data metric function. The data types of the columns must match the data types of the columns specified in the data metric function definition.
- `schedule_status` (String) The status of the metrics association. Valid values are: `STARTED` | `SUSPENDED`. When status of a data metric function is changed, it is being reassigned with `DROP DATA METRIC FUNCTION` and `ADD DATA METRIC FUNCTION`, and then its status is changed by `MODIFY DATA METRIC FUNCTION`


<a id="nestedblock--data_metric_schedule"></a>
Expand Down
18 changes: 16 additions & 2 deletions examples/resources/snowflake_view/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ resource "snowflake_view" "view" {
select * from foo;
SQL
}
# resource with attached policies and data metric functions
# resource with attached policies, columns and data metric functions
resource "snowflake_view" "test" {
database = "database"
schema = "schema"
Expand All @@ -27,6 +27,20 @@ resource "snowflake_view" "test" {
is_secure = "true"
change_tracking = "true"
is_temporary = "true"
column {
column_name = "id"
comment = "column comment"
}
column {
column_name = "address"
projection_policy {
policy_name = "projection_policy"
}
masking_policy {
policy_name = "masking_policy"
using = ["address"]
}
}
row_access_policy {
policy_name = "row_access_policy"
on = ["id"]
Expand All @@ -43,6 +57,6 @@ resource "snowflake_view" "test" {
using_cron = "15 * * * * UTC"
}
statement = <<-SQL
SELECT id FROM TABLE;
SELECT id, address FROM TABLE;
SQL
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package objectassert

import (
"fmt"
"slices"
"testing"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers"

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

Expand All @@ -28,3 +31,71 @@ func (v *ViewAssert) HasNonEmptyText() *ViewAssert {
})
return v
}

func (v *ViewAssert) HasNoRowAccessPolicyReferences(client *helpers.TestClient) *ViewAssert {
return v.hasNoPolicyReference(client, sdk.PolicyKindRowAccessPolicy)
}

func (v *ViewAssert) HasNoAggregationPolicyReferences(client *helpers.TestClient) *ViewAssert {
return v.hasNoPolicyReference(client, sdk.PolicyKindAggregationPolicy)
}

func (v *ViewAssert) HasNoMaskingPolicyReferences(client *helpers.TestClient) *ViewAssert {
return v.hasNoPolicyReference(client, sdk.PolicyKindMaskingPolicy)
}

func (v *ViewAssert) HasNoProjectionPolicyReferences(client *helpers.TestClient) *ViewAssert {
return v.hasNoPolicyReference(client, sdk.PolicyKindProjectionPolicy)
}

func (v *ViewAssert) hasNoPolicyReference(client *helpers.TestClient, kind sdk.PolicyKind) *ViewAssert {
v.AddAssertion(func(t *testing.T, o *sdk.View) error {
t.Helper()
refs, err := client.PolicyReferences.GetPolicyReferences(t, o.ID(), sdk.ObjectTypeView)
if err != nil {
return err
}
refs = slices.DeleteFunc(refs, func(reference helpers.PolicyReference) bool {
return reference.PolicyKind != string(kind)
})
if len(refs) > 0 {
return fmt.Errorf("expected no %s policy references; got: %v", kind, refs)
}
return nil
})
return v
}

func (v *ViewAssert) HasRowAccessPolicyReferences(client *helpers.TestClient, n int) *ViewAssert {
return v.hasPolicyReference(client, sdk.PolicyKindRowAccessPolicy, n)
}

func (v *ViewAssert) HasAggregationPolicyReferences(client *helpers.TestClient, n int) *ViewAssert {
return v.hasPolicyReference(client, sdk.PolicyKindAggregationPolicy, n)
}

func (v *ViewAssert) HasMaskingPolicyReferences(client *helpers.TestClient, n int) *ViewAssert {
return v.hasPolicyReference(client, sdk.PolicyKindMaskingPolicy, n)
}

func (v *ViewAssert) HasProjectionPolicyReferences(client *helpers.TestClient, n int) *ViewAssert {
return v.hasPolicyReference(client, sdk.PolicyKindProjectionPolicy, n)
}

func (v *ViewAssert) hasPolicyReference(client *helpers.TestClient, kind sdk.PolicyKind, n int) *ViewAssert {
v.AddAssertion(func(t *testing.T, o *sdk.View) error {
t.Helper()
refs, err := client.PolicyReferences.GetPolicyReferences(t, o.ID(), sdk.ObjectTypeView)
if err != nil {
return err
}
refs = slices.DeleteFunc(refs, func(reference helpers.PolicyReference) bool {
return reference.PolicyKind != string(kind)
})
if len(refs) != n {
return fmt.Errorf("expected %d %s policy references; got: %d, %v", n, kind, len(refs), refs)
}
return nil
})
return v
}
Loading
Loading