Skip to content

Commit

Permalink
Merge branch 'main' into event-tables-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-swinkler authored Dec 5, 2023
2 parents c884a41 + 1fcd393 commit 38fffb9
Show file tree
Hide file tree
Showing 48 changed files with 2,159 additions and 18 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/reviewdog-staticcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: staticcheck
on: [pull_request]
jobs:
reviewdog:
# disable the job temporarily (until we configure linters appropriately)
if: false
name: reviewdog
runs-on: ubuntu-latest
steps:
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [0.77.0](https://github.com/Snowflake-Labs/terraform-provider-snowflake/compare/v0.76.0...v0.77.0) (2023-11-30)


### 🎉 **What's new:**

* Add unsafe_execute resource ([#2225](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2225)) ([196134c](https://github.com/Snowflake-Labs/terraform-provider-snowflake/commit/196134cbf91996eabc50bdc586a657fe7ac71900))
* Introduce simple arch tests ([#2210](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2210)) ([c60db80](https://github.com/Snowflake-Labs/terraform-provider-snowflake/commit/c60db80f44d949258f0a692baafdc22b886c3010))


### 🐛 **Bug fixes:**

* cleanup workflows and makefile ([#2150](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2150)) ([64335e7](https://github.com/Snowflake-Labs/terraform-provider-snowflake/commit/64335e72e480393437dff9f88122a256a2ac0814))
* documentation for role ownership grant ([#2203](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2203)) ([e3d405c](https://github.com/Snowflake-Labs/terraform-provider-snowflake/commit/e3d405c91b494413d432e1aef9ff1da1f9ede4a7))
* Fix workflows ([#2206](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2206)) ([6d7f833](https://github.com/Snowflake-Labs/terraform-provider-snowflake/commit/6d7f8336897dee17c102d69a517e2525c1bb4d91))

## [0.76.0](https://github.com/Snowflake-Labs/terraform-provider-snowflake/compare/v0.75.0...v0.76.0) (2023-11-15)


Expand Down
9 changes: 6 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ install: ## install the binary
go install -v ./...

lint: # Run static code analysis, check formatting. See https://golangci-lint.run/
golangci-lint run ./... -v
./bin/golangci-lint run ./... -v

lint-fix: ## Run static code analysis, check formatting and try to fix findings
golangci-lint run ./... -v --fix
./bin/golangci-lint run ./... -v --fix

mod: ## add missing and remove unused modules
go mod tidy -compat=1.20

mod-check: mod ## check if there are any missing/unused modules
git diff --exit-code -- go.mod go.sum

pre-push: fmt docs mod lint ## Run a few checks before pushing a change (docs, fmt, mod, etc.)
pre-push: fmt docs mod lint test-architecture ## Run a few checks before pushing a change (docs, fmt, mod, etc.)

pre-push-check: fmt-check docs-check lint-check mod-check ## Run a few checks before pushing a change (docs, fmt, mod, etc.)

Expand All @@ -68,6 +68,9 @@ test: ## run unit and integration tests
test-acceptance: ## run acceptance tests
TF_ACC=1 go test -run "^TestAcc_" -v -cover -timeout=30m ./...

test-architecture: ## check architecture constraints between packages
go test ./pkg/architests/... -v

build-local: ## build the binary locally
go build -o $(BASE_BINARY_NAME) .

Expand Down
143 changes: 143 additions & 0 deletions docs/resources/unsafe_execute.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "snowflake_unsafe_execute Resource - terraform-provider-snowflake"
subcategory: ""
description: |-
Experimental resource used for testing purposes only. Allows to execute ANY SQL statement.
---

# snowflake_unsafe_execute (Resource)

!> **Warning** This is a dangerous resource that allows executing **ANY** SQL statement. It may destroy resources if used incorrectly. It may behave incorrectly combined with other resources. Will be deleted in the upcoming versions. Use at your own risk.

~> **Note** It can be theoretically used to manage resource that are not supported by the provider. This is risky and may brake other resources if used incorrectly.

~> **Note** Use `query` parameter with caution. It will fetch **ALL** the results returned by the query provided. Try to limit the number of results by writing query with filters. Query failure does not stop resource creation; it simply results in `query_results` being empty.

Experimental resource used for testing purposes only. Allows to execute ANY SQL statement.

## Example Usage

```terraform
##################################
### simple use cases
##################################
# create and destroy resource
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
}
# create and destroy resource using qualified name
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE \"abc\""
revert = "DROP DATABASE \"abc\""
}
# with query
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
query = "SHOW DATABASES LIKE '%ABC%'"
}
##################################
### grants example
##################################
# grant and revoke privilege USAGE to ROLE on database
resource "snowflake_unsafe_execute" "test" {
execute = "GRANT USAGE ON DATABASE ABC TO ROLE XYZ"
revert = "REVOKE USAGE ON DATABASE ABC FROM ROLE XYZ"
}
# grant and revoke with for_each
variable "database_grants" {
type = list(object({
database_name = string
role_id = string
privileges = list(string)
}))
}
resource "snowflake_unsafe_execute" "test" {
for_each = { for index, db_grant in var.database_grants : index => db_grant }
execute = "GRANT ${join(",", each.value.privileges)} ON DATABASE ${each.value.database_name} TO ROLE ${each.value.role_id}"
revert = "REVOKE ${join(",", each.value.privileges)} ON DATABASE ${each.value.database_name} FROM ROLE ${each.value.role_id}"
}
##################################
### fixing bad configuration
##################################
# bad revert - simple
# 1 - resource created with a bad revert; it is constructed, revert is not validated before destroy happens
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "SELECT 1"
}
# 2 - fix the revert first; resource won't be recreated
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
}
# bad revert - complex (we assume that the problem is spotted after trying to change the execute)
# 1 - resource created with a bad revert; it is constructed, revert is not validated before destroy happens
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "SELECT 1"
}
# 2 - try to create different database; it will fail on bad destroy
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE XYZ"
revert = "SELECT 1"
}
# 3 - fix the revert first
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
}
# 4 - create different database updating revert also
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE XYZ"
revert = "DROP DATABASE XYZ"
}
# bad query
# 1 - resource will be created; query_results will be empty
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
query = "bad query"
}
# 2 - fix the query; query_results will be calculated; resource won't be recreated
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
query = "SHOW DATABASES LIKE '%ABC%'"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `execute` (String) SQL statement to execute. Forces recreation of resource on change.
- `revert` (String) SQL statement to revert the execute statement. Invoked when resource is being destroyed.

### Optional

- `query` (String) Optional SQL statement to do a read. Invoked after creation and every time it is changed.

### Read-Only

- `id` (String) The ID of this resource.
- `query_results` (List of Map of String) List of key-value maps (text to text) retrieved after executing read query. Will be empty if the query results in an error.
104 changes: 104 additions & 0 deletions examples/resources/snowflake_unsafe_execute/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
##################################
### simple use cases
##################################

# create and destroy resource
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
}

# create and destroy resource using qualified name
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE \"abc\""
revert = "DROP DATABASE \"abc\""
}

# with query
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
query = "SHOW DATABASES LIKE '%ABC%'"
}

##################################
### grants example
##################################

# grant and revoke privilege USAGE to ROLE on database
resource "snowflake_unsafe_execute" "test" {
execute = "GRANT USAGE ON DATABASE ABC TO ROLE XYZ"
revert = "REVOKE USAGE ON DATABASE ABC FROM ROLE XYZ"
}

# grant and revoke with for_each
variable "database_grants" {
type = list(object({
database_name = string
role_id = string
privileges = list(string)
}))
}

resource "snowflake_unsafe_execute" "test" {
for_each = { for index, db_grant in var.database_grants : index => db_grant }
execute = "GRANT ${join(",", each.value.privileges)} ON DATABASE ${each.value.database_name} TO ROLE ${each.value.role_id}"
revert = "REVOKE ${join(",", each.value.privileges)} ON DATABASE ${each.value.database_name} FROM ROLE ${each.value.role_id}"
}

##################################
### fixing bad configuration
##################################

# bad revert - simple
# 1 - resource created with a bad revert; it is constructed, revert is not validated before destroy happens
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "SELECT 1"
}

# 2 - fix the revert first; resource won't be recreated
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
}

# bad revert - complex (we assume that the problem is spotted after trying to change the execute)
# 1 - resource created with a bad revert; it is constructed, revert is not validated before destroy happens
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "SELECT 1"
}

# 2 - try to create different database; it will fail on bad destroy
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE XYZ"
revert = "SELECT 1"
}

# 3 - fix the revert first
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
}

# 4 - create different database updating revert also
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE XYZ"
revert = "DROP DATABASE XYZ"
}

# bad query
# 1 - resource will be created; query_results will be empty
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
query = "bad query"
}

# 2 - fix the query; query_results will be calculated; resource won't be recreated
resource "snowflake_unsafe_execute" "test" {
execute = "CREATE DATABASE ABC"
revert = "DROP DATABASE ABC"
query = "SHOW DATABASES LIKE '%ABC%'"
}
8 changes: 8 additions & 0 deletions pkg/acceptance/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,11 @@ func ConfigurationSameAsStepN(step int) func(config.TestStepConfigRequest) strin
return filepath.Join("testdata", req.TestName, strconv.Itoa(step))
}
}

// ConfigurationDirectory should be used to obtain configuration if the same can be shared between multiple tests to avoid duplication of configuration and var files.
// Based on config.TestNameDirectory. Similar to config.StaticDirectory but prefixed provided directory with `testdata`.
func ConfigurationDirectory(directory string) func(config.TestStepConfigRequest) string {
return func(req config.TestStepConfigRequest) string {
return filepath.Join("testdata", directory)
}
}
Loading

0 comments on commit 38fffb9

Please sign in to comment.