Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Mark V1 ready preview resources #3218

Merged
merged 4 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,67 @@ across different versions.

## v0.99.0 ➞ v1.0.0

### Preview features flag
All of the preview features objects are now disabled by default. This includes:
- Resources
- `snowflake_account_password_policy_attachment`
- `snowflake_alert`
- `snowflake_api_integration`
- `snowflake_cortex_search_service`
- `snowflake_dynamic_table`
- `snowflake_external_function`
- `snowflake_external_table`
- `snowflake_external_volume`
- `snowflake_failover_group`
- `snowflake_file_format`
- `snowflake_managed_account`
- `snowflake_materialized_view`
- `snowflake_network_policy_attachment`
- `snowflake_network_rule`
- `snowflake_email_notification_integration`
- `snowflake_notification_integration`
- `snowflake_object_parameter`
- `snowflake_password_policy`
- `snowflake_pipe`
- `snowflake_sequence`
- `snowflake_share`
- `snowflake_stage`
- `snowflake_storage_integration`
- `snowflake_table_column_masking_policy_application`
- `snowflake_table_constraint`
- `snowflake_user_public_keys`
- `snowflake_user_password_policy_attachment`
- Data sources
- `snowflake_current_account`
- `snowflake_alerts`
- `snowflake_cortex_search_services`
- `snowflake_database`
- `snowflake_database_role`
- `snowflake_dynamic_tables`
- `snowflake_external_functions`
- `snowflake_external_tables`
- `snowflake_failover_groups`
- `snowflake_file_formats`
- `snowflake_materialized_views`
- `snowflake_pipes`
- `snowflake_current_role`
- `snowflake_sequences`
- `snowflake_shares`
- `snowflake_parameters`
- `snowflake_stages`
- `snowflake_storage_integrations`
- `snowflake_system_generate_scim_access_token`
- `snowflake_system_get_aws_sns_iam_policy`
- `snowflake_system_get_privatelink_config`
- `snowflake_system_get_snowflake_platform_info`

If you want to have them enabled, add the feature name to the provider configuration (with `_datasource` or `_resource` suffix), like this:
sfc-gh-jcieslak marked this conversation as resolved.
Show resolved Hide resolved
```terraform
provider "snowflake" {
preview_features_enabled = ["snowflake_current_account_datasource", "snowflake_alert_resource"]
}
```

### Removed deprecated objects
All of the deprecated objects are removed from v1 release. This includes:
<!-- TODO(next pr): link to entries in the migration guide regarding details for each of the resource/data source-->
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ test: test-client ## run unit and integration tests
go test -v -cover -timeout=45m ./...

test-acceptance: ## run acceptance tests
TF_ACC=1 SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE=true TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX=1 go test -run "^TestAcc_" -v -cover -timeout=120m ./...
TF_ACC=1 SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE=true TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX=1 SF_TF_ACC_TEST_ENABLE_ALL_PREVIEW_FEATURES=true go test -run "^TestAcc_" -v -cover -timeout=120m ./...

test-integration: ## run SDK integration tests
TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX=1 go test -run "^TestInt_" -v -cover -timeout=45m ./...
Expand All @@ -80,7 +80,7 @@ test-object-renaming: ## runs tests in object_renaming_acceptance_test.go
TEST_SF_TF_ENABLE_OBJECT_RENAMING=1 go test ./pkg/resources/object_renaming_acceptace_test.go -v

test-acceptance-%: ## run acceptance tests for the given resource only, e.g. test-acceptance-Warehouse
TF_ACC=1 TF_LOG=DEBUG SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE=true go test -run ^TestAcc_$*_ -v -timeout=20m ./pkg/resources
TF_ACC=1 TF_LOG=DEBUG SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE=true SF_TF_ACC_TEST_ENABLE_ALL_PREVIEW_FEATURES=true go test -run ^TestAcc_$*_ -v -timeout=20m ./pkg/resources

