Skip to content

Commit

Permalink
Create new resource iamoauthclientcredential
Browse files Browse the repository at this point in the history
  • Loading branch information
plus-1s committed Mar 1, 2025
1 parent fed2c98 commit 5d2ce17
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 0 deletions.
108 changes: 108 additions & 0 deletions mmv1/products/iamworkforcepool/OauthClientCredential.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
name: OauthClientCredential
description: |
Represents an OAuth Client Credential. Used to authenticate an OAuth Client
while accessing Google Cloud resources on behalf of a Workforce Identity Federation user
by using OAuth 2.0 Protocol.
references:
guides:
"Managing OAuth clients": "https://cloud.google.com/iam/docs/workforce-manage-oauth-app#manage-clients"
api: "https://cloud.google.com/iam/docs/reference/rest/v1/projects.locations.oauthClients.credentials"
base_url: projects/{{project}}/locations/{{location}}/oauthClients/{{oauthclient}}/credentials
update_mask: true
self_link: projects/{{project}}/locations/{{location}}/oauthClients/{{oauthclient}}/credentials/{{oauth_client_credential_id}}
create_url: projects/{{project}}/locations/{{location}}/oauthClients/{{oauthclient}}/credentials?oauthClientCredentialId={{oauth_client_credential_id}}
update_verb: PATCH
id_format: projects/{{project}}/locations/{{location}}/oauthClients/{{oauthclient}}/credentials/{{oauth_client_credential_id}}
import_format:
- projects/{{project}}/locations/{{location}}/oauthClients/{{oauthclient}}/credentials/{{oauth_client_credential_id}}
timeouts:
insert_minutes: 20
update_minutes: 20
delete_minutes: 20
custom_code:
constants: "templates/terraform/constants/iam_oauth_client_credential.go.tmpl"
decoder: "templates/terraform/decoders/treat_deleted_state_as_gone.go.tmpl"
test_check_destroy: "templates/terraform/custom_check_destroy/iam_oauth_client_credential.go.tmpl"
post_create: "templates/terraform/post_create/sleep.go.tmpl"
post_update: "templates/terraform/post_create/sleep.go.tmpl"
post_delete: "templates/terraform/post_create/sleep.go.tmpl"
exclude_sweeper: true
examples:
- name: "iam_oauth_client_credential_basic"
primary_resource_id: "example"
vars:
oauth_client_id: "example-client-id"
oauth_client_credential_id: "cred-id"
- name: "iam_oauth_client_credential_full"
primary_resource_id: "example"
vars:
oauth_client_id: "example-client-id"
oauth_client_credential_id: "cred-id"
parameters:
- name: location
type: String
description: Resource ID segment making up resource `name`. It identifies the resource within its parent collection as described in https://google.aip.dev/122.
immutable: true
url_param_only: true
required: true
- name: oauthclient
type: String
description: Resource ID segment making up resource `name`. It identifies the resource within its parent collection as described in https://google.aip.dev/122.
immutable: true
url_param_only: true
required: true
- name: oauthClientCredentialId
type: String
description: |-
Required. The ID to use for the OauthClientCredential, which becomes the
final component of the resource name. This value should be 4-32 characters,
and may contain the characters [a-z0-9-]. The prefix `gcp-` is
reserved for use by Google, and may not be specified.
immutable: true
url_param_only: true
required: true
properties:
- name: disabled
type: Boolean
description: |-
Optional. Whether the OauthClientCredential is disabled. You cannot use a
disabled OauthClientCredential.
- name: clientSecret
type: String
description: |-
Output only. The system-generated OAuth client secret.
The client secret must be stored securely. If the client secret is
leaked, you must delete and re-create the client credential. To learn
more, see [OAuth client and credential security risks and
mitigations](https://cloud.google.com/iam/docs/workforce-oauth-app#security)
output: true
- name: displayName
type: String
description: |-
Optional. A user-specified display name of the OauthClientCredential.
Cannot exceed 32 characters.
- name: name
type: String
description: |-
Immutable. Identifier. The resource name of the OauthClientCredential.
Format:
`projects/{project}/locations/{location}/oauthClients/{oauth_client}/credentials/{credential}`
output: true
immutable: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const oauthClientCredentialIdRegexp = `^[a-z0-9-]{4,32}$`

func ValidateOauthClientCredentialId(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

if strings.HasPrefix(value, "gcp-") {
errors = append(errors, fmt.Errorf(
"%q (%q) can not start with \"gcp-\". " +
"The prefix `gcp-` is reserved for use by Google, and may not be specified.", k, value))
}

if !regexp.MustCompile(oauthClientCredentialIdRegexp).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q (%q) must be 4-32 characters, and may contain the characters [a-z0-9-].", k, value))
}

return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
config := acctest.GoogleProviderConfig(t)

url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{"{{"}}IAMWorkforcePoolBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/locations/global/oauthClients/{{"{{"}}oauth_client_id{{"}}"}}/credentials/{{"{{"}}oauth_client_credential_id{{"}}"}}")
if err != nil {
return err
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "GET",
RawURL: url,
UserAgent: config.UserAgent,
})
if err != nil {
return nil
}

if v := res["state"]; v == "DELETED" {
return nil
}

return fmt.Errorf("IAMOAuthClientCredential still exists at %s", url)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "google_iam_oauth_client" "oauth_client" {
oauth_client_id = "{{index $.Vars "oauth_client_id"}}"
location = "global"
allowed_grant_types = ["AUTHORIZATION_CODE_GRANT"]
allowed_redirect_uris = ["https://www.example.com"]
allowed_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
client_type = "CONFIDENTIAL_CLIENT"
}

