From d10474ababa7489dec3bf6c220b419b3e6a97c8b Mon Sep 17 00:00:00 2001 From: Jakub Michalak Date: Wed, 10 Jul 2024 15:24:49 +0200 Subject: [PATCH] feat: Security integrations datasource v1 readiness (#2913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Handle fields in describe for all types of security integrations. ## Test Plan * [x] acceptance tests --------- Co-authored-by: Jan Cieślak --- MIGRATION_GUIDE.md | 23 +- docs/data-sources/security_integrations.md | 444 +++++++++++++ pkg/acceptance/check_destroy.go | 9 + .../security_integrations_acceptance_test.go | 586 +++++++++++++++++- .../optionals_set/test.tf | 19 + .../optionals_set/variables.tf | 33 + .../optionals_unset/test.tf | 20 + .../optionals_unset/variables.tf | 33 + .../optionals_set/test.tf | 18 + .../optionals_set/variables.tf | 30 + .../optionals_unset/test.tf | 19 + .../optionals_unset/variables.tf | 30 + .../external_oauth/optionals_set/test.tf | 21 + .../external_oauth/optionals_set/variables.tf | 39 ++ .../external_oauth/optionals_unset/test.tf | 22 + .../optionals_unset/variables.tf | 39 ++ .../multiple_types/test.tf | 20 + .../multiple_types/variables.tf | 34 + .../optionals_set/test.tf | 24 + .../optionals_set/variables.tf | 46 ++ .../optionals_unset/test.tf | 25 + .../optionals_unset/variables.tf | 46 ++ .../optionals_set/test.tf | 16 + .../optionals_set/variables.tf | 24 + .../optionals_unset/test.tf | 17 + .../optionals_unset/variables.tf | 24 + .../optionals_set/test.tf | 11 +- .../optionals_set/variables.tf | 3 + .../optionals_unset/test.tf | 13 +- .../optionals_unset/variables.tf | 3 + .../saml2/optionals_set/test.tf | 25 + .../saml2/optionals_set/variables.tf | 52 ++ .../saml2/optionals_unset/test.tf | 26 + .../saml2/optionals_unset/variables.tf | 52 ++ pkg/helpers/helpers.go | 23 + pkg/provider/resources/resources.go | 93 +-- ...tegration_with_authorization_code_grant.go | 2 +- ...uthorization_code_grant_acceptance_test.go | 3 + ...ion_integration_with_client_credentials.go | 2 +- ...with_client_credentials_acceptance_test.go | 3 + ...hentication_integration_with_jwt_bearer.go | 2 +- pkg/resources/database.go | 2 +- pkg/resources/helpers.go | 14 - pkg/resources/secondary_database.go | 2 +- pkg/resources/shared_database.go | 2 +- ...api_authentication_security_integration.go | 33 +- .../external_oauth_security_integration.go | 34 +- .../oauth_integration_for_custom_clients.go | 48 +- ...ty_integration_for_partner_applications.go | 48 +- pkg/schemas/saml2_security_integration.go | 49 +- pkg/schemas/scim_security_integration.go | 28 +- pkg/schemas/security_integration.go | 74 +-- 52 files changed, 2058 insertions(+), 250 deletions(-) create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/variables.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/test.tf create mode 100644 pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/variables.tf diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 9764cd426d..97bbbb6c66 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -85,16 +85,22 @@ The fields listed below had diff suppress which removed '-' from strings. Now, t - `external_oauth_type` - `external_oauth_any_role_mode` +### *(new feature)* snowflake_saml2_integration resource + +The new `snowflake_saml2_integration` is introduced and deprecates `snowflake_saml_integration`. It contains new fields +and follows our new conventions making it more stable. The old SAML integration wasn't changed, so no migration needed, +but we recommend to eventually migrate to the newer counterpart. + ### snowflake_scim_integration resource changes #### *(behavior change)* Changed behavior of `sync_password` -Now, the `sync_password` field will set the state value to `unknown` whenever the value is not set in the config. This indicates that the value on the Snowflake side is set to the Snowflake default. +Now, the `sync_password` field will set the state value to `default` whenever the value is not set in the config. This indicates that the value on the Snowflake side is set to the Snowflake default. #### *(behavior change)* Renamed fields Renamed field `provisioner_role` to `run_as_role` to align with Snowflake docs. Please rename this field in your configuration files. State will be migrated automatically. -#### *(feature)* New fields +#### *(new feature)* New fields Fields added to the resource: - `enabled` - `sync_password` @@ -104,7 +110,7 @@ Fields added to the resource: New field `enabled` is required. Previously the default value during create in Snowflake was `true`. If you created a resource with Terraform, please add `enabled = true` to have the same value. #### *(behavior change)* Force new for multiple attributes -Force new was added for the following attributes (because there are no usable SQL alter statements for them): +ForceNew was added for the following attributes (because there are no usable SQL alter statements for them): - `scim_client` - `run_as_role` @@ -122,9 +128,9 @@ As part of the [redesign](https://github.com/Snowflake-Labs/terraform-provider-s - `statement_queued_timeout_in_seconds` (previously `0`) - `statement_timeout_in_seconds` (previously `172800`) -**Beware!** For attributes being Snowflake parameters (in case of warehouse: `max_concurrency_level`, `statement_queued_timeout_in_seconds`, and `statement_timeout_in_seconds`), this is a breaking change (read more in [Snowflake parameters](./v1-preparations/CHANGES_BEFORE_V1.md#snowflake-parameters)). Previously, not setting a value for them was treated as a fallback to values hardcoded on the provider side. This caused warehouse creation with these parameters set on the warehouse level (and not using the Snowflake default from hierarchy; read more in the [parameters documentation](https://docs.snowflake.com/en/sql-reference/parameters)). To keep the previous values, fill in your configs to the default values listed above. +**Beware!** For attributes being Snowflake parameters (in case of warehouse: `max_concurrency_level`, `statement_queued_timeout_in_seconds`, and `statement_timeout_in_seconds`), this is a breaking change (read more in [Snowflake parameters](./v1-preparations/CHANGES_BEFORE_V1.md#snowflake-parameters)). Previously, not setting a value for them was treated as a fallback to values hardcoded on the provider side. This caused warehouse creation with these parameters set on the warehouse level (and not using the Snowflake default from hierarchy; read more in the [parameters documentation](https://docs.snowflake.com/en/sql-reference/parameters)). To keep the previous values, fill in your configs to the default values listed above. -All previous defaults were aligned with the current Snowflake ones, however it's not possible to distinguish between filled out value and no value in the automatic state upgrader. Therefore, if the given attribute is not filled out in your configuration, terraform will try to perform update after the change (to UNSET the given attribute to the Snowflake default); it should result in no changes on Snowflake object side, but it is required to make Terraform state aligned with your config. **All** other optional fields that were not set inside the config at all (because of the change in handling state logic on our provider side) will follow the same logic. To avoid the need for the changes, fill out the default fields in your config. Alternatively run apply; no further changes should be shown as a part of the plan. +All previous defaults were aligned with the current Snowflake ones, however it's not possible to distinguish between filled out value and no value in the automatic state upgrader. Therefore, if the given attribute is not filled out in your configuration, terraform will try to perform update after the change (to UNSET the given attribute to the Snowflake default); it should result in no changes on Snowflake object side, but it is required to make Terraform state aligned with your config. **All** other optional fields that were not set inside the config at all (because of the change in handling state logic on our provider side) will follow the same logic. To avoid the need for the changes, fill out the default fields in your config. Alternatively, run `terraform apply`; no further changes should be shown as a part of the plan. #### *(note)* Automatic state migrations There are three migrations that should happen automatically with the version bump: @@ -172,7 +178,7 @@ To easily handle three-value logic (true, false, unknown) in provider's configs, You can read more in ["raw Snowflake output"](./v1-preparations/CHANGES_BEFORE_V1.md#empty-values). -### new database resources +### *(new feature)* new database resources As part of the [preparation for v1](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/ROADMAP.md#preparing-essential-ga-objects-for-the-provider-v1), we split up the database resource into multiple ones: - Standard database - can be used as `snowflake_database` (replaces the old one and is used to create databases with optional ability to become a primary database ready for replication) - Shared database - can be used as `snowflake_shared_database` (used to create databases from externally defined shares) @@ -184,7 +190,6 @@ All the field changes in comparison to the previous database resource are: - removed: the field is removed from `snowflake_shared_database` as it doesn't have any effect on shared databases. - `from_database` - database cloning was entirely removed and is not possible by any of the new database resources. - `from_share` - the parameter was moved to the dedicated resource for databases created from shares `snowflake_shared_database`. Right now, it's a text field instead of a map. Additionally, instead of legacy account identifier format we're expecting the new one that with share looks like this: `..`. For more information on account identifiers, visit the [official documentation](https://docs.snowflake.com/en/user-guide/admin-account-identifier). -- p, - `from_replication` - the parameter was moved to the dedicated resource for databases created from primary databases `snowflake_secondary_database` - `replication_configuration` - renamed: was renamed to `configuration` and is only available in the `snowflake_database`. Its internal schema changed that instead of list of accounts, we expect a list of nested objects with accounts for which replication (and optionally failover) should be enabled. More information about converting between both versions [here](#resource-renamed-snowflake_database---snowflake_database_old). Additionally, instead of legacy account identifier format we're expecting the new one that looks like this: `.` (it will be automatically migrated to the recommended format by the state upgrader). For more information on account identifiers, visit the [official documentation](https://docs.snowflake.com/en/user-guide/admin-account-identifier). - `data_retention_time_in_days` @@ -212,7 +217,7 @@ All the field changes in comparison to the previous database resource are: The split was done (and will be done for several objects during the refactor) to simplify the resource on maintainability and usage level. Its purpose was also to divide the resources by their specific purpose rather than cramping every use case of an object into one resource. -### Resource renamed snowflake_database -> snowflake_database_old +### *(behavior change)* Resource renamed snowflake_database -> snowflake_database_old We made a decision to use the existing `snowflake_database` resource for redesigning it into a standard database. The previous `snowflake_database` was renamed to `snowflake_database_old` and the current `snowflake_database` contains completely new implementation that follows our guidelines we set for V1. @@ -258,7 +263,7 @@ cloned databases diverge in behavior from standard databases, it may cause issue For databases with one of the fields mentioned above, manual migration will be needed. Please refer to our [migration guide](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/docs/technical-documentation/resource_migration.md) to perform zero downtime migration. -If you would like to upgrade to the latest version and postpone the upgrade, you still have to perform the maunal migration +If you would like to upgrade to the latest version and postpone the upgrade, you still have to perform the manual migration to the `snowflake_database_old` resource by following the [zero downtime migrations document](https://github.com/Snowflake-Labs/terraform-provider-snowflake/blob/main/docs/technical-documentation/resource_migration.md). The only difference would be that instead of writing/generating new configurations you have to just rename the existing ones to contain `_old` suffix. diff --git a/docs/data-sources/security_integrations.md b/docs/data-sources/security_integrations.md index 30ffc50dcb..16f187dfb3 100644 --- a/docs/data-sources/security_integrations.md +++ b/docs/data-sources/security_integrations.md @@ -100,25 +100,95 @@ Read-Only: Read-Only: +- `allowed_email_patterns` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--allowed_email_patterns)) +- `allowed_user_domains` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--allowed_user_domains)) +- `auth_type` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--auth_type)) - `blocked_roles_list` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--blocked_roles_list)) - `comment` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--comment)) - `enabled` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--enabled)) +- `external_oauth_allowed_roles_list` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_allowed_roles_list)) +- `external_oauth_any_role_mode` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_any_role_mode)) +- `external_oauth_audience_list` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_audience_list)) +- `external_oauth_blocked_roles_list` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_blocked_roles_list)) +- `external_oauth_issuer` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_issuer)) +- `external_oauth_jws_keys_url` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_jws_keys_url)) +- `external_oauth_rsa_public_key` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_rsa_public_key)) +- `external_oauth_rsa_public_key_2` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_rsa_public_key_2)) +- `external_oauth_scope_delimiter` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_scope_delimiter)) +- `external_oauth_snowflake_user_mapping_attribute` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_snowflake_user_mapping_attribute)) +- `external_oauth_token_user_mapping_claim` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--external_oauth_token_user_mapping_claim)) - `network_policy` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--network_policy)) +- `oauth_access_token_validity` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_access_token_validity)) - `oauth_allow_non_tls_redirect_uri` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_allow_non_tls_redirect_uri)) - `oauth_allowed_authorization_endpoints` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_allowed_authorization_endpoints)) +- `oauth_allowed_scopes` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_allowed_scopes)) - `oauth_allowed_token_endpoints` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_allowed_token_endpoints)) - `oauth_authorization_endpoint` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_authorization_endpoint)) +- `oauth_client_auth_method` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_client_auth_method)) - `oauth_client_id` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_client_id)) - `oauth_client_rsa_public_key_2_fp` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_client_rsa_public_key_2_fp)) - `oauth_client_rsa_public_key_fp` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_client_rsa_public_key_fp)) - `oauth_client_type` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_client_type)) - `oauth_enforce_pkce` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_enforce_pkce)) +- `oauth_grant` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_grant)) - `oauth_issue_refresh_tokens` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_issue_refresh_tokens)) - `oauth_redirect_uri` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_redirect_uri)) - `oauth_refresh_token_validity` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_refresh_token_validity)) - `oauth_token_endpoint` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_token_endpoint)) - `oauth_use_secondary_roles` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--oauth_use_secondary_roles)) +- `parent_integration` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--parent_integration)) - `pre_authorized_roles_list` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--pre_authorized_roles_list)) +- `run_as_role` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--run_as_role)) +- `saml2_digest_methods_used` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_digest_methods_used)) +- `saml2_enable_sp_initiated` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_enable_sp_initiated)) +- `saml2_force_authn` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_force_authn)) +- `saml2_issuer` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_issuer)) +- `saml2_post_logout_redirect_url` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_post_logout_redirect_url)) +- `saml2_provider` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_provider)) +- `saml2_requested_nameid_format` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_requested_nameid_format)) +- `saml2_sign_request` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_sign_request)) +- `saml2_signature_methods_used` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_signature_methods_used)) +- `saml2_snowflake_acs_url` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_snowflake_acs_url)) +- `saml2_snowflake_issuer_url` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_snowflake_issuer_url)) +- `saml2_snowflake_metadata` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_snowflake_metadata)) +- `saml2_snowflake_x509_cert` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_snowflake_x509_cert)) +- `saml2_sp_initiated_login_page_label` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_sp_initiated_login_page_label)) +- `saml2_sso_url` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_sso_url)) +- `saml2_x509_cert` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--saml2_x509_cert)) +- `sync_password` (List of Object) (see [below for nested schema](#nestedobjatt--security_integrations--describe_output--sync_password)) + + +### Nested Schema for `security_integrations.describe_output.allowed_email_patterns` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.allowed_user_domains` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.auth_type` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + ### Nested Schema for `security_integrations.describe_output.blocked_roles_list` @@ -153,6 +223,127 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.external_oauth_allowed_roles_list` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_any_role_mode` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_audience_list` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_blocked_roles_list` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_issuer` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_jws_keys_url` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_rsa_public_key` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_rsa_public_key_2` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_scope_delimiter` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_snowflake_user_mapping_attribute` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.external_oauth_token_user_mapping_claim` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.describe_output.network_policy` @@ -164,6 +355,17 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.oauth_access_token_validity` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.describe_output.oauth_allow_non_tls_redirect_uri` @@ -186,6 +388,17 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.oauth_allowed_scopes` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.describe_output.oauth_allowed_token_endpoints` @@ -208,6 +421,17 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.oauth_client_auth_method` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.describe_output.oauth_client_id` @@ -263,6 +487,17 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.oauth_grant` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.describe_output.oauth_issue_refresh_tokens` @@ -318,6 +553,17 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.parent_integration` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.describe_output.pre_authorized_roles_list` @@ -329,6 +575,204 @@ Read-Only: - `value` (String) + +### Nested Schema for `security_integrations.describe_output.run_as_role` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_digest_methods_used` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_enable_sp_initiated` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_force_authn` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_issuer` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_post_logout_redirect_url` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_provider` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_requested_nameid_format` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_sign_request` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_signature_methods_used` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_snowflake_acs_url` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_snowflake_issuer_url` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_snowflake_metadata` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_snowflake_x509_cert` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_sp_initiated_login_page_label` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_sso_url` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.saml2_x509_cert` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + + +### Nested Schema for `security_integrations.describe_output.sync_password` + +Read-Only: + +- `default` (String) +- `name` (String) +- `type` (String) +- `value` (String) + + ### Nested Schema for `security_integrations.show_output` diff --git a/pkg/acceptance/check_destroy.go b/pkg/acceptance/check_destroy.go index 5483146d8b..b7ea0a9012 100644 --- a/pkg/acceptance/check_destroy.go +++ b/pkg/acceptance/check_destroy.go @@ -67,6 +67,15 @@ var showByIdFunctions = map[resources.Resource]showByIdFunc{ resources.Alert: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error { return runShowById(ctx, id, client.Alerts.ShowByID) }, + resources.ApiAuthenticationIntegrationWithAuthorizationCodeGrant: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error { + return runShowById(ctx, id, client.SecurityIntegrations.ShowByID) + }, + resources.ApiAuthenticationIntegrationWithClientCredentials: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error { + return runShowById(ctx, id, client.SecurityIntegrations.ShowByID) + }, + resources.ApiAuthenticationIntegrationWithJwtBearer: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error { + return runShowById(ctx, id, client.SecurityIntegrations.ShowByID) + }, resources.ApiIntegration: func(ctx context.Context, client *sdk.Client, id sdk.ObjectIdentifier) error { return runShowById(ctx, id, client.ApiIntegrations.ShowByID) }, diff --git a/pkg/datasources/security_integrations_acceptance_test.go b/pkg/datasources/security_integrations_acceptance_test.go index 178153b801..8294157454 100644 --- a/pkg/datasources/security_integrations_acceptance_test.go +++ b/pkg/datasources/security_integrations_acceptance_test.go @@ -6,9 +6,9 @@ import ( "testing" acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/snowflakeroles" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random" - "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-testing/config" @@ -16,16 +16,579 @@ import ( "github.com/hashicorp/terraform-plugin-testing/tfversion" ) -// TODO [SNOW-1348100]: add other security integrations when they are ready -// TODO [SNOW-1348100]: test specific describe properties -func TestAcc_SecurityIntegrations_Scim(t *testing.T) { - _ = testenvs.GetOrSkipTest(t, testenvs.ConfigureClientOnce) +func TestAcc_SecurityIntegrations_MultipleTypes(t *testing.T) { + prefix := random.AlphaN(4) + idOne := acc.TestClient().Ids.RandomAccountObjectIdentifierWithPrefix(prefix) + idTwo := acc.TestClient().Ids.RandomAccountObjectIdentifierWithPrefix(prefix) + issuer := acc.TestClient().Ids.Alpha() + cert := random.GenerateX509(t) + validUrl := "http://example.com" + + role := snowflakeroles.GenericScimProvisioner + configVariables := config.Variables{ + // saml2 + "name_1": config.StringVariable(idOne.Name()), + "saml2_issuer": config.StringVariable(issuer), + "saml2_provider": config.StringVariable(string(sdk.Saml2SecurityIntegrationSaml2ProviderCustom)), + "saml2_sso_url": config.StringVariable(validUrl), + "saml2_x509_cert": config.StringVariable(cert), + // scim + "name_2": config.StringVariable(idTwo.Name()), + "scim_client": config.StringVariable(string(sdk.ScimSecurityIntegrationScimClientGeneric)), + "run_as_role": config.StringVariable(role.Name()), + "enabled": config.BoolVariable(true), + + "like": config.StringVariable(prefix + "%"), + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/multiple_types"), + ConfigVariables: configVariables, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "2"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", idOne.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "SCIM - GENERIC"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", sdk.SecurityIntegrationCategory), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.run_as_role.0.value", "GENERIC_SCIM_PROVISIONER"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.sync_password.0.value", "true"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.show_output.0.name", idTwo.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.show_output.0.integration_type", "SAML2"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.show_output.0.category", sdk.SecurityIntegrationCategory), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.show_output.0.enabled", "false"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.1.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.describe_output.0.saml2_issuer.0.value", issuer), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.describe_output.0.saml2_provider.0.value", "CUSTOM"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.describe_output.0.saml2_sso_url.0.value", validUrl), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.1.describe_output.0.saml2_x509_cert.0.value", cert), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_ApiAuthenticationWithAuthorizationCodeGrant(t *testing.T) { + id := acc.TestClient().Ids.RandomAccountObjectIdentifier() + + m := func() map[string]config.Variable { + return map[string]config.Variable{ + "comment": config.StringVariable("foo"), + "enabled": config.BoolVariable(true), + "name": config.StringVariable(id.Name()), + "oauth_access_token_validity": config.IntegerVariable(42), + "oauth_authorization_endpoint": config.StringVariable("https://example.com"), + "oauth_client_auth_method": config.StringVariable(string(sdk.ApiAuthenticationSecurityIntegrationOauthClientAuthMethodClientSecretPost)), + "oauth_client_id": config.StringVariable("foo"), + "oauth_client_secret": config.StringVariable("foo"), + "oauth_refresh_token_validity": config.IntegerVariable(12345), + "oauth_token_endpoint": config.StringVariable("https://example.com"), + "oauth_allowed_scopes": config.SetVariable(config.StringVariable("foo")), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.ApiAuthenticationIntegrationWithAuthorizationCodeGrant), + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "API_AUTHENTICATION"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_access_token_validity.0.value", "42"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_refresh_token_validity.0.value", "12345"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_id.0.value", "foo"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_auth_method.0.value", string(sdk.ApiAuthenticationSecurityIntegrationOauthClientAuthMethodClientSecretPost)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_authorization_endpoint.0.value", "https://example.com"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_token_endpoint.0.value", "https://example.com"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allowed_scopes.0.value", "[foo]"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_grant.0.value", sdk.ApiAuthenticationSecurityIntegrationOauthGrantAuthorizationCode), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.parent_integration.0.value", ""), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.auth_type.0.value", "OAUTH2"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", "foo")), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "API_AUTHENTICATION"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "0"), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_ApiAuthenticationWithClientCredentials(t *testing.T) { + id := acc.TestClient().Ids.RandomAccountObjectIdentifier() + + m := func() map[string]config.Variable { + return map[string]config.Variable{ + "comment": config.StringVariable("foo"), + "enabled": config.BoolVariable(true), + "name": config.StringVariable(id.Name()), + "oauth_access_token_validity": config.IntegerVariable(42), + "oauth_client_auth_method": config.StringVariable(string(sdk.ApiAuthenticationSecurityIntegrationOauthClientAuthMethodClientSecretPost)), + "oauth_client_id": config.StringVariable("foo"), + "oauth_client_secret": config.StringVariable("foo"), + "oauth_refresh_token_validity": config.IntegerVariable(12345), + "oauth_token_endpoint": config.StringVariable("https://example.com"), + "oauth_allowed_scopes": config.SetVariable(config.StringVariable("foo")), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.ApiAuthenticationIntegrationWithClientCredentials), + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "API_AUTHENTICATION"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_access_token_validity.0.value", "42"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_refresh_token_validity.0.value", "12345"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_id.0.value", "foo"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_auth_method.0.value", string(sdk.ApiAuthenticationSecurityIntegrationOauthClientAuthMethodClientSecretPost)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_token_endpoint.0.value", "https://example.com"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allowed_scopes.0.value", "[foo]"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_grant.0.value", sdk.ApiAuthenticationSecurityIntegrationOauthGrantClientCredentials), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.parent_integration.0.value", ""), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.auth_type.0.value", "OAUTH2"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", "foo")), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "API_AUTHENTICATION"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "0"), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_ExternalOauth(t *testing.T) { + id := acc.TestClient().Ids.RandomAccountObjectIdentifier() + role, roleCleanup := acc.TestClient().Role.CreateRole(t) + issuer := random.String() + t.Cleanup(roleCleanup) + + m := func() map[string]config.Variable { + return map[string]config.Variable{ + "comment": config.StringVariable("foo"), + "enabled": config.BoolVariable(true), + "external_oauth_allowed_roles_list": config.SetVariable(config.StringVariable(role.ID().Name())), + "external_oauth_any_role_mode": config.StringVariable(string(sdk.ExternalOauthSecurityIntegrationAnyRoleModeDisable)), + "external_oauth_audience_list": config.SetVariable(config.StringVariable("foo")), + "external_oauth_issuer": config.StringVariable(issuer), + "external_oauth_jws_keys_url": config.SetVariable(config.StringVariable("https://example.com")), + "external_oauth_scope_delimiter": config.StringVariable("."), + "external_oauth_scope_mapping_attribute": config.StringVariable("foo"), + "external_oauth_snowflake_user_mapping_attribute": config.StringVariable(string(sdk.ExternalOauthSecurityIntegrationSnowflakeUserMappingAttributeEmailAddress)), + "external_oauth_token_user_mapping_claim": config.SetVariable(config.StringVariable("foo")), + "name": config.StringVariable(id.Name()), + "external_oauth_type": config.StringVariable(string(sdk.ExternalOauthSecurityIntegrationTypeCustom)), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.ExternalOauthSecurityIntegration), + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/external_oauth/optionals_set"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "EXTERNAL_OAUTH - CUSTOM"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_issuer.0.value", issuer), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_jws_keys_url.0.value", "https://example.com"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_any_role_mode.0.value", string(sdk.ExternalOauthSecurityIntegrationAnyRoleModeDisable)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_allowed_roles_list.0.value", role.Name), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_audience_list.0.value", "foo"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_token_user_mapping_claim.0.value", "['foo']"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_snowflake_user_mapping_attribute.0.value", string(sdk.ExternalOauthSecurityIntegrationSnowflakeUserMappingAttributeEmailAddress)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.external_oauth_scope_delimiter.0.value", "."), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", "foo"), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/external_oauth/optionals_unset"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "EXTERNAL_OAUTH - CUSTOM"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "0"), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_OauthForCustomClients(t *testing.T) { + networkPolicy, networkPolicyCleanup := acc.TestClient().NetworkPolicy.CreateNetworkPolicy(t) + t.Cleanup(networkPolicyCleanup) + + preAuthorizedRole, preauthorizedRoleCleanup := acc.TestClient().Role.CreateRole(t) + t.Cleanup(preauthorizedRoleCleanup) + + blockedRole, blockedRoleCleanup := acc.TestClient().Role.CreateRole(t) + t.Cleanup(blockedRoleCleanup) + + validUrl := "https://example.com" + id := acc.TestClient().Ids.RandomAccountObjectIdentifier() + key, _ := random.GenerateRSAPublicKey(t) + comment := random.Comment() + m := func() map[string]config.Variable { + return map[string]config.Variable{ + "name": config.StringVariable(id.Name()), + "oauth_client_type": config.StringVariable(string(sdk.OauthSecurityIntegrationClientTypeConfidential)), + "oauth_redirect_uri": config.StringVariable(validUrl), + "blocked_roles_list": config.SetVariable(config.StringVariable("ACCOUNTADMIN"), config.StringVariable("SECURITYADMIN"), config.StringVariable(blockedRole.ID().Name())), + "comment": config.StringVariable(comment), + "enabled": config.BoolVariable(true), + "network_policy": config.StringVariable(networkPolicy.Name), + "oauth_allow_non_tls_redirect_uri": config.BoolVariable(true), + "oauth_allowed_authorization_endpoints": config.SetVariable(config.StringVariable("http://allowed.com")), + "oauth_allowed_token_endpoints": config.SetVariable(config.StringVariable("http://allowed.com")), + "oauth_authorization_endpoint": config.StringVariable("http://auth.com"), + "oauth_client_rsa_public_key": config.StringVariable(key), + "oauth_client_rsa_public_key_2": config.StringVariable(key), + "oauth_enforce_pkce": config.BoolVariable(true), + "oauth_issue_refresh_tokens": config.BoolVariable(true), + "oauth_refresh_token_validity": config.IntegerVariable(86400), + "oauth_token_endpoint": config.StringVariable("http://auth.com"), + "oauth_use_secondary_roles": config.StringVariable(string(sdk.OauthSecurityIntegrationUseSecondaryRolesNone)), + "pre_authorized_roles_list": config.SetVariable(config.StringVariable(preAuthorizedRole.ID().Name())), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.OauthIntegrationForCustomClients), + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_type.0.value", string(sdk.OauthSecurityIntegrationClientTypeConfidential)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_redirect_uri.0.value", validUrl), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allow_non_tls_redirect_uri.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_enforce_pkce.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_use_secondary_roles.0.value", string(sdk.OauthSecurityIntegrationUseSecondaryRolesNone)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.pre_authorized_roles_list.0.value", preAuthorizedRole.ID().Name()), + // Not asserted, because it also contains other default roles + // resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.blocked_roles_list.0.value"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_issue_refresh_tokens.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_refresh_token_validity.0.value", "86400"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.network_policy.0.value", sdk.NewAccountObjectIdentifier(networkPolicy.Name).Name()), // TODO(SNOW-999049): Fix during identifiers rework + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_rsa_public_key_fp.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_rsa_public_key_2_fp.0.value"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", comment), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_id.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_authorization_endpoint.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_token_endpoint.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allowed_authorization_endpoints.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allowed_token_endpoints.0.value"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "OAUTH - CUSTOM"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", comment), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "OAUTH - CUSTOM"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", comment), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "0"), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_OauthForPartnerApplications(t *testing.T) { id := acc.TestClient().Ids.RandomAccountObjectIdentifier() comment := random.Comment() + m := func() map[string]config.Variable { + return map[string]config.Variable{ + "name": config.StringVariable(id.Name()), + "oauth_client": config.StringVariable(string(sdk.OauthSecurityIntegrationClientTableauServer)), + "blocked_roles_list": config.SetVariable(config.StringVariable("ACCOUNTADMIN"), config.StringVariable("SECURITYADMIN")), + "enabled": config.BoolVariable(true), + "oauth_issue_refresh_tokens": config.BoolVariable(false), + "oauth_refresh_token_validity": config.IntegerVariable(86400), + "oauth_use_secondary_roles": config.StringVariable(string(sdk.OauthSecurityIntegrationUseSecondaryRolesImplicit)), + "comment": config.StringVariable(comment), + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.OauthIntegrationForPartnerApplications), + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_type.0.value", string(sdk.OauthSecurityIntegrationClientTypePublic)), + resource.TestCheckNoResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_redirect_uri.0.value"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_use_secondary_roles.0.value", string(sdk.OauthSecurityIntegrationUseSecondaryRolesImplicit)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.blocked_roles_list.0.value", "ACCOUNTADMIN,SECURITYADMIN"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_issue_refresh_tokens.0.value", "false"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_refresh_token_validity.0.value", "86400"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", comment), + resource.TestCheckNoResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_client_id.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_authorization_endpoint.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_token_endpoint.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allowed_authorization_endpoints.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.oauth_allowed_token_endpoints.0.value"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "OAUTH - TABLEAU_SERVER"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", comment), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "OAUTH - TABLEAU_SERVER"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", comment), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "0"), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_Saml2(t *testing.T) { + id := acc.TestClient().Ids.RandomAccountObjectIdentifier() + issuer := acc.TestClient().Ids.Alpha() + cert := random.GenerateX509(t) + validUrl := "http://example.com" + acsURL := acc.TestClient().Context.ACSURL(t) + issuerURL := acc.TestClient().Context.IssuerURL(t) + + m := func() map[string]config.Variable { + return map[string]config.Variable{ + "allowed_email_patterns": config.ListVariable(config.StringVariable("^(.+dev)@example.com$")), + "allowed_user_domains": config.ListVariable(config.StringVariable("example.com")), + "comment": config.StringVariable("foo"), + "enabled": config.BoolVariable(true), + "name": config.StringVariable(id.Name()), + "saml2_enable_sp_initiated": config.BoolVariable(true), + "saml2_force_authn": config.BoolVariable(true), + "saml2_issuer": config.StringVariable(issuer), + "saml2_post_logout_redirect_url": config.StringVariable(validUrl), + "saml2_provider": config.StringVariable(string(sdk.Saml2SecurityIntegrationSaml2ProviderCustom)), + "saml2_requested_nameid_format": config.StringVariable(string(sdk.Saml2SecurityIntegrationSaml2RequestedNameidFormatUnspecified)), + "saml2_sign_request": config.BoolVariable(true), + "saml2_snowflake_acs_url": config.StringVariable(acsURL), + "saml2_snowflake_issuer_url": config.StringVariable(issuerURL), + "saml2_sp_initiated_login_page_label": config.StringVariable("foo"), + "saml2_sso_url": config.StringVariable(validUrl), + "saml2_x509_cert": config.StringVariable(cert), + // TODO(SNOW-1479617): set saml2_snowflake_x509_cert + } + } + + resource.Test(t, resource.TestCase{ + ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories, + TerraformVersionChecks: []tfversion.TerraformVersionCheck{ + tfversion.RequireAbove(tfversion.Version1_5_0), + }, + CheckDestroy: acc.CheckDestroy(t, resources.Saml2SecurityIntegration), + Steps: []resource.TestStep{ + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/saml2/optionals_set"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_issuer.0.value", issuer), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_sso_url.0.value", validUrl), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_provider.0.value", string(sdk.Saml2SecurityIntegrationSaml2ProviderCustom)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_x509_cert.0.value", cert), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_sp_initiated_login_page_label.0.value", "foo"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_enable_sp_initiated.0.value", "true"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_snowflake_x509_cert.0.value"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_sign_request.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_requested_nameid_format.0.value", string(sdk.Saml2SecurityIntegrationSaml2RequestedNameidFormatUnspecified)), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_post_logout_redirect_url.0.value", "http://example.com"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_force_authn.0.value", "true"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_snowflake_issuer_url.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_snowflake_acs_url.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_snowflake_metadata.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_digest_methods_used.0.value"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.saml2_signature_methods_used.0.value"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.allowed_user_domains.0.value", "[example.com]"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.allowed_email_patterns.0.value", "[^(.+dev)@example.com$]"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", "foo"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "SAML2"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + ), + }, + { + ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/saml2/optionals_unset"), + ConfigVariables: m(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.#", "1"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.integration_type", "SAML2"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.category", "SECURITY"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.enabled", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.comment", "foo"), + resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), + + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "0"), + ), + }, + }, + }) +} + +func TestAcc_SecurityIntegrations_Scim(t *testing.T) { + id := acc.TestClient().Ids.RandomAccountObjectIdentifier() + comment := random.Comment() + networkPolicy, networkPolicyCleanup := acc.TestClient().NetworkPolicy.CreateNetworkPolicy(t) + t.Cleanup(networkPolicyCleanup) configVariables := config.Variables{ - "name": config.StringVariable(id.Name()), - "comment": config.StringVariable(comment), + "name": config.StringVariable(id.Name()), + "comment": config.StringVariable(comment), + "network_policy": config.StringVariable(networkPolicy.Name), } resource.Test(t, resource.TestCase{ @@ -38,7 +601,7 @@ func TestAcc_SecurityIntegrations_Scim(t *testing.T) { { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/optionals_set"), ConfigVariables: configVariables, - Check: resource.ComposeTestCheckFunc( + Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), @@ -49,14 +612,17 @@ func TestAcc_SecurityIntegrations_Scim(t *testing.T) { resource.TestCheckResourceAttrSet("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.created_on"), resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.#", "1"), - resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.#", "1"), resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.enabled.0.value", "false"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.network_policy.0.value", sdk.NewAccountObjectIdentifier(networkPolicy.Name).Name()), // TODO(SNOW-999049): Fix during identifiers rework + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.run_as_role.0.value", "GENERIC_SCIM_PROVISIONER"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.sync_password.0.value", "true"), + resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.describe_output.0.comment.0.value", comment), ), }, { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_SecurityIntegrations/optionals_unset"), ConfigVariables: configVariables, - Check: resource.ComposeTestCheckFunc( + Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.#", "1"), resource.TestCheckResourceAttr("data.snowflake_security_integrations.test", "security_integrations.0.show_output.0.name", id.Name()), diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/test.tf new file mode 100644 index 0000000000..930dad11c2 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/test.tf @@ -0,0 +1,19 @@ +resource "snowflake_api_authentication_integration_with_authorization_code_grant" "test" { + comment = var.comment + enabled = var.enabled + name = var.name + oauth_access_token_validity = var.oauth_access_token_validity + oauth_authorization_endpoint = var.oauth_authorization_endpoint + oauth_client_auth_method = var.oauth_client_auth_method + oauth_client_id = var.oauth_client_id + oauth_client_secret = var.oauth_client_secret + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_token_endpoint = var.oauth_token_endpoint + oauth_allowed_scopes = var.oauth_allowed_scopes +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_api_authentication_integration_with_authorization_code_grant.test] + + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/variables.tf new file mode 100644 index 0000000000..06e9998ff5 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_set/variables.tf @@ -0,0 +1,33 @@ +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "oauth_access_token_validity" { + type = number +} +variable "oauth_authorization_endpoint" { + type = string +} +variable "oauth_client_auth_method" { + type = string +} +variable "oauth_client_id" { + type = string +} +variable "oauth_client_secret" { + type = string +} +variable "oauth_refresh_token_validity" { + type = number +} +variable "oauth_token_endpoint" { + type = string +} +variable "oauth_allowed_scopes" { + type = set(string) +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/test.tf new file mode 100644 index 0000000000..c96b04b898 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/test.tf @@ -0,0 +1,20 @@ +resource "snowflake_api_authentication_integration_with_authorization_code_grant" "test" { + comment = var.comment + enabled = var.enabled + name = var.name + oauth_access_token_validity = var.oauth_access_token_validity + oauth_authorization_endpoint = var.oauth_authorization_endpoint + oauth_client_auth_method = var.oauth_client_auth_method + oauth_client_id = var.oauth_client_id + oauth_client_secret = var.oauth_client_secret + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_token_endpoint = var.oauth_token_endpoint + oauth_allowed_scopes = var.oauth_allowed_scopes +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_api_authentication_integration_with_authorization_code_grant.test] + + with_describe = false + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/variables.tf new file mode 100644 index 0000000000..06e9998ff5 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_authorization_code_grant/optionals_unset/variables.tf @@ -0,0 +1,33 @@ +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "oauth_access_token_validity" { + type = number +} +variable "oauth_authorization_endpoint" { + type = string +} +variable "oauth_client_auth_method" { + type = string +} +variable "oauth_client_id" { + type = string +} +variable "oauth_client_secret" { + type = string +} +variable "oauth_refresh_token_validity" { + type = number +} +variable "oauth_token_endpoint" { + type = string +} +variable "oauth_allowed_scopes" { + type = set(string) +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/test.tf new file mode 100644 index 0000000000..bf8e125fe0 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/test.tf @@ -0,0 +1,18 @@ +resource "snowflake_api_authentication_integration_with_client_credentials" "test" { + comment = var.comment + enabled = var.enabled + name = var.name + oauth_access_token_validity = var.oauth_access_token_validity + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_client_auth_method = var.oauth_client_auth_method + oauth_client_id = var.oauth_client_id + oauth_client_secret = var.oauth_client_secret + oauth_token_endpoint = var.oauth_token_endpoint + oauth_allowed_scopes = var.oauth_allowed_scopes +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_api_authentication_integration_with_client_credentials.test] + + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/variables.tf new file mode 100644 index 0000000000..4ccccac436 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_set/variables.tf @@ -0,0 +1,30 @@ +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "oauth_access_token_validity" { + type = number +} +variable "oauth_refresh_token_validity" { + type = number +} +variable "oauth_client_auth_method" { + type = string +} +variable "oauth_client_id" { + type = string +} +variable "oauth_client_secret" { + type = string +} +variable "oauth_token_endpoint" { + type = string +} +variable "oauth_allowed_scopes" { + type = set(string) +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/test.tf new file mode 100644 index 0000000000..487a75acc7 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/test.tf @@ -0,0 +1,19 @@ +resource "snowflake_api_authentication_integration_with_client_credentials" "test" { + comment = var.comment + enabled = var.enabled + name = var.name + oauth_access_token_validity = var.oauth_access_token_validity + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_client_auth_method = var.oauth_client_auth_method + oauth_client_id = var.oauth_client_id + oauth_client_secret = var.oauth_client_secret + oauth_token_endpoint = var.oauth_token_endpoint + oauth_allowed_scopes = var.oauth_allowed_scopes +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_api_authentication_integration_with_client_credentials.test] + + with_describe = false + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/variables.tf new file mode 100644 index 0000000000..4ccccac436 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/api_authentication_with_client_credentials/optionals_unset/variables.tf @@ -0,0 +1,30 @@ +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "oauth_access_token_validity" { + type = number +} +variable "oauth_refresh_token_validity" { + type = number +} +variable "oauth_client_auth_method" { + type = string +} +variable "oauth_client_id" { + type = string +} +variable "oauth_client_secret" { + type = string +} +variable "oauth_token_endpoint" { + type = string +} +variable "oauth_allowed_scopes" { + type = set(string) +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/test.tf new file mode 100644 index 0000000000..2eeca56bed --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/test.tf @@ -0,0 +1,21 @@ +resource "snowflake_external_oauth_integration" "test" { + comment = var.comment + enabled = var.enabled + external_oauth_allowed_roles_list = var.external_oauth_allowed_roles_list + external_oauth_any_role_mode = var.external_oauth_any_role_mode + external_oauth_audience_list = var.external_oauth_audience_list + external_oauth_issuer = var.external_oauth_issuer + external_oauth_jws_keys_url = var.external_oauth_jws_keys_url + external_oauth_scope_delimiter = var.external_oauth_scope_delimiter + external_oauth_scope_mapping_attribute = var.external_oauth_scope_mapping_attribute + external_oauth_snowflake_user_mapping_attribute = var.external_oauth_snowflake_user_mapping_attribute + external_oauth_token_user_mapping_claim = var.external_oauth_token_user_mapping_claim + name = var.name + external_oauth_type = var.external_oauth_type +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_external_oauth_integration.test] + + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/variables.tf new file mode 100644 index 0000000000..ac964d6100 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_set/variables.tf @@ -0,0 +1,39 @@ +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "external_oauth_allowed_roles_list" { + type = set(string) +} +variable "external_oauth_any_role_mode" { + type = string +} +variable "external_oauth_audience_list" { + type = set(string) +} +variable "external_oauth_issuer" { + type = string +} +variable "external_oauth_jws_keys_url" { + type = set(string) +} +variable "external_oauth_scope_delimiter" { + type = string +} +variable "external_oauth_scope_mapping_attribute" { + type = string +} +variable "external_oauth_snowflake_user_mapping_attribute" { + type = string +} +variable "external_oauth_token_user_mapping_claim" { + type = set(string) +} +variable "name" { + type = string +} +variable "external_oauth_type" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/test.tf new file mode 100644 index 0000000000..f432e7031a --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/test.tf @@ -0,0 +1,22 @@ +resource "snowflake_external_oauth_integration" "test" { + comment = var.comment + enabled = var.enabled + external_oauth_allowed_roles_list = var.external_oauth_allowed_roles_list + external_oauth_any_role_mode = var.external_oauth_any_role_mode + external_oauth_audience_list = var.external_oauth_audience_list + external_oauth_issuer = var.external_oauth_issuer + external_oauth_jws_keys_url = var.external_oauth_jws_keys_url + external_oauth_scope_delimiter = var.external_oauth_scope_delimiter + external_oauth_scope_mapping_attribute = var.external_oauth_scope_mapping_attribute + external_oauth_snowflake_user_mapping_attribute = var.external_oauth_snowflake_user_mapping_attribute + external_oauth_token_user_mapping_claim = var.external_oauth_token_user_mapping_claim + name = var.name + external_oauth_type = var.external_oauth_type +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_external_oauth_integration.test] + + with_describe = false + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/variables.tf new file mode 100644 index 0000000000..ac964d6100 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/external_oauth/optionals_unset/variables.tf @@ -0,0 +1,39 @@ +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "external_oauth_allowed_roles_list" { + type = set(string) +} +variable "external_oauth_any_role_mode" { + type = string +} +variable "external_oauth_audience_list" { + type = set(string) +} +variable "external_oauth_issuer" { + type = string +} +variable "external_oauth_jws_keys_url" { + type = set(string) +} +variable "external_oauth_scope_delimiter" { + type = string +} +variable "external_oauth_scope_mapping_attribute" { + type = string +} +variable "external_oauth_snowflake_user_mapping_attribute" { + type = string +} +variable "external_oauth_token_user_mapping_claim" { + type = set(string) +} +variable "name" { + type = string +} +variable "external_oauth_type" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/test.tf new file mode 100644 index 0000000000..dfaf0ebbd7 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/test.tf @@ -0,0 +1,20 @@ +resource "snowflake_scim_integration" "test" { + name = var.name_1 + scim_client = var.scim_client + run_as_role = var.run_as_role + enabled = var.enabled +} + +resource "snowflake_saml2_integration" "test" { + name = var.name_2 + saml2_issuer = var.saml2_issuer + saml2_sso_url = var.saml2_sso_url + saml2_provider = var.saml2_provider + saml2_x509_cert = var.saml2_x509_cert +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_scim_integration.test, snowflake_saml2_integration.test] + + like = var.like +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/variables.tf new file mode 100644 index 0000000000..960c2cf847 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/multiple_types/variables.tf @@ -0,0 +1,34 @@ +# saml2 +variable "name_1" { + type = string +} +variable "saml2_issuer" { + type = string +} +variable "saml2_provider" { + type = string +} +variable "saml2_sso_url" { + type = string +} +variable "saml2_x509_cert" { + type = string +} + +# scim +variable "name_2" { + type = string +} +variable "scim_client" { + type = string +} +variable "run_as_role" { + type = string +} +variable "enabled" { + type = bool +} + +variable "like" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/test.tf new file mode 100644 index 0000000000..b1faba1325 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/test.tf @@ -0,0 +1,24 @@ +resource "snowflake_oauth_integration_for_custom_clients" "test" { + blocked_roles_list = var.blocked_roles_list + comment = var.comment + enabled = var.enabled + name = var.name + network_policy = var.network_policy + oauth_allow_non_tls_redirect_uri = var.oauth_allow_non_tls_redirect_uri + oauth_client_rsa_public_key = var.oauth_client_rsa_public_key + oauth_client_rsa_public_key_2 = var.oauth_client_rsa_public_key_2 + oauth_client_type = var.oauth_client_type + oauth_enforce_pkce = var.oauth_enforce_pkce + oauth_issue_refresh_tokens = var.oauth_issue_refresh_tokens + oauth_redirect_uri = var.oauth_redirect_uri + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_use_secondary_roles = var.oauth_use_secondary_roles + pre_authorized_roles_list = var.pre_authorized_roles_list +} + + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_oauth_integration_for_custom_clients.test] + + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/variables.tf new file mode 100644 index 0000000000..9d98ea92c8 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_set/variables.tf @@ -0,0 +1,46 @@ + +variable "blocked_roles_list" { + type = set(string) +} +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "network_policy" { + type = string +} +variable "oauth_allow_non_tls_redirect_uri" { + type = bool +} +variable "oauth_client_rsa_public_key" { + type = string +} +variable "oauth_client_rsa_public_key_2" { + type = string +} +variable "oauth_client_type" { + type = string +} +variable "oauth_enforce_pkce" { + type = bool +} +variable "oauth_issue_refresh_tokens" { + type = bool +} +variable "oauth_redirect_uri" { + type = string +} +variable "oauth_refresh_token_validity" { + type = number +} +variable "oauth_use_secondary_roles" { + type = string +} +variable "pre_authorized_roles_list" { + type = set(string) +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/test.tf new file mode 100644 index 0000000000..e780bf0c13 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/test.tf @@ -0,0 +1,25 @@ +resource "snowflake_oauth_integration_for_custom_clients" "test" { + blocked_roles_list = var.blocked_roles_list + comment = var.comment + enabled = var.enabled + name = var.name + network_policy = var.network_policy + oauth_allow_non_tls_redirect_uri = var.oauth_allow_non_tls_redirect_uri + oauth_client_rsa_public_key = var.oauth_client_rsa_public_key + oauth_client_rsa_public_key_2 = var.oauth_client_rsa_public_key_2 + oauth_client_type = var.oauth_client_type + oauth_enforce_pkce = var.oauth_enforce_pkce + oauth_issue_refresh_tokens = var.oauth_issue_refresh_tokens + oauth_redirect_uri = var.oauth_redirect_uri + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_use_secondary_roles = var.oauth_use_secondary_roles + pre_authorized_roles_list = var.pre_authorized_roles_list +} + + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_oauth_integration_for_custom_clients.test] + + with_describe = false + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/variables.tf new file mode 100644 index 0000000000..9d98ea92c8 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_custom_clients/optionals_unset/variables.tf @@ -0,0 +1,46 @@ + +variable "blocked_roles_list" { + type = set(string) +} +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "network_policy" { + type = string +} +variable "oauth_allow_non_tls_redirect_uri" { + type = bool +} +variable "oauth_client_rsa_public_key" { + type = string +} +variable "oauth_client_rsa_public_key_2" { + type = string +} +variable "oauth_client_type" { + type = string +} +variable "oauth_enforce_pkce" { + type = bool +} +variable "oauth_issue_refresh_tokens" { + type = bool +} +variable "oauth_redirect_uri" { + type = string +} +variable "oauth_refresh_token_validity" { + type = number +} +variable "oauth_use_secondary_roles" { + type = string +} +variable "pre_authorized_roles_list" { + type = set(string) +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/test.tf new file mode 100644 index 0000000000..77382c9177 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/test.tf @@ -0,0 +1,16 @@ +resource "snowflake_oauth_integration_for_partner_applications" "test" { + name = var.name + oauth_client = var.oauth_client + blocked_roles_list = var.blocked_roles_list + enabled = var.enabled + oauth_issue_refresh_tokens = var.oauth_issue_refresh_tokens + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_use_secondary_roles = var.oauth_use_secondary_roles + comment = var.comment +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_oauth_integration_for_partner_applications.test] + + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/variables.tf new file mode 100644 index 0000000000..0c6ad5489e --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_set/variables.tf @@ -0,0 +1,24 @@ +variable "name" { + type = string +} +variable "oauth_client" { + type = string +} +variable "blocked_roles_list" { + type = set(string) +} +variable "enabled" { + type = string +} +variable "oauth_issue_refresh_tokens" { + type = string +} +variable "oauth_refresh_token_validity" { + type = string +} +variable "oauth_use_secondary_roles" { + type = string +} +variable "comment" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/test.tf new file mode 100644 index 0000000000..5d0b5c0ba6 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/test.tf @@ -0,0 +1,17 @@ +resource "snowflake_oauth_integration_for_partner_applications" "test" { + name = var.name + oauth_client = var.oauth_client + blocked_roles_list = var.blocked_roles_list + enabled = var.enabled + oauth_issue_refresh_tokens = var.oauth_issue_refresh_tokens + oauth_refresh_token_validity = var.oauth_refresh_token_validity + oauth_use_secondary_roles = var.oauth_use_secondary_roles + comment = var.comment +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_oauth_integration_for_partner_applications.test] + + with_describe = false + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/variables.tf new file mode 100644 index 0000000000..0c6ad5489e --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/oauth_for_partner_applications/optionals_unset/variables.tf @@ -0,0 +1,24 @@ +variable "name" { + type = string +} +variable "oauth_client" { + type = string +} +variable "blocked_roles_list" { + type = set(string) +} +variable "enabled" { + type = string +} +variable "oauth_issue_refresh_tokens" { + type = string +} +variable "oauth_refresh_token_validity" { + type = string +} +variable "oauth_use_secondary_roles" { + type = string +} +variable "comment" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/test.tf index dbd9db0930..d5e5f705aa 100644 --- a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/test.tf +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/test.tf @@ -1,9 +1,10 @@ resource "snowflake_scim_integration" "test" { - name = var.name - enabled = false - scim_client = "GENERIC" - run_as_role = "GENERIC_SCIM_PROVISIONER" - comment = var.comment + name = var.name + enabled = false + scim_client = "GENERIC" + run_as_role = "GENERIC_SCIM_PROVISIONER" + network_policy = var.network_policy + comment = var.comment } data "snowflake_security_integrations" "test" { diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/variables.tf index 821eeebe89..d77b1d5405 100644 --- a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/variables.tf +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_set/variables.tf @@ -5,3 +5,6 @@ variable "name" { variable "comment" { type = string } +variable "network_policy" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/test.tf index e5cc5bddb8..c30f18b62f 100644 --- a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/test.tf +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/test.tf @@ -1,9 +1,10 @@ resource "snowflake_scim_integration" "test" { - name = var.name - enabled = false - scim_client = "GENERIC" - run_as_role = "GENERIC_SCIM_PROVISIONER" - comment = var.comment + name = var.name + enabled = false + scim_client = "GENERIC" + run_as_role = "GENERIC_SCIM_PROVISIONER" + network_policy = var.network_policy + comment = var.comment } data "snowflake_security_integrations" "test" { @@ -11,4 +12,4 @@ data "snowflake_security_integrations" "test" { with_describe = false like = var.name -} \ No newline at end of file +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/variables.tf index 821eeebe89..d77b1d5405 100644 --- a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/variables.tf +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/optionals_unset/variables.tf @@ -5,3 +5,6 @@ variable "name" { variable "comment" { type = string } +variable "network_policy" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/test.tf new file mode 100644 index 0000000000..eb65721110 --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/test.tf @@ -0,0 +1,25 @@ +resource "snowflake_saml2_integration" "test" { + allowed_email_patterns = var.allowed_email_patterns + allowed_user_domains = var.allowed_user_domains + comment = var.comment + enabled = var.enabled + name = var.name + saml2_enable_sp_initiated = var.saml2_enable_sp_initiated + saml2_force_authn = var.saml2_force_authn + saml2_issuer = var.saml2_issuer + saml2_post_logout_redirect_url = var.saml2_post_logout_redirect_url + saml2_provider = var.saml2_provider + saml2_requested_nameid_format = var.saml2_requested_nameid_format + saml2_sign_request = var.saml2_sign_request + saml2_snowflake_acs_url = var.saml2_snowflake_acs_url + saml2_snowflake_issuer_url = var.saml2_snowflake_issuer_url + saml2_sp_initiated_login_page_label = var.saml2_sp_initiated_login_page_label + saml2_sso_url = var.saml2_sso_url + saml2_x509_cert = var.saml2_x509_cert +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_saml2_integration.test] + + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/variables.tf new file mode 100644 index 0000000000..a2fe9260ee --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_set/variables.tf @@ -0,0 +1,52 @@ + +variable "allowed_email_patterns" { + type = list(string) +} +variable "allowed_user_domains" { + type = list(string) +} +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "saml2_enable_sp_initiated" { + type = bool +} +variable "saml2_force_authn" { + type = bool +} +variable "saml2_issuer" { + type = string +} +variable "saml2_post_logout_redirect_url" { + type = string +} +variable "saml2_provider" { + type = string +} +variable "saml2_requested_nameid_format" { + type = string +} +variable "saml2_sign_request" { + type = bool +} +variable "saml2_snowflake_acs_url" { + type = string +} +variable "saml2_snowflake_issuer_url" { + type = string +} +variable "saml2_sp_initiated_login_page_label" { + type = string +} +variable "saml2_sso_url" { + type = string +} +variable "saml2_x509_cert" { + type = string +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/test.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/test.tf new file mode 100644 index 0000000000..a691106eee --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/test.tf @@ -0,0 +1,26 @@ +resource "snowflake_saml2_integration" "test" { + allowed_email_patterns = var.allowed_email_patterns + allowed_user_domains = var.allowed_user_domains + comment = var.comment + enabled = var.enabled + name = var.name + saml2_enable_sp_initiated = var.saml2_enable_sp_initiated + saml2_force_authn = var.saml2_force_authn + saml2_issuer = var.saml2_issuer + saml2_post_logout_redirect_url = var.saml2_post_logout_redirect_url + saml2_provider = var.saml2_provider + saml2_requested_nameid_format = var.saml2_requested_nameid_format + saml2_sign_request = var.saml2_sign_request + saml2_snowflake_acs_url = var.saml2_snowflake_acs_url + saml2_snowflake_issuer_url = var.saml2_snowflake_issuer_url + saml2_sp_initiated_login_page_label = var.saml2_sp_initiated_login_page_label + saml2_sso_url = var.saml2_sso_url + saml2_x509_cert = var.saml2_x509_cert +} + +data "snowflake_security_integrations" "test" { + depends_on = [snowflake_saml2_integration.test] + + with_describe = false + like = var.name +} diff --git a/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/variables.tf b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/variables.tf new file mode 100644 index 0000000000..a2fe9260ee --- /dev/null +++ b/pkg/datasources/testdata/TestAcc_SecurityIntegrations/saml2/optionals_unset/variables.tf @@ -0,0 +1,52 @@ + +variable "allowed_email_patterns" { + type = list(string) +} +variable "allowed_user_domains" { + type = list(string) +} +variable "comment" { + type = string +} +variable "enabled" { + type = bool +} +variable "name" { + type = string +} +variable "saml2_enable_sp_initiated" { + type = bool +} +variable "saml2_force_authn" { + type = bool +} +variable "saml2_issuer" { + type = string +} +variable "saml2_post_logout_redirect_url" { + type = string +} +variable "saml2_provider" { + type = string +} +variable "saml2_requested_nameid_format" { + type = string +} +variable "saml2_sign_request" { + type = bool +} +variable "saml2_snowflake_acs_url" { + type = string +} +variable "saml2_snowflake_issuer_url" { + type = string +} +variable "saml2_sp_initiated_login_page_label" { + type = string +} +variable "saml2_sso_url" { + type = string +} +variable "saml2_x509_cert" { + type = string +} diff --git a/pkg/helpers/helpers.go b/pkg/helpers/helpers.go index 47263e19ac..c190f4f3d9 100644 --- a/pkg/helpers/helpers.go +++ b/pkg/helpers/helpers.go @@ -137,3 +137,26 @@ func DecodeSnowflakeAccountIdentifier(identifier string) (sdk.AccountIdentifier, return sdk.AccountIdentifier{}, fmt.Errorf("unable to classify account identifier: %s, expected format: .", identifier) } } + +// TODO(SNOW-1479870): Test +// MergeMaps takes any number of maps (of the same type) and concatenates them. +// In case of key collision, the value will be selected from the map that is provided +// later in the src function parameter. +func MergeMaps[M ~map[K]V, K comparable, V any](src ...M) M { + merged := make(M) + for _, m := range src { + for k, v := range m { + merged[k] = v + } + } + return merged +} + +// TODO: use slices.Concat in Go 1.22 +func ConcatSlices[T any](slices ...[]T) []T { + var tmp []T + for _, s := range slices { + tmp = append(tmp, s...) + } + return tmp +} diff --git a/pkg/provider/resources/resources.go b/pkg/provider/resources/resources.go index 07825cdad0..aac1e43d65 100644 --- a/pkg/provider/resources/resources.go +++ b/pkg/provider/resources/resources.go @@ -3,51 +3,54 @@ package resources type resource string const ( - Account resource = "snowflake_account" - Alert resource = "snowflake_alert" - ApiIntegration resource = "snowflake_api_integration" - CortexSearchService resource = "snowflake_cortex_search_service" - DatabaseOld resource = "snowflake_database_old" - Database resource = "snowflake_database" - DatabaseRole resource = "snowflake_database_role" - DynamicTable resource = "snowflake_dynamic_table" - EmailNotificationIntegration resource = "snowflake_email_notification_integration" - ExternalFunction resource = "snowflake_external_function" - ExternalTable resource = "snowflake_external_table" - ExternalOauthSecurityIntegration resource = "snowflake_external_oauth_security_integration" - FailoverGroup resource = "snowflake_failover_group" - FileFormat resource = "snowflake_file_format" - Function resource = "snowflake_function" - ManagedAccount resource = "snowflake_managed_account" - MaskingPolicy resource = "snowflake_masking_policy" - MaterializedView resource = "snowflake_materialized_view" - NetworkPolicy resource = "snowflake_network_policy" - NetworkRule resource = "snowflake_network_rule" - NotificationIntegration resource = "snowflake_notification_integration" - OauthIntegrationForCustomClients resource = "snowflake_oauth_integration_for_custom_clients" - OauthIntegrationForPartnerApplications resource = "snowflake_oauth_integration_for_partner_applications" - PasswordPolicy resource = "snowflake_password_policy" - Pipe resource = "snowflake_pipe" - Procedure resource = "snowflake_procedure" - ResourceMonitor resource = "snowflake_resource_monitor" - Role resource = "snowflake_role" - RowAccessPolicy resource = "snowflake_row_access_policy" - Saml2SecurityIntegration resource = "snowflake_saml2_integration" - Schema resource = "snowflake_schema" - ScimSecurityIntegration resource = "snowflake_scim_integration" - SecondaryDatabase resource = "snowflake_secondary_database" - Sequence resource = "snowflake_sequence" - Share resource = "snowflake_share" - SharedDatabase resource = "snowflake_shared_database" - Stage resource = "snowflake_stage" - StorageIntegration resource = "snowflake_storage_integration" - Stream resource = "snowflake_stream" - Table resource = "snowflake_table" - Tag resource = "snowflake_tag" - Task resource = "snowflake_task" - User resource = "snowflake_user" - View resource = "snowflake_view" - Warehouse resource = "snowflake_warehouse" + Account resource = "snowflake_account" + Alert resource = "snowflake_alert" + ApiAuthenticationIntegrationWithAuthorizationCodeGrant resource = "snowflake_api_authentication_integration_with_authorization_code_grant" + ApiAuthenticationIntegrationWithClientCredentials resource = "snowflake_api_authentication_integration_with_client_credentials" + ApiAuthenticationIntegrationWithJwtBearer resource = "snowflake_api_authentication_integration_with_jwt_bearer" + ApiIntegration resource = "snowflake_api_integration" + CortexSearchService resource = "snowflake_cortex_search_service" + DatabaseOld resource = "snowflake_database_old" + Database resource = "snowflake_database" + DatabaseRole resource = "snowflake_database_role" + DynamicTable resource = "snowflake_dynamic_table" + EmailNotificationIntegration resource = "snowflake_email_notification_integration" + ExternalFunction resource = "snowflake_external_function" + ExternalTable resource = "snowflake_external_table" + ExternalOauthSecurityIntegration resource = "snowflake_external_oauth_security_integration" + FailoverGroup resource = "snowflake_failover_group" + FileFormat resource = "snowflake_file_format" + Function resource = "snowflake_function" + ManagedAccount resource = "snowflake_managed_account" + MaskingPolicy resource = "snowflake_masking_policy" + MaterializedView resource = "snowflake_materialized_view" + NetworkPolicy resource = "snowflake_network_policy" + NetworkRule resource = "snowflake_network_rule" + NotificationIntegration resource = "snowflake_notification_integration" + OauthIntegrationForCustomClients resource = "snowflake_oauth_integration_for_custom_clients" + OauthIntegrationForPartnerApplications resource = "snowflake_oauth_integration_for_partner_applications" + PasswordPolicy resource = "snowflake_password_policy" + Pipe resource = "snowflake_pipe" + Procedure resource = "snowflake_procedure" + ResourceMonitor resource = "snowflake_resource_monitor" + Role resource = "snowflake_role" + RowAccessPolicy resource = "snowflake_row_access_policy" + Saml2SecurityIntegration resource = "snowflake_saml2_integration" + Schema resource = "snowflake_schema" + ScimSecurityIntegration resource = "snowflake_scim_integration" + SecondaryDatabase resource = "snowflake_secondary_database" + Sequence resource = "snowflake_sequence" + Share resource = "snowflake_share" + SharedDatabase resource = "snowflake_shared_database" + Stage resource = "snowflake_stage" + StorageIntegration resource = "snowflake_storage_integration" + Stream resource = "snowflake_stream" + Table resource = "snowflake_table" + Tag resource = "snowflake_tag" + Task resource = "snowflake_task" + User resource = "snowflake_user" + View resource = "snowflake_view" + Warehouse resource = "snowflake_warehouse" ) type Resource interface { diff --git a/pkg/resources/api_authentication_integration_with_authorization_code_grant.go b/pkg/resources/api_authentication_integration_with_authorization_code_grant.go index 8bad64fd68..9f320e33c5 100644 --- a/pkg/resources/api_authentication_integration_with_authorization_code_grant.go +++ b/pkg/resources/api_authentication_integration_with_authorization_code_grant.go @@ -31,7 +31,7 @@ var apiAuthAuthorizationCodeGrantSchema = func() map[string]*schema.Schema { Description: "Specifies a list of scopes to use when making a request from the OAuth by a role with USAGE on the integration during the OAuth client credentials flow.", }, } - return MergeMaps(apiAuthCommonSchema, apiAuthAuthorizationCodeGrant) + return helpers.MergeMaps(apiAuthCommonSchema, apiAuthAuthorizationCodeGrant) }() func ApiAuthenticationIntegrationWithAuthorizationCodeGrant() *schema.Resource { diff --git a/pkg/resources/api_authentication_integration_with_authorization_code_grant_acceptance_test.go b/pkg/resources/api_authentication_integration_with_authorization_code_grant_acceptance_test.go index ee2caa26a1..046f5d0cc6 100644 --- a/pkg/resources/api_authentication_integration_with_authorization_code_grant_acceptance_test.go +++ b/pkg/resources/api_authentication_integration_with_authorization_code_grant_acceptance_test.go @@ -6,6 +6,7 @@ import ( acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/importchecks" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-testing/config" @@ -39,6 +40,7 @@ func TestAcc_ApiAuthenticationIntegrationWithAuthorizationCodeGrant_basic(t *tes TerraformVersionChecks: []tfversion.TerraformVersionCheck{ tfversion.RequireAbove(tfversion.Version1_5_0), }, + CheckDestroy: acc.CheckDestroy(t, resources.ApiAuthenticationIntegrationWithAuthorizationCodeGrant), Steps: []resource.TestStep{ { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ApiAuthenticationIntegrationWithAuthorizationCodeGrant/basic"), @@ -194,6 +196,7 @@ func TestAcc_ApiAuthenticationIntegrationWithAuthorizationCodeGrant_complete(t * TerraformVersionChecks: []tfversion.TerraformVersionCheck{ tfversion.RequireAbove(tfversion.Version1_5_0), }, + CheckDestroy: acc.CheckDestroy(t, resources.ApiAuthenticationIntegrationWithAuthorizationCodeGrant), Steps: []resource.TestStep{ { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ApiAuthenticationIntegrationWithAuthorizationCodeGrant/complete"), diff --git a/pkg/resources/api_authentication_integration_with_client_credentials.go b/pkg/resources/api_authentication_integration_with_client_credentials.go index 862c2ed21f..40e3736f7f 100644 --- a/pkg/resources/api_authentication_integration_with_client_credentials.go +++ b/pkg/resources/api_authentication_integration_with_client_credentials.go @@ -26,7 +26,7 @@ var apiAuthClientCredentialsSchema = func() map[string]*schema.Schema { Description: "Specifies a list of scopes to use when making a request from the OAuth by a role with USAGE on the integration during the OAuth client credentials flow.", }, } - return MergeMaps(apiAuthCommonSchema, apiAuthClientCredentials) + return helpers.MergeMaps(apiAuthCommonSchema, apiAuthClientCredentials) }() func ApiAuthenticationIntegrationWithClientCredentials() *schema.Resource { diff --git a/pkg/resources/api_authentication_integration_with_client_credentials_acceptance_test.go b/pkg/resources/api_authentication_integration_with_client_credentials_acceptance_test.go index 1609e678ab..3b259d8026 100644 --- a/pkg/resources/api_authentication_integration_with_client_credentials_acceptance_test.go +++ b/pkg/resources/api_authentication_integration_with_client_credentials_acceptance_test.go @@ -6,6 +6,7 @@ import ( acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/importchecks" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/provider/resources" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" "github.com/hashicorp/terraform-plugin-testing/config" @@ -38,6 +39,7 @@ func TestAcc_ApiAuthenticationIntegrationWithClientCredentials_basic(t *testing. TerraformVersionChecks: []tfversion.TerraformVersionCheck{ tfversion.RequireAbove(tfversion.Version1_5_0), }, + CheckDestroy: acc.CheckDestroy(t, resources.ApiAuthenticationIntegrationWithClientCredentials), Steps: []resource.TestStep{ { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ApiAuthenticationIntegrationWithClientCredentials/basic"), @@ -188,6 +190,7 @@ func TestAcc_ApiAuthenticationIntegrationWithClientCredentials_complete(t *testi TerraformVersionChecks: []tfversion.TerraformVersionCheck{ tfversion.RequireAbove(tfversion.Version1_5_0), }, + CheckDestroy: acc.CheckDestroy(t, resources.ApiAuthenticationIntegrationWithClientCredentials), Steps: []resource.TestStep{ { ConfigDirectory: acc.ConfigurationDirectory("TestAcc_ApiAuthenticationIntegrationWithClientCredentials/complete"), diff --git a/pkg/resources/api_authentication_integration_with_jwt_bearer.go b/pkg/resources/api_authentication_integration_with_jwt_bearer.go index e93d40ced9..73252185d5 100644 --- a/pkg/resources/api_authentication_integration_with_jwt_bearer.go +++ b/pkg/resources/api_authentication_integration_with_jwt_bearer.go @@ -29,7 +29,7 @@ var apiAuthJwtBearerSchema = func() map[string]*schema.Schema { Required: true, }, } - return MergeMaps(apiAuthCommonSchema, apiAuthJwtBearer) + return helpers.MergeMaps(apiAuthCommonSchema, apiAuthJwtBearer) }() func ApiAuthenticationIntegrationWithJwtBearer() *schema.Resource { diff --git a/pkg/resources/database.go b/pkg/resources/database.go index bc73e4ec5b..d6c1085cf1 100644 --- a/pkg/resources/database.go +++ b/pkg/resources/database.go @@ -84,7 +84,7 @@ func Database() *schema.Resource { DeleteContext: DeleteDatabase, Description: "Represents a standard database. If replication configuration is specified, the database is promoted to serve as a primary database for replication.", - Schema: MergeMaps(databaseSchema, DatabaseParametersSchema), + Schema: helpers.MergeMaps(databaseSchema, DatabaseParametersSchema), Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, diff --git a/pkg/resources/helpers.go b/pkg/resources/helpers.go index e661f7b761..7b91689d48 100644 --- a/pkg/resources/helpers.go +++ b/pkg/resources/helpers.go @@ -295,20 +295,6 @@ func getTags(from interface{}) (to tags) { return to } -// TODO(SNOW-1479870): Test -// MergeMaps takes any number of maps (of the same type) and concatenates them. -// In case of key collision, the value will be selected from the map that is provided -// later in the src function parameter. -func MergeMaps[M ~map[K]V, K comparable, V any](src ...M) M { - merged := make(M) - for _, m := range src { - for k, v := range m { - merged[k] = v - } - } - return merged -} - // TODO(SNOW-1479870): Test // JoinDiags iterates through passed diag.Diagnostics and joins them into one diag.Diagnostics. // If none of the passed diagnostics contained any element a nil reference will be returned. diff --git a/pkg/resources/secondary_database.go b/pkg/resources/secondary_database.go index a1110251cb..a135663732 100644 --- a/pkg/resources/secondary_database.go +++ b/pkg/resources/secondary_database.go @@ -46,7 +46,7 @@ func SecondaryDatabase() *schema.Resource { Description: "A secondary database creates a replica of an existing primary database (i.e. a secondary database). For more information about database replication, see [Introduction to database replication across multiple accounts](https://docs.snowflake.com/en/user-guide/db-replication-intro).", CustomizeDiff: DatabaseParametersCustomDiff, - Schema: MergeMaps(secondaryDatabaseSchema, DatabaseParametersSchema), + Schema: helpers.MergeMaps(secondaryDatabaseSchema, DatabaseParametersSchema), Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, diff --git a/pkg/resources/shared_database.go b/pkg/resources/shared_database.go index 6bbf799d2f..a9c26400b6 100644 --- a/pkg/resources/shared_database.go +++ b/pkg/resources/shared_database.go @@ -46,7 +46,7 @@ func SharedDatabase() *schema.Resource { DeleteContext: DeleteSharedDatabase, Description: "A shared database creates a database from a share provided by another Snowflake account. For more information about shares, see [Introduction to Secure Data Sharing](https://docs.snowflake.com/en/user-guide/data-sharing-intro).", - Schema: MergeMaps(sharedDatabaseSchema, SharedDatabaseParametersSchema), + Schema: helpers.MergeMaps(sharedDatabaseSchema, SharedDatabaseParametersSchema), Importer: &schema.ResourceImporter{ StateContext: schema.ImportStatePassthroughContext, }, diff --git a/pkg/schemas/api_authentication_security_integration.go b/pkg/schemas/api_authentication_security_integration.go index 913c99574e..1fb2de6bca 100644 --- a/pkg/schemas/api_authentication_security_integration.go +++ b/pkg/schemas/api_authentication_security_integration.go @@ -2,6 +2,7 @@ package schemas import ( "log" + "slices" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -24,28 +25,30 @@ var DescribeApiAuthSecurityIntegrationSchema = map[string]*schema.Schema{ "comment": DescribePropertyListSchema, } +var ApiAuthenticationPropertiesNames = []string{ + "ENABLED", + "OAUTH_ACCESS_TOKEN_VALIDITY", + "OAUTH_REFRESH_TOKEN_VALIDITY", + "OAUTH_CLIENT_ID", + "OAUTH_CLIENT_AUTH_METHOD", + "OAUTH_AUTHORIZATION_ENDPOINT", + "OAUTH_TOKEN_ENDPOINT", + "OAUTH_ALLOWED_SCOPES", + "OAUTH_GRANT", + "PARENT_INTEGRATION", + "AUTH_TYPE", + "COMMENT", +} var _ = DescribeApiAuthSecurityIntegrationSchema func ApiAuthSecurityIntegrationPropertiesToSchema(securityIntegrationProperties []sdk.SecurityIntegrationProperty) map[string]any { securityIntegrationSchema := make(map[string]any) for _, securityIntegrationProperty := range securityIntegrationProperties { securityIntegrationProperty := securityIntegrationProperty - switch securityIntegrationProperty.Name { - case "ENABLED", - "OAUTH_ACCESS_TOKEN_VALIDITY", - "OAUTH_REFRESH_TOKEN_VALIDITY", - "OAUTH_CLIENT_ID", - "OAUTH_CLIENT_AUTH_METHOD", - "OAUTH_AUTHORIZATION_ENDPOINT", - "OAUTH_TOKEN_ENDPOINT", - "OAUTH_ALLOWED_SCOPES", - "OAUTH_GRANT", - "PARENT_INTEGRATION", - "AUTH_TYPE", - "COMMENT": + if slices.Contains(ApiAuthenticationPropertiesNames, securityIntegrationProperty.Name) { securityIntegrationSchema[strings.ToLower(securityIntegrationProperty.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&securityIntegrationProperty)} - default: - log.Printf("unknown field from DESCRIBE: %v", securityIntegrationProperty.Name) + } else { + log.Printf("[WARN] unexpected property %v in api auth security integration returned from Snowflake", securityIntegrationProperty.Name) } } return securityIntegrationSchema diff --git a/pkg/schemas/external_oauth_security_integration.go b/pkg/schemas/external_oauth_security_integration.go index 544d057690..4150f64b73 100644 --- a/pkg/schemas/external_oauth_security_integration.go +++ b/pkg/schemas/external_oauth_security_integration.go @@ -1,6 +1,7 @@ package schemas import ( + "log" "slices" "strings" @@ -25,27 +26,30 @@ var DescribeExternalOauthSecurityIntegrationSchema = map[string]*schema.Schema{ "comment": DescribePropertyListSchema, } -var _ = DescribeExternalOauthSecurityIntegrationSchema +var ExternalOauthPropertiesNames = []string{ + "ENABLED", + "EXTERNAL_OAUTH_ISSUER", + "EXTERNAL_OAUTH_JWS_KEYS_URL", + "EXTERNAL_OAUTH_ANY_ROLE_MODE", + "EXTERNAL_OAUTH_RSA_PUBLIC_KEY", + "EXTERNAL_OAUTH_RSA_PUBLIC_KEY_2", + "EXTERNAL_OAUTH_BLOCKED_ROLES_LIST", + "EXTERNAL_OAUTH_ALLOWED_ROLES_LIST", + "EXTERNAL_OAUTH_AUDIENCE_LIST", + "EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM", + "EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE", + "EXTERNAL_OAUTH_SCOPE_DELIMITER", + "COMMENT", +} func ExternalOauthSecurityIntegrationPropertiesToSchema(securityIntegrationProperties []sdk.SecurityIntegrationProperty) map[string]any { securityIntegrationSchema := make(map[string]any) for _, securityIntegrationProperty := range securityIntegrationProperties { securityIntegrationProperty := securityIntegrationProperty - switch securityIntegrationProperty.Name { - case "ENABLED", - "EXTERNAL_OAUTH_ISSUER", - "EXTERNAL_OAUTH_JWS_KEYS_URL", - "EXTERNAL_OAUTH_ANY_ROLE_MODE", - "EXTERNAL_OAUTH_RSA_PUBLIC_KEY", - "EXTERNAL_OAUTH_RSA_PUBLIC_KEY_2", - "EXTERNAL_OAUTH_BLOCKED_ROLES_LIST", - "EXTERNAL_OAUTH_ALLOWED_ROLES_LIST", - "EXTERNAL_OAUTH_AUDIENCE_LIST", - "EXTERNAL_OAUTH_TOKEN_USER_MAPPING_CLAIM", - "EXTERNAL_OAUTH_SNOWFLAKE_USER_MAPPING_ATTRIBUTE", - "EXTERNAL_OAUTH_SCOPE_DELIMITER", - "COMMENT": + if slices.Contains(ExternalOauthPropertiesNames, securityIntegrationProperty.Name) { securityIntegrationSchema[strings.ToLower(securityIntegrationProperty.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&securityIntegrationProperty)} + } else { + log.Printf("[WARN] unexpected property %v in external oauth security integration returned from Snowflake", securityIntegrationProperty.Name) } } return securityIntegrationSchema diff --git a/pkg/schemas/oauth_integration_for_custom_clients.go b/pkg/schemas/oauth_integration_for_custom_clients.go index 06f35e4106..c517f9b03b 100644 --- a/pkg/schemas/oauth_integration_for_custom_clients.go +++ b/pkg/schemas/oauth_integration_for_custom_clients.go @@ -2,6 +2,7 @@ package schemas import ( "log" + "slices" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -30,33 +31,36 @@ var DescribeOauthIntegrationForCustomClients = map[string]*schema.Schema{ "oauth_allowed_token_endpoints": DescribePropertyListSchema, } +var OauthIntegrationForCustomClientsPropertiesNames = []string{ + "OAUTH_CLIENT_TYPE", + "OAUTH_REDIRECT_URI", + "ENABLED", + "OAUTH_ALLOW_NON_TLS_REDIRECT_URI", + "OAUTH_ENFORCE_PKCE", + "OAUTH_USE_SECONDARY_ROLES", + "PRE_AUTHORIZED_ROLES_LIST", + "BLOCKED_ROLES_LIST", + "OAUTH_ISSUE_REFRESH_TOKENS", + "OAUTH_REFRESH_TOKEN_VALIDITY", + "NETWORK_POLICY", + "OAUTH_CLIENT_RSA_PUBLIC_KEY_FP", + "OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP", + "COMMENT", + "OAUTH_CLIENT_ID", + "OAUTH_AUTHORIZATION_ENDPOINT", + "OAUTH_TOKEN_ENDPOINT", + "OAUTH_ALLOWED_AUTHORIZATION_ENDPOINTS", + "OAUTH_ALLOWED_TOKEN_ENDPOINTS", +} + func DescribeOauthIntegrationForCustomClientsToSchema(integrationProperties []sdk.SecurityIntegrationProperty) map[string]any { propsSchema := make(map[string]any) for _, property := range integrationProperties { property := property - switch property.Name { - case "OAUTH_CLIENT_TYPE", - "OAUTH_REDIRECT_URI", - "ENABLED", - "OAUTH_ALLOW_NON_TLS_REDIRECT_URI", - "OAUTH_ENFORCE_PKCE", - "OAUTH_USE_SECONDARY_ROLES", - "PRE_AUTHORIZED_ROLES_LIST", - "BLOCKED_ROLES_LIST", - "OAUTH_ISSUE_REFRESH_TOKENS", - "OAUTH_REFRESH_TOKEN_VALIDITY", - "NETWORK_POLICY", - "OAUTH_CLIENT_RSA_PUBLIC_KEY_FP", - "OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP", - "COMMENT", - "OAUTH_CLIENT_ID", - "OAUTH_AUTHORIZATION_ENDPOINT", - "OAUTH_TOKEN_ENDPOINT", - "OAUTH_ALLOWED_AUTHORIZATION_ENDPOINTS", - "OAUTH_ALLOWED_TOKEN_ENDPOINTS": + if slices.Contains(OauthIntegrationForCustomClientsPropertiesNames, property.Name) { propsSchema[strings.ToLower(property.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&property)} - default: - log.Printf("[WARN] unexpected property %v returned from Snowflake", property.Name) + } else { + log.Printf("[WARN] unexpected property %v in oauth security integration for custom clients returned from Snowflake", property.Name) } } return propsSchema diff --git a/pkg/schemas/oauth_security_integration_for_partner_applications.go b/pkg/schemas/oauth_security_integration_for_partner_applications.go index b17811f3cd..61bb3d2efc 100644 --- a/pkg/schemas/oauth_security_integration_for_partner_applications.go +++ b/pkg/schemas/oauth_security_integration_for_partner_applications.go @@ -2,6 +2,7 @@ package schemas import ( "log" + "slices" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -30,33 +31,36 @@ var DescribeOauthIntegrationForPartnerApplications = map[string]*schema.Schema{ "oauth_allowed_token_endpoints": DescribePropertyListSchema, } +var OauthIntegrationForPartnerApplicationsPropertiesNames = []string{ + "OAUTH_CLIENT_TYPE", + "OAUTH_REDIRECT_URI", + "ENABLED", + "OAUTH_ALLOW_NON_TLS_REDIRECT_URI", + "OAUTH_ENFORCE_PKCE", + "OAUTH_USE_SECONDARY_ROLES", + "PRE_AUTHORIZED_ROLES_LIST", + "BLOCKED_ROLES_LIST", + "OAUTH_ISSUE_REFRESH_TOKENS", + "OAUTH_REFRESH_TOKEN_VALIDITY", + "NETWORK_POLICY", + "OAUTH_CLIENT_RSA_PUBLIC_KEY_FP", + "OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP", + "COMMENT", + "OAUTH_CLIENT_ID", + "OAUTH_AUTHORIZATION_ENDPOINT", + "OAUTH_TOKEN_ENDPOINT", + "OAUTH_ALLOWED_AUTHORIZATION_ENDPOINTS", + "OAUTH_ALLOWED_TOKEN_ENDPOINTS", +} + func DescribeOauthIntegrationForPartnerApplicationsToSchema(integrationProperties []sdk.SecurityIntegrationProperty) map[string]any { securityIntegrationProperties := make(map[string]any) for _, property := range integrationProperties { property := property - switch property.Name { - case "OAUTH_CLIENT_TYPE", - "OAUTH_REDIRECT_URI", - "ENABLED", - "OAUTH_ALLOW_NON_TLS_REDIRECT_URI", - "OAUTH_ENFORCE_PKCE", - "OAUTH_USE_SECONDARY_ROLES", - "PRE_AUTHORIZED_ROLES_LIST", - "BLOCKED_ROLES_LIST", - "OAUTH_ISSUE_REFRESH_TOKENS", - "OAUTH_REFRESH_TOKEN_VALIDITY", - "NETWORK_POLICY", - "OAUTH_CLIENT_RSA_PUBLIC_KEY_FP", - "OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP", - "COMMENT", - "OAUTH_CLIENT_ID", - "OAUTH_AUTHORIZATION_ENDPOINT", - "OAUTH_TOKEN_ENDPOINT", - "OAUTH_ALLOWED_AUTHORIZATION_ENDPOINTS", - "OAUTH_ALLOWED_TOKEN_ENDPOINTS": + if slices.Contains(OauthIntegrationForPartnerApplicationsPropertiesNames, property.Name) { securityIntegrationProperties[strings.ToLower(property.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&property)} - default: - log.Printf("[WARN] unexpected property %v returned from Snowflake", property.Name) + } else { + log.Printf("[WARN] unexpected property %v in oauth security integration for partner applications returned from Snowflake", property.Name) } } return securityIntegrationProperties diff --git a/pkg/schemas/saml2_security_integration.go b/pkg/schemas/saml2_security_integration.go index 6c1ed3ef8d..b5e180e8f4 100644 --- a/pkg/schemas/saml2_security_integration.go +++ b/pkg/schemas/saml2_security_integration.go @@ -2,6 +2,7 @@ package schemas import ( "log" + "slices" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -30,34 +31,36 @@ var DescribeSaml2IntegrationSchema = map[string]*schema.Schema{ "comment": DescribePropertyListSchema, } +var Saml2PropertiesNames = []string{ + "COMMENT", + "SAML2_ISSUER", + "SAML2_SSO_URL", + "SAML2_PROVIDER", + "SAML2_X509_CERT", + "SAML2_SP_INITIATED_LOGIN_PAGE_LABEL", + "SAML2_SNOWFLAKE_X509_CERT", + "SAML2_REQUESTED_NAMEID_FORMAT", + "SAML2_POST_LOGOUT_REDIRECT_URL", + "SAML2_SNOWFLAKE_ISSUER_URL", + "SAML2_SNOWFLAKE_ACS_URL", + "SAML2_SNOWFLAKE_METADATA", + "SAML2_DIGEST_METHODS_USED", + "SAML2_SIGNATURE_METHODS_USED", + "SAML2_ENABLE_SP_INITIATED", + "SAML2_SIGN_REQUEST", + "SAML2_FORCE_AUTHN", + "ALLOWED_USER_DOMAINS", + "ALLOWED_EMAIL_PATTERNS", +} + func DescribeSaml2IntegrationToSchema(props []sdk.SecurityIntegrationProperty) map[string]any { propsSchema := make(map[string]any) for _, property := range props { property := property - switch property.Name { - case "ENABLED", - "COMMENT", - "SAML2_ISSUER", - "SAML2_SSO_URL", - "SAML2_PROVIDER", - "SAML2_X509_CERT", - "SAML2_SP_INITIATED_LOGIN_PAGE_LABEL", - "SAML2_SNOWFLAKE_X509_CERT", - "SAML2_REQUESTED_NAMEID_FORMAT", - "SAML2_POST_LOGOUT_REDIRECT_URL", - "SAML2_SNOWFLAKE_ISSUER_URL", - "SAML2_SNOWFLAKE_ACS_URL", - "SAML2_SNOWFLAKE_METADATA", - "SAML2_DIGEST_METHODS_USED", - "SAML2_SIGNATURE_METHODS_USED", - "SAML2_ENABLE_SP_INITIATED", - "SAML2_SIGN_REQUEST", - "SAML2_FORCE_AUTHN", - "ALLOWED_USER_DOMAINS", - "ALLOWED_EMAIL_PATTERNS": + if slices.Contains(Saml2PropertiesNames, property.Name) { propsSchema[strings.ToLower(property.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&property)} - default: - log.Printf("[WARN] unexpected property %v returned from Snowflake", property.Name) + } else { + log.Printf("[WARN] unexpected property %v in saml2 security integration returned from Snowflake", property.Name) } } return propsSchema diff --git a/pkg/schemas/scim_security_integration.go b/pkg/schemas/scim_security_integration.go index f21083bd4e..0fa5fa35f3 100644 --- a/pkg/schemas/scim_security_integration.go +++ b/pkg/schemas/scim_security_integration.go @@ -1,6 +1,8 @@ package schemas import ( + "log" + "slices" "strings" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" @@ -16,19 +18,25 @@ var DescribeScimSecurityIntegrationSchema = map[string]*schema.Schema{ "comment": DescribePropertyListSchema, } -var _ = DescribeScimSecurityIntegrationSchema +var ( + _ = DescribeScimSecurityIntegrationSchema + ScimPropertiesNames = []string{ + "ENABLED", + "NETWORK_POLICY", + "RUN_AS_ROLE", + "SYNC_PASSWORD", + "COMMENT", + } +) func ScimSecurityIntegrationPropertiesToSchema(securityIntegrationProperties []sdk.SecurityIntegrationProperty) map[string]any { securityIntegrationSchema := make(map[string]any) - for _, securityIntegrationProperty := range securityIntegrationProperties { - securityIntegrationProperty := securityIntegrationProperty - switch securityIntegrationProperty.Name { - case "ENABLED", - "NETWORK_POLICY", - "RUN_AS_ROLE", - "SYNC_PASSWORD", - "COMMENT": - securityIntegrationSchema[strings.ToLower(securityIntegrationProperty.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&securityIntegrationProperty)} + for _, property := range securityIntegrationProperties { + property := property + if slices.Contains(ScimPropertiesNames, property.Name) { + securityIntegrationSchema[strings.ToLower(property.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&property)} + } else { + log.Printf("[WARN] unexpected property %v in scim security integration returned from Snowflake", property.Name) } } return securityIntegrationSchema diff --git a/pkg/schemas/security_integration.go b/pkg/schemas/security_integration.go index d0278f5cd2..051b49ea5d 100644 --- a/pkg/schemas/security_integration.go +++ b/pkg/schemas/security_integration.go @@ -2,62 +2,40 @@ package schemas import ( "log" + "slices" "strings" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers" "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -// TODO [SNOW-1348100]: multiple PRs touching the security integrations are in progress, this should be filled by all the possible properties (the mapping method below should be too) -var SecurityIntegrationDescribeSchema = map[string]*schema.Schema{ - "oauth_client_type": DescribePropertyListSchema, - "oauth_redirect_uri": DescribePropertyListSchema, - "enabled": DescribePropertyListSchema, - "oauth_allow_non_tls_redirect_uri": DescribePropertyListSchema, - "oauth_enforce_pkce": DescribePropertyListSchema, - "oauth_use_secondary_roles": DescribePropertyListSchema, - "pre_authorized_roles_list": DescribePropertyListSchema, - "blocked_roles_list": DescribePropertyListSchema, - "oauth_issue_refresh_tokens": DescribePropertyListSchema, - "oauth_refresh_token_validity": DescribePropertyListSchema, - "network_policy": DescribePropertyListSchema, - "oauth_client_rsa_public_key_fp": DescribePropertyListSchema, - "oauth_client_rsa_public_key_2_fp": DescribePropertyListSchema, - "comment": DescribePropertyListSchema, - "oauth_client_id": DescribePropertyListSchema, - "oauth_authorization_endpoint": DescribePropertyListSchema, - "oauth_token_endpoint": DescribePropertyListSchema, - "oauth_allowed_authorization_endpoints": DescribePropertyListSchema, - "oauth_allowed_token_endpoints": DescribePropertyListSchema, -} +var ( + SecurityIntegrationDescribeSchema = helpers.MergeMaps( + DescribeApiAuthSecurityIntegrationSchema, + DescribeExternalOauthSecurityIntegrationSchema, + DescribeOauthIntegrationForCustomClients, + DescribeOauthIntegrationForPartnerApplications, + DescribeSaml2IntegrationSchema, + DescribeScimSecurityIntegrationSchema, + ) + allSecurityIntegrationPropertiesNames = helpers.ConcatSlices( + ApiAuthenticationPropertiesNames, + ExternalOauthPropertiesNames, + OauthIntegrationForCustomClientsPropertiesNames, + OauthIntegrationForPartnerApplicationsPropertiesNames, + Saml2PropertiesNames, + ScimPropertiesNames, + ) +) func SecurityIntegrationsDescriptionsToSchema(integrationProperties []sdk.SecurityIntegrationProperty) map[string]any { securityIntegrationProperties := make(map[string]any) - for _, property := range integrationProperties { - property := property - switch property.Name { - case "OAUTH_CLIENT_TYPE", - "OAUTH_REDIRECT_URI", - "ENABLED", - "OAUTH_ALLOW_NON_TLS_REDIRECT_URI", - "OAUTH_ENFORCE_PKCE", - "OAUTH_USE_SECONDARY_ROLES", - "PRE_AUTHORIZED_ROLES_LIST", - "BLOCKED_ROLES_LIST", - "OAUTH_ISSUE_REFRESH_TOKENS", - "OAUTH_REFRESH_TOKEN_VALIDITY", - "NETWORK_POLICY", - "OAUTH_CLIENT_RSA_PUBLIC_KEY_FP", - "OAUTH_CLIENT_RSA_PUBLIC_KEY_2_FP", - "COMMENT", - "OAUTH_CLIENT_ID", - "OAUTH_AUTHORIZATION_ENDPOINT", - "OAUTH_TOKEN_ENDPOINT", - "OAUTH_ALLOWED_AUTHORIZATION_ENDPOINTS", - "OAUTH_ALLOWED_TOKEN_ENDPOINTS": - securityIntegrationProperties[strings.ToLower(property.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&property)} - default: - log.Printf("[WARN] unexpected property %v returned from Snowflake", property.Name) + for _, desc := range integrationProperties { + desc := desc + if slices.Contains(allSecurityIntegrationPropertiesNames, desc.Name) { + securityIntegrationProperties[strings.ToLower(desc.Name)] = []map[string]any{SecurityIntegrationPropertyToSchema(&desc)} + } else { + log.Printf("[WARN] unexpected property %v in security integration returned from Snowflake", desc.Name) } } return securityIntegrationProperties