build-local: ## build the binary locally
go build -o $(BASE_BINARY_NAME) .
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ provider "snowflake" {
- `passcode_in_password` (Boolean) False by default. Set to true if the MFA passcode is embedded to the configured password. Can also be sourced from the `SNOWFLAKE_PASSCODE_IN_PASSWORD` environment variable.
- `password` (String, Sensitive) Password for user + password auth. Cannot be used with `browser_auth` or `private_key_path`. Can also be sourced from the `SNOWFLAKE_PASSWORD` environment variable.
- `port` (Number) Specifies a custom port value used by the driver for privatelink connections. Can also be sourced from the `SNOWFLAKE_PORT` environment variable.
- `preview_features_enabled` (Set of String) A list of preview features that are handled by the provider. See [preview features list](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/v1-preparations/LIST_OF_PREVIEW_FEATURES_FOR_V1.md). Preview features may have breaking changes in future releases, even without raising the major version. This field can not be set with environmental variables. Valid options are: `snowflake_current_account_datasource` | `snowflake_account_password_policy_attachment_resource` | `snowflake_alert_resource` | `snowflake_alerts_datasource` | `snowflake_api_integration_resource` | `snowflake_cortex_search_service_resource` | `snowflake_cortex_search_services_datasource` | `snowflake_database_datasource` | `snowflake_database_role_datasource` | `snowflake_dynamic_table_resource` | `snowflake_dynamic_tables_datasource` | `snowflake_external_function_resource` | `snowflake_external_functions_datasource` | `snowflake_external_table_resource` | `snowflake_external_tables_datasource` | `snowflake_external_volume_resource` | `snowflake_failover_group_resource` | `snowflake_failover_groups_datasource` | `snowflake_file_format_resource` | `snowflake_file_formats_datasource` | `snowflake_managed_account_resource` | `snowflake_materialized_view_resource` | `snowflake_materialized_views_datasource` | `snowflake_network_policy_attachment_resource` | `snowflake_network_rule_resource` | `snowflake_email_notification_integration_resource` | `snowflake_notification_integration_resource` | `snowflake_object_parameter_resource` | `snowflake_password_policy_resource` | `snowflake_pipe_resource` | `snowflake_pipes_datasource` | `snowflake_current_role_datasource` | `snowflake_sequence_resource` | `snowflake_sequences_datasource` | `snowflake_share_resource` | `snowflake_shares_datasource` | `snowflake_parameters_datasource` | `snowflake_stage_resource` | `snowflake_stages_datasource` | `snowflake_storage_integration_resource` | `snowflake_storage_integrations_datasource` | `snowflake_system_generate_scim_access_token_datasource` | `snowflake_system_get_aws_sns_iam_policy_datasource` | `snowflake_system_get_privatelink_config_datasource` | `snowflake_system_get_snowflake_platform_info_datasource` | `snowflake_table_column_masking_policy_application_resource` | `snowflake_table_constraint_resource` | `snowflake_user_public_keys_resource` | `snowflake_user_password_policy_attachment_resource`.
- `private_key` (String, Sensitive) Private Key for username+private-key auth. Cannot be used with `password`. Can also be sourced from the `SNOWFLAKE_PRIVATE_KEY` environment variable.
- `private_key_passphrase` (String, Sensitive) Supports the encryption ciphers aes-128-cbc, aes-128-gcm, aes-192-cbc, aes-192-gcm, aes-256-cbc, aes-256-gcm, and des-ede3-cbc. Can also be sourced from the `SNOWFLAKE_PRIVATE_KEY_PASSPHRASE` environment variable.
- `profile` (String) Sets the profile to read from ~/.snowflake/config file. Can also be sourced from the `SNOWFLAKE_PROFILE` environment variable.
Expand Down
1 change: 1 addition & 0 deletions pkg/acceptance/testenvs/testing_environment_variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
EnableSweep env = "TEST_SF_TF_ENABLE_SWEEP"
EnableManual env = "TEST_SF_TF_ENABLE_MANUAL_TESTS"
ConfigureClientOnce env = "SF_TF_ACC_TEST_CONFIGURE_CLIENT_ONCE"
EnableAllPreviewFeatures env = "SF_TF_ACC_TEST_ENABLE_ALL_PREVIEW_FEATURES"
TestObjectsSuffix env = "TEST_SF_TF_TEST_OBJECT_SUFFIX"
RequireTestObjectsSuffix env = "TEST_SF_TF_REQUIRE_TEST_OBJECT_SUFFIX"
)
Expand Down
16 changes: 16 additions & 0 deletions pkg/datasources/common.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package datasources

import (
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/previewfeatures"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/resources"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -147,3 +149,17 @@ func handleExtendedIn(d *schema.ResourceData, setField **sdk.ExtendedIn) error {
}
return nil
}