resource "google_iam_oauth_client_credential" "{{$.PrimaryResourceId}}" {
oauthclient = google_iam_oauth_client.oauth_client.oauth_client_id
location = google_iam_oauth_client.oauth_client.location
oauth_client_credential_id = "{{index $.Vars "oauth_client_credential_id"}}"
disabled = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
resource "google_iam_oauth_client" "oauth_client" {
oauth_client_id = "{{index $.Vars "oauth_client_id"}}"
location = "global"
allowed_grant_types = ["AUTHORIZATION_CODE_GRANT"]
allowed_redirect_uris = ["https://www.example.com"]
allowed_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
client_type = "CONFIDENTIAL_CLIENT"
}

resource "google_iam_oauth_client_credential" "{{$.PrimaryResourceId}}" {
oauthclient = google_iam_oauth_client.oauth_client.oauth_client_id
location = google_iam_oauth_client.oauth_client.location
oauth_client_credential_id = "{{index $.Vars "oauth_client_credential_id"}}"
disabled = true
display_name = "Display Name of credential"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package iamworkforcepool_test

import (
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"

"github.com/hashicorp/terraform-provider-google/google/acctest"
)

func TestAccIAMWorkforcePoolOauthClientCredential_basic(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckIAMWorkforcePoolOauthClientCredentialDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccIAMWorkforcePoolOauthClientCredential_basic(context),
},
{
ResourceName: "google_iam_oauth_client_credential.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "oauth_client_credential_id", "oauthclient"},
},
{
Config: testAccIAMWorkforcePoolOauthClientCredential_basic_update(context),
},
{
ResourceName: "google_iam_oauth_client_credential.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "oauth_client_credential_id", "oauthclient"},
},
},
})
}

func testAccIAMWorkforcePoolOauthClientCredential_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_iam_oauth_client" "oauth_client" {
oauth_client_id = "tf-test-example-client-id%{random_suffix}"
location = "global"
allowed_grant_types = ["AUTHORIZATION_CODE_GRANT"]
allowed_redirect_uris = ["https://www.example.com"]
allowed_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
client_type = "CONFIDENTIAL_CLIENT"
}

resource "google_iam_oauth_client_credential" "example" {
oauthclient = google_iam_oauth_client.oauth_client.oauth_client_id
location = google_iam_oauth_client.oauth_client.location
oauth_client_credential_id = "tf-test-cred-id%{random_suffix}"
disabled = true
}
`, context)
}

func testAccIAMWorkforcePoolOauthClientCredential_basic_update(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_iam_oauth_client" "oauth_client" {
oauth_client_id = "tf-test-example-client-id%{random_suffix}"
location = "global"
allowed_grant_types = ["AUTHORIZATION_CODE_GRANT"]
allowed_redirect_uris = ["https://www.example.com"]
allowed_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
client_type = "CONFIDENTIAL_CLIENT"
}

resource "google_iam_oauth_client_credential" "example" {
oauthclient = google_iam_oauth_client.oauth_client.oauth_client_id
location = google_iam_oauth_client.oauth_client.location
oauth_client_credential_id = "tf-test-cred-id%{random_suffix}"
disabled = true
}
`, context)
}


func TestAccIAMWorkforcePoolOauthClientCredential_full(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckIAMWorkforcePoolOauthClientCredentialDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccIAMWorkforcePoolOauthClientCredential_full(context),
},
{
ResourceName: "google_iam_oauth_client_credential.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "oauth_client_credential_id", "oauthclient"},
},
{
Config: testAccIAMWorkforcePoolOauthClientCredential_full_update(context),
},
{
ResourceName: "google_iam_oauth_client_credential.example",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"location", "oauth_client_credential_id", "oauthclient"},
},
},
})
}

func testAccIAMWorkforcePoolOauthClientCredential_full(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_iam_oauth_client" "oauth_client" {
oauth_client_id = "tf-test-example-client-id%{random_suffix}"
location = "global"
allowed_grant_types = ["AUTHORIZATION_CODE_GRANT"]
allowed_redirect_uris = ["https://www.example.com"]
allowed_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
client_type = "CONFIDENTIAL_CLIENT"
}

resource "google_iam_oauth_client_credential" "example" {
oauthclient = google_iam_oauth_client.oauth_client.oauth_client_id
location = google_iam_oauth_client.oauth_client.location
oauth_client_credential_id = "tf-test-cred-id%{random_suffix}"
disabled = true
display_name = "Display Name of credential"
}
`, context)
}

func testAccIAMWorkforcePoolOauthClientCredential_full_update(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_iam_oauth_client" "oauth_client" {
oauth_client_id = "tf-test-example-client-id%{random_suffix}"
location = "global"
allowed_grant_types = ["AUTHORIZATION_CODE_GRANT"]
allowed_redirect_uris = ["https://www.example.com"]
allowed_scopes = ["https://www.googleapis.com/auth/cloud-platform"]
client_type = "CONFIDENTIAL_CLIENT"
}

resource "google_iam_oauth_client_credential" "example" {
oauthclient = google_iam_oauth_client.oauth_client.oauth_client_id
location = google_iam_oauth_client.oauth_client.location
oauth_client_credential_id = "tf-test-cred-id%{random_suffix}"
disabled = true
display_name = "Updated displayName"
}
`, context)
}

0 comments on commit 5d2ce17

Please sign in to comment.