Skip to content

Commit

Permalink
chore: Add usage tracking for the rest of the resources and fix views (
Browse files Browse the repository at this point in the history
…#3223)

## Changes
- Add usage tracking to the remaining resources (had to change their
method signature to the new one containing context)
- Fix views (trimmed the tracking comment from the text column that
contains the command run to create the view)
- Applied the same fix for materialized view and dynamic table that also
contain self reference to create command
  • Loading branch information
sfc-gh-jcieslak authored Nov 26, 2024
1 parent e2284d9 commit 231f653
Show file tree
Hide file tree
Showing 44 changed files with 1,150 additions and 1,018 deletions.
5 changes: 5 additions & 0 deletions pkg/internal/tracking/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"strings"
)

func TrimMetadata(sql string) string {
queryParts := strings.Split(sql, fmt.Sprintf(" --%s", MetadataPrefix))
return queryParts[0]
}

func AppendMetadata(sql string, metadata Metadata) (string, error) {
bytes, err := json.Marshal(metadata)
if err != nil {
Expand Down
37 changes: 37 additions & 0 deletions pkg/internal/tracking/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,47 @@ import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources"
"github.com/stretchr/testify/require"
)

func TestTrimMetadata(t *testing.T) {
testCases := []struct {
Input string
Expected string
}{
{
Input: "select 1",
Expected: "select 1",
},
{
Input: "select 1; --some comment",
Expected: "select 1; --some comment",
},
{
Input: fmt.Sprintf("select 1; --%s", MetadataPrefix),
Expected: "select 1;",
},
{
Input: fmt.Sprintf("select 1; --%s ", MetadataPrefix),
Expected: "select 1;",
},
{
Input: fmt.Sprintf("select 1; --%s some text after", MetadataPrefix),
Expected: "select 1;",
},
}

for _, tc := range testCases {
t.Run("TrimMetadata: "+tc.Input, func(t *testing.T) {
trimmedInput := TrimMetadata(tc.Input)
assert.Equal(t, tc.Expected, trimmedInput)
})
}
}

func TestAppendMetadata(t *testing.T) {
metadata := NewMetadata("123", resources.Account, CreateOperation)
sql := "SELECT 1"
Expand Down
13 changes: 13 additions & 0 deletions pkg/provider/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ type resource string

const (
Account resource = "snowflake_account"
AccountAuthenticationPolicyAttachment resource = "snowflake_account_authentication_policy_attachment"
AccountParameter resource = "snowflake_account_parameter"
AccountPasswordPolicyAttachment resource = "snowflake_account_password_policy_attachment"
AccountRole resource = "snowflake_account_role"
Alert resource = "snowflake_alert"
ApiAuthenticationIntegrationWithAuthorizationCodeGrant resource = "snowflake_api_authentication_integration_with_authorization_code_grant"
Expand Down Expand Up @@ -36,17 +39,21 @@ const (
MaskingPolicy resource = "snowflake_masking_policy"
MaterializedView resource = "snowflake_materialized_view"
NetworkPolicy resource = "snowflake_network_policy"
NetworkPolicyAttachment resource = "snowflake_network_policy_attachment"
NetworkRule resource = "snowflake_network_rule"
NotificationIntegration resource = "snowflake_notification_integration"
OauthIntegration resource = "snowflake_oauth_integration"
OauthIntegrationForCustomClients resource = "snowflake_oauth_integration_for_custom_clients"
OauthIntegrationForPartnerApplications resource = "snowflake_oauth_integration_for_partner_applications"
ObjectParameter resource = "snowflake_object_parameter"
PasswordPolicy resource = "snowflake_password_policy"
Pipe resource = "snowflake_pipe"
PrimaryConnection resource = "snowflake_primary_connection"
Procedure resource = "snowflake_procedure"
ResourceMonitor resource = "snowflake_resource_monitor"
Role resource = "snowflake_role"
RowAccessPolicy resource = "snowflake_row_access_policy"
SamlSecurityIntegration resource = "snowflake_saml_integration"
Saml2SecurityIntegration resource = "snowflake_saml2_integration"
Schema resource = "snowflake_schema"
ScimSecurityIntegration resource = "snowflake_scim_integration"
Expand All @@ -56,6 +63,7 @@ const (
SecretWithBasicAuthentication resource = "snowflake_secret_with_basic_authentication"
SecretWithClientCredentials resource = "snowflake_secret_with_client_credentials"
SecretWithGenericString resource = "snowflake_secret_with_generic_string"
SessionParameter resource = "snowflake_session_parameter"
Sequence resource = "snowflake_sequence"
ServiceUser resource = "snowflake_service_user"
Share resource = "snowflake_share"
Expand All @@ -69,12 +77,17 @@ const (
StreamOnView resource = "snowflake_stream_on_view"
Streamlit resource = "snowflake_streamlit"
Table resource = "snowflake_table"
TableColumnMaskingPolicyApplication resource = "snowflake_table_column_masking_policy_application"
TableConstraint resource = "snowflake_table_constraint"
Tag resource = "snowflake_tag"
TagAssociation resource = "snowflake_tag_association"
TagMaskingPolicyAssociation resource = "snowflake_tag_masking_policy_association"
Task resource = "snowflake_task"
UnsafeExecute resource = "snowflake_unsafe_execute"
User resource = "snowflake_user"
UserAuthenticationPolicyAttachment resource = "snowflake_user_authentication_policy_attachment"
UserPasswordPolicyAttachment resource = "snowflake_user_password_policy_attachment"
UserPublicKeys resource = "snowflake_user_public_keys"
View resource = "snowflake_view"
Warehouse resource = "snowflake_warehouse"
)
Expand Down
51 changes: 25 additions & 26 deletions pkg/resources/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
Expand Down Expand Up @@ -212,11 +214,11 @@ var accountSchema = map[string]*schema.Schema{

func Account() *schema.Resource {
return &schema.Resource{
Description: "The account resource allows you to create and manage Snowflake accounts.",
Create: CreateAccount,
Read: ReadAccount,
Update: UpdateAccount,
Delete: DeleteAccount,
Description: "The account resource allows you to create and manage Snowflake accounts.",
CreateContext: TrackingCreateWrapper(resources.Account, CreateAccount),
ReadContext: TrackingReadWrapper(resources.Account, ReadAccount),
UpdateContext: TrackingUpdateWrapper(resources.Account, UpdateAccount),
DeleteContext: TrackingDeleteWrapper(resources.Account, DeleteAccount),

CustomizeDiff: TrackingCustomDiffWrapper(resources.Account, customdiff.All(
ComputedIfAnyAttributeChanged(accountSchema, FullyQualifiedNameAttributeName, "name"),
Expand All @@ -230,9 +232,8 @@ func Account() *schema.Resource {
}

// CreateAccount implements schema.CreateFunc.
func CreateAccount(d *schema.ResourceData, meta interface{}) error {
func CreateAccount(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*provider.Context).Client
ctx := context.Background()

name := d.Get("name").(string)
objectIdentifier := sdk.NewAccountObjectIdentifier(name)
Expand Down Expand Up @@ -267,7 +268,7 @@ func CreateAccount(d *schema.ResourceData, meta interface{}) error {
// For organizations that have accounts in multiple region groups, returns <region_group>.<region> so we need to split on "."
currentRegion, err := client.ContextFunctions.CurrentRegion(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
regionParts := strings.Split(currentRegion, ".")
if len(regionParts) == 2 {
Expand All @@ -280,7 +281,7 @@ func CreateAccount(d *schema.ResourceData, meta interface{}) error {
// For organizations that have accounts in multiple region groups, returns <region_group>.<region> so we need to split on "."
currentRegion, err := client.ContextFunctions.CurrentRegion(ctx)
if err != nil {
return err
return diag.FromErr(err)
}
regionParts := strings.Split(currentRegion, ".")
if len(regionParts) == 2 {
Expand All @@ -295,7 +296,7 @@ func CreateAccount(d *schema.ResourceData, meta interface{}) error {

err := client.Accounts.Create(ctx, objectIdentifier, createOptions)
if err != nil {
return err
return diag.FromErr(err)
}

var account *sdk.Account
Expand All @@ -308,17 +309,16 @@ func CreateAccount(d *schema.ResourceData, meta interface{}) error {
return nil, true
})
if err != nil {
return err
return diag.FromErr(err)
}

d.SetId(helpers.EncodeSnowflakeID(account.AccountLocator))
return ReadAccount(d, meta)
return ReadAccount(ctx, d, meta)
}

// ReadAccount implements schema.ReadFunc.
func ReadAccount(d *schema.ResourceData, meta interface{}) error {
func ReadAccount(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*provider.Context).Client
ctx := context.Background()

id := helpers.DecodeSnowflakeID(d.Id()).(sdk.AccountObjectIdentifier)

Expand All @@ -333,42 +333,42 @@ func ReadAccount(d *schema.ResourceData, meta interface{}) error {
return nil, true
})
if err != nil {
return err
return diag.FromErr(err)
}

if err := d.Set(FullyQualifiedNameAttributeName, id.FullyQualifiedName()); err != nil {
return err
return diag.FromErr(err)
}

if err = d.Set("name", acc.AccountName); err != nil {
return fmt.Errorf("error setting name: %w", err)
return diag.FromErr(fmt.Errorf("error setting name: %w", err))
}

if err = d.Set("edition", acc.Edition); err != nil {
return fmt.Errorf("error setting edition: %w", err)
return diag.FromErr(fmt.Errorf("error setting edition: %w", err))
}

if err = d.Set("region_group", acc.RegionGroup); err != nil {
return fmt.Errorf("error setting region_group: %w", err)
return diag.FromErr(fmt.Errorf("error setting region_group: %w", err))
}

if err = d.Set("region", acc.SnowflakeRegion); err != nil {
return fmt.Errorf("error setting region: %w", err)
return diag.FromErr(fmt.Errorf("error setting region: %w", err))
}

if err = d.Set("comment", acc.Comment); err != nil {
return fmt.Errorf("error setting comment: %w", err)
return diag.FromErr(fmt.Errorf("error setting comment: %w", err))
}

if err = d.Set("is_org_admin", acc.IsOrgAdmin); err != nil {
return fmt.Errorf("error setting is_org_admin: %w", err)
return diag.FromErr(fmt.Errorf("error setting is_org_admin: %w", err))
}

return nil
}

// UpdateAccount implements schema.UpdateFunc.
func UpdateAccount(d *schema.ResourceData, meta interface{}) error {
func UpdateAccount(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
/*
todo: comments may eventually work again for accounts, so this can be uncommented when that happens
client := meta.(*provider.Context).Client
Expand All @@ -394,12 +394,11 @@ func UpdateAccount(d *schema.ResourceData, meta interface{}) error {
}

// DeleteAccount implements schema.DeleteFunc.
func DeleteAccount(d *schema.ResourceData, meta interface{}) error {
func DeleteAccount(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*provider.Context).Client
ctx := context.Background()
gracePeriodInDays := d.Get("grace_period_in_days").(int)
err := client.Accounts.Drop(ctx, helpers.DecodeSnowflakeID(d.Id()).(sdk.AccountObjectIdentifier), gracePeriodInDays, &sdk.DropAccountOptions{
IfExists: sdk.Bool(true),
})
return err
return diag.FromErr(err)
}
27 changes: 14 additions & 13 deletions pkg/resources/account_authentication_policy_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"context"
"fmt"

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

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
Expand All @@ -26,9 +29,9 @@ func AccountAuthenticationPolicyAttachment() *schema.Resource {
return &schema.Resource{
Description: "Specifies the authentication policy to use for the current account. To set the authentication policy of a different account, use a provider alias.",

Create: CreateAccountAuthenticationPolicyAttachment,
Read: ReadAccountAuthenticationPolicyAttachment,
Delete: DeleteAccountAuthenticationPolicyAttachment,
CreateContext: TrackingCreateWrapper(resources.AccountAuthenticationPolicyAttachment, CreateAccountAuthenticationPolicyAttachment),
ReadContext: TrackingReadWrapper(resources.AccountAuthenticationPolicyAttachment, ReadAccountAuthenticationPolicyAttachment),
DeleteContext: TrackingDeleteWrapper(resources.AccountAuthenticationPolicyAttachment, DeleteAccountAuthenticationPolicyAttachment),

Schema: accountAuthenticationPolicyAttachmentSchema,
Importer: &schema.ResourceImporter{
Expand All @@ -38,13 +41,12 @@ func AccountAuthenticationPolicyAttachment() *schema.Resource {
}

// CreateAccountAuthenticationPolicyAttachment implements schema.CreateFunc.
func CreateAccountAuthenticationPolicyAttachment(d *schema.ResourceData, meta interface{}) error {
func CreateAccountAuthenticationPolicyAttachment(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*provider.Context).Client
ctx := context.Background()

authenticationPolicy, ok := sdk.NewObjectIdentifierFromFullyQualifiedName(d.Get("authentication_policy").(string)).(sdk.SchemaObjectIdentifier)
if !ok {
return fmt.Errorf("authentication_policy %s is not a valid authentication policy qualified name, expected format: `\"db\".\"schema\".\"policy\"`", d.Get("authentication_policy"))
return diag.FromErr(fmt.Errorf("authentication_policy %s is not a valid authentication policy qualified name, expected format: `\"db\".\"schema\".\"policy\"`", d.Get("authentication_policy")))
}

err := client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{
Expand All @@ -53,35 +55,34 @@ func CreateAccountAuthenticationPolicyAttachment(d *schema.ResourceData, meta in
},
})
if err != nil {
return err
return diag.FromErr(err)
}

d.SetId(helpers.EncodeSnowflakeID(authenticationPolicy))

return ReadAccountAuthenticationPolicyAttachment(d, meta)
return ReadAccountAuthenticationPolicyAttachment(ctx, d, meta)
}

func ReadAccountAuthenticationPolicyAttachment(d *schema.ResourceData, meta interface{}) error {
func ReadAccountAuthenticationPolicyAttachment(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
authenticationPolicy := helpers.DecodeSnowflakeID(d.Id())
if err := d.Set("authentication_policy", authenticationPolicy.FullyQualifiedName()); err != nil {
return err
return diag.FromErr(err)
}

return nil
}

// DeleteAccountAuthenticationPolicyAttachment implements schema.DeleteFunc.
func DeleteAccountAuthenticationPolicyAttachment(d *schema.ResourceData, meta interface{}) error {
func DeleteAccountAuthenticationPolicyAttachment(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*provider.Context).Client
ctx := context.Background()

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

return nil
Expand Down
Loading

0 comments on commit 231f653

Please sign in to comment.