Skip to content

Commit

Permalink
feat: Add account data source (#3261)
Browse files Browse the repository at this point in the history
### Changes
- Refactor accounts data source
- Adjust acceptance test
- Add examples
- Adjust migration guide
  • Loading branch information
sfc-gh-jcieslak authored Dec 11, 2024
1 parent 211ad46 commit 6087fc9
Show file tree
Hide file tree
Showing 6 changed files with 344 additions and 132 deletions.
24 changes: 24 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ Changes:
- The underlying resource identifier was changed from `<account_locator>` to `<organization_name>.<account_name>`. Migration will be done automatically. Notice this introduces changes in how `snowflake_account` resource is imported.
- New `show_output` field was added (see [raw Snowflake output](./v1-preparations/CHANGES_BEFORE_V1.md#raw-snowflake-output)).

### snowflake_accounts data source changes
New filtering options:
- `with_history`

New output fields
- `show_output`

Breaking changes:
- `pattern` renamed to `like`
- `accounts` field now organizes output of show under `show_output` field and the output of show parameters under `parameters` field.

Before:
```terraform
output "simple_output" {
value = data.snowflake_accounts.test.accounts[0].account_name
}
```
After:
```terraform
output "simple_output" {
value = data.snowflake_accounts.test.accounts[0].show_output[0].account_name
}
```

### snowflake_tag_association resource changes
#### *(behavior change)* new id format
To provide more functionality for tagging objects, we have changed the resource id from `"TAG_DATABASE"."TAG_SCHEMA"."TAG_NAME"` to `"TAG_DATABASE"."TAG_SCHEMA"."TAG_NAME"|TAG_VALUE|OBJECT_TYPE`. This allows to group tags associations per tag ID, tag value and object type in one resource.
Expand Down
78 changes: 75 additions & 3 deletions docs/data-sources/accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,117 @@
page_title: "snowflake_accounts Data Source - terraform-provider-snowflake"
subcategory: ""
description: |-
Data source used to get details of filtered accounts. Filtering is aligned with the current possibilities for SHOW ACCOUNTS https://docs.snowflake.com/en/sql-reference/sql/show-accounts query. The results of SHOW are encapsulated in one output collection accounts.
---

# snowflake_accounts (Data Source)

Data source used to get details of filtered accounts. Filtering is aligned with the current possibilities for [SHOW ACCOUNTS](https://docs.snowflake.com/en/sql-reference/sql/show-accounts) query. The results of SHOW are encapsulated in one output collection `accounts`.

## Example Usage

```terraform
# Simple usage
data "snowflake_accounts" "simple" {
}
output "simple_output" {
value = data.snowflake_accounts.simple.accounts
}
# Filtering (like)
data "snowflake_accounts" "like" {
like = "account-name"
}
output "like_output" {
value = data.snowflake_accounts.like.accounts
}
# With history
data "snowflake_accounts" "with_history" {
with_history = true
}
output "with_history_output" {
value = data.snowflake_accounts.like.accounts
}
# Ensure the number of accounts is equal to at least one element (with the use of postcondition)
data "snowflake_accounts" "assert_with_postcondition" {
like = "account-name"
lifecycle {
postcondition {
condition = length(self.accounts) > 0
error_message = "there should be at least one account"
}
}
}
# Ensure the number of accounts is equal to at exactly one element (with the use of check block)
check "account_check" {
data "snowflake_accounts" "assert_with_check_block" {
like = "account-name"
}
assert {
condition = length(data.snowflake_accounts.assert_with_check_block.accounts) == 1
error_message = "accounts filtered by '${data.snowflake_accounts.assert_with_check_block.like}' returned ${length(data.snowflake_accounts.assert_with_check_block.accounts)} accounts where one was expected"
}
}
```

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

### Optional

- `pattern` (String) Specifies an account name pattern. If a pattern is specified, only accounts matching the pattern are returned.
- `like` (String) Filters the output with **case-insensitive** pattern, with support for SQL wildcard characters (`%` and `_`).
- `with_history` (Boolean) Includes dropped accounts that have not yet been deleted.

### Read-Only

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

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

Read-Only:

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

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

Read-Only:

- `account_locator` (String)
- `account_locator_url` (String)
- `account_name` (String)
- `account_old_url_last_used` (String)
- `account_old_url_saved_on` (String)
- `account_url` (String)
- `comment` (String)
- `consumption_billing_entity_name` (String)
- `created_on` (String)
- `dropped_on` (String)
- `edition` (String)
- `is_events_account` (Boolean)
- `is_org_admin` (Boolean)
- `is_organization_account` (Boolean)
- `managed_accounts` (Number)
- `marketplace_consumer_billing_entity_name` (String)
- `marketplace_provider_billing_entity_name` (String)
- `moved_on` (String)
- `moved_to_organization` (String)
- `old_account_url` (String)
- `organization_name` (String)
- `organization_old_url` (String)
- `organization_old_url_last_used` (String)
- `organization_old_url_saved_on` (String)
- `organization_url_expiration_on` (String)
- `region_group` (String)
- `restored_on` (String)
- `scheduled_deletion_time` (String)
- `snowflake_region` (String)
48 changes: 48 additions & 0 deletions examples/data-sources/snowflake_accounts/data-source.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Simple usage
data "snowflake_accounts" "simple" {
}

output "simple_output" {
value = data.snowflake_accounts.simple.accounts
}

# Filtering (like)
data "snowflake_accounts" "like" {
like = "account-name"
}

output "like_output" {
value = data.snowflake_accounts.like.accounts
}

# With history
data "snowflake_accounts" "with_history" {
with_history = true
}

output "with_history_output" {
value = data.snowflake_accounts.like.accounts
}

# Ensure the number of accounts is equal to at least one element (with the use of postcondition)
data "snowflake_accounts" "assert_with_postcondition" {
like = "account-name"
lifecycle {
postcondition {
condition = length(self.accounts) > 0
error_message = "there should be at least one account"
}
}
}

# Ensure the number of accounts is equal to at exactly one element (with the use of check block)
check "account_check" {
data "snowflake_accounts" "assert_with_check_block" {
like = "account-name"
}

assert {
condition = length(data.snowflake_accounts.assert_with_check_block.accounts) == 1
error_message = "accounts filtered by '${data.snowflake_accounts.assert_with_check_block.like}' returned ${length(data.snowflake_accounts.assert_with_check_block.accounts)} accounts where one was expected"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
package resourceshowoutputassert

import (
"testing"

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

func AccountDatasourceShowOutput(t *testing.T, name string) *AccountShowOutputAssert {
t.Helper()

a := AccountShowOutputAssert{
ResourceAssert: assert.NewDatasourceAssert("data."+name, "show_output", "accounts.0."),
}
a.AddAssertion(assert.ValueSet("show_output.#", "1"))
return &a
}

func (a *AccountShowOutputAssert) HasAccountUrlNotEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValuePresent("account_url"))
return a
Expand All @@ -29,52 +41,132 @@ func (a *AccountShowOutputAssert) HasConsumptionBillingEntityNameNotEmpty() *Acc
return a
}

func (a *AccountShowOutputAssert) HasNoOrganizationOldUrl() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("organization_old_url"))
return a
}

func (a *AccountShowOutputAssert) HasOrganizationOldUrlEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("organization_old_url", ""))
return a
}

func (a *AccountShowOutputAssert) HasMarketplaceProviderBillingEntityNameNotEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValuePresent("marketplace_provider_billing_entity_name"))
return a
}

