Skip to content

Commit

Permalink
feat: account password policy attachment (#1824)
Browse files Browse the repository at this point in the history
* Add password policy qualified name attribute.

* Add snowflake_account_password_policy_attachment resource.
  • Loading branch information
sfc-gh-ngaberel authored Jun 14, 2023
1 parent 6aa8fa1 commit f408828
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 0 deletions.
38 changes: 38 additions & 0 deletions docs/resources/account_password_policy_attachment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "snowflake_account_password_policy_attachment Resource - terraform-provider-snowflake"
subcategory: ""
description: |-
Specifies the password policy to use for the current account. To set the password policy of a different account, use a provider alias.
---

# snowflake_account_password_policy_attachment (Resource)

Specifies the password policy to use for the current account. To set the password policy of a different account, use a provider alias.

## Example Usage

```terraform
resource "snowflake_password_policy" "default" {
database = "prod"
schema = "security"
name = "default_policy"
}
resource "snowflake_account_password_policy_attachment" "attachment" {
password_policy = snowflake_password_policy.default.qualified_name
}
```

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

### Required

- `password_policy` (String) Qualified name (`"db"."schema"."policy_name"`) of the password policy to apply to the current account.

### Read-Only

- `id` (String) The ID of this resource.


1 change: 1 addition & 0 deletions docs/resources/password_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@ A password policy specifies the requirements that must be met to create and rese
### Read-Only

- `id` (String) The ID of this resource.
- `qualified_name` (String) The qualified name for the password policy.


Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "snowflake_password_policy" "default" {
database = "prod"
schema = "security"
name = "default_policy"
}

resource "snowflake_account_password_policy_attachment" "attachment" {
password_policy = snowflake_password_policy.default.qualified_name
}
1 change: 1 addition & 0 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ func getResources() map[string]*schema.Resource {
// NOTE(): do not add grant resources here
others := map[string]*schema.Resource{
"snowflake_account": resources.Account(),
"snowflake_account_password_policy_attachment": resources.AccountPasswordPolicyAttachment(),
"snowflake_account_parameter": resources.AccountParameter(),
"snowflake_alert": resources.Alert(),
"snowflake_api_integration": resources.APIIntegration(),
Expand Down
89 changes: 89 additions & 0 deletions pkg/resources/account_password_policy_attachment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package resources

import (
"context"
"database/sql"
"fmt"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var accountPasswordPolicyAttachmentSchema = map[string]*schema.Schema{
"password_policy": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Qualified name (`\"db\".\"schema\".\"policy_name\"`) of the password policy to apply to the current account.",
},
}

// AccountPasswordPolicyAttachment returns a pointer to the resource representing an api integration.
func AccountPasswordPolicyAttachment() *schema.Resource {
return &schema.Resource{
Description: "Specifies the password policy to use for the current account. To set the password policy of a different account, use a provider alias.",

Create: CreateAccountPasswordPolicyAttachment,
Read: ReadAccountPasswordPolicyAttachment,
Delete: DeleteAccountPasswordPolicyAttachment,

Schema: accountPasswordPolicyAttachmentSchema,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
}
}

// CreateAccountPasswordPolicyAttachment implements schema.CreateFunc.
func CreateAccountPasswordPolicyAttachment(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
client := sdk.NewClientFromDB(db)
ctx := context.Background()

passwordPolicy, ok := sdk.NewObjectIdentifierFromFullyQualifiedName(d.Get("password_policy").(string)).(sdk.SchemaObjectIdentifier)
if !ok {
return fmt.Errorf("password_policy %s is not a valid password policy qualified name, expected format: `\"db\".\"schema\".\"policy\"`", d.Get("password_policy"))
}
// passwordPolicy := sdk.NewAccountObjectIdentifier(d.Get("password_policy").(string))

err := client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{
Set: &sdk.AccountSet{
PasswordPolicy: passwordPolicy,
},
})
if err != nil {
return err
}

d.SetId(helpers.EncodeSnowflakeID(passwordPolicy))

return nil
}

func ReadAccountPasswordPolicyAttachment(d *schema.ResourceData, meta interface{}) error {
passwordPolicy := helpers.DecodeSnowflakeID(d.Id())
if err := d.Set("password_policy", passwordPolicy.FullyQualifiedName()); err != nil {
return err
}

return nil
}

// DeleteAccountPasswordPolicyAttachment implements schema.DeleteFunc.
func DeleteAccountPasswordPolicyAttachment(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
client := sdk.NewClientFromDB(db)
ctx := context.Background()

err := client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{
Unset: &sdk.AccountUnset{
PasswordPolicy: sdk.Bool(true),
},
})
if err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package resources_test

import (
"fmt"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAcc_AccountPasswordPolicyAttachment(t *testing.T) {
prefix := "tst-terraform" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))

resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: accountPasswordPolicyAttachmentConfig(prefix),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("snowflake_account_password_policy_attachment.att", "id"),
),
},
{
ResourceName: "snowflake_account_password_policy_attachment.att",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"initially_suspended",
"wait_for_provisioning",
"query_acceleration_max_scale_factor",
"max_concurrency_level",
"statement_queued_timeout_in_seconds",
"statement_timeout_in_seconds",
},
},
},
})
}

func accountPasswordPolicyAttachmentConfig(prefix string) string {
s := `
resource "snowflake_database" "test" {
name = "%v"
comment = "Terraform acceptance test"
}
resource "snowflake_schema" "test" {
name = "%v"
database = snowflake_database.test.name
comment = "Terraform acceptance test"
}
resource "snowflake_password_policy" "pa" {
database = snowflake_database.test.name
schema = snowflake_schema.test.name
name = "%v"
}
resource "snowflake_account_password_policy_attachment" "att" {
password_policy = snowflake_password_policy.pa.qualified_name
}
`
return fmt.Sprintf(s, prefix, prefix, prefix)
}
10 changes: 10 additions & 0 deletions pkg/resources/password_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ var passwordPolicySchema = map[string]*schema.Schema{
Optional: true,
Description: "Adds a comment or overwrites an existing comment for the password policy.",
},
"qualified_name": {
Type: schema.TypeString,
Computed: true,
Description: "The qualified name for the password policy.",
},
}

func PasswordPolicy() *schema.Resource {
Expand Down Expand Up @@ -175,6 +180,11 @@ func ReadPasswordPolicy(d *schema.ResourceData, meta interface{}) error {
client := sdk.NewClientFromDB(db)
ctx := context.Background()
objectIdentifier := helpers.DecodeSnowflakeID(d.Id()).(sdk.SchemaObjectIdentifier)

if err := d.Set("qualified_name", objectIdentifier.FullyQualifiedName()); err != nil {
return err
}

passwordPolicy, err := client.PasswordPolicies.ShowByID(ctx, objectIdentifier)
if err != nil {
return err
Expand Down

0 comments on commit f408828

Please sign in to comment.