Skip to content

Commit

Permalink
Propose additional debug logging
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-asawicki committed Dec 8, 2023
1 parent 774a7db commit 17a15a6
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 2 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ Some links that might help you:
- **If you are an enterprise customer**, reach out to your account team. This helps us prioritize issues.
- The [issues section](https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues) might already have an issue addressing your question.

## Additional debug logs for `snowflake_grant_privileges_to_role` resource
Set environment variable `SF_TF_ADDITIONAL_DEBUG_LOGGING` to a non-empty value. Additional logs will be visible with `sf-tf-additional-debug` prefix, e.g.:
```text
2023/12/08 12:58:22.497078 sf-tf-additional-debug [DEBUG] Creating new client from db
```

## Contributing

Cf. [Contributing](./CONTRIBUTING.md).
18 changes: 18 additions & 0 deletions pkg/internal/logging/debug_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package logging

import (
"io"
"log"
"os"
)

func init() {
additionalDebugLoggingEnabled = os.Getenv("SF_TF_ADDITIONAL_DEBUG_LOGGING") != ""
DebugLogger = log.New(os.Stderr, "sf-tf-additional-debug ", log.LstdFlags|log.Lmsgprefix|log.LUTC|log.Lmicroseconds)
if !additionalDebugLoggingEnabled {
DebugLogger.SetOutput(io.Discard)
}
}

var additionalDebugLoggingEnabled bool

Check failure on line 17 in pkg/internal/logging/debug_helpers.go

View workflow job for this annotation

GitHub Actions / reviewdog

[golangci] reported by reviewdog 🐶 File is not `gofumpt`-ed (gofumpt) Raw Output: pkg/internal/logging/debug_helpers.go:17: File is not `gofumpt`-ed (gofumpt) var additionalDebugLoggingEnabled bool var DebugLogger *log.Logger
var DebugLogger *log.Logger
58 changes: 57 additions & 1 deletion pkg/resources/grant_privileges_to_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging"

Check failure on line 7 in pkg/resources/grant_privileges_to_role.go

View workflow job for this annotation

GitHub Actions / reviewdog

[golangci] reported by reviewdog 🐶 File is not `gofumpt`-ed (gofumpt) Raw Output: pkg/resources/grant_privileges_to_role.go:7: File is not `gofumpt`-ed (gofumpt) "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging"
"log"
"strings"

Expand Down Expand Up @@ -442,12 +443,15 @@ func (v GrantPrivilegesToAccountRoleID) String() string {
}

func CreateGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
logging.DebugLogger.Printf("[DEBUG] Entering create grant privileges to role")
db := meta.(*sql.DB)
logging.DebugLogger.Printf("[DEBUG] Creating new client from db")
client := sdk.NewClientFromDB(db)
ctx := context.Background()
resourceID := &GrantPrivilegesToAccountRoleID{}
var privileges []string
if p, ok := d.GetOk("privileges"); ok {
logging.DebugLogger.Printf("[DEBUG] Building privileges list based on config")
privileges = expandStringList(p.(*schema.Set).List())
resourceID.Privileges = privileges
}
Expand All @@ -465,17 +469,22 @@ func CreateGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error
roleName := d.Get("role_name").(string)
resourceID.RoleName = roleName
roleID := sdk.NewAccountObjectIdentifier(roleName)
logging.DebugLogger.Printf("[DEBUG] About to grant privileges to account role")
err = client.Grants.GrantPrivilegesToAccountRole(ctx, privilegesToGrant, on, roleID, &opts)
logging.DebugLogger.Printf("[DEBUG] After granting privileges to account role: err = %v", err)
if err != nil {
return fmt.Errorf("error granting privileges to account role: %w", err)
}

logging.DebugLogger.Printf("[DEBUG] Setting ID to %s", resourceID.String())
d.SetId(resourceID.String())
return ReadGrantPrivilegesToRole(d, meta)
}

func ReadGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
logging.DebugLogger.Printf("[DEBUG] Entering read grant privileges to role")
db := meta.(*sql.DB)
logging.DebugLogger.Printf("[DEBUG] Creating new client from db")
client := sdk.NewClientFromDB(db)
ctx := context.Background()
resourceID := NewGrantPrivilegesToAccountRoleID(d.Id())
Expand All @@ -488,6 +497,7 @@ func ReadGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
var opts sdk.ShowGrantOptions
var grantOn sdk.ObjectType
if resourceID.OnAccount {
logging.DebugLogger.Printf("[DEBUG] Preparing to read privileges: on account")
grantOn = sdk.ObjectTypeAccount
opts = sdk.ShowGrantOptions{
On: &sdk.ShowGrantsOn{
Expand All @@ -497,6 +507,7 @@ func ReadGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
}

if resourceID.OnAccountObject {
logging.DebugLogger.Printf("[DEBUG] Preparing to read privileges: on account object")
objectType := sdk.ObjectType(resourceID.ObjectType)
grantOn = objectType
opts = sdk.ShowGrantOptions{
Expand All @@ -510,6 +521,7 @@ func ReadGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
}

if resourceID.OnSchema {
logging.DebugLogger.Printf("[DEBUG] Preparing to read privileges: on schema")
grantOn = sdk.ObjectTypeSchema
if resourceID.SchemaName != "" {
opts = sdk.ShowGrantOptions{
Expand All @@ -536,6 +548,7 @@ func ReadGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
}

if resourceID.OnSchemaObject {
logging.DebugLogger.Printf("[DEBUG] Preparing to read privileges: on schema object")
if resourceID.ObjectName != "" {
objectType := sdk.ObjectType(resourceID.ObjectType)
grantOn = objectType
Expand Down Expand Up @@ -582,15 +595,19 @@ func ReadGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
}

func UpdateGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
logging.DebugLogger.Printf("[DEBUG] Entering update grant privileges to role")
db := meta.(*sql.DB)
logging.DebugLogger.Printf("[DEBUG] Creating new client from db")
client := sdk.NewClientFromDB(db)
ctx := context.Background()

// the only thing that can change is "privileges"
roleName := d.Get("role_name").(string)
roleID := sdk.NewAccountObjectIdentifier(roleName)

logging.DebugLogger.Printf("[DEBUG] Checking if privileges have changed")
if d.HasChange("privileges") {
logging.DebugLogger.Printf("[DEBUG] Privileges have changed")
old, new := d.GetChange("privileges")
oldPrivileges := expandStringList(old.(*schema.Set).List())
newPrivileges := expandStringList(new.(*schema.Set).List())
Expand All @@ -611,27 +628,34 @@ func UpdateGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error

// first add new privileges
if len(addPrivileges) > 0 {
logging.DebugLogger.Printf("[DEBUG] Adding new privileges")
privilegesToGrant, on, err := configureAccountRoleGrantPrivilegeOptions(d, addPrivileges, false, &GrantPrivilegesToAccountRoleID{})
if err != nil {
return fmt.Errorf("error configuring account role grant privilege options: %w", err)
}
logging.DebugLogger.Printf("[DEBUG] About to grant privileges to account role")
err = client.Grants.GrantPrivilegesToAccountRole(ctx, privilegesToGrant, on, roleID, nil)
logging.DebugLogger.Printf("[DEBUG] After granting privileges to account role: err = %v", err)
if err != nil {
return fmt.Errorf("error granting privileges to account role: %w", err)
}
}

// then remove old privileges
if len(removePrivileges) > 0 {
logging.DebugLogger.Printf("[DEBUG] Removing old privileges")
privilegesToRevoke, on, err := configureAccountRoleGrantPrivilegeOptions(d, removePrivileges, false, &GrantPrivilegesToAccountRoleID{})
if err != nil {
return fmt.Errorf("error configuring account role grant privilege options: %w", err)
}
logging.DebugLogger.Printf("[DEBUG] About to revoke privileges from account role")
err = client.Grants.RevokePrivilegesFromAccountRole(ctx, privilegesToRevoke, on, roleID, nil)
logging.DebugLogger.Printf("[DEBUG] After revoking privileges from account role: err = %v", err)
if err != nil {
return fmt.Errorf("error revoking privileges from account role: %w", err)
}
}
logging.DebugLogger.Printf("[DEBUG] Setting new values")
resourceID := NewGrantPrivilegesToAccountRoleID(d.Id())
resourceID.Privileges = newPrivileges
d.SetId(resourceID.String())
Expand All @@ -640,7 +664,9 @@ func UpdateGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error
}

func DeleteGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error {
logging.DebugLogger.Printf("[DEBUG] Entering delete grant privileges to role")
db := meta.(*sql.DB)
logging.DebugLogger.Printf("[DEBUG] Creating new client from db")
client := sdk.NewClientFromDB(db)
ctx := context.Background()

Expand All @@ -656,26 +682,31 @@ func DeleteGrantPrivilegesToRole(d *schema.ResourceData, meta interface{}) error
if err != nil {
return fmt.Errorf("error configuring account role grant privilege options: %w", err)
}

logging.DebugLogger.Printf("[DEBUG] About to revoke privileges from account role")
err = client.Grants.RevokePrivilegesFromAccountRole(ctx, privilegesToRevoke, on, roleID, nil)
logging.DebugLogger.Printf("[DEBUG] After revoking privileges from account role: err = %v", err)
if err != nil {
return fmt.Errorf("error revoking privileges from account role: %w", err)
}
logging.DebugLogger.Printf("[DEBUG] Cleaning resource id")
d.SetId("")
return nil
}

func configureAccountRoleGrantPrivilegeOptions(d *schema.ResourceData, privileges []string, allPrivileges bool, resourceID *GrantPrivilegesToAccountRoleID) (*sdk.AccountRoleGrantPrivileges, *sdk.AccountRoleGrantOn, error) {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options")
var privilegesToGrant *sdk.AccountRoleGrantPrivileges
on := sdk.AccountRoleGrantOn{}
if v, ok := d.GetOk("on_account"); ok && v.(bool) {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: on account")
on.Account = sdk.Bool(true)
resourceID.OnAccount = true
privilegesToGrant = setAccountRolePrivilegeOptions(privileges, allPrivileges, true, false, false, false)
return privilegesToGrant, &on, nil
}

if v, ok := d.GetOk("on_account_object"); ok && len(v.([]interface{})) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: on account object")
on.AccountObject = &sdk.GrantOnAccountObject{}
resourceID.OnAccountObject = true
onAccountObject := v.([]interface{})[0].(map[string]interface{})
Expand Down Expand Up @@ -707,21 +738,25 @@ func configureAccountRoleGrantPrivilegeOptions(d *schema.ResourceData, privilege
}

if v, ok := d.GetOk("on_schema"); ok && len(v.([]interface{})) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: on schema")
onSchema := v.([]interface{})[0].(map[string]interface{})
on.Schema = &sdk.GrantOnSchema{}
resourceID.OnSchema = true
if v, ok := onSchema["schema_name"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting schema name")
resourceID.SchemaName = v.(string)
on.Schema.Schema = sdk.Pointer(sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(v.(string)))
}
if v, ok := onSchema["all_schemas_in_database"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting all schemas in database")
resourceID.All = true
resourceID.InDatabase = true
resourceID.DatabaseName = v.(string)
on.Schema.AllSchemasInDatabase = sdk.Pointer(sdk.NewAccountObjectIdentifierFromFullyQualifiedName(v.(string)))
}

if v, ok := onSchema["future_schemas_in_database"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting future schemas in database")
resourceID.Future = true
resourceID.InDatabase = true
resourceID.DatabaseName = v.(string)
Expand All @@ -732,51 +767,60 @@ func configureAccountRoleGrantPrivilegeOptions(d *schema.ResourceData, privilege
}

if v, ok := d.GetOk("on_schema_object"); ok && len(v.([]interface{})) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: on schema object")
onSchemaObject := v.([]interface{})[0].(map[string]interface{})
on.SchemaObject = &sdk.GrantOnSchemaObject{}
resourceID.OnSchemaObject = true
if v, ok := onSchemaObject["object_type"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting schema object type")
resourceID.ObjectType = v.(string)
on.SchemaObject.SchemaObject = &sdk.Object{
ObjectType: sdk.ObjectType(v.(string)),
}
}
if v, ok := onSchemaObject["object_name"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting schema object name")
resourceID.ObjectName = v.(string)
on.SchemaObject.SchemaObject.Name = sdk.Pointer(sdk.NewSchemaObjectIdentifierFromFullyQualifiedName(v.(string)))
}
if v, ok := onSchemaObject["all"]; ok && len(v.([]interface{})) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting all")
all := v.([]interface{})[0].(map[string]interface{})
on.SchemaObject.All = &sdk.GrantOnSchemaObjectIn{}
resourceID.All = true
pluralObjectType := all["object_type_plural"].(string)
resourceID.ObjectTypePlural = pluralObjectType
on.SchemaObject.All.PluralObjectType = sdk.PluralObjectType(pluralObjectType)
if v, ok := all["in_database"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting all in database")
resourceID.InDatabase = true
resourceID.DatabaseName = v.(string)
on.SchemaObject.All.InDatabase = sdk.Pointer(sdk.NewAccountObjectIdentifierFromFullyQualifiedName(v.(string)))
}
if v, ok := all["in_schema"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting all in schema")
resourceID.InSchema = true
resourceID.SchemaName = v.(string)
on.SchemaObject.All.InSchema = sdk.Pointer(sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(v.(string)))
}
}

if v, ok := onSchemaObject["future"]; ok && len(v.([]interface{})) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting future")
future := v.([]interface{})[0].(map[string]interface{})
resourceID.Future = true
on.SchemaObject.Future = &sdk.GrantOnSchemaObjectIn{}
pluralObjectType := future["object_type_plural"].(string)
resourceID.ObjectTypePlural = pluralObjectType
on.SchemaObject.Future.PluralObjectType = sdk.PluralObjectType(pluralObjectType)
if v, ok := future["in_database"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting future in database")
resourceID.InDatabase = true
resourceID.DatabaseName = v.(string)
on.SchemaObject.Future.InDatabase = sdk.Pointer(sdk.NewAccountObjectIdentifierFromFullyQualifiedName(v.(string)))
}
if v, ok := future["in_schema"]; ok && len(v.(string)) > 0 {
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: setting future in schema")
resourceID.InSchema = true
resourceID.SchemaName = v.(string)
on.SchemaObject.Future.InSchema = sdk.Pointer(sdk.NewDatabaseObjectIdentifierFromFullyQualifiedName(v.(string)))
Expand All @@ -786,48 +830,57 @@ func configureAccountRoleGrantPrivilegeOptions(d *schema.ResourceData, privilege
privilegesToGrant = setAccountRolePrivilegeOptions(privileges, allPrivileges, false, false, false, true)
return privilegesToGrant, &on, nil
}
logging.DebugLogger.Printf("[DEBUG] Configuring account role grant privileges options: invalid")
return nil, nil, fmt.Errorf("invalid grant options")
}

func setAccountRolePrivilegeOptions(privileges []string, allPrivileges bool, onAccount bool, onAccountObject bool, onSchema bool, onSchemaObject bool) *sdk.AccountRoleGrantPrivileges {
privilegesToGrant := &sdk.AccountRoleGrantPrivileges{}
if allPrivileges {
logging.DebugLogger.Printf("[DEBUG] Setting all privileges on privileges to grant")
privilegesToGrant.AllPrivileges = sdk.Bool(true)
return privilegesToGrant
}
if onAccount {
logging.DebugLogger.Printf("[DEBUG] Setting global privileges on privileges to grant")
privilegesToGrant.GlobalPrivileges = []sdk.GlobalPrivilege{}
for _, privilege := range privileges {
privilegesToGrant.GlobalPrivileges = append(privilegesToGrant.GlobalPrivileges, sdk.GlobalPrivilege(privilege))
}
return privilegesToGrant
}
if onAccountObject {
logging.DebugLogger.Printf("[DEBUG] Setting account object privileges on privileges to grant")
privilegesToGrant.AccountObjectPrivileges = []sdk.AccountObjectPrivilege{}
for _, privilege := range privileges {
privilegesToGrant.AccountObjectPrivileges = append(privilegesToGrant.AccountObjectPrivileges, sdk.AccountObjectPrivilege(privilege))
}
return privilegesToGrant
}
if onSchema {
logging.DebugLogger.Printf("[DEBUG] Setting schema privileges on privileges to grant")
privilegesToGrant.SchemaPrivileges = []sdk.SchemaPrivilege{}
for _, privilege := range privileges {
privilegesToGrant.SchemaPrivileges = append(privilegesToGrant.SchemaPrivileges, sdk.SchemaPrivilege(privilege))
}
return privilegesToGrant
}
if onSchemaObject {
logging.DebugLogger.Printf("[DEBUG] Setting schema object privileges on privileges to grant")
privilegesToGrant.SchemaObjectPrivileges = []sdk.SchemaObjectPrivilege{}
for _, privilege := range privileges {
privilegesToGrant.SchemaObjectPrivileges = append(privilegesToGrant.SchemaObjectPrivileges, sdk.SchemaObjectPrivilege(privilege))
}
return privilegesToGrant
}
logging.DebugLogger.Printf("[DEBUG] Not setting any privileges on privileges to grant")
return nil
}

func readAccountRoleGrantPrivileges(ctx context.Context, client *sdk.Client, grantedOn sdk.ObjectType, id GrantPrivilegesToAccountRoleID, opts *sdk.ShowGrantOptions, d *schema.ResourceData) error {
logging.DebugLogger.Printf("[DEBUG] About to show grants")
grants, err := client.Grants.Show(ctx, opts)
logging.DebugLogger.Printf("[DEBUG] After showing grants: err = %v", err)
if err != nil {
return fmt.Errorf("error retrieving grants for account role: %w", err)
}
Expand All @@ -836,6 +889,7 @@ func readAccountRoleGrantPrivileges(ctx context.Context, client *sdk.Client, gra
privileges := []string{}
roleName := d.Get("role_name").(string)

logging.DebugLogger.Printf("[DEBUG] Filtering grants to be set on account: count = %d", len(grants))
for _, grant := range grants {
// Only consider privileges that are already present in the ID so we
// don't delete privileges managed by other resources.
Expand All @@ -854,7 +908,9 @@ func readAccountRoleGrantPrivileges(ctx context.Context, client *sdk.Client, gra
}
}
}
logging.DebugLogger.Printf("[DEBUG] Setting privileges on account")
if err := d.Set("privileges", privileges); err != nil {
logging.DebugLogger.Printf("[DEBUG] Error setting privileges for account role: err = %v", err)
return fmt.Errorf("error setting privileges for account role: %w", err)
}
return nil
Expand Down
Loading

0 comments on commit 17a15a6

Please sign in to comment.