diff --git a/pkg/resources/network_policy_attachment.go b/pkg/resources/network_policy_attachment.go index 55a5596eca..0a7aa141ff 100644 --- a/pkg/resources/network_policy_attachment.go +++ b/pkg/resources/network_policy_attachment.go @@ -3,13 +3,11 @@ package resources import ( "context" "database/sql" - "errors" "fmt" "log" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -78,8 +76,9 @@ func CreateNetworkPolicyAttachment(d *schema.ResourceData, meta interface{}) err // ReadNetworkPolicyAttachment implements schema.ReadFunc. func ReadNetworkPolicyAttachment(d *schema.ResourceData, meta interface{}) error { db := meta.(*sql.DB) + ctx := context.Background() + client := sdk.NewClientFromDB(db) policyName := strings.Replace(d.Id(), "_attachment", "", 1) - builder := snowflake.NetworkPolicy(policyName) var currentUsers []string if err := d.Set("network_policy_name", policyName); err != nil { @@ -89,14 +88,13 @@ func ReadNetworkPolicyAttachment(d *schema.ResourceData, meta interface{}) error if u, ok := d.GetOk("users"); ok { users := expandStringList(u.(*schema.Set).List()) for _, user := range users { - row := snowflake.QueryRow(db, builder.ShowOnUser(user)) - attachment, err := snowflake.ScanNetworkPolicyAttachment(row) - if errors.Is(err, sql.ErrNoRows) { + parameter, err := client.Parameters.ShowUserParameter(ctx, sdk.UserParameterNetworkPolicy, sdk.NewAccountObjectIdentifier(user)) + if err != nil { log.Printf("[DEBUG] network policy (%s) not found on user (%s)", d.Id(), user) continue } - if attachment.Level.String == "USER" && attachment.Key.String == "NETWORK_POLICY" && attachment.Value.String == policyName { + if parameter.Level == "USER" && parameter.Key == "NETWORK_POLICY" && parameter.Value == policyName { currentUsers = append(currentUsers, user) } } @@ -107,14 +105,14 @@ func ReadNetworkPolicyAttachment(d *schema.ResourceData, meta interface{}) error } isSetOnAccount := false - row := snowflake.QueryRow(db, builder.ShowOnAccount()) - attachment, err := snowflake.ScanNetworkPolicyAttachment(row) - if errors.Is(err, sql.ErrNoRows) { + + parameter, err := client.Parameters.ShowAccountParameter(ctx, sdk.AccountParameterNetworkPolicy) + if err != nil { log.Printf("[DEBUG] network policy (%s) not found on account", d.Id()) isSetOnAccount = false } - if err == nil && attachment.Level.String == "ACCOUNT" && attachment.Key.String == "NETWORK_POLICY" && attachment.Value.String == policyName { + if err == nil && parameter.Level == "ACCOUNT" && parameter.Key == "NETWORK_POLICY" && parameter.Value == policyName { isSetOnAccount = true } @@ -201,11 +199,12 @@ func DeleteNetworkPolicyAttachment(d *schema.ResourceData, meta interface{}) err // Note: the ip address of the session executing this SQL must be allowed by the network policy being set. func setOnAccount(d *schema.ResourceData, meta interface{}) error { db := meta.(*sql.DB) + ctx := context.Background() + client := sdk.NewClientFromDB(db) policyName := d.Get("network_policy_name").(string) - acctSQL := snowflake.NetworkPolicy(policyName).SetOnAccount() - - if err := snowflake.Exec(db, acctSQL); err != nil { + err := client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{Set: &sdk.AccountSet{Parameters: &sdk.AccountLevelParameters{ObjectParameters: &sdk.ObjectParameters{NetworkPolicy: sdk.String(policyName)}}}}) + if err != nil { return fmt.Errorf("error setting network policy %v on account err = %w", policyName, err) } @@ -215,11 +214,12 @@ func setOnAccount(d *schema.ResourceData, meta interface{}) error { // setOnAccount unsets the network policy globally for the Snowflake account. func unsetOnAccount(d *schema.ResourceData, meta interface{}) error { db := meta.(*sql.DB) + ctx := context.Background() + client := sdk.NewClientFromDB(db) policyName := d.Get("network_policy_name").(string) - acctSQL := snowflake.NetworkPolicy(policyName).UnsetOnAccount() - - if err := snowflake.Exec(db, acctSQL); err != nil { + err := client.Accounts.Alter(ctx, &sdk.AlterAccountOptions{Unset: &sdk.AccountUnset{Parameters: &sdk.AccountLevelParametersUnset{ObjectParameters: &sdk.ObjectParametersUnset{NetworkPolicy: sdk.Bool(true)}}}}) + if err != nil { return fmt.Errorf("error unsetting network policy %v on account err = %w", policyName, err) } @@ -241,9 +241,12 @@ func setOnUsers(users []string, data *schema.ResourceData, meta interface{}) err // setOnUser sets the network policy for a given user. func setOnUser(user string, data *schema.ResourceData, meta interface{}) error { db := meta.(*sql.DB) + ctx := context.Background() + client := sdk.NewClientFromDB(db) policyName := data.Get("network_policy_name").(string) - userSQL := snowflake.NetworkPolicy(policyName).SetOnUser(user) - if err := snowflake.Exec(db, userSQL); err != nil { + + err := client.Users.Alter(ctx, sdk.NewAccountObjectIdentifier(user), &sdk.AlterUserOptions{Set: &sdk.UserSet{ObjectParameters: &sdk.UserObjectParameters{NetworkPolicy: sdk.String(policyName)}}}) + if err != nil { return fmt.Errorf("error setting network policy %v on user %v err = %w", policyName, user, err) } @@ -265,9 +268,12 @@ func unsetOnUsers(users []string, data *schema.ResourceData, meta interface{}) e // unsetOnUser sets the network policy for a given user. func unsetOnUser(user string, data *schema.ResourceData, meta interface{}) error { db := meta.(*sql.DB) + ctx := context.Background() + client := sdk.NewClientFromDB(db) policyName := data.Get("network_policy_name").(string) - userSQL := snowflake.NetworkPolicy(policyName).UnsetOnUser(user) - if err := snowflake.Exec(db, userSQL); err != nil { + + err := client.Users.Alter(ctx, sdk.NewAccountObjectIdentifier(user), &sdk.AlterUserOptions{Unset: &sdk.UserUnset{ObjectParameters: &sdk.UserObjectParametersUnset{NetworkPolicy: sdk.Bool(true)}}}) + if err != nil { return fmt.Errorf("error unsetting network policy %v on user %v", policyName, user) } diff --git a/pkg/resources/network_policy_attachment_test.go b/pkg/resources/network_policy_attachment_test.go deleted file mode 100644 index ff9af671ff..0000000000 --- a/pkg/resources/network_policy_attachment_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package resources_test - -import ( - "database/sql" - "testing" - - sqlmock "github.com/DATA-DOG/go-sqlmock" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources" - . "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/testhelpers" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/stretchr/testify/require" -) - -func TestNetworkPolicyAttachment(t *testing.T) { - r := require.New(t) - err := resources.NetworkPolicyAttachment().InternalValidate(provider.Provider().Schema, true) - r.NoError(err) -} - -func TestNetworkPolicyAttachmentCreate(t *testing.T) { - r := require.New(t) - - in := map[string]interface{}{ - "network_policy_name": "test-network-policy", - "set_for_account": true, - "users": []interface{}{"test-user"}, - } - d := schema.TestResourceDataRaw(t, resources.NetworkPolicyAttachment().Schema, in) - r.NotNil(d) - - WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { - mock.ExpectExec(`^ALTER ACCOUNT SET NETWORK_POLICY = "test-network-policy"$`).WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec(`^DESCRIBE USER "test-user"$`).WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec(`^ALTER USER "test-user" SET NETWORK_POLICY = "test-network-policy"$`).WillReturnResult(sqlmock.NewResult(1, 1)) - - err := resources.CreateNetworkPolicyAttachment(d, db) - r.NoError(err) - }) -} - -func TestNetworkPolicyAttachmentSetOnAccountDelete(t *testing.T) { - r := require.New(t) - - in := map[string]interface{}{ - "network_policy_name": "test-network-policy", - "set_for_account": true, - "users": []interface{}{"test-user"}, - } - d := schema.TestResourceDataRaw(t, resources.NetworkPolicyAttachment().Schema, in) - r.NotNil(d) - - WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { - mock.ExpectExec(`^ALTER ACCOUNT UNSET NETWORK_POLICY$`).WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec(`^DESCRIBE USER "test-user"$`).WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec(`^ALTER USER "test-user" UNSET NETWORK_POLICY$`).WillReturnResult(sqlmock.NewResult(1, 1)) - - err := resources.DeleteNetworkPolicyAttachment(d, db) - r.NoError(err) - }) -} - -func TestNetworkPolicyAttachmentDelete(t *testing.T) { - r := require.New(t) - - in := map[string]interface{}{ - "network_policy_name": "test-network-policy", - "set_for_account": false, - "users": []interface{}{"test-user"}, - } - d := schema.TestResourceDataRaw(t, resources.NetworkPolicyAttachment().Schema, in) - r.NotNil(d) - - WithMockDb(t, func(db *sql.DB, mock sqlmock.Sqlmock) { - mock.ExpectExec(`^DESCRIBE USER "test-user"$`).WillReturnResult(sqlmock.NewResult(1, 1)) - mock.ExpectExec(`^ALTER USER "test-user" UNSET NETWORK_POLICY$`).WillReturnResult(sqlmock.NewResult(1, 1)) - - err := resources.DeleteNetworkPolicyAttachment(d, db) - r.NoError(err) - }) -} diff --git a/pkg/sdk/parameters.go b/pkg/sdk/parameters.go index 76b5f6a8f2..8bd98344ee 100644 --- a/pkg/sdk/parameters.go +++ b/pkg/sdk/parameters.go @@ -474,6 +474,7 @@ const ( UserParameterJsonIndent UserParameter = "JSON_INDENT" UserParameterLockTimeout UserParameter = "LOCK_TIMEOUT" UserParameterMultiStatementCount UserParameter = "MULTI_STATEMENT_COUNT" + UserParameterNetworkPolicy UserParameter = "NETWORK_POLICY" UserParameterQueryTag UserParameter = "QUERY_TAG" UserParameterQuotedIdentifiersIgnoreCase UserParameter = "QUOTED_IDENTIFIERS_IGNORE_CASE" UserParameterRowsPerResultset UserParameter = "ROWS_PER_RESULTSET" diff --git a/pkg/snowflake/network_policy.go b/pkg/snowflake/network_policy.go deleted file mode 100644 index d7d75dd5a5..0000000000 --- a/pkg/snowflake/network_policy.go +++ /dev/null @@ -1,72 +0,0 @@ -package snowflake - -import ( - "database/sql" - "fmt" - - "github.com/jmoiron/sqlx" -) - -// NetworkPolicyBuilder abstracts the creation of SQL queries for a Snowflake Network Policy. -type NetworkPolicyBuilder struct { - name string - comment string - allowedIPList string - blockedIPList string -} - -// NetworkPolicy returns a pointer to a Builder that abstracts the DDL operations for a network policy. -// -// Supported DDL operations are: -// - CREATE NETWORK POLICY -// - DROP NETWORK POLICY -// - SHOW NETWORK POLICIES -// -// [Snowflake Reference](https://docs.snowflake.com/en/user-guide/network-policies.html) -func NetworkPolicy(name string) *NetworkPolicyBuilder { - return &NetworkPolicyBuilder{ - name: name, - } -} - -// SetOnAccount returns the SQL query that will set the network policy globally on your Snowflake account. -func (npb *NetworkPolicyBuilder) SetOnAccount() string { - return fmt.Sprintf(`ALTER ACCOUNT SET NETWORK_POLICY = "%v"`, npb.name) -} - -// UnsetOnAccount returns the SQL query that will unset the network policy globally on your Snowflake account. -func (npb *NetworkPolicyBuilder) UnsetOnAccount() string { - return `ALTER ACCOUNT UNSET NETWORK_POLICY` -} - -// SetOnUser returns the SQL query that will set the network policy on a given user. -func (npb *NetworkPolicyBuilder) SetOnUser(u string) string { - return fmt.Sprintf(`ALTER USER "%v" SET NETWORK_POLICY = "%v"`, u, npb.name) -} - -// UnsetOnUser returns the SQL query that will unset the network policy of a given user. -func (npb *NetworkPolicyBuilder) UnsetOnUser(u string) string { - return fmt.Sprintf(`ALTER USER "%v" UNSET NETWORK_POLICY`, u) -} - -// ShowOnUser returns the SQL query that will SHOW network policy set on a specific User. -func (npb *NetworkPolicyBuilder) ShowOnUser(u string) string { - return fmt.Sprintf(`SHOW PARAMETERS LIKE 'network_policy' IN USER "%v"`, u) -} - -// ShowOnAccount returns the SQL query that will SHOW network policy set on Account. -func (npb *NetworkPolicyBuilder) ShowOnAccount() string { - return `SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT` -} - -type NetworkPolicyAttachmentStruct struct { - Key sql.NullString `db:"key"` - Value sql.NullString `db:"value"` - Level sql.NullString `db:"level"` -} - -func ScanNetworkPolicyAttachment(row *sqlx.Row) (*NetworkPolicyAttachmentStruct, error) { - r := &NetworkPolicyAttachmentStruct{} - err := row.StructScan(r) - return r, err -} diff --git a/pkg/snowflake/network_policy_test.go b/pkg/snowflake/network_policy_test.go deleted file mode 100644 index e85505dd64..0000000000 --- a/pkg/snowflake/network_policy_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package snowflake_test - -import ( - "testing" - - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake" - "github.com/stretchr/testify/require" -) - -func TestNetworkPolicySetOnAccount(t *testing.T) { - r := require.New(t) - s := snowflake.NetworkPolicy("test_network_policy") - r.NotNil(s) - - q := s.SetOnAccount() - r.Equal(`ALTER ACCOUNT SET NETWORK_POLICY = "test_network_policy"`, q) -} - -func TestNetworkPolicyUnsetOnAccount(t *testing.T) { - r := require.New(t) - s := snowflake.NetworkPolicy("test_network_policy") - r.NotNil(s) - - q := s.UnsetOnAccount() - r.Equal(`ALTER ACCOUNT UNSET NETWORK_POLICY`, q) -} - -func TestNetworkPolicySetOnUser(t *testing.T) { - r := require.New(t) - s := snowflake.NetworkPolicy("test_network_policy") - r.NotNil(s) - - q := s.SetOnUser("testuser") - r.Equal(`ALTER USER "testuser" SET NETWORK_POLICY = "test_network_policy"`, q) -} - -func TestNetworkPolicyUnsetOnUser(t *testing.T) { - r := require.New(t) - s := snowflake.NetworkPolicy("test_network_policy") - r.NotNil(s) - - q := s.UnsetOnUser("testuser") - r.Equal(`ALTER USER "testuser" UNSET NETWORK_POLICY`, q) -} - -func TestNetworkPolicyShowOnUser(t *testing.T) { - r := require.New(t) - s := snowflake.NetworkPolicy("test_network_policy") - r.NotNil(s) - - q := s.ShowOnUser("testuser") - r.Equal(`SHOW PARAMETERS LIKE 'network_policy' IN USER "testuser"`, q) -} - -func TestNetworkPolicyShowOnAccount(t *testing.T) { - r := require.New(t) - s := snowflake.NetworkPolicy("test_network_policy") - r.NotNil(s) - - q := s.ShowOnAccount() - r.Equal(`SHOW PARAMETERS LIKE 'network_policy' IN ACCOUNT`, q) -}