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: Add account data source #3261

Merged
merged 3 commits into from
Dec 11, 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
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
Loading