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: use roles from the SDK #2405

Merged
merged 4 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 3 additions & 2 deletions pkg/datasources/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ var roleSchema = map[string]*schema.Schema{
// Role Snowflake Role resource.
func Role() *schema.Resource {
return &schema.Resource{
Read: ReadRole,
Schema: roleSchema,
Read: ReadRole,
Schema: roleSchema,
DeprecationMessage: "This resource is deprecated and will be removed in a future major version release. Please use snowflake_roles instead.",
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
71 changes: 39 additions & 32 deletions pkg/datasources/roles.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package datasources

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

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

var rolesSchema = map[string]*schema.Schema{
var accountRolesSchema = map[string]*schema.Schema{
"pattern": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -41,47 +42,53 @@ var rolesSchema = map[string]*schema.Schema{
},
}

// Roles Snowflake Roles resource.
func Roles() *schema.Resource {
return &schema.Resource{
Read: ReadRoles,
Schema: rolesSchema,
ReadContext: ReadAccountRoles,
Schema: accountRolesSchema,
}
}

// ReadRoles Reads the database metadata information.
func ReadRoles(d *schema.ResourceData, meta interface{}) error {
func ReadAccountRoles(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
db := meta.(*sql.DB)
d.SetId("roles_read")
rolePattern := d.Get("pattern").(string)
client := sdk.NewClientFromDB(db)

listRoles, err := snowflake.ListRoles(db, rolePattern)
if errors.Is(err, sql.ErrNoRows) {
log.Printf("[DEBUG] no roles found in account (%s)", d.Id())
d.SetId("")
return nil
} else if err != nil {
log.Println("[DEBUG] failed to list roles")
d.SetId("")
return nil
req := sdk.NewShowRoleRequest()
if pattern, ok := d.GetOk("pattern"); ok {
req.WithLike(sdk.NewLikeRequest(pattern.(string)))
}

log.Printf("[DEBUG] list roles: %v", listRoles)
roles, err := client.Roles.Show(ctx, req)
if err != nil {
return diag.Diagnostics{
diag.Diagnostic{
Severity: diag.Error,
Summary: "Failed to show account roles",
Detail: fmt.Sprintf("Search pattern: %v, err: %s", d.Get("pattern").(string), err),
},
}
}

roles := []map[string]interface{}{}
for _, role := range listRoles {
roleMap := map[string]interface{}{}
if !role.Name.Valid {
continue
mappedRoles := make([]map[string]any, len(roles))
for i, role := range roles {
mappedRoles[i] = map[string]any{
"name": role.Name,
"comment": role.Comment,
"owner": role.Owner,
}
roleMap["name"] = role.Name.String
roleMap["comment"] = role.Comment.String
roleMap["owner"] = role.Owner.String
roles = append(roles, roleMap)
}

if err := d.Set("roles", roles); err != nil {
return err
if err := d.Set("roles", mappedRoles); err != nil {
return diag.Diagnostics{
diag.Diagnostic{
Severity: diag.Error,
Summary: "Failed to set roles",
Detail: fmt.Sprintf("Search pattern: %v, err: %s", d.Get("pattern").(string), err),
},
}
}

d.SetId("roles_read")

return nil
}
80 changes: 80 additions & 0 deletions pkg/datasources/roles_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ package datasources_test

import (
"fmt"
"strconv"
"strings"
"testing"

acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance"
"github.com/hashicorp/terraform-plugin-testing/config"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/hashicorp/terraform-plugin-testing/tfversion"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)
Expand Down Expand Up @@ -43,6 +49,80 @@ func TestAcc_Roles(t *testing.T) {
})
}

func TestAcc_AccountRoles_basic(t *testing.T) {
accountRoleNamePrefix := "account_roles_test_prefix_"
accountRoleName1 := accountRoleNamePrefix + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
accountRoleName2 := accountRoleNamePrefix + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
accountRoleName3 := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
comment := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))

configVariables := config.Variables{
"account_role_name_1": config.StringVariable(accountRoleName1),
"account_role_name_2": config.StringVariable(accountRoleName2),
"account_role_name_3": config.StringVariable(accountRoleName3),
"pattern": config.StringVariable(accountRoleNamePrefix + "%"),
"comment": config.StringVariable(comment),
}

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
PreCheck: func() { acc.TestAccPreCheck(t) },
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.RequireAbove(tfversion.Version1_5_0),
},
Steps: []resource.TestStep{
{
ConfigDirectory: config.TestNameDirectory(),
ConfigVariables: configVariables,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.snowflake_roles.test", "roles.#", "2"),
containsAccountRole(accountRoleName1, comment),
containsAccountRole(accountRoleName2, comment),
doesntContainAccountRole(accountRoleName3, comment),
),
},
},
})
}

func doesntContainAccountRole(name string, comment string) func(s *terraform.State) error {
return func(state *terraform.State) error {
err := containsAccountRole(name, comment)(state)
if err.Error() == fmt.Sprintf("role %s not found", name) {
return nil
}
return fmt.Errorf("expected %s not to be present", name)
}
}

func containsAccountRole(name string, comment string) func(s *terraform.State) error {
return func(s *terraform.State) error {
for _, rs := range s.RootModule().Resources {
if rs.Type != "snowflake_roles" {
continue
}

iter, err := strconv.ParseInt(rs.Primary.Attributes["roles.#"], 10, 32)
if err != nil {
return err
}

for i := 0; i < int(iter); i++ {
if rs.Primary.Attributes[fmt.Sprintf("roles.%d.name", i)] == name {
actualComment := rs.Primary.Attributes[fmt.Sprintf("roles.%d.comment", i)]
if actualComment != comment {
return fmt.Errorf("expected comment: %s, but got: %s", comment, actualComment)
}

return nil
}
}
}

return fmt.Errorf("role %s not found", name)
}
}

func roles(roleName, roleName2, comment string) string {
return fmt.Sprintf(`
resource snowflake_role "test_role" {
Expand Down
23 changes: 23 additions & 0 deletions pkg/datasources/testdata/TestAcc_AccountRoles_basic/test.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
resource "snowflake_role" "test1" {
name = var.account_role_name_1
comment = var.comment
}

resource "snowflake_role" "test2" {
name = var.account_role_name_2
comment = var.comment
}

resource "snowflake_role" "test3" {
name = var.account_role_name_3
comment = var.comment
}

data "snowflake_roles" "test" {
depends_on = [
snowflake_role.test1,
snowflake_role.test2,
snowflake_role.test3,
]
pattern = var.pattern
}
19 changes: 19 additions & 0 deletions pkg/datasources/testdata/TestAcc_AccountRoles_basic/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
variable "account_role_name_1" {
type = string
}

variable "account_role_name_2" {
type = string
}

variable "account_role_name_3" {
type = string
}

variable "comment" {
type = string
}

variable "pattern" {
type = string
}
12 changes: 5 additions & 7 deletions pkg/resources/database_role_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ import (
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

var (
resourceName = "snowflake_database_role.test_db_role"
dbRoleName = "db_role_" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
comment = "dummy"
comment2 = "test comment"
)

func TestAcc_DatabaseRole(t *testing.T) {
resourceName := "snowflake_database_role.test_db_role"
dbRoleName := "db_role_" + strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
comment := "dummy"
comment2 := "test comment"

resource.Test(t, resource.TestCase{
Providers: acc.TestAccProviders(),
PreCheck: func() { acc.TestAccPreCheck(t) },
Expand Down
4 changes: 2 additions & 2 deletions pkg/resources/dynamic_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

var dynamicTableShema = map[string]*schema.Schema{
var dynamicTableSchema = map[string]*schema.Schema{
"or_replace": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -145,7 +145,7 @@ func DynamicTable() *schema.Resource {
Update: UpdateDynamicTable,
Delete: DeleteDynamicTable,

Schema: dynamicTableShema,
Schema: dynamicTableSchema,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
24 changes: 14 additions & 10 deletions pkg/resources/external_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,18 +285,22 @@ func UpdateExternalTable(d *schema.ResourceData, meta any) error {
if d.HasChange("tag") {
unsetTags, setTags := GetTagsDiff(d, "tag")

err := client.ExternalTables.Alter(ctx, sdk.NewAlterExternalTableRequest(id).WithUnsetTag(unsetTags))
if err != nil {
return fmt.Errorf("error setting tags on %v, err = %w", d.Id(), err)
if len(unsetTags) > 0 {
sfc-gh-swinkler marked this conversation as resolved.
Show resolved Hide resolved
err := client.ExternalTables.Alter(ctx, sdk.NewAlterExternalTableRequest(id).WithUnsetTag(unsetTags))
if err != nil {
return fmt.Errorf("error setting tags on %v, err = %w", d.Id(), err)
}
}

tagAssociationRequests := make([]*sdk.TagAssociationRequest, len(setTags))
for i, t := range setTags {
tagAssociationRequests[i] = sdk.NewTagAssociationRequest(t.Name, t.Value)
}
err = client.ExternalTables.Alter(ctx, sdk.NewAlterExternalTableRequest(id).WithSetTag(tagAssociationRequests))
if err != nil {
return fmt.Errorf("error setting tags on %v, err = %w", d.Id(), err)
if len(setTags) > 0 {
tagAssociationRequests := make([]*sdk.TagAssociationRequest, len(setTags))
for i, t := range setTags {
tagAssociationRequests[i] = sdk.NewTagAssociationRequest(t.Name, t.Value)
}
err := client.ExternalTables.Alter(ctx, sdk.NewAlterExternalTableRequest(id).WithSetTag(tagAssociationRequests))
if err != nil {
return fmt.Errorf("error setting tags on %v, err = %w", d.Id(), err)
}
}
}

Expand Down
Loading
Loading