diff --git a/pkg/sdk/client.go b/pkg/sdk/client.go index f816d82748..75fc53b1b6 100644 --- a/pkg/sdk/client.go +++ b/pkg/sdk/client.go @@ -59,6 +59,7 @@ type Client struct { MaskingPolicies MaskingPolicies MaterializedViews MaterializedViews NetworkPolicies NetworkPolicies + NetworkRules NetworkRules NotificationIntegrations NotificationIntegrations Parameters Parameters PasswordPolicies PasswordPolicies @@ -212,6 +213,7 @@ func (c *Client) initialize() { c.MaskingPolicies = &maskingPolicies{client: c} c.MaterializedViews = &materializedViews{client: c} c.NetworkPolicies = &networkPolicies{client: c} + c.NetworkRules = &networkRules{client: c} c.NotificationIntegrations = ¬ificationIntegrations{client: c} c.Parameters = ¶meters{client: c} c.PasswordPolicies = &passwordPolicies{client: c} diff --git a/pkg/sdk/network_rule_def.go b/pkg/sdk/network_rule_def.go new file mode 100644 index 0000000000..0a90f495c0 --- /dev/null +++ b/pkg/sdk/network_rule_def.go @@ -0,0 +1,140 @@ +package sdk + +import g "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/poc/generator" + +//go:generate go run ./poc/main.go + +type NetworkRuleType string + +const ( + NetworkRuleTypeIpv4 NetworkRuleType = "IPV4" + NetworkRuleTypeAwsVpcEndpointId NetworkRuleType = "AWSVPCEID" + NetworkRuleTypeAzureLinkId NetworkRuleType = "AZURELINKID" + NetworkRuleTypeHostPort NetworkRuleType = "HOST_PORT" +) + +type NetworkRuleMode string + +const ( + NetworkRuleModeIngress NetworkRuleMode = "INGRESS" + NetworkRuleModeInternalStage NetworkRuleMode = "INTERNAL_STAGE" + NetworkRuleModeEgress NetworkRuleMode = "EGRESS" +) + +var NetworkRuleDef = g.NewInterface( + "NetworkRules", + "NetworkRule", + g.KindOfT[SchemaObjectIdentifier](), +). + CreateOperation( + "https://docs.snowflake.com/en/sql-reference/sql/create-network-rule", + g.NewQueryStruct("CreateNetworkRule"). + Create(). + OrReplace(). + SQL("NETWORK RULE"). + Name(). + Assignment("TYPE", g.KindOfT[NetworkRuleType](), g.ParameterOptions().Required().NoQuotes()). + ListAssignment("VALUE_LIST", "NetworkRuleValue", g.ParameterOptions().Required().Parentheses()). + Assignment("MODE", g.KindOfT[NetworkRuleMode](), g.ParameterOptions().Required().NoQuotes()). + OptionalComment(). + WithValidation(g.ValidIdentifier, "name"), + g.NewQueryStruct("NetworkRuleValue"). + Text("Value", g.KeywordOptions().SingleQuotes().Required()), + ). + AlterOperation( + "https://docs.snowflake.com/en/sql-reference/sql/alter-network-rule", + g.NewQueryStruct("AlterNetworkRule"). + Alter(). + SQL("NETWORK RULE"). + IfExists(). + Name(). + OptionalQueryStructField( + "Set", + g.NewQueryStruct("NetworkRuleSet"). + ListAssignment("VALUE_LIST", "NetworkRuleValue", g.ParameterOptions().Required().Parentheses()). + OptionalComment(). + WithValidation(g.AtLeastOneValueSet, "ValueList", "Comment"), + g.ListOptions().SQL("SET"), + ). + OptionalQueryStructField( + "Unset", + g.NewQueryStruct("NetworkRuleUnset"). + OptionalSQL("VALUE_LIST"). + OptionalSQL("COMMENT"). + WithValidation(g.AtLeastOneValueSet, "ValueList", "Comment"), + g.ListOptions().SQL("UNSET"), + ). + WithValidation(g.ValidIdentifier, "name"). + WithValidation(g.AtLeastOneValueSet, "Set", "Unset"), + ). + DropOperation( + "https://docs.snowflake.com/en/sql-reference/sql/drop-network-rule", + g.NewQueryStruct("DropNetworkRule"). + Drop(). + SQL("NETWORK RULE"). + IfExists(). + Name(). + WithValidation(g.ValidIdentifier, "name"), + ). + ShowOperation( + "https://docs.snowflake.com/en/sql-reference/sql/show-network-rules", + g.DbStruct("ShowNetworkRulesRow"). + Time("created_on"). + Text("name"). + Text("database_name"). + Text("schema_name"). + Text("owner"). + Text("comment"). + Text("type"). + Text("mode"). + Number("entries_in_valuelist"). + Text("owner_role_type"), + g.PlainStruct("NetworkRule"). + Time("CreatedOn"). + Text("Name"). + Text("DatabaseName"). + Text("SchemaName"). + Text("Owner"). + Text("Comment"). + Text("Type"). + Text("Mode"). + Number("EntriesInValueList"). + Text("OwnerRoleType"), + g.NewQueryStruct("ShowNetworkRules"). + Show(). + SQL("NETWORK RULES"). + OptionalLike(). + OptionalIn(). + OptionalStartsWith(). + OptionalLimitFrom(), + ). + ShowByIdOperation(). + DescribeOperation( + g.DescriptionMappingKindSingleValue, + "https://docs.snowflake.com/en/sql-reference/sql/desc-network-rule", + g.DbStruct("DescNetworkRulesRow"). + Time("created_on"). + Text("name"). + Text("database_name"). + Text("schema_name"). + Text("owner"). + Text("comment"). + Text("type"). + Text("mode"). + Text("value_list"), + g.PlainStruct("NetworkRuleDetails"). + Time("CreatedOn"). + Text("Name"). + Text("DatabaseName"). + Text("SchemaName"). + Text("Owner"). + Text("Comment"). + Text("Type"). + Text("Mode"). + Field("ValueList", "[]string"), + g.NewQueryStruct("ShowNetworkRules"). + Describe(). + SQL("NETWORK RULE"). + Name(). + WithValidation(g.ValidIdentifier, "name"), + ) diff --git a/pkg/sdk/network_rule_dto_builders_gen.go b/pkg/sdk/network_rule_dto_builders_gen.go new file mode 100644 index 0000000000..553e648568 --- /dev/null +++ b/pkg/sdk/network_rule_dto_builders_gen.go @@ -0,0 +1,124 @@ +// Code generated by dto builder generator; DO NOT EDIT. + +package sdk + +import () + +func NewCreateNetworkRuleRequest( + name SchemaObjectIdentifier, + Type NetworkRuleType, + ValueList []NetworkRuleValue, + Mode NetworkRuleMode, +) *CreateNetworkRuleRequest { + s := CreateNetworkRuleRequest{} + s.name = name + s.Type = Type + s.ValueList = ValueList + s.Mode = Mode + return &s +} + +func (s *CreateNetworkRuleRequest) WithOrReplace(OrReplace *bool) *CreateNetworkRuleRequest { + s.OrReplace = OrReplace + return s +} + +func (s *CreateNetworkRuleRequest) WithComment(Comment *string) *CreateNetworkRuleRequest { + s.Comment = Comment + return s +} + +func NewAlterNetworkRuleRequest( + name SchemaObjectIdentifier, +) *AlterNetworkRuleRequest { + s := AlterNetworkRuleRequest{} + s.name = name + return &s +} + +func (s *AlterNetworkRuleRequest) WithIfExists(IfExists *bool) *AlterNetworkRuleRequest { + s.IfExists = IfExists + return s +} + +func (s *AlterNetworkRuleRequest) WithSet(Set *NetworkRuleSetRequest) *AlterNetworkRuleRequest { + s.Set = Set + return s +} + +func (s *AlterNetworkRuleRequest) WithUnset(Unset *NetworkRuleUnsetRequest) *AlterNetworkRuleRequest { + s.Unset = Unset + return s +} + +func NewNetworkRuleSetRequest( + ValueList []NetworkRuleValue, +) *NetworkRuleSetRequest { + s := NetworkRuleSetRequest{} + s.ValueList = ValueList + return &s +} + +func (s *NetworkRuleSetRequest) WithComment(Comment *string) *NetworkRuleSetRequest { + s.Comment = Comment + return s +} + +func NewNetworkRuleUnsetRequest() *NetworkRuleUnsetRequest { + return &NetworkRuleUnsetRequest{} +} + +func (s *NetworkRuleUnsetRequest) WithValueList(ValueList *bool) *NetworkRuleUnsetRequest { + s.ValueList = ValueList + return s +} + +func (s *NetworkRuleUnsetRequest) WithComment(Comment *bool) *NetworkRuleUnsetRequest { + s.Comment = Comment + return s +} + +func NewDropNetworkRuleRequest( + name SchemaObjectIdentifier, +) *DropNetworkRuleRequest { + s := DropNetworkRuleRequest{} + s.name = name + return &s +} + +func (s *DropNetworkRuleRequest) WithIfExists(IfExists *bool) *DropNetworkRuleRequest { + s.IfExists = IfExists + return s +} + +func NewShowNetworkRuleRequest() *ShowNetworkRuleRequest { + return &ShowNetworkRuleRequest{} +} + +func (s *ShowNetworkRuleRequest) WithLike(Like *Like) *ShowNetworkRuleRequest { + s.Like = Like + return s +} + +func (s *ShowNetworkRuleRequest) WithIn(In *In) *ShowNetworkRuleRequest { + s.In = In + return s +} + +func (s *ShowNetworkRuleRequest) WithStartsWith(StartsWith *string) *ShowNetworkRuleRequest { + s.StartsWith = StartsWith + return s +} + +func (s *ShowNetworkRuleRequest) WithLimit(Limit *LimitFrom) *ShowNetworkRuleRequest { + s.Limit = Limit + return s +} + +func NewDescribeNetworkRuleRequest( + name SchemaObjectIdentifier, +) *DescribeNetworkRuleRequest { + s := DescribeNetworkRuleRequest{} + s.name = name + return &s +} diff --git a/pkg/sdk/network_rule_dto_gen.go b/pkg/sdk/network_rule_dto_gen.go new file mode 100644 index 0000000000..64adcd952c --- /dev/null +++ b/pkg/sdk/network_rule_dto_gen.go @@ -0,0 +1,53 @@ +package sdk + +//go:generate go run ./dto-builder-generator/main.go + +var ( + _ optionsProvider[CreateNetworkRuleOptions] = new(CreateNetworkRuleRequest) + _ optionsProvider[AlterNetworkRuleOptions] = new(AlterNetworkRuleRequest) + _ optionsProvider[DropNetworkRuleOptions] = new(DropNetworkRuleRequest) + _ optionsProvider[ShowNetworkRuleOptions] = new(ShowNetworkRuleRequest) + _ optionsProvider[DescribeNetworkRuleOptions] = new(DescribeNetworkRuleRequest) +) + +type CreateNetworkRuleRequest struct { + OrReplace *bool + name SchemaObjectIdentifier // required + Type NetworkRuleType // required + ValueList []NetworkRuleValue // required + Mode NetworkRuleMode // required + Comment *string +} + +type AlterNetworkRuleRequest struct { + IfExists *bool + name SchemaObjectIdentifier // required + Set *NetworkRuleSetRequest + Unset *NetworkRuleUnsetRequest +} + +type NetworkRuleSetRequest struct { + ValueList []NetworkRuleValue // required + Comment *string +} + +type NetworkRuleUnsetRequest struct { + ValueList *bool + Comment *bool +} + +type DropNetworkRuleRequest struct { + IfExists *bool + name SchemaObjectIdentifier // required +} + +type ShowNetworkRuleRequest struct { + Like *Like + In *In + StartsWith *string + Limit *LimitFrom +} + +type DescribeNetworkRuleRequest struct { + name SchemaObjectIdentifier // required +} diff --git a/pkg/sdk/network_rule_gen.go b/pkg/sdk/network_rule_gen.go new file mode 100644 index 0000000000..4088903736 --- /dev/null +++ b/pkg/sdk/network_rule_gen.go @@ -0,0 +1,126 @@ +package sdk + +import ( + "context" + "time" +) + +type NetworkRules interface { + Create(ctx context.Context, request *CreateNetworkRuleRequest) error + Alter(ctx context.Context, request *AlterNetworkRuleRequest) error + Drop(ctx context.Context, request *DropNetworkRuleRequest) error + Show(ctx context.Context, request *ShowNetworkRuleRequest) ([]NetworkRule, error) + ShowByID(ctx context.Context, id SchemaObjectIdentifier) (*NetworkRule, error) + Describe(ctx context.Context, id SchemaObjectIdentifier) (*NetworkRuleDetails, error) +} + +// CreateNetworkRuleOptions is based on https://docs.snowflake.com/en/sql-reference/sql/create-network-rule. +type CreateNetworkRuleOptions struct { + create bool `ddl:"static" sql:"CREATE"` + OrReplace *bool `ddl:"keyword" sql:"OR REPLACE"` + networkRule bool `ddl:"static" sql:"NETWORK RULE"` + name SchemaObjectIdentifier `ddl:"identifier"` + Type NetworkRuleType `ddl:"parameter,no_quotes" sql:"TYPE"` + ValueList []NetworkRuleValue `ddl:"parameter,parentheses" sql:"VALUE_LIST"` + Mode NetworkRuleMode `ddl:"parameter,no_quotes" sql:"MODE"` + Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"` +} + +type NetworkRuleValue struct { + Value string `ddl:"keyword,single_quotes"` +} + +// AlterNetworkRuleOptions is based on https://docs.snowflake.com/en/sql-reference/sql/alter-network-rule. +type AlterNetworkRuleOptions struct { + alter bool `ddl:"static" sql:"ALTER"` + networkRule bool `ddl:"static" sql:"NETWORK RULE"` + IfExists *bool `ddl:"keyword" sql:"IF EXISTS"` + name SchemaObjectIdentifier `ddl:"identifier"` + Set *NetworkRuleSet `ddl:"list" sql:"SET"` + Unset *NetworkRuleUnset `ddl:"list" sql:"UNSET"` +} + +type NetworkRuleSet struct { + ValueList []NetworkRuleValue `ddl:"parameter,parentheses" sql:"VALUE_LIST"` + Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"` +} + +type NetworkRuleUnset struct { + ValueList *bool `ddl:"keyword" sql:"VALUE_LIST"` + Comment *bool `ddl:"keyword" sql:"COMMENT"` +} + +// DropNetworkRuleOptions is based on https://docs.snowflake.com/en/sql-reference/sql/drop-network-rule. +type DropNetworkRuleOptions struct { + drop bool `ddl:"static" sql:"DROP"` + networkRule bool `ddl:"static" sql:"NETWORK RULE"` + IfExists *bool `ddl:"keyword" sql:"IF EXISTS"` + name SchemaObjectIdentifier `ddl:"identifier"` +} + +// ShowNetworkRuleOptions is based on https://docs.snowflake.com/en/sql-reference/sql/show-network-rules. +type ShowNetworkRuleOptions struct { + show bool `ddl:"static" sql:"SHOW"` + networkRules bool `ddl:"static" sql:"NETWORK RULES"` + Like *Like `ddl:"keyword" sql:"LIKE"` + In *In `ddl:"keyword" sql:"IN"` + StartsWith *string `ddl:"parameter,single_quotes,no_equals" sql:"STARTS WITH"` + Limit *LimitFrom `ddl:"keyword" sql:"LIMIT"` +} + +type ShowNetworkRulesRow struct { + CreatedOn time.Time `db:"created_on"` + Name string `db:"name"` + DatabaseName string `db:"database_name"` + SchemaName string `db:"schema_name"` + Owner string `db:"owner"` + Comment string `db:"comment"` + Type string `db:"type"` + Mode string `db:"mode"` + EntriesInValueList int `db:"entries_in_valuelist"` + OwnerRoleType string `db:"owner_role_type"` +} + +type NetworkRule struct { + CreatedOn time.Time + Name string + DatabaseName string + SchemaName string + Owner string + Comment string + Type NetworkRuleType + Mode NetworkRuleMode + EntriesInValueList int + OwnerRoleType string +} + +// DescribeNetworkRuleOptions is based on https://docs.snowflake.com/en/sql-reference/sql/desc-network-rule. +type DescribeNetworkRuleOptions struct { + describe bool `ddl:"static" sql:"DESCRIBE"` + networkRule bool `ddl:"static" sql:"NETWORK RULE"` + name SchemaObjectIdentifier `ddl:"identifier"` +} + +type DescNetworkRulesRow struct { + CreatedOn time.Time `db:"created_on"` + Name string `db:"name"` + DatabaseName string `db:"database_name"` + SchemaName string `db:"schema_name"` + Owner string `db:"owner"` + Comment string `db:"comment"` + Type string `db:"type"` + Mode string `db:"mode"` + ValueList string `db:"value_list"` +} + +type NetworkRuleDetails struct { + CreatedOn time.Time + Name string + DatabaseName string + SchemaName string + Owner string + Comment string + Type NetworkRuleType + Mode NetworkRuleMode + ValueList []string +} diff --git a/pkg/sdk/network_rule_gen_test.go b/pkg/sdk/network_rule_gen_test.go new file mode 100644 index 0000000000..a925a0e718 --- /dev/null +++ b/pkg/sdk/network_rule_gen_test.go @@ -0,0 +1,195 @@ +package sdk + +import "testing" + +func TestNetworkRules_Create(t *testing.T) { + id := RandomSchemaObjectIdentifier() + + // Minimal valid CreateNetworkRuleOptions + defaultOpts := func() *CreateNetworkRuleOptions { + return &CreateNetworkRuleOptions{ + name: id, + Type: NetworkRuleTypeIpv4, + ValueList: []NetworkRuleValue{ + {Value: "0.0.0.0"}, + {Value: "1.1.1.1"}, + }, + Mode: NetworkRuleModeIngress, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *CreateNetworkRuleOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: valid identifier for [opts.name]", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewSchemaObjectIdentifier("", "", "") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("basic", func(t *testing.T) { + opts := defaultOpts() + assertOptsValidAndSQLEquals(t, opts, `CREATE NETWORK RULE %s TYPE = IPV4 VALUE_LIST = ('0.0.0.0', '1.1.1.1') MODE = INGRESS`, id.FullyQualifiedName()) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + opts.OrReplace = Bool(true) + opts.Comment = String("some comment") + assertOptsValidAndSQLEquals(t, opts, `CREATE OR REPLACE NETWORK RULE %s TYPE = IPV4 VALUE_LIST = ('0.0.0.0', '1.1.1.1') MODE = INGRESS COMMENT = 'some comment'`, id.FullyQualifiedName()) + }) +} + +func TestNetworkRules_Alter(t *testing.T) { + id := RandomSchemaObjectIdentifier() + + // Minimal valid AlterNetworkRuleOptions + defaultOpts := func() *AlterNetworkRuleOptions { + return &AlterNetworkRuleOptions{ + name: id, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *AlterNetworkRuleOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: valid identifier for [opts.name]", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewSchemaObjectIdentifier("", "", "") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("validation: at least one of the fields [opts.Set opts.Unset] should be set", func(t *testing.T) { + opts := defaultOpts() + assertOptsInvalidJoinedErrors(t, opts, errAtLeastOneOf("AlterNetworkRuleOptions", "Set", "Unset")) + }) + + t.Run("validation: at least one of the fields [opts.Set.ValueList opts.Set.Comment] should be set", func(t *testing.T) { + opts := defaultOpts() + opts.Set = &NetworkRuleSet{} + assertOptsInvalidJoinedErrors(t, opts, errAtLeastOneOf("AlterNetworkRuleOptions.Set", "ValueList", "Comment")) + }) + + t.Run("validation: at least one of the fields [opts.Unset.ValueList opts.Unset.Comment] should be set", func(t *testing.T) { + opts := defaultOpts() + opts.Unset = &NetworkRuleUnset{} + assertOptsInvalidJoinedErrors(t, opts, errAtLeastOneOf("AlterNetworkRuleOptions.Unset", "ValueList", "Comment")) + }) + + t.Run("all options set", func(t *testing.T) { + opts := defaultOpts() + opts.Set = &NetworkRuleSet{ + ValueList: []NetworkRuleValue{ + {Value: "0.0.0.0"}, + {Value: "1.1.1.1"}, + }, + Comment: String("some comment"), + } + assertOptsValidAndSQLEquals(t, opts, `ALTER NETWORK RULE %s SET VALUE_LIST = ('0.0.0.0', '1.1.1.1'), COMMENT = 'some comment'`, id.FullyQualifiedName()) + }) + + t.Run("all options unset", func(t *testing.T) { + opts := defaultOpts() + opts.Unset = &NetworkRuleUnset{ + ValueList: Bool(true), + Comment: Bool(true), + } + assertOptsValidAndSQLEquals(t, opts, `ALTER NETWORK RULE %s UNSET VALUE_LIST, COMMENT`, id.FullyQualifiedName()) + }) +} + +func TestNetworkRules_Drop(t *testing.T) { + id := RandomSchemaObjectIdentifier() + + // Minimal valid DropNetworkRuleOptions + defaultOpts := func() *DropNetworkRuleOptions { + return &DropNetworkRuleOptions{ + name: id, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *DropNetworkRuleOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: valid identifier for [opts.name]", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewSchemaObjectIdentifier("", "", "") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("basic", func(t *testing.T) { + opts := defaultOpts() + assertOptsValidAndSQLEquals(t, opts, `DROP NETWORK RULE %s`, id.FullyQualifiedName()) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + opts.IfExists = Bool(true) + assertOptsValidAndSQLEquals(t, opts, `DROP NETWORK RULE IF EXISTS %s`, id.FullyQualifiedName()) + }) +} + +func TestNetworkRules_Show(t *testing.T) { + // Minimal valid ShowNetworkRuleOptions + defaultOpts := func() *ShowNetworkRuleOptions { + return &ShowNetworkRuleOptions{} + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *ShowNetworkRuleOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("basic", func(t *testing.T) { + opts := defaultOpts() + assertOptsValidAndSQLEquals(t, opts, `SHOW NETWORK RULES`) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + opts.Like = &Like{ + Pattern: String("name"), + } + opts.In = &In{ + Database: NewAccountObjectIdentifier("database-name"), + } + opts.StartsWith = String("abc") + opts.Limit = &LimitFrom{ + Rows: Int(10), + } + assertOptsValidAndSQLEquals(t, opts, `SHOW NETWORK RULES LIKE 'name' IN DATABASE "database-name" STARTS WITH 'abc' LIMIT 10`) + }) +} + +func TestNetworkRules_Describe(t *testing.T) { + id := RandomSchemaObjectIdentifier() + + // Minimal valid DescribeNetworkRuleOptions + defaultOpts := func() *DescribeNetworkRuleOptions { + return &DescribeNetworkRuleOptions{ + name: id, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *DescribeNetworkRuleOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: valid identifier for [opts.name]", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewSchemaObjectIdentifier("", "", "") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + assertOptsValidAndSQLEquals(t, opts, `DESCRIBE NETWORK RULE %s`, id.FullyQualifiedName()) + }) +} diff --git a/pkg/sdk/network_rule_impl_gen.go b/pkg/sdk/network_rule_impl_gen.go new file mode 100644 index 0000000000..3e4cd49980 --- /dev/null +++ b/pkg/sdk/network_rule_impl_gen.go @@ -0,0 +1,152 @@ +package sdk + +import ( + "context" + "strings" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/collections" +) + +var _ NetworkRules = (*networkRules)(nil) + +type networkRules struct { + client *Client +} + +func (v *networkRules) Create(ctx context.Context, request *CreateNetworkRuleRequest) error { + opts := request.toOpts() + return validateAndExec(v.client, ctx, opts) +} + +func (v *networkRules) Alter(ctx context.Context, request *AlterNetworkRuleRequest) error { + opts := request.toOpts() + return validateAndExec(v.client, ctx, opts) +} + +func (v *networkRules) Drop(ctx context.Context, request *DropNetworkRuleRequest) error { + opts := request.toOpts() + return validateAndExec(v.client, ctx, opts) +} + +func (v *networkRules) Show(ctx context.Context, request *ShowNetworkRuleRequest) ([]NetworkRule, error) { + opts := request.toOpts() + dbRows, err := validateAndQuery[ShowNetworkRulesRow](v.client, ctx, opts) + if err != nil { + return nil, err + } + resultList := convertRows[ShowNetworkRulesRow, NetworkRule](dbRows) + return resultList, nil +} + +func (v *networkRules) ShowByID(ctx context.Context, id SchemaObjectIdentifier) (*NetworkRule, error) { + networkRules, err := v.Show(ctx, NewShowNetworkRuleRequest().WithIn(&In{ + Schema: NewDatabaseObjectIdentifier(id.DatabaseName(), id.SchemaName()), + }).WithLike(&Like{ + Pattern: String(id.Name()), + })) + if err != nil { + return nil, err + } + return collections.FindOne(networkRules, func(r NetworkRule) bool { return r.Name == id.Name() }) +} + +func (v *networkRules) Describe(ctx context.Context, id SchemaObjectIdentifier) (*NetworkRuleDetails, error) { + opts := &DescribeNetworkRuleOptions{ + name: id, + } + result, err := validateAndQueryOne[DescNetworkRulesRow](v.client, ctx, opts) + if err != nil { + return nil, err + } + return result.convert(), nil +} + +func (r *CreateNetworkRuleRequest) toOpts() *CreateNetworkRuleOptions { + opts := &CreateNetworkRuleOptions{ + OrReplace: r.OrReplace, + name: r.name, + Type: r.Type, + ValueList: r.ValueList, + Mode: r.Mode, + Comment: r.Comment, + } + return opts +} + +func (r *AlterNetworkRuleRequest) toOpts() *AlterNetworkRuleOptions { + opts := &AlterNetworkRuleOptions{ + IfExists: r.IfExists, + name: r.name, + } + if r.Set != nil { + opts.Set = &NetworkRuleSet{ + ValueList: r.Set.ValueList, + Comment: r.Set.Comment, + } + } + if r.Unset != nil { + opts.Unset = &NetworkRuleUnset{ + ValueList: r.Unset.ValueList, + Comment: r.Unset.Comment, + } + } + return opts +} + +func (r *DropNetworkRuleRequest) toOpts() *DropNetworkRuleOptions { + opts := &DropNetworkRuleOptions{ + IfExists: r.IfExists, + name: r.name, + } + return opts +} + +func (r *ShowNetworkRuleRequest) toOpts() *ShowNetworkRuleOptions { + opts := &ShowNetworkRuleOptions{ + Like: r.Like, + In: r.In, + StartsWith: r.StartsWith, + Limit: r.Limit, + } + return opts +} + +func (row ShowNetworkRulesRow) convert() *NetworkRule { + return &NetworkRule{ + CreatedOn: row.CreatedOn, + Name: row.Name, + DatabaseName: row.DatabaseName, + SchemaName: row.SchemaName, + Owner: row.Owner, + Comment: row.Comment, + Type: NetworkRuleType(row.Type), + Mode: NetworkRuleMode(row.Mode), + EntriesInValueList: row.EntriesInValueList, + OwnerRoleType: row.OwnerRoleType, + } +} + +func (r *DescribeNetworkRuleRequest) toOpts() *DescribeNetworkRuleOptions { + opts := &DescribeNetworkRuleOptions{ + name: r.name, + } + return opts +} + +func (row DescNetworkRulesRow) convert() *NetworkRuleDetails { + valueList := strings.Split(row.ValueList, ",") + if len(valueList) == 1 && valueList[0] == "" { + valueList = []string{} + } + return &NetworkRuleDetails{ + CreatedOn: row.CreatedOn, + Name: row.Name, + DatabaseName: row.DatabaseName, + SchemaName: row.SchemaName, + Owner: row.Owner, + Comment: row.Comment, + Type: NetworkRuleType(row.Type), + Mode: NetworkRuleMode(row.Mode), + ValueList: valueList, + } +} diff --git a/pkg/sdk/network_rule_validations_gen.go b/pkg/sdk/network_rule_validations_gen.go new file mode 100644 index 0000000000..e86eb4d376 --- /dev/null +++ b/pkg/sdk/network_rule_validations_gen.go @@ -0,0 +1,74 @@ +package sdk + +var ( + _ validatable = new(CreateNetworkRuleOptions) + _ validatable = new(AlterNetworkRuleOptions) + _ validatable = new(DropNetworkRuleOptions) + _ validatable = new(ShowNetworkRuleOptions) + _ validatable = new(DescribeNetworkRuleOptions) +) + +func (opts *CreateNetworkRuleOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + return JoinErrors(errs...) +} + +func (opts *AlterNetworkRuleOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + if !anyValueSet(opts.Set, opts.Unset) { + errs = append(errs, errAtLeastOneOf("AlterNetworkRuleOptions", "Set", "Unset")) + } + if valueSet(opts.Set) { + if !anyValueSet(opts.Set.ValueList, opts.Set.Comment) { + errs = append(errs, errAtLeastOneOf("AlterNetworkRuleOptions.Set", "ValueList", "Comment")) + } + } + if valueSet(opts.Unset) { + if !anyValueSet(opts.Unset.ValueList, opts.Unset.Comment) { + errs = append(errs, errAtLeastOneOf("AlterNetworkRuleOptions.Unset", "ValueList", "Comment")) + } + } + return JoinErrors(errs...) +} + +func (opts *DropNetworkRuleOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + return JoinErrors(errs...) +} + +func (opts *ShowNetworkRuleOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + return JoinErrors(errs...) +} + +func (opts *DescribeNetworkRuleOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + return JoinErrors(errs...) +} diff --git a/pkg/sdk/poc/main.go b/pkg/sdk/poc/main.go index 4e3cf2a88c..d626fe16af 100644 --- a/pkg/sdk/poc/main.go +++ b/pkg/sdk/poc/main.go @@ -38,6 +38,7 @@ var definitionMapping = map[string]*generator.Interface{ "notification_integrations_def.go": sdk.NotificationIntegrationsDef, "external_functions_def.go": sdk.ExternalFunctionsDef, "streamlits_def.go": sdk.StreamlitsDef, + "network_rule_def.go": sdk.NetworkRuleDef, } func main() { diff --git a/pkg/sdk/testint/network_rule_gen_integration_test.go b/pkg/sdk/testint/network_rule_gen_integration_test.go new file mode 100644 index 0000000000..69d60c41de --- /dev/null +++ b/pkg/sdk/testint/network_rule_gen_integration_test.go @@ -0,0 +1,137 @@ +package testint + +import ( + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/random" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestInt_NetworkRules(t *testing.T) { + client := testClient(t) + ctx := testContext(t) + + assertValuesAndComment := func(id sdk.SchemaObjectIdentifier, expectedValueList []string, expectedComment string) { + rule, err := client.NetworkRules.ShowByID(ctx, id) + require.NoError(t, err) + + ruleDetails, err := client.NetworkRules.Describe(ctx, id) + require.NoError(t, err) + + require.Len(t, expectedValueList, rule.EntriesInValueList) + require.Equal(t, expectedValueList, ruleDetails.ValueList) + require.Equal(t, expectedComment, rule.Comment) + } + + t.Run("Create", func(t *testing.T) { + id := sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(20)) + err := client.NetworkRules.Create(ctx, sdk.NewCreateNetworkRuleRequest(id, sdk.NetworkRuleTypeIpv4, []sdk.NetworkRuleValue{}, sdk.NetworkRuleModeIngress)) + require.NoError(t, err) + + t.Cleanup(func() { + err := client.NetworkRules.Drop(ctx, sdk.NewDropNetworkRuleRequest(id)) + require.NoError(t, err) + }) + + _, err = client.NetworkRules.ShowByID(ctx, id) + require.NoError(t, err) + }) + + t.Run("Alter: set and unset", func(t *testing.T) { + id := sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(20)) + err := client.NetworkRules.Create(ctx, sdk.NewCreateNetworkRuleRequest(id, sdk.NetworkRuleTypeIpv4, []sdk.NetworkRuleValue{}, sdk.NetworkRuleModeIngress)) + require.NoError(t, err) + + t.Cleanup(func() { + err := client.NetworkRules.Drop(ctx, sdk.NewDropNetworkRuleRequest(id)) + require.NoError(t, err) + }) + + setReq := sdk.NewNetworkRuleSetRequest([]sdk.NetworkRuleValue{ + {Value: "0.0.0.0"}, + {Value: "1.1.1.1"}, + }).WithComment(sdk.String("some comment")) + err = client.NetworkRules.Alter(ctx, sdk.NewAlterNetworkRuleRequest(id).WithSet(setReq)) + require.NoError(t, err) + + assertValuesAndComment(id, []string{"0.0.0.0", "1.1.1.1"}, "some comment") + + unsetReq := sdk.NewNetworkRuleUnsetRequest(). + WithValueList(sdk.Bool(true)). + WithComment(sdk.Bool(true)) + err = client.NetworkRules.Alter(ctx, sdk.NewAlterNetworkRuleRequest(id).WithUnset(unsetReq)) + require.NoError(t, err) + + assertValuesAndComment(id, []string{}, "") + }) + + t.Run("Drop", func(t *testing.T) { + id := sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(20)) + err := client.NetworkRules.Create(ctx, sdk.NewCreateNetworkRuleRequest(id, sdk.NetworkRuleTypeIpv4, []sdk.NetworkRuleValue{}, sdk.NetworkRuleModeIngress)) + require.NoError(t, err) + + _, err = client.NetworkRules.ShowByID(ctx, id) + require.NoError(t, err) + + err = client.NetworkRules.Drop(ctx, sdk.NewDropNetworkRuleRequest(id)) + require.NoError(t, err) + + _, err = client.NetworkRules.ShowByID(ctx, id) + require.Error(t, err, sdk.ErrObjectNotExistOrAuthorized) + }) + + t.Run("Show", func(t *testing.T) { + id := sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(20)) + err := client.NetworkRules.Create(ctx, sdk.NewCreateNetworkRuleRequest(id, sdk.NetworkRuleTypeIpv4, []sdk.NetworkRuleValue{}, sdk.NetworkRuleModeIngress).WithComment(sdk.String("some comment"))) + require.NoError(t, err) + + t.Cleanup(func() { + err := client.NetworkRules.Drop(ctx, sdk.NewDropNetworkRuleRequest(id)) + require.NoError(t, err) + }) + + networkRules, err := client.NetworkRules.Show(ctx, sdk.NewShowNetworkRuleRequest().WithIn(&sdk.In{ + Schema: sdk.NewDatabaseObjectIdentifier(id.DatabaseName(), id.SchemaName()), + }).WithLike(&sdk.Like{ + Pattern: sdk.String(id.Name()), + })) + require.NoError(t, err) + + require.Equal(t, 1, len(networkRules)) + require.False(t, networkRules[0].CreatedOn.IsZero()) + require.Equal(t, id.Name(), networkRules[0].Name) + require.Equal(t, id.DatabaseName(), networkRules[0].DatabaseName) + require.Equal(t, id.SchemaName(), networkRules[0].SchemaName) + require.Equal(t, "ACCOUNTADMIN", networkRules[0].Owner) + require.Equal(t, "some comment", networkRules[0].Comment) + require.Equal(t, sdk.NetworkRuleTypeIpv4, networkRules[0].Type) + require.Equal(t, sdk.NetworkRuleModeIngress, networkRules[0].Mode) + require.Equal(t, 0, networkRules[0].EntriesInValueList) + require.Equal(t, "ROLE", networkRules[0].OwnerRoleType) + }) + + t.Run("Describe", func(t *testing.T) { + id := sdk.NewSchemaObjectIdentifier(TestDatabaseName, TestSchemaName, random.AlphaN(20)) + err := client.NetworkRules.Create(ctx, sdk.NewCreateNetworkRuleRequest(id, sdk.NetworkRuleTypeIpv4, []sdk.NetworkRuleValue{}, sdk.NetworkRuleModeIngress).WithComment(sdk.String("some comment"))) + require.NoError(t, err) + + t.Cleanup(func() { + err := client.NetworkRules.Drop(ctx, sdk.NewDropNetworkRuleRequest(id)) + require.NoError(t, err) + }) + + ruleDetails, err := client.NetworkRules.Describe(ctx, id) + require.NoError(t, err) + assert.False(t, ruleDetails.CreatedOn.IsZero()) + assert.Equal(t, id.DatabaseName(), ruleDetails.DatabaseName) + assert.Equal(t, id.SchemaName(), ruleDetails.SchemaName) + assert.Equal(t, id.Name(), ruleDetails.Name) + require.Equal(t, "ACCOUNTADMIN", ruleDetails.Owner) + assert.Equal(t, "some comment", ruleDetails.Comment) + assert.Empty(t, ruleDetails.ValueList) + assert.Equal(t, sdk.NetworkRuleModeIngress, ruleDetails.Mode) + assert.Equal(t, sdk.NetworkRuleTypeIpv4, ruleDetails.Type) + }) +} diff --git a/pkg/sdk/testint/sequences_integration_test.go b/pkg/sdk/testint/sequences_integration_test.go index be1af06fa4..d6d71f381b 100644 --- a/pkg/sdk/testint/sequences_integration_test.go +++ b/pkg/sdk/testint/sequences_integration_test.go @@ -145,7 +145,7 @@ func TestInt_Sequences(t *testing.T) { increment := 2 err := client.Sequences.Alter(ctx, sdk.NewAlterSequenceRequest(id).WithSetIncrement(&increment)) require.NoError(t, err) - assertSequence(t, id, 2, true, "") + assertSequence(t, id, 2, false, "") }) t.Run("alter sequence: rename", func(t *testing.T) {