Skip to content

Commit e3f9ae6

Browse files
Adding support for extended attributes in workforce pool provider (#15077)
1 parent a534009 commit e3f9ae6

7 files changed

+672
-2
lines changed

mmv1/products/iamworkforcepool/WorkforcePoolProvider.yaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,26 @@ examples:
114114
ignore_read_extra:
115115
- 'oidc.0.client_secret.0.value.0.plain_text'
116116
- 'extra_attributes_oauth2_client.0.client_secret.0.value.0.plain_text'
117+
- name: 'iam_workforce_pool_provider_extended_attributes_oauth2_config_client_basic'
118+
primary_resource_id: 'example'
119+
vars:
120+
workforce_pool_id: 'example-pool'
121+
provider_id: 'example-prvdr'
122+
test_env_vars:
123+
org_id: 'ORG_ID'
124+
ignore_read_extra:
125+
- 'oidc.0.client_secret.0.value.0.plain_text'
126+
- 'extended_attributes_oauth2_client.0.client_secret.0.value.0.plain_text'
127+
- name: 'iam_workforce_pool_provider_extended_attributes_oauth2_config_client_full'
128+
primary_resource_id: 'example'
129+
vars:
130+
workforce_pool_id: 'example-pool'
131+
provider_id: 'example-prvdr'
132+
test_env_vars:
133+
org_id: 'ORG_ID'
134+
ignore_read_extra:
135+
- 'oidc.0.client_secret.0.value.0.plain_text'
136+
- 'extended_attributes_oauth2_client.0.client_secret.0.value.0.plain_text'
117137
parameters:
118138
properties:
119139
- name: 'location'
@@ -461,3 +481,78 @@ properties:
461481
The filter used to request specific records from IdP. In case of attributes type as AZURE_AD_GROUPS_MAIL and AZURE_AD_GROUPS_ID, it represents the
462482
filter used to request specific groups for users from IdP. By default, all of the groups associated with the user are fetched. The
463483
groups should be security enabled. See https://learn.microsoft.com/en-us/graph/search-query-parameter for more details.
484+
- name: 'extendedAttributesOauth2Client'
485+
type: NestedObject
486+
description: |
487+
The configuration for OAuth 2.0 client used to get the extended group
488+
memberships for user identities. Only the `AZURE_AD_GROUPS_ID` attribute
489+
type is supported. Extended groups supports a subset of Google Cloud
490+
services. When the user accesses these services, extended group memberships
491+
override the mapped `google.groups` attribute. Extended group memberships
492+
cannot be used in attribute mapping or attribute condition expressions.
493+
494+
To keep extended group memberships up to date, extended groups are
495+
retrieved when the user signs in and at regular intervals during the user's
496+
active session. Each user identity in the workforce identity pool must map
497+
to a unique Microsoft Entra ID user.
498+
properties:
499+
- name: 'issuerUri'
500+
type: String
501+
description: |
502+
The OIDC identity provider's issuer URI. Must be a valid URI using the `https` scheme. Required to get the OIDC discovery document.
503+
required: true
504+
- name: 'clientId'
505+
type: String
506+
description: |
507+
The OAuth 2.0 client ID for retrieving extended attributes from the identity provider. Required to get the Access Token using client credentials grant flow.
508+
required: true
509+
- name: 'clientSecret'
510+
type: NestedObject
511+
description: |
512+
The OAuth 2.0 client secret for retrieving extended attributes from the identity provider. Required to get the Access Token using client credentials grant flow.
513+
required: true
514+
properties:
515+
- name: 'value'
516+
type: NestedObject
517+
description: |
518+
The value of the client secret.
519+
custom_flatten: 'templates/terraform/custom_flatten/iam_workforce_pool_provider_extended_attributes_oauth2_config_client_secret_value.go.tmpl'
520+
properties:
521+
- name: 'plainText'
522+
type: String
523+
description: |
524+
The plain text of the client secret value.
525+
required: true
526+
validation:
527+
function: 'validation.StringIsNotEmpty'
528+
- name: 'thumbprint'
529+
type: String
530+
description: |
531+
A thumbprint to represent the current client secret value.
532+
output: true
533+
- name: 'attributesType'
534+
type: Enum
535+
description: |
536+
Represents the IdP and type of claims that should be fetched.
537+
* AZURE_AD_GROUPS_ID: Used to get the user's group claims from the Azure AD identity provider
538+
using configuration provided in ExtendedAttributesOAuth2Client and `id`
539+
property of the `microsoft.graph.group` object is used for claim mapping. See
540+
https://learn.microsoft.com/en-us/graph/api/resources/group?view=graph-rest-1.0#properties
541+
for more details on `microsoft.graph.group` properties. The
542+
group IDs obtained from Azure AD are present in `assertion.groups` for
543+
OIDC providers and `assertion.attributes.groups` for SAML providers for
544+
attribute mapping.
545+
required: true
546+
enum_values:
547+
- 'AZURE_AD_GROUPS_ID'
548+
- name: 'queryParameters'
549+
type: NestedObject
550+
description: |
551+
Represents the parameters to control which claims are fetched from an IdP.
552+
properties:
553+
- name: 'filter'
554+
type: String
555+
description: |
556+
The filter used to request specific records from IdP. In case of attributes type as AZURE_AD_GROUPS_ID, it represents the
557+
filter used to request specific groups for users from IdP. By default, all of the groups associated with the user are fetched. The
558+
groups should be security enabled. See https://learn.microsoft.com/en-us/graph/search-query-parameter for more details.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{{/*
2+
The license inside this block applies to this file
3+
Copyright 2024 Google Inc.
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/ -}}
13+
func flatten{{$.GetPrefix}}{{$.TitlelizeProperty}}(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
14+
if v == nil {
15+
return nil
16+
}
17+
original := v.(map[string]interface{})
18+
if len(original) == 0 {
19+
return nil
20+
}
21+
transformed := make(map[string]interface{})
22+
transformed["thumbprint"] = original["thumbprint"]
23+
// Trigger a diff based on the plain_text if there is no change in the thumbprint,
24+
// otherwise leave plain_text empty to always trigger a diff.
25+
if original["thumbprint"].(string) == d.Get("extended_attributes_oauth2_client.0.client_secret.0.value.0.thumbprint").(string) {
26+
transformed["plain_text"] = d.Get("extended_attributes_oauth2_client.0.client_secret.0.value.0.plain_text")
27+
}
28+
return []interface{}{transformed}
29+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
resource "google_iam_workforce_pool" "pool" {
2+
workforce_pool_id = "{{index $.Vars "workforce_pool_id"}}"
3+
parent = "organizations/{{index $.TestEnvVars "org_id"}}"
4+
location = "global"
5+
}
6+
7+
resource "google_iam_workforce_pool_provider" "{{$.PrimaryResourceId}}" {
8+
workforce_pool_id = google_iam_workforce_pool.pool.workforce_pool_id
9+
location = google_iam_workforce_pool.pool.location
10+
provider_id = "{{index $.Vars "provider_id"}}"
11+
attribute_mapping = {
12+
"google.subject" = "assertion.sub"
13+
}
14+
oidc {
15+
issuer_uri = "https://login.microsoftonline.com/826602fe-2101-470c-9d71-ee1343668989/v2.0"
16+
client_id = "https://analysis.windows.net/powerbi/connector/GoogleBigQuery"
17+
web_sso_config {
18+
response_type = "CODE"
19+
assertion_claims_behavior = "MERGE_USER_INFO_OVER_ID_TOKEN_CLAIMS"
20+
}
21+
client_secret {
22+
value {
23+
plain_text = "client-secret"
24+
}
25+
}
26+
}
27+
extended_attributes_oauth2_client {
28+
issuer_uri = "https://login.microsoftonline.com/826602fe-2101-470c-9d71-ee1343668989/v2.0"
29+
client_id = "client-id"
30+
client_secret {
31+
value {
32+
plain_text = "client-secret"
33+
}
34+
}
35+
attributes_type = "AZURE_AD_GROUPS_ID"
36+
}
37+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
resource "google_iam_workforce_pool" "pool" {
2+
workforce_pool_id = "{{index $.Vars "workforce_pool_id"}}"
3+
parent = "organizations/{{index $.TestEnvVars "org_id"}}"
4+
location = "global"
5+
}
6+
7+
resource "google_iam_workforce_pool_provider" "{{$.PrimaryResourceId}}" {
8+
workforce_pool_id = google_iam_workforce_pool.pool.workforce_pool_id
9+
location = google_iam_workforce_pool.pool.location
10+
provider_id = "{{index $.Vars "provider_id"}}"
11+
attribute_mapping = {
12+
"google.subject" = "assertion.sub"
13+
}
14+
oidc {
15+
issuer_uri = "https://login.microsoftonline.com/826602fe-2101-470c-9d71-ee1343668989/v2.0"
16+
client_id = "https://analysis.windows.net/powerbi/connector/GoogleBigQuery"
17+
client_secret {
18+
value {
19+
plain_text = "client-secret"
20+
}
21+
}
22+
web_sso_config {
23+
response_type = "CODE"
24+
assertion_claims_behavior = "MERGE_USER_INFO_OVER_ID_TOKEN_CLAIMS"
25+
}
26+
}
27+
extended_attributes_oauth2_client {
28+
issuer_uri = "https://login.microsoftonline.com/826602fe-2101-470c-9d71-ee1343668989/v2.0"
29+
client_id = "client-id"
30+
client_secret {
31+
value {
32+
plain_text = "client-secret"
33+
}
34+
}
35+
attributes_type = "AZURE_AD_GROUPS_ID"
36+
query_parameters {
37+
filter = "mail:gcp"
38+
}
39+
}
40+
}

mmv1/templates/terraform/post_create/iam_workforce_pool_provider.go.tmpl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
createdOidcClientSecret := d.Get("oidc.0.client_secret.0.value.0.plain_text")
22
createdExtraAttributesClientSecret := d.Get("extra_attributes_oauth2_client.0.client_secret.0.value.0.plain_text")
3+
createdExtendedAttributesClientSecret := d.Get("extended_attributes_oauth2_client.0.client_secret.0.value.0.plain_text")
34

4-
if (createdOidcClientSecret != nil && createdOidcClientSecret != "") || (createdExtraAttributesClientSecret != nil && createdExtraAttributesClientSecret != "") {
5+
if (createdOidcClientSecret != nil && createdOidcClientSecret != "") || (createdExtraAttributesClientSecret != nil && createdExtraAttributesClientSecret != "") || (createdExtendedAttributesClientSecret != nil && createdExtendedAttributesClientSecret != "") {
56
// After the create, reading from the API returns a new thumbprint
67
// for the client secret value, which clears the plain_text. We set the plain_text since
78
// this case should not warrant a diff.
@@ -20,6 +21,17 @@ if (createdOidcClientSecret != nil && createdOidcClientSecret != "") || (created
2021
}
2122
}
2223

24+
// Populate ExtendedAttributesOauth2Client the client secret plain text
25+
if createdExtendedAttributesClientSecret != nil && createdExtendedAttributesClientSecret != "" {
26+
extendedAttributesOauth2Client := d.Get("extended_attributes_oauth2_client")
27+
clientSecret := extendedAttributesOauth2Client.([]interface{})[0].(map[string]interface{})["client_secret"]
28+
clientSecretValue := clientSecret.([]interface{})[0].(map[string]interface{})["value"]
29+
clientSecretValue.([]interface{})[0].(map[string]interface{})["plain_text"] = createdExtendedAttributesClientSecret
30+
if err := d.Set("extended_attributes_oauth2_client", extendedAttributesOauth2Client); err != nil {
31+
return err
32+
}
33+
}
34+
2335
// Populate OIDC the client secret plain text
2436
if createdOidcClientSecret != nil && createdOidcClientSecret != "" {
2537
oidc := d.Get("oidc")

mmv1/templates/terraform/post_update/iam_workforce_pool_provider.go.tmpl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
if d.HasChange("oidc") || d.HasChange("extra_attributes_oauth2_client") {
1+
if d.HasChange("oidc") || d.HasChange("extra_attributes_oauth2_client") || d.HasChange("extended_attributes_oauth2_client") {
22
updatedOidcClientSecret := d.Get("oidc.0.client_secret.0.value.0.plain_text")
33
updatedExtraAttributesOauth2ClientSecret := d.Get("extra_attributes_oauth2_client.0.client_secret.0.value.0.plain_text")
4+
updatedExtendedAttributesOauth2ClientSecret := d.Get("extended_attributes_oauth2_client.0.client_secret.0.value.0.plain_text")
45
// After the update, reading from the API returns a different thumbprint
56
// for the client secret value, which clears the plain_text. We set the plain_text since
67
// this case should not warrant a diff.
@@ -27,5 +28,15 @@ if d.HasChange("oidc") || d.HasChange("extra_attributes_oauth2_client") {
2728
return err
2829
}
2930
}
31+
32+
if updatedExtendedAttributesOauth2ClientSecret != nil && updatedExtendedAttributesOauth2ClientSecret != "" {
33+
extendedAttributesOauth2Client := d.Get("extended_attributes_oauth2_client")
34+
clientSecret := extendedAttributesOauth2Client.([]interface{})[0].(map[string]interface{})["client_secret"]
35+
clientSecretValue := clientSecret.([]interface{})[0].(map[string]interface{})["value"]
36+
clientSecretValue.([]interface{})[0].(map[string]interface{})["plain_text"] = updatedExtendedAttributesOauth2ClientSecret
37+
if err := d.Set("extended_attributes_oauth2_client", extendedAttributesOauth2Client); err != nil {
38+
return err
39+
}
40+
}
3041
return nil
3142
}

0 commit comments

Comments
 (0)