func PreviewFeatureReadWrapper(featureRaw string, readFunc schema.ReadFunc) schema.ReadFunc { //nolint
return func(d *schema.ResourceData, meta interface{}) error {
enabled := meta.(*provider.Context).EnabledFeatures
feature, err := previewfeatures.StringToFeature(featureRaw)
if err != nil {
return err
}
if err := previewfeatures.EnsurePreviewFeatureEnabled(feature, enabled); err != nil {
return err
}
return readFunc(d, meta)
}
}
3 changes: 2 additions & 1 deletion pkg/datasources/current_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"

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

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
Expand Down Expand Up @@ -33,7 +34,7 @@ var currentAccountSchema = map[string]*schema.Schema{
// CurrentAccount the Snowflake current account resource.
func CurrentAccount() *schema.Resource {
return &schema.Resource{
Read: ReadCurrentAccount,
Read: PreviewFeatureReadWrapper(string(previewfeatures.CurrentAccountDatasource), ReadCurrentAccount),
Schema: currentAccountSchema,
}
}
Expand Down
1 change: 0 additions & 1 deletion pkg/datasources/current_account_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ func TestAcc_CurrentAccount(t *testing.T) {
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.RequireAbove(tfversion.Version1_5_0),
},
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: currentAccount(),
Expand Down
3 changes: 2 additions & 1 deletion pkg/internal/provider/provider_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ package provider
import "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"

type Context struct {
Client *sdk.Client
Client *sdk.Client
EnabledFeatures []string
}
2 changes: 1 addition & 1 deletion pkg/internal/tracking/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

const (
ProviderVersion string = "v0.99.0" // TODO(SNOW-1814934): Currently hardcoded, make it computed
ProviderVersion string = "v1.0.0-rc.1" // TODO(SNOW-1814934): Currently hardcoded, make it computed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make it v1.0.0-rc1

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially did, but realized that in semantic versioning they use . here: https://semver.org/

Copy link
Collaborator

@sfc-gh-asawicki sfc-gh-asawicki Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version. (https://semver.org/#spec-item-9) - so in our case I would say that rc1 is and identifier (not two identifiers rc and 1), so I agree with @sfc-gh-jcieslak

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this in the next pr.

MetadataPrefix string = "terraform_provider_usage_tracking"
)

Expand Down
137 changes: 137 additions & 0 deletions pkg/provider/previewfeatures/preview_features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package previewfeatures

import (
"fmt"
"slices"
"strings"
)

type feature string

const (
CurrentAccountDatasource feature = "snowflake_current_account_datasource"
AccountPasswordPolicyAttachmentResource feature = "snowflake_account_password_policy_attachment_resource"
AlertResource feature = "snowflake_alert_resource"
AlertsDatasource feature = "snowflake_alerts_datasource"
ApiIntegrationResource feature = "snowflake_api_integration_resource"
CortexSearchServiceResource feature = "snowflake_cortex_search_service_resource"
CortexSearchServicesDatasource feature = "snowflake_cortex_search_services_datasource"
DatabaseDatasource feature = "snowflake_database_datasource"
DatabaseRoleDatasource feature = "snowflake_database_role_datasource"
DynamicTableResource feature = "snowflake_dynamic_table_resource"
DynamicTablesDatasource feature = "snowflake_dynamic_tables_datasource"
ExternalFunctionResource feature = "snowflake_external_function_resource"
ExternalFunctionsDatasource feature = "snowflake_external_functions_datasource"
ExternalTableResource feature = "snowflake_external_table_resource"
ExternalTablesDatasource feature = "snowflake_external_tables_datasource"
ExternalVolumeResource feature = "snowflake_external_volume_resource"
FailoverGroupResource feature = "snowflake_failover_group_resource"
FailoverGroupsDatasource feature = "snowflake_failover_groups_datasource"
FileFormatResource feature = "snowflake_file_format_resource"
FileFormatsDatasource feature = "snowflake_file_formats_datasource"
ManagedAccountResource feature = "snowflake_managed_account_resource"
MaterializedViewResource feature = "snowflake_materialized_view_resource"
MaterializedViewsDatasource feature = "snowflake_materialized_views_datasource"
NetworkPolicyAttachmentResource feature = "snowflake_network_policy_attachment_resource"
NetworkRuleResource feature = "snowflake_network_rule_resource"
EmailNotificationIntegrationResource feature = "snowflake_email_notification_integration_resource"
NotificationIntegrationResource feature = "snowflake_notification_integration_resource"
ObjectParameterResource feature = "snowflake_object_parameter_resource"
PasswordPolicyResource feature = "snowflake_password_policy_resource"
PipeResource feature = "snowflake_pipe_resource"
PipesDatasource feature = "snowflake_pipes_datasource"
CurrentRoleDatasource feature = "snowflake_current_role_datasource"
SequenceResource feature = "snowflake_sequence_resource"
SequencesDatasource feature = "snowflake_sequences_datasource"
ShareResource feature = "snowflake_share_resource"
SharesDatasource feature = "snowflake_shares_datasource"
ParametersDatasource feature = "snowflake_parameters_datasource"
StageResource feature = "snowflake_stage_resource"
StageDatasource feature = "snowflake_stages_datasource"
StorageIntegrationResource feature = "snowflake_storage_integration_resource"
StorageIntegrationsDatasource feature = "snowflake_storage_integrations_datasource"
SystemGenerateSCIMAccessTokenDatasource feature = "snowflake_system_generate_scim_access_token_datasource"
SystemGetAWSSNSIAMPolicyDatasource feature = "snowflake_system_get_aws_sns_iam_policy_datasource"
SystemGetPrivateLinkConfigDatasource feature = "snowflake_system_get_privatelink_config_datasource"
SystemGetSnowflakePlatformInfoDatasource feature = "snowflake_system_get_snowflake_platform_info_datasource"
TableColumnMaskingPolicyApplicationResource feature = "snowflake_table_column_masking_policy_application_resource"
TableConstraintResource feature = "snowflake_table_constraint_resource"
UserPublicKeysResource feature = "snowflake_user_public_keys_resource"
UserPasswordPolicyAttachmentResource feature = "snowflake_user_password_policy_attachment_resource"
)

var allPreviewFeatures = []feature{
CurrentAccountDatasource,
AccountPasswordPolicyAttachmentResource,
AlertResource,
AlertsDatasource,
ApiIntegrationResource,
CortexSearchServiceResource,
CortexSearchServicesDatasource,
DatabaseDatasource,
DatabaseRoleDatasource,
DynamicTableResource,
DynamicTablesDatasource,
ExternalFunctionResource,
ExternalFunctionsDatasource,
ExternalTableResource,
ExternalTablesDatasource,
ExternalVolumeResource,
FailoverGroupResource,
FailoverGroupsDatasource,
FileFormatResource,
FileFormatsDatasource,
ManagedAccountResource,
MaterializedViewResource,
MaterializedViewsDatasource,
NetworkPolicyAttachmentResource,
NetworkRuleResource,
EmailNotificationIntegrationResource,
NotificationIntegrationResource,
ObjectParameterResource,
PasswordPolicyResource,
PipeResource,
PipesDatasource,
CurrentRoleDatasource,
SequenceResource,
SequencesDatasource,
ShareResource,
SharesDatasource,
ParametersDatasource,
StageResource,
StageDatasource,
StorageIntegrationResource,
StorageIntegrationsDatasource,
SystemGenerateSCIMAccessTokenDatasource,
SystemGetAWSSNSIAMPolicyDatasource,
SystemGetPrivateLinkConfigDatasource,
SystemGetSnowflakePlatformInfoDatasource,
TableColumnMaskingPolicyApplicationResource,
TableConstraintResource,
UserPublicKeysResource,
UserPasswordPolicyAttachmentResource,
}
var AllPreviewFeatures = make([]string, len(allPreviewFeatures))

func init() {
for i, v := range allPreviewFeatures {
AllPreviewFeatures[i] = string(v)
}
}

func EnsurePreviewFeatureEnabled(feat feature, enabledFeatures []string) error {
if !slices.ContainsFunc(enabledFeatures, func(s string) bool {
return s == string(feat)
}) {
return fmt.Errorf("%[1]s is currently a preview feature, and must be enabled by adding %[1]s to `preview_features_enabled` in Terraform configuration.", feat)
}
return nil
}

func StringToFeature(featRaw string) (feature, error) {
feat := feature(strings.ToLower(featRaw))
if !slices.Contains(allPreviewFeatures, feat) {
return "", fmt.Errorf("%[1]s is currently a preview feature, and must be enabled by adding %[1]s to `preview_features_enabled` in Terraform configuration.", feat)
}
return feat, nil
}
Loading
Loading