func (a *AccountShowOutputAssert) HasNoAccountOldUrlSavedOn() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("account_old_url_saved_on"))
return a
}

func (a *AccountShowOutputAssert) HasAccountOldUrlSavedOnEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("account_old_url_saved_on", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoAccountOldUrlLastUsed() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("account_old_url_last_used"))
return a
}

func (a *AccountShowOutputAssert) HasAccountOldUrlLastUsedEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("account_old_url_last_used", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoOrganizationOldUrlSavedOn() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("organization_old_url_saved_on"))
return a
}

func (a *AccountShowOutputAssert) HasOrganizationOldUrlSavedOnEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("organization_old_url_saved_on", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoOrganizationOldUrlLastUsed() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("organization_old_url_last_used"))
return a
}

func (a *AccountShowOutputAssert) HasOrganizationOldUrlLastUsedEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("organization_old_url_last_used", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoDroppedOn() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("dropped_on"))
return a
}

func (a *AccountShowOutputAssert) HasDroppedOnEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("dropped_on", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoScheduledDeletionTime() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("scheduled_deletion_time"))
return a
}

func (a *AccountShowOutputAssert) HasScheduledDeletionTimeEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("scheduled_deletion_time", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoRestoredOn() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("restored_on"))
return a
}

func (a *AccountShowOutputAssert) HasRestoredOnEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("restored_on", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoMovedToOrganization() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("moved_to_organization"))
return a
}

func (a *AccountShowOutputAssert) HasMovedToOrganizationEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("moved_to_organization", ""))
return a
}

func (a *AccountShowOutputAssert) HasMovedOnEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("moved_on", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoOrganizationUrlExpirationOn() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("organization_url_expiration_on"))
return a
}

func (a *AccountShowOutputAssert) HasOrganizationUrlExpirationOnEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("organization_url_expiration_on", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoIsEventsAccount() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("is_events_account"))
return a
}

func (a *AccountShowOutputAssert) HasIsEventsAccountEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("is_events_account", ""))
return a
}

func (a *AccountShowOutputAssert) HasNoIsOrganizationAccount() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueNotSet("is_organization_account"))
return a
}

func (a *AccountShowOutputAssert) HasIsOrganizationAccountEmpty() *AccountShowOutputAssert {
a.AddAssertion(assert.ResourceShowOutputValueSet("is_organization_account", ""))
return a
}
Loading

0 comments on commit 6087fc9

Please sign in to comment.