Skip to content

Commit

Permalink
Review comments 2
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-jmichalak committed Jul 5, 2024
1 parent 32a0c0b commit b7f5ef2
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 80 deletions.
6 changes: 6 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ Conditional force new was added for the following attributes when they are remov
- `external_oauth_jws_keys_url`
- `external_oauth_token_user_mapping_claim`

#### *(behavior change)* Conflicting fields
Fields listed below can not be set at the same time in Snowflake. They are marked as conflicting fields.
- `external_oauth_jws_keys_url` <-> `external_oauth_rsa_public_key`
- `external_oauth_jws_keys_url` <-> `external_oauth_rsa_public_key_2`
- `external_oauth_allowed_roles_list` <-> `external_oauth_blocked_roles_list`

#### *(behavior change)* Changed diff suppress for some fields
The fields listed below had diff suppress which removed '-' from strings. Now, this behavior is removed, so if you had '-' in these strings, please remove them. Note that '-' in these values is not allowed by Snowflake.
- `external_oauth_snowflake_user_mapping_attribute`
Expand Down
34 changes: 17 additions & 17 deletions docs/resources/external_oauth_integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
page_title: "snowflake_external_oauth_integration Resource - terraform-provider-snowflake"
subcategory: ""
description: |-
Resource used to manage external oauth security integrations. For more information, check documentation https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-external.
---

# snowflake_external_oauth_integration (Resource)


Resource used to manage external oauth security integrations. For more information, check [documentation](https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-external).

## Example Usage

Expand Down Expand Up @@ -63,29 +63,29 @@ resource "snowflake_external_oauth_integration" "test" {

- `enabled` (Boolean) Specifies whether to initiate operation of the integration or suspend it.
- `external_oauth_issuer` (String) Specifies the URL to define the OAuth 2.0 authorization server.
- `external_oauth_snowflake_user_mapping_attribute` (String) Indicates which Snowflake user record attribute should be used to map the access token to a Snowflake user record. Valid options are: [LOGIN_NAME EMAIL_ADDRESS]
- `external_oauth_token_user_mapping_claim` (Set of String) Specifies the access token claim or claims that can be used to map the access token to a Snowflake user record.
- `external_oauth_type` (String) Specifies the OAuth 2.0 authorization server to be Okta, Microsoft Azure AD, Ping Identity PingFederate, or a Custom OAuth 2.0 authorization server. Valid options are: [OKTA AZURE PING_FEDERATE CUSTOM]
- `external_oauth_snowflake_user_mapping_attribute` (String) Indicates which Snowflake user record attribute should be used to map the access token to a Snowflake user record. Valid values are (case-insensitive): `LOGIN_NAME` | `EMAIL_ADDRESS`.
- `external_oauth_token_user_mapping_claim` (Set of String) Specifies the access token claim or claims that can be used to map the access token to a Snowflake user record. If removed from the config, the resource is recreated.
- `external_oauth_type` (String) Specifies the OAuth 2.0 authorization server to be Okta, Microsoft Azure AD, Ping Identity PingFederate, or a Custom OAuth 2.0 authorization server. Valid values are (case-insensitive): `OKTA` | `AZURE` | `PING_FEDERATE` | `CUSTOM`.
- `name` (String) Specifies the name of the External Oath integration. This name follows the rules for Object Identifiers. The name should be unique among security integrations in your account.

### Optional

- `comment` (String) Specifies a comment for the OAuth integration.
- `external_oauth_allowed_roles_list` (Set of String) Specifies the list of roles that the client can set as the primary role.
- `external_oauth_any_role_mode` (String) Specifies whether the OAuth client or user can use a role that is not defined in the OAuth access token. Valid options are: [DISABLE ENABLE ENABLE_FOR_PRIVILEGE]
- `external_oauth_any_role_mode` (String) Specifies whether the OAuth client or user can use a role that is not defined in the OAuth access token. Valid values are (case-insensitive): `DISABLE` | `ENABLE` | `ENABLE_FOR_PRIVILEGE`.
- `external_oauth_audience_list` (Set of String) Specifies additional values that can be used for the access token's audience validation on top of using the Customer's Snowflake Account URL
- `external_oauth_blocked_roles_list` (Set of String) Specifies the list of roles that a client cannot set as the primary role. By default, this list includes the ACCOUNTADMIN, and SECURITYADMIN roles. To remove these privileged roles from the list, use the ALTER ACCOUNT command to set the EXTERNAL_OAUTH_ADD_PRIVILEGED_ROLES_TO_BLOCKED_LIST account parameter to FALSE.
- `external_oauth_jws_keys_url` (Set of String) Specifies the endpoint or a list of endpoints from which to download public keys or certificates to validate an External OAuth access token. The maximum number of URLs that can be specified in the list is 3.
- `external_oauth_rsa_public_key` (String) Specifies a Base64-encoded RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers.
- `external_oauth_rsa_public_key_2` (String) Specifies a second RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers. Used for key rotation.
- `external_oauth_blocked_roles_list` (Set of String) Specifies the list of roles that a client cannot set as the primary role. By default, this list includes the ACCOUNTADMIN, ORGADMIN and SECURITYADMIN roles. To remove these privileged roles from the list, use the ALTER ACCOUNT command to set the EXTERNAL_OAUTH_ADD_PRIVILEGED_ROLES_TO_BLOCKED_LIST account parameter to FALSE.
- `external_oauth_jws_keys_url` (Set of String) Specifies the endpoint or a list of endpoints from which to download public keys or certificates to validate an External OAuth access token. The maximum number of URLs that can be specified in the list is 3. If removed from the config, the resource is recreated.
- `external_oauth_rsa_public_key` (String) Specifies a Base64-encoded RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers. If removed from the config, the resource is recreated.
- `external_oauth_rsa_public_key_2` (String) Specifies a second RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers. Used for key rotation. If removed from the config, the resource is recreated.
- `external_oauth_scope_delimiter` (String) Specifies the scope delimiter in the authorization token.
- `external_oauth_scope_mapping_attribute` (String) Specifies the access token claim to map the access token to an account role.
- `external_oauth_scope_mapping_attribute` (String) Specifies the access token claim to map the access token to an account role. If removed from the config, the resource is recreated.

### Read-Only

- `describe_output` (List of Object) Outputs the result of `DESCRIBE SECURITY INTEGRATIONS` for the given security integration. (see [below for nested schema](#nestedatt--describe_output))
- `id` (String) The ID of this resource.
- `parameters` (List of Object) Paramteres related to this security integration. (see [below for nested schema](#nestedatt--parameters))
- `related_parameters` (List of Object) Paramteres related to this security integration. (see [below for nested schema](#nestedatt--related_parameters))
- `show_output` (List of Object) Outputs the result of `SHOW SECURITY INTEGRATIONS` for the given security integration. (see [below for nested schema](#nestedatt--show_output))

<a id="nestedatt--describe_output"></a>
Expand Down Expand Up @@ -251,15 +251,15 @@ Read-Only:



<a id="nestedatt--parameters"></a>
### Nested Schema for `parameters`
<a id="nestedatt--related_parameters"></a>
### Nested Schema for `related_parameters`

Read-Only:

- `external_oauth_add_privileged_roles_to_blocked_list` (List of Object) (see [below for nested schema](#nestedobjatt--parameters--external_oauth_add_privileged_roles_to_blocked_list))
- `external_oauth_add_privileged_roles_to_blocked_list` (List of Object) (see [below for nested schema](#nestedobjatt--related_parameters--external_oauth_add_privileged_roles_to_blocked_list))

<a id="nestedobjatt--parameters--external_oauth_add_privileged_roles_to_blocked_list"></a>
### Nested Schema for `parameters.external_oauth_add_privileged_roles_to_blocked_list`
<a id="nestedobjatt--related_parameters--external_oauth_add_privileged_roles_to_blocked_list"></a>
### Nested Schema for `related_parameters.external_oauth_add_privileged_roles_to_blocked_list`

Read-Only:

Expand Down
16 changes: 0 additions & 16 deletions pkg/resources/custom_diffs.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,6 @@ func ComputedIfAnyAttributeChanged(key string, changedAttributeKeys ...string) s
})
}

// ForceNewIfChangeToEmptyString sets a ForceNew for a string field which was set to an empty value.
func ForceNewIfChangeToEmptyString(key string) schema.CustomizeDiffFunc {
return customdiff.ForceNewIfChange(key, func(ctx context.Context, oldValue, newValue, meta any) bool {
oldString, newString := oldValue.(string), newValue.(string)
return len(oldString) > 0 && len(newString) == 0
})
}

// ForceNewIfChangeToEmptySet sets a ForceNew for a set field which was set to an empty value.
func ForceNewIfChangeToEmptySet(key string) schema.CustomizeDiffFunc {
return customdiff.ForceNewIfChange(key, func(ctx context.Context, oldValue, newValue, meta any) bool {
oldList, newList := oldValue.(*schema.Set).List(), newValue.(*schema.Set).List()
return len(oldList) > 0 && len(newList) == 0
})
}

type parameter struct {
parameterName sdk.AccountParameter
valueType valueType
Expand Down
25 changes: 13 additions & 12 deletions pkg/resources/external_oauth_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ var oauthExternalIntegrationSchema = map[string]*schema.Schema{
"external_oauth_type": {
Type: schema.TypeString,
Required: true,
Description: fmt.Sprintf("Specifies the OAuth 2.0 authorization server to be Okta, Microsoft Azure AD, Ping Identity PingFederate, or a Custom OAuth 2.0 authorization server. Valid options are: %v", sdk.AllExternalOauthSecurityIntegrationTypes),
Description: fmt.Sprintf("Specifies the OAuth 2.0 authorization server to be Okta, Microsoft Azure AD, Ping Identity PingFederate, or a Custom OAuth 2.0 authorization server. Valid values are (case-insensitive): %s.", possibleValuesListed(sdk.AsStringList(sdk.AllExternalOauthSecurityIntegrationTypes))),
ValidateDiagFunc: sdkValidation(sdk.ToExternalOauthSecurityIntegrationTypeOption),
DiffSuppressFunc: NormalizeAndCompare(sdk.ToExternalOauthSecurityIntegrationTypeOption),
},
Expand All @@ -48,12 +48,12 @@ var oauthExternalIntegrationSchema = map[string]*schema.Schema{
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Required: true,
Description: "Specifies the access token claim or claims that can be used to map the access token to a Snowflake user record.",
Description: "Specifies the access token claim or claims that can be used to map the access token to a Snowflake user record. If removed from the config, the resource is recreated.",
},
"external_oauth_snowflake_user_mapping_attribute": {
Type: schema.TypeString,
Required: true,
Description: fmt.Sprintf("Indicates which Snowflake user record attribute should be used to map the access token to a Snowflake user record. Valid options are: %v", sdk.AllExternalOauthSecurityIntegrationSnowflakeUserMappingAttributes),
Description: fmt.Sprintf("Indicates which Snowflake user record attribute should be used to map the access token to a Snowflake user record. Valid values are (case-insensitive): %s.", possibleValuesListed(sdk.AsStringList(sdk.AllExternalOauthSecurityIntegrationSnowflakeUserMappingAttributes))),
ValidateDiagFunc: sdkValidation(sdk.ToExternalOauthSecurityIntegrationSnowflakeUserMappingAttributeOption),
DiffSuppressFunc: NormalizeAndCompare(sdk.ToExternalOauthSecurityIntegrationSnowflakeUserMappingAttributeOption),
},
Expand All @@ -63,27 +63,27 @@ var oauthExternalIntegrationSchema = map[string]*schema.Schema{
MaxItems: 3,
Optional: true,
ConflictsWith: []string{"external_oauth_rsa_public_key", "external_oauth_rsa_public_key_2"},
Description: "Specifies the endpoint or a list of endpoints from which to download public keys or certificates to validate an External OAuth access token. The maximum number of URLs that can be specified in the list is 3.",
Description: "Specifies the endpoint or a list of endpoints from which to download public keys or certificates to validate an External OAuth access token. The maximum number of URLs that can be specified in the list is 3. If removed from the config, the resource is recreated.",
},
"external_oauth_rsa_public_key": {
Type: schema.TypeString,
Optional: true,
Description: "Specifies a Base64-encoded RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers.",
Description: "Specifies a Base64-encoded RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers. If removed from the config, the resource is recreated.",
DiffSuppressFunc: ignoreTrimSpaceSuppressFunc,
ConflictsWith: []string{"external_oauth_jws_keys_url"},
},
"external_oauth_rsa_public_key_2": {
Type: schema.TypeString,
Optional: true,
Description: "Specifies a second RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers. Used for key rotation.",
Description: "Specifies a second RSA public key, without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers. Used for key rotation. If removed from the config, the resource is recreated.",
DiffSuppressFunc: ignoreTrimSpaceSuppressFunc,
ConflictsWith: []string{"external_oauth_jws_keys_url"},
},
"external_oauth_blocked_roles_list": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "Specifies the list of roles that a client cannot set as the primary role. By default, this list includes the ACCOUNTADMIN, and SECURITYADMIN roles. To remove these privileged roles from the list, use the ALTER ACCOUNT command to set the EXTERNAL_OAUTH_ADD_PRIVILEGED_ROLES_TO_BLOCKED_LIST account parameter to FALSE.",
Description: "Specifies the list of roles that a client cannot set as the primary role. By default, this list includes the ACCOUNTADMIN, ORGADMIN and SECURITYADMIN roles. To remove these privileged roles from the list, use the ALTER ACCOUNT command to set the EXTERNAL_OAUTH_ADD_PRIVILEGED_ROLES_TO_BLOCKED_LIST account parameter to FALSE.",
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
params := d.Get(ParametersAttributeName).([]any)
var found *sdk.Parameter
Expand All @@ -97,7 +97,7 @@ var oauthExternalIntegrationSchema = map[string]*schema.Schema{
return false
}

return slices.Contains([]string{"ACCOUNTADMIN", "SECURITYADMIN"}, old)
return slices.Contains([]string{"ACCOUNTADMIN", "SECURITYADMIN", "ORGADMIN"}, old)
},
ConflictsWith: []string{"external_oauth_allowed_roles_list"},
},
Expand All @@ -117,7 +117,7 @@ var oauthExternalIntegrationSchema = map[string]*schema.Schema{
"external_oauth_any_role_mode": {
Type: schema.TypeString,
Optional: true,
Description: fmt.Sprintf("Specifies whether the OAuth client or user can use a role that is not defined in the OAuth access token. Valid options are: %v", sdk.AsStringList(sdk.AllExternalOauthSecurityIntegrationAnyRoleModes)),
Description: fmt.Sprintf("Specifies whether the OAuth client or user can use a role that is not defined in the OAuth access token. Valid values are (case-insensitive): %s.", possibleValuesListed(sdk.AsStringList(sdk.AsStringList(sdk.AllExternalOauthSecurityIntegrationAnyRoleModes)))),
ValidateDiagFunc: sdkValidation(sdk.ToExternalOauthSecurityIntegrationAnyRoleModeOption),
DiffSuppressFunc: NormalizeAndCompare(sdk.ToExternalOauthSecurityIntegrationAnyRoleModeOption),
},
Expand All @@ -129,7 +129,7 @@ var oauthExternalIntegrationSchema = map[string]*schema.Schema{
"external_oauth_scope_mapping_attribute": {
Type: schema.TypeString,
Optional: true,
Description: "Specifies the access token claim to map the access token to an account role.",
Description: "Specifies the access token claim to map the access token to an account role. If removed from the config, the resource is recreated.",
},
"comment": {
Type: schema.TypeString,
Expand Down Expand Up @@ -186,6 +186,7 @@ func ExternalOauthIntegration() *schema.Resource {
Importer: &schema.ResourceImporter{
StateContext: ImportExternalOauthIntegration,
},
Description: "Resource used to manage external oauth security integrations. For more information, check [documentation](https://docs.snowflake.com/en/sql-reference/sql/create-security-integration-oauth-external).",

StateUpgraders: []schema.StateUpgrader{
{
Expand Down Expand Up @@ -268,10 +269,10 @@ func ImportExternalOauthIntegration(ctx context.Context, d *schema.ResourceData,
}

var roles []string
if err == nil && (*found).Value == "true" {
if err == nil && found.Value == "true" {
unfilteredRoles := sdk.ParseCommaSeparatedStringArray(prop.Value, false)
for _, role := range unfilteredRoles {
if !slices.Contains([]string{"ACCOUNTADMIN", "SECURITYADMIN"}, role) {
if !slices.Contains([]string{"ACCOUNTADMIN", "ORGADMIN", "SECURITYADMIN"}, role) {
roles = append(roles, role)
}
}
Expand Down
Loading

0 comments on commit b7f5ef2

Please sign in to comment.