From fdb784e81346e417ec44c078d31588bfcb7bd295 Mon Sep 17 00:00:00 2001 From: Jakub Michalak Date: Tue, 29 Oct 2024 16:35:12 +0100 Subject: [PATCH] Move code to internal package --- pkg/helpers/doc.go | 14 ----- pkg/helpers/special_values.go | 60 ------------------- pkg/internal/provider/docs/doc_helpers.go | 9 +++ .../provider/docs/doc_helpers_test.go} | 2 +- pkg/internal/provider/special_values.go | 33 ++++++++++ .../provider/validators}/validators.go | 29 ++++++++- .../provider/validators}/validators_test.go | 2 +- pkg/provider/provider.go | 46 +++++++------- pkg/resources/doc_helpers.go | 4 +- pkg/resources/validators.go | 7 ++- 10 files changed, 100 insertions(+), 106 deletions(-) delete mode 100644 pkg/helpers/doc.go delete mode 100644 pkg/helpers/special_values.go rename pkg/{helpers/doc_test.go => internal/provider/docs/doc_helpers_test.go} (97%) create mode 100644 pkg/internal/provider/special_values.go rename pkg/{helpers => internal/provider/validators}/validators.go (80%) rename pkg/{helpers => internal/provider/validators}/validators_test.go (99%) diff --git a/pkg/helpers/doc.go b/pkg/helpers/doc.go deleted file mode 100644 index 4c699a7f3c..0000000000 --- a/pkg/helpers/doc.go +++ /dev/null @@ -1,14 +0,0 @@ -package helpers - -import ( - "fmt" - "strings" -) - -func PossibleValuesListed[T ~string | ~int](values []T) string { - valuesWrapped := make([]string, len(values)) - for i, value := range values { - valuesWrapped[i] = fmt.Sprintf("`%v`", value) - } - return strings.Join(valuesWrapped, " | ") -} diff --git a/pkg/helpers/special_values.go b/pkg/helpers/special_values.go deleted file mode 100644 index f1f86d9ad3..0000000000 --- a/pkg/helpers/special_values.go +++ /dev/null @@ -1,60 +0,0 @@ -package helpers - -import ( - "fmt" - "strings" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -const ( - BooleanTrue = "true" - BooleanFalse = "false" - BooleanDefault = "default" - - IntDefault = -1 - IntDefaultString = "-1" -) - -// StringInSlice has the same implementation as validation.StringInSlice, but adapted to schema.SchemaValidateDiagFunc -func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateDiagFunc { - return func(i interface{}, path cty.Path) diag.Diagnostics { - v, ok := i.(string) - if !ok { - return diag.Errorf("expected type of %v to be string", path) - } - - for _, str := range valid { - if v == str || (ignoreCase && strings.EqualFold(v, str)) { - return nil - } - } - - return diag.Errorf("expected %v to be one of %q, got %s", path, valid, v) - } -} - -var ValidateBooleanString = StringInSlice([]string{BooleanTrue, BooleanFalse}, false) - -var ValidateBooleanStringWithDefault = StringInSlice([]string{BooleanTrue, BooleanFalse, BooleanDefault}, false) - -func booleanStringFromBool(value bool) string { - if value { - return BooleanTrue - } else { - return BooleanFalse - } -} - -func BooleanStringToBool(value string) (bool, error) { - switch value { - case BooleanTrue: - return true, nil - case BooleanFalse: - return false, nil - default: - return false, fmt.Errorf("cannot retrieve boolean value from %s", value) - } -} diff --git a/pkg/internal/provider/docs/doc_helpers.go b/pkg/internal/provider/docs/doc_helpers.go index 82877a8b8b..80d1339b85 100644 --- a/pkg/internal/provider/docs/doc_helpers.go +++ b/pkg/internal/provider/docs/doc_helpers.go @@ -3,6 +3,7 @@ package docs import ( "fmt" "regexp" + "strings" ) // deprecationMessageRegex is the message that should be used in resource/datasource DeprecationMessage to get a nice link in the documentation to the replacing resource. @@ -23,3 +24,11 @@ func GetDeprecatedResourceReplacement(deprecationMessage string) (replacement st func RelativeLink(title string, path string) string { return fmt.Sprintf(`[%s](./%s)`, title, path) } + +func PossibleValuesListed[T ~string | ~int](values []T) string { + valuesWrapped := make([]string, len(values)) + for i, value := range values { + valuesWrapped[i] = fmt.Sprintf("`%v`", value) + } + return strings.Join(valuesWrapped, " | ") +} diff --git a/pkg/helpers/doc_test.go b/pkg/internal/provider/docs/doc_helpers_test.go similarity index 97% rename from pkg/helpers/doc_test.go rename to pkg/internal/provider/docs/doc_helpers_test.go index 9ed2192f97..e65b860073 100644 --- a/pkg/helpers/doc_test.go +++ b/pkg/internal/provider/docs/doc_helpers_test.go @@ -1,4 +1,4 @@ -package helpers +package docs import ( "testing" diff --git a/pkg/internal/provider/special_values.go b/pkg/internal/provider/special_values.go new file mode 100644 index 0000000000..0348299950 --- /dev/null +++ b/pkg/internal/provider/special_values.go @@ -0,0 +1,33 @@ +package provider + +import ( + "fmt" +) + +const ( + BooleanTrue = "true" + BooleanFalse = "false" + BooleanDefault = "default" + + IntDefault = -1 + IntDefaultString = "-1" +) + +func booleanStringFromBool(value bool) string { + if value { + return BooleanTrue + } else { + return BooleanFalse + } +} + +func BooleanStringToBool(value string) (bool, error) { + switch value { + case BooleanTrue: + return true, nil + case BooleanFalse: + return false, nil + default: + return false, fmt.Errorf("cannot retrieve boolean value from %s", value) + } +} diff --git a/pkg/helpers/validators.go b/pkg/internal/provider/validators/validators.go similarity index 80% rename from pkg/helpers/validators.go rename to pkg/internal/provider/validators/validators.go index 80a04bc116..edb2a93757 100644 --- a/pkg/helpers/validators.go +++ b/pkg/internal/provider/validators/validators.go @@ -1,9 +1,12 @@ -package helpers +package validators import ( "fmt" "reflect" + "strings" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -49,7 +52,7 @@ func IsValidIdentifier[T sdk.AccountObjectIdentifier | sdk.DatabaseObjectIdentif } stringValue := value.(string) - id, err := DecodeSnowflakeParameterID(stringValue) + id, err := helpers.DecodeSnowflakeParameterID(stringValue) if err != nil { return diag.Diagnostics{ diag.Diagnostic{ @@ -108,3 +111,25 @@ func getExpectedIdentifierForm(id any) string { } return "" } + +// StringInSlice has the same implementation as validation.StringInSlice, but adapted to schema.SchemaValidateDiagFunc +func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateDiagFunc { + return func(i interface{}, path cty.Path) diag.Diagnostics { + v, ok := i.(string) + if !ok { + return diag.Errorf("expected type of %v to be string", path) + } + + for _, str := range valid { + if v == str || (ignoreCase && strings.EqualFold(v, str)) { + return nil + } + } + + return diag.Errorf("expected %v to be one of %q, got %s", path, valid, v) + } +} + +var ValidateBooleanString = StringInSlice([]string{provider.BooleanTrue, provider.BooleanFalse}, false) + +var ValidateBooleanStringWithDefault = StringInSlice([]string{provider.BooleanTrue, provider.BooleanFalse, provider.BooleanDefault}, false) diff --git a/pkg/helpers/validators_test.go b/pkg/internal/provider/validators/validators_test.go similarity index 99% rename from pkg/helpers/validators_test.go rename to pkg/internal/provider/validators/validators_test.go index ac6e7ad37d..634fcc47b2 100644 --- a/pkg/helpers/validators_test.go +++ b/pkg/internal/provider/validators/validators_test.go @@ -1,4 +1,4 @@ -package helpers +package validators import ( "testing" diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 987e76a2fa..9369ca0451 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -11,9 +11,9 @@ import ( "time" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/datasources" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider/docs" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider/validators" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/snowflakeenvs" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -58,7 +58,7 @@ func Provider() *schema.Provider { Description: envNameFieldDescription("Username. Required unless using `profile`.", snowflakeenvs.User), Optional: true, DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.User, nil), - ValidateDiagFunc: helpers.IsValidIdentifier[sdk.AccountObjectIdentifier](), + ValidateDiagFunc: validators.IsValidIdentifier[sdk.AccountObjectIdentifier](), }, "password": { Type: schema.TypeString, @@ -73,21 +73,21 @@ func Provider() *schema.Provider { Description: envNameFieldDescription("Specifies the virtual warehouse to use by default for queries, loading, etc. in the client session.", snowflakeenvs.Warehouse), Optional: true, DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.Warehouse, nil), - ValidateDiagFunc: helpers.IsValidIdentifier[sdk.AccountObjectIdentifier](), + ValidateDiagFunc: validators.IsValidIdentifier[sdk.AccountObjectIdentifier](), }, "role": { Type: schema.TypeString, Description: envNameFieldDescription("Specifies the role to use by default for accessing Snowflake objects in the client session.", snowflakeenvs.Role), Optional: true, - ValidateDiagFunc: helpers.IsValidIdentifier[sdk.AccountObjectIdentifier](), + ValidateDiagFunc: validators.IsValidIdentifier[sdk.AccountObjectIdentifier](), DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.Role, nil), }, "validate_default_parameters": { Type: schema.TypeString, Description: envNameFieldDescription("True by default. If false, disables the validation checks for Database, Schema, Warehouse and Role at the time a connection is established.", snowflakeenvs.ValidateDefaultParameters), Optional: true, - ValidateDiagFunc: helpers.ValidateBooleanStringWithDefault, - DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.ValidateDefaultParameters, helpers.BooleanDefault), + ValidateDiagFunc: validators.ValidateBooleanStringWithDefault, + DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.ValidateDefaultParameters, provider.BooleanDefault), }, "params": { Type: schema.TypeMap, @@ -103,10 +103,10 @@ func Provider() *schema.Provider { }, "protocol": { Type: schema.TypeString, - Description: envNameFieldDescription(fmt.Sprintf("A protocol used in the connection. Valid options are: %v.", helpers.PossibleValuesListed(allProtocols)), snowflakeenvs.Protocol), + Description: envNameFieldDescription(fmt.Sprintf("A protocol used in the connection. Valid options are: %v.", docs.PossibleValuesListed(allProtocols)), snowflakeenvs.Protocol), Optional: true, DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.Protocol, nil), - ValidateDiagFunc: helpers.NormalizeValidation(toProtocol), + ValidateDiagFunc: validators.NormalizeValidation(toProtocol), }, "host": { Type: schema.TypeString, @@ -126,7 +126,7 @@ func Provider() *schema.Provider { Description: envNameFieldDescription("Specifies the [authentication type](https://pkg.go.dev/github.com/snowflakedb/gosnowflake#AuthType) to use when connecting to Snowflake. Valid values include: Snowflake, OAuth, ExternalBrowser, Okta, JWT, TokenAccessor, UsernamePasswordMFA. It has to be set explicitly to JWT for private key authentication.", snowflakeenvs.Authenticator), Optional: true, DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.Authenticator, string(authenticationTypeSnowflake)), - ValidateDiagFunc: helpers.NormalizeValidation(toAuthenticatorType), + ValidateDiagFunc: validators.NormalizeValidation(toAuthenticatorType), }, "passcode": { Type: schema.TypeString, @@ -201,8 +201,8 @@ func Provider() *schema.Provider { Type: schema.TypeString, Description: envNameFieldDescription("True represents OCSP fail open mode. False represents OCSP fail closed mode. Fail open true by default.", snowflakeenvs.OcspFailOpen), Optional: true, - DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.OcspFailOpen, helpers.BooleanDefault), - ValidateDiagFunc: helpers.ValidateBooleanStringWithDefault, + DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.OcspFailOpen, provider.BooleanDefault), + ValidateDiagFunc: validators.ValidateBooleanStringWithDefault, }, "token": { Type: schema.TypeString, @@ -288,15 +288,15 @@ func Provider() *schema.Provider { Type: schema.TypeString, Description: envNameFieldDescription("When true the MFA token is cached in the credential manager. True by default in Windows/OSX. False for Linux.", snowflakeenvs.ClientRequestMfaToken), Optional: true, - DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.ClientRequestMfaToken, helpers.BooleanDefault), - ValidateDiagFunc: helpers.ValidateBooleanStringWithDefault, + DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.ClientRequestMfaToken, provider.BooleanDefault), + ValidateDiagFunc: validators.ValidateBooleanStringWithDefault, }, "client_store_temporary_credential": { Type: schema.TypeString, Description: envNameFieldDescription("When true the ID token is cached in the credential manager. True by default in Windows/OSX. False for Linux.", snowflakeenvs.ClientStoreTemporaryCredential), Optional: true, - DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.ClientStoreTemporaryCredential, helpers.BooleanDefault), - ValidateDiagFunc: helpers.ValidateBooleanStringWithDefault, + DefaultFunc: schema.EnvDefaultFunc(snowflakeenvs.ClientStoreTemporaryCredential, provider.BooleanDefault), + ValidateDiagFunc: validators.ValidateBooleanStringWithDefault, }, "disable_query_context_cache": { Type: schema.TypeBool, @@ -604,8 +604,8 @@ func ConfigureProvider(ctx context.Context, s *schema.ResourceData) (any, diag.D config.Region = v.(string) } - if v := s.Get("validate_default_parameters").(string); v != helpers.BooleanDefault { - parsed, err := helpers.BooleanStringToBool(v) + if v := s.Get("validate_default_parameters").(string); v != provider.BooleanDefault { + parsed, err := provider.BooleanStringToBool(v) if err != nil { return nil, diag.FromErr(err) } @@ -705,8 +705,8 @@ func ConfigureProvider(ctx context.Context, s *schema.ResourceData) (any, diag.D config.InsecureMode = v.(bool) } - if v := s.Get("ocsp_fail_open").(string); v != helpers.BooleanDefault { - parsed, err := helpers.BooleanStringToBool(v) + if v := s.Get("ocsp_fail_open").(string); v != provider.BooleanDefault { + parsed, err := provider.BooleanStringToBool(v) if err != nil { return nil, diag.FromErr(err) } @@ -758,8 +758,8 @@ func ConfigureProvider(ctx context.Context, s *schema.ResourceData) (any, diag.D config.DisableTelemetry = v.(bool) } - if v := s.Get("client_request_mfa_token").(string); v != helpers.BooleanDefault { - parsed, err := helpers.BooleanStringToBool(v) + if v := s.Get("client_request_mfa_token").(string); v != provider.BooleanDefault { + parsed, err := provider.BooleanStringToBool(v) if err != nil { return nil, diag.FromErr(err) } @@ -770,8 +770,8 @@ func ConfigureProvider(ctx context.Context, s *schema.ResourceData) (any, diag.D } } - if v := s.Get("client_store_temporary_credential").(string); v != helpers.BooleanDefault { - parsed, err := helpers.BooleanStringToBool(v) + if v := s.Get("client_store_temporary_credential").(string); v != provider.BooleanDefault { + parsed, err := provider.BooleanStringToBool(v) if err != nil { return nil, diag.FromErr(err) } diff --git a/pkg/resources/doc_helpers.go b/pkg/resources/doc_helpers.go index a0dfcb8d39..8476ed050b 100644 --- a/pkg/resources/doc_helpers.go +++ b/pkg/resources/doc_helpers.go @@ -4,11 +4,11 @@ import ( "fmt" "strings" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider/docs" ) func possibleValuesListed[T ~string | ~int](values []T) string { - return helpers.PossibleValuesListed(values) + return docs.PossibleValuesListed(values) } func characterList(values []rune) string { diff --git a/pkg/resources/validators.go b/pkg/resources/validators.go index 6232df8670..071a73a33c 100644 --- a/pkg/resources/validators.go +++ b/pkg/resources/validators.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider/validators" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/go-cty/cty" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" @@ -29,7 +30,7 @@ func IsDataType() schema.SchemaValidateFunc { //nolint:staticcheck } func IsValidIdentifier[T sdk.AccountObjectIdentifier | sdk.DatabaseObjectIdentifier | sdk.SchemaObjectIdentifier | sdk.TableColumnIdentifier]() schema.SchemaValidateDiagFunc { - return helpers.IsValidIdentifier[T]() + return validators.IsValidIdentifier[T]() } // IsValidAccountIdentifier is a validator that can be used for validating account identifiers passed in resources and data sources. @@ -72,7 +73,7 @@ func IsValidAccountIdentifier() schema.SchemaValidateDiagFunc { // StringInSlice has the same implementation as validation.StringInSlice, but adapted to schema.SchemaValidateDiagFunc func StringInSlice(valid []string, ignoreCase bool) schema.SchemaValidateDiagFunc { - return helpers.StringInSlice(valid, ignoreCase) + return validators.StringInSlice(valid, ignoreCase) } // IntInSlice has the same implementation as validation.StringInSlice, but adapted to schema.SchemaValidateDiagFunc @@ -94,7 +95,7 @@ func IntInSlice(valid []int) schema.SchemaValidateDiagFunc { } func sdkValidation[T any](normalize func(string) (T, error)) schema.SchemaValidateDiagFunc { - return helpers.NormalizeValidation(normalize) + return validators.NormalizeValidation(normalize) } func isNotEqualTo(notExpectedValue string, errorMessage string) schema.SchemaValidateDiagFunc {