diff --git a/docs/resources/account.md b/docs/resources/account.md index 4d3a8fea48..1caf592f99 100644 --- a/docs/resources/account.md +++ b/docs/resources/account.md @@ -2,12 +2,12 @@ page_title: "snowflake_account Resource - terraform-provider-snowflake" subcategory: "" description: |- - The account resource allows you to create and manage Snowflake accounts. + The account resource allows you to create and manage Snowflake accounts. To use this resource, make sure you use an account with the ORGADMIN role. --- # snowflake_account (Resource) -The account resource allows you to create and manage Snowflake accounts. +The account resource allows you to create and manage Snowflake accounts. To use this resource, make sure you use an account with the ORGADMIN role. !> **Warning** This resource cannot be destroyed!!! The only way to delete accounts is to go through [Snowflake Support](https://docs.snowflake.com/en/user-guide/organizations-manage-accounts.html#deleting-an-account) @@ -16,23 +16,14 @@ The account resource allows you to create and manage Snowflake accounts. ## Example Usage ```terraform -provider "snowflake" { - role = "ORGADMIN" - alias = "orgadmin" +## TODO: + +## Minimal +resource "snowflake_account" "minimal" { } -resource "snowflake_account" "ac1" { - provider = snowflake.orgadmin - name = "SNOWFLAKE_TEST_ACCOUNT" - admin_name = "John Doe" - admin_password = "Abcd1234!" - email = "john.doe@snowflake.com" - first_name = "John" - last_name = "Doe" - must_change_password = true - edition = "STANDARD" - comment = "Snowflake Test Account" - region = "AWS_US_WEST_2" +## Complete (with every optional set) +resource "snowflake_account" "complete" { } ``` -> **Note** Instead of using fully_qualified_name, you can reference objects managed outside Terraform by constructing a correct ID, consult [identifiers guide](https://registry.terraform.io/providers/Snowflake-Labs/snowflake/latest/docs/guides/identifiers#new-computed-fully-qualified-name-field-in-resources). @@ -43,28 +34,65 @@ resource "snowflake_account" "ac1" { ### Required -- `admin_name` (String) Login name of the initial administrative user of the account. A new user is created in the new account with this name and password and granted the ACCOUNTADMIN role in the account. A login name can be any string consisting of letters, numbers, and underscores. Login names are always case-insensitive. -- `edition` (String) [Snowflake Edition](https://docs.snowflake.com/en/user-guide/intro-editions.html) of the account. Valid values are: STANDARD | ENTERPRISE | BUSINESS_CRITICAL -- `email` (String, Sensitive) Email address of the initial administrative user of the account. This email address is used to send any notifications about the account. -- `name` (String) Specifies the identifier (i.e. name) for the account; must be unique within an organization, regardless of which Snowflake Region the account is in. In addition, the identifier must start with an alphabetic character and cannot contain spaces or special characters except for underscores (_). Note that if the account name includes underscores, features that do not accept account names with underscores (e.g. Okta SSO or SCIM) can reference a version of the account name that substitutes hyphens (-) for the underscores. +- `admin_name` (String, Sensitive) Login name of the initial administrative user of the account. A new user is created in the new account with this name and password and granted the ACCOUNTADMIN role in the account. A login name can be any string consisting of letters, numbers, and underscores. Login names are always case-insensitive. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `edition` (String) Snowflake Edition of the account. See more about Snowflake Editions in the [official documentation](https://docs.snowflake.com/en/user-guide/intro-editions). Valid options are: `STANDARD` | `ENTERPRISE` | `BUSINESS_CRITICAL` +- `email` (String, Sensitive) Email address of the initial administrative user of the account. This email address is used to send any notifications about the account. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `grace_period_in_days` (Number) Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days. +- `name` (String) Specifies the identifier (i.e. name) for the account. It be unique within an organization, regardless of which Snowflake Region the account is in and must start with an alphabetic character and cannot contain spaces or special characters except for underscores (_). Note that if the account name includes underscores, features that do not accept account names with underscores (e.g. Okta SSO or SCIM) can reference a version of the account name that substitutes hyphens (-) for the underscores. ### Optional -- `admin_password` (String, Sensitive) Password for the initial administrative user of the account. Optional if the `ADMIN_RSA_PUBLIC_KEY` parameter is specified. For more information about passwords in Snowflake, see [Snowflake-provided Password Policy](https://docs.snowflake.com/en/sql-reference/sql/create-account.html#:~:text=Snowflake%2Dprovided%20Password%20Policy). -- `admin_rsa_public_key` (String, Sensitive) Assigns a public key to the initial administrative user of the account in order to implement [key pair authentication](https://docs.snowflake.com/en/sql-reference/sql/create-account.html#:~:text=key%20pair%20authentication) for the user. Optional if the `ADMIN_PASSWORD` parameter is specified. +- `admin_password` (String, Sensitive) Password for the initial administrative user of the account. Either admin_password or admin_rsa_public_key has to be specified. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `admin_rsa_public_key` (String, Sensitive) Assigns a public key to the initial administrative user of the account. Either admin_password or admin_rsa_public_key has to be specified. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `admin_user_type` (String) Used for setting the type of the first user that is assigned the ACCOUNTADMIN role during account creation. Valid options are: `PERSON` | `SERVICE` | `LEGACY_SERVICE` External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". - `comment` (String) Specifies a comment for the account. -- `first_name` (String, Sensitive) First name of the initial administrative user of the account -- `grace_period_in_days` (Number) Specifies the number of days to wait before dropping the account. The default is 3 days. -- `last_name` (String, Sensitive) Last name of the initial administrative user of the account -- `must_change_password` (Boolean) Specifies whether the new user created to administer the account is forced to change their password upon first login into the account. -- `region` (String) ID of the Snowflake Region where the account is created. If no value is provided, Snowflake creates the account in the same Snowflake Region as the current account (i.e. the account in which the CREATE ACCOUNT statement is executed.) -- `region_group` (String) ID of the Snowflake Region where the account is created. If no value is provided, Snowflake creates the account in the same Snowflake Region as the current account (i.e. the account in which the CREATE ACCOUNT statement is executed.) +- `first_name` (String, Sensitive) First name of the initial administrative user of the account. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `is_org_admin` (String) Sets an account property that determines whether the ORGADMIN role is enabled in the account. Only an organization administrator (i.e. user with the ORGADMIN role) can set the property. +- `last_name` (String, Sensitive) Last name of the initial administrative user of the account. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `must_change_password` (String) Specifies whether the new user created to administer the account is forced to change their password upon first login into the account. External changes for this field won't be detected. In case you want to apply external changes, you can re-create the resource manually using "terraform taint". +- `region` (String) [Snowflake Region ID](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html#label-snowflake-region-ids) of the region where the account is created. If no value is provided, Snowflake creates the account in the same Snowflake Region as the current account (i.e. the account in which the CREATE ACCOUNT statement is executed.) +- `region_group` (String) ID of the region group where the account is created. To retrieve the region group ID for existing accounts in your organization, execute the [SHOW REGIONS](https://docs.snowflake.com/en/sql-reference/sql/show-regions) command. For information about when you might need to specify region group, see [Region groups](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html#label-region-groups). ### Read-Only - `fully_qualified_name` (String) Fully qualified name of the resource. For more information, see [object name resolution](https://docs.snowflake.com/en/sql-reference/name-resolution). - `id` (String) The ID of this resource. -- `is_org_admin` (Boolean) Indicates whether the ORGADMIN role is enabled in an account. If TRUE, the role is enabled. +- `show_output` (List of Object) Outputs the result of `SHOW ACCOUNTS` for the given account. (see [below for nested schema](#nestedatt--show_output)) + + +### Nested Schema for `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) ## Import diff --git a/examples/resources/snowflake_account/resource.tf b/examples/resources/snowflake_account/resource.tf index 3de2897d40..6b53dacf8e 100644 --- a/examples/resources/snowflake_account/resource.tf +++ b/examples/resources/snowflake_account/resource.tf @@ -1,18 +1,10 @@ -provider "snowflake" { - role = "ORGADMIN" - alias = "orgadmin" + +## TODO: + +## Minimal +resource "snowflake_account" "minimal" { } -resource "snowflake_account" "ac1" { - provider = snowflake.orgadmin - name = "SNOWFLAKE_TEST_ACCOUNT" - admin_name = "John Doe" - admin_password = "Abcd1234!" - email = "john.doe@snowflake.com" - first_name = "John" - last_name = "Doe" - must_change_password = true - edition = "STANDARD" - comment = "Snowflake Test Account" - region = "AWS_US_WEST_2" +## Complete (with every optional set) +resource "snowflake_account" "complete" { } diff --git a/pkg/acceptance/helpers/random/certs.go b/pkg/acceptance/helpers/random/certs.go index ca74761ec0..b314a0cbfa 100644 --- a/pkg/acceptance/helpers/random/certs.go +++ b/pkg/acceptance/helpers/random/certs.go @@ -60,24 +60,6 @@ func GenerateRSAPublicKeyFromPrivateKey(t *testing.T, key *rsa.PrivateKey) (stri return encode(t, "RSA PUBLIC KEY", b), hash(t, b) } -func GenerateRSAPublicKeyBasedOnPrivateKey(t *testing.T, key *rsa.PrivateKey) (string, string) { - t.Helper() - - pub := key.Public() - b, err := x509.MarshalPKIXPublicKey(pub.(*rsa.PublicKey)) - require.NoError(t, err) - return encode(t, "RSA PUBLIC KEY", b), hash(t, b) -} - -func GenerateRSAPublicKeyBasedOnPrivateKey(t *testing.T, key *rsa.PrivateKey) (string, string) { - t.Helper() - - pub := key.Public() - b, err := x509.MarshalPKIXPublicKey(pub.(*rsa.PublicKey)) - require.NoError(t, err) - return encode(t, "RSA PUBLIC KEY", b), hash(t, b) -} - // GenerateRSAPrivateKey returns an RSA private key. func GenerateRSAPrivateKey(t *testing.T) *rsa.PrivateKey { t.Helper() diff --git a/pkg/acceptance/helpers/random/random_helpers.go b/pkg/acceptance/helpers/random/random_helpers.go index 6e11e7cd05..e9176206a9 100644 --- a/pkg/acceptance/helpers/random/random_helpers.go +++ b/pkg/acceptance/helpers/random/random_helpers.go @@ -1,9 +1,10 @@ package random import ( + "strings" + "github.com/brianvoe/gofakeit/v6" "github.com/hashicorp/go-uuid" - "strings" ) func UUID() string { diff --git a/pkg/resources/account.go b/pkg/resources/account.go index 72758965bd..22a620fc09 100644 --- a/pkg/resources/account.go +++ b/pkg/resources/account.go @@ -3,11 +3,15 @@ package resources import ( "context" "errors" + "fmt" + "strings" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider/docs" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/snowflakeroles" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" @@ -20,24 +24,23 @@ import ( var accountSchema = map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, - // TODO: Sensitive? - Description: "TODO", + Type: schema.TypeString, + Required: true, + Description: "Specifies the identifier (i.e. name) for the account. It be unique within an organization, regardless of which Snowflake Region the account is in and must start with an alphabetic character and cannot contain spaces or special characters except for underscores (_). Note that if the account name includes underscores, features that do not accept account names with underscores (e.g. Okta SSO or SCIM) can reference a version of the account name that substitutes hyphens (-) for the underscores.", ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](), }, "admin_name": { - Type: schema.TypeString, - Required: true, - // TODO: Sensitive? - Description: externalChangesNotDetectedFieldDescription("TODO"), + Type: schema.TypeString, + Required: true, + Sensitive: true, + Description: externalChangesNotDetectedFieldDescription("Login name of the initial administrative user of the account. A new user is created in the new account with this name and password and granted the ACCOUNTADMIN role in the account. A login name can be any string consisting of letters, numbers, and underscores. Login names are always case-insensitive."), DiffSuppressFunc: IgnoreAfterCreation, }, "admin_password": { Type: schema.TypeString, Optional: true, Sensitive: true, - Description: externalChangesNotDetectedFieldDescription("TODO"), + Description: externalChangesNotDetectedFieldDescription("Password for the initial administrative user of the account. Either admin_password or admin_rsa_public_key has to be specified."), DiffSuppressFunc: IgnoreAfterCreation, AtLeastOneOf: []string{"admin_password", "admin_rsa_public_key"}, }, @@ -45,15 +48,14 @@ var accountSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, Sensitive: true, - Description: externalChangesNotDetectedFieldDescription("TODO"), + Description: externalChangesNotDetectedFieldDescription("Assigns a public key to the initial administrative user of the account. Either admin_password or admin_rsa_public_key has to be specified."), DiffSuppressFunc: IgnoreAfterCreation, AtLeastOneOf: []string{"admin_password", "admin_rsa_public_key"}, }, "admin_user_type": { - Type: schema.TypeString, - Required: true, - // TODO: Valid options - Description: externalChangesNotDetectedFieldDescription("TODO"), + Type: schema.TypeString, + Optional: true, + Description: externalChangesNotDetectedFieldDescription(fmt.Sprintf("Used for setting the type of the first user that is assigned the ACCOUNTADMIN role during account creation. Valid options are: %s", docs.PossibleValuesListed(sdk.AllUserTypes))), DiffSuppressFunc: SuppressIfAny(IgnoreAfterCreation, NormalizeAndCompare(sdk.ToUserType)), ValidateDiagFunc: sdkValidation(sdk.ToUserType), }, @@ -61,28 +63,28 @@ var accountSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, Sensitive: true, - Description: externalChangesNotDetectedFieldDescription("TODO"), + Description: externalChangesNotDetectedFieldDescription("First name of the initial administrative user of the account."), DiffSuppressFunc: IgnoreAfterCreation, }, "last_name": { Type: schema.TypeString, Optional: true, Sensitive: true, - Description: externalChangesNotDetectedFieldDescription("TODO"), + Description: externalChangesNotDetectedFieldDescription("Last name of the initial administrative user of the account."), DiffSuppressFunc: IgnoreAfterCreation, }, "email": { Type: schema.TypeString, Required: true, Sensitive: true, - Description: externalChangesNotDetectedFieldDescription("TODO"), + Description: externalChangesNotDetectedFieldDescription("Email address of the initial administrative user of the account. This email address is used to send any notifications about the account."), DiffSuppressFunc: IgnoreAfterCreation, }, "must_change_password": { Type: schema.TypeString, Optional: true, Default: BooleanDefault, - Description: externalChangesNotDetectedFieldDescription("TODO"), + Description: externalChangesNotDetectedFieldDescription("Specifies whether the new user created to administer the account is forced to change their password upon first login into the account."), DiffSuppressFunc: IgnoreAfterCreation, ValidateDiagFunc: validateBooleanString, }, @@ -90,20 +92,20 @@ var accountSchema = map[string]*schema.Schema{ Type: schema.TypeString, Required: true, ForceNew: true, - Description: "TODO", + Description: fmt.Sprintf("Snowflake Edition of the account. See more about Snowflake Editions in the [official documentation](https://docs.snowflake.com/en/user-guide/intro-editions). Valid options are: %s", docs.PossibleValuesListed(sdk.AllAccountEditions)), ValidateDiagFunc: sdkValidation(sdk.ToAccountEdition), }, "region_group": { Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "ID of the region group where the account is created. To retrieve the region group ID for existing accounts in your organization, execute the [SHOW REGIONS](https://docs.snowflake.com/en/sql-reference/sql/show-regions) command. For information about when you might need to specify region group, see [Region groups](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html#label-region-groups).", }, "region": { Type: schema.TypeString, Optional: true, ForceNew: true, - Description: "TODO", + Description: "[Snowflake Region ID](https://docs.snowflake.com/en/user-guide/admin-account-identifier.html#label-snowflake-region-ids) of the region where the account is created. If no value is provided, Snowflake creates the account in the same Snowflake Region as the current account (i.e. the account in which the CREATE ACCOUNT statement is executed.)", }, "comment": { Type: schema.TypeString, @@ -123,12 +125,12 @@ var accountSchema = map[string]*schema.Schema{ Default: BooleanDefault, DiffSuppressFunc: IgnoreChangeToCurrentSnowflakeValueInShow("is_org_admin"), ValidateDiagFunc: validateBooleanString, - Description: "TODO", + Description: "Sets an account property that determines whether the ORGADMIN role is enabled in the account. Only an organization administrator (i.e. user with the ORGADMIN role) can set the property.", }, "grace_period_in_days": { Type: schema.TypeInt, Required: true, - Description: "TODO", + Description: "Specifies the number of days during which the account can be restored (“undropped”). The minimum is 3 days and the maximum is 90 days.", ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(3)), }, FullyQualifiedNameAttributeName: schemas.FullyQualifiedNameSchema, @@ -144,8 +146,7 @@ var accountSchema = map[string]*schema.Schema{ func Account() *schema.Resource { return &schema.Resource{ - // TODO: Desc - Description: "The account resource allows you to create and manage Snowflake accounts.", + Description: "The account resource allows you to create and manage Snowflake accounts. To use this resource, make sure you use an account with the ORGADMIN role.", CreateContext: TrackingCreateWrapper(resources.Account, CreateAccount), ReadContext: TrackingReadWrapper(resources.Account, ReadAccount(true)), UpdateContext: TrackingUpdateWrapper(resources.Account, UpdateAccount), @@ -161,7 +162,6 @@ func Account() *schema.Resource { StateContext: TrackingImportWrapper(resources.Account, ImportAccount), }, - // TODO: State upgrader SchemaVersion: 1, StateUpgraders: []schema.StateUpgrader{ { @@ -174,20 +174,6 @@ func Account() *schema.Resource { } } -func v0_99_0_AccountStateUpgrader(ctx context.Context, state map[string]any, meta any) (map[string]any, error) { - client := meta.(*provider.Context).Client - state["must_change_password"] = booleanStringFromBool(state["must_change_password"].(bool)) - state["is_org_admin"] = booleanStringFromBool(state["is_org_admin"].(bool)) - account, err := client.Accounts.ShowByID(ctx, sdk.NewAccountObjectIdentifier(state["name"].(string))) - if err != nil { - return nil, err - } - - state["id"] = helpers.EncodeResourceIdentifier(sdk.NewAccountIdentifier(account.OrganizationName, account.AccountName)) - - return state, nil -} - func ImportAccount(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) { client := meta.(*provider.Context).Client @@ -287,15 +273,6 @@ func CreateAccount(ctx context.Context, d *schema.ResourceData, meta any) diag.D opts.Comment = sdk.String(v.(string)) } - // TODO(TODO): next prs - //if v := d.Get("polaris"); v != BooleanDefault { - // parsedBool, err := booleanStringToBool(v.(string)) - // if err != nil { - // return diag.FromErr(err) - // } - // opts.Polaris = &parsedBool - //} - createResponse, err := client.Accounts.Create(ctx, id, opts) if err != nil { return diag.FromErr(err) @@ -441,7 +418,8 @@ func UpdateAccount(ctx context.Context, d *schema.ResourceData, meta any) diag.D Name: id.AccountId(), OrgAdmin: false, }, - }); err != nil && !strings.Contains(err.Error(), "already has ORGADMIN disabled") { // TODO: What to do about this error? + // This error may happen when a user removes is_org_admin, and previously it was explicitly set to false. + }); err != nil && !strings.Contains(err.Error(), "already has ORGADMIN disabled") { return diag.FromErr(err) } } diff --git a/pkg/resources/account_acceptance_test.go b/pkg/resources/account_acceptance_test.go index b64bb3ca52..94afd44903 100644 --- a/pkg/resources/account_acceptance_test.go +++ b/pkg/resources/account_acceptance_test.go @@ -2,6 +2,9 @@ package resources_test import ( "fmt" + "regexp" + "testing" + acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/resourceassert" @@ -15,8 +18,6 @@ import ( r "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-testing/plancheck" - "regexp" - "testing" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" @@ -445,7 +446,7 @@ func TestAcc_Account_IgnoreUpdateAfterCreationOnCertainFields(t *testing.T) { HasFullyQualifiedNameString(accountId.FullyQualifiedName()). HasAdminNameString(name). HasAdminPasswordString(pass). - //HasAdminUserType(). TODO + // HasAdminUserType(). TODO HasEmailString(email). HasFirstNameString(firstName). HasLastNameString(lastName). @@ -540,7 +541,7 @@ func TestAcc_Account_InvalidValues(t *testing.T) { }, { Config: config.FromModel(t, configModelInvalidGracePeriodInDays), - ExpectError: regexp.MustCompile("Error: expected grace_period_in_days to be at least \\(3\\), got 2"), + ExpectError: regexp.MustCompile(`Error: expected grace_period_in_days to be at least \(3\), got 2`), }, }, }) @@ -647,5 +648,3 @@ resource "snowflake_account" "test" { comment, ) } - -// TODO: State upgrader diff --git a/pkg/resources/account_state_upgraders.go b/pkg/resources/account_state_upgraders.go new file mode 100644 index 0000000000..63965731c8 --- /dev/null +++ b/pkg/resources/account_state_upgraders.go @@ -0,0 +1,24 @@ +package resources + +import ( + "context" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" +) + +func v0_99_0_AccountStateUpgrader(ctx context.Context, state map[string]any, meta any) (map[string]any, error) { + client := meta.(*provider.Context).Client + state["must_change_password"] = booleanStringFromBool(state["must_change_password"].(bool)) + state["is_org_admin"] = booleanStringFromBool(state["is_org_admin"].(bool)) + account, err := client.Accounts.ShowByID(ctx, sdk.NewAccountObjectIdentifier(state["name"].(string))) + if err != nil { + return nil, err + } + + state["id"] = helpers.EncodeResourceIdentifier(sdk.NewAccountIdentifier(account.OrganizationName, account.AccountName)) + + return state, nil +} diff --git a/pkg/sdk/accounts.go b/pkg/sdk/accounts.go index 02a22a6049..94a4dd8666 100644 --- a/pkg/sdk/accounts.go +++ b/pkg/sdk/accounts.go @@ -6,10 +6,11 @@ import ( "encoding/json" "errors" "fmt" - "github.com/snowflakedb/gosnowflake" "strings" "time" + "github.com/snowflakedb/gosnowflake" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/collections" ) @@ -43,6 +44,12 @@ var ( EditionBusinessCritical AccountEdition = "BUSINESS_CRITICAL" ) +var AllAccountEditions = []AccountEdition{ + EditionStandard, + EditionEnterprise, + EditionBusinessCritical, +} + // TODO: test func ToAccountEdition(edition string) (AccountEdition, error) { switch typedEdition := AccountEdition(strings.ToUpper(edition)); typedEdition { @@ -137,7 +144,7 @@ func (c *accounts) Create(ctx context.Context, id AccountObjectIdentifier, opts queryId := <-queryChanId rows, err := c.client.QueryUnsafe(gosnowflake.WithFetchResultByID(ctx, queryId), "") - if len(rows) == 1 && rows[0]["status"] != nil { + if err != nil && len(rows) == 1 && rows[0]["status"] != nil { if status, ok := (*rows[0]["status"]).(string); ok { return ToAccountCreateResponse(status) } diff --git a/pkg/sdk/accounts_test.go b/pkg/sdk/accounts_test.go index 8faca70e9c..3b5e48e5bd 100644 --- a/pkg/sdk/accounts_test.go +++ b/pkg/sdk/accounts_test.go @@ -3,9 +3,10 @@ package sdk import ( "encoding/json" "fmt" - "github.com/stretchr/testify/assert" "testing" + "github.com/stretchr/testify/assert" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random" )