Add a datasource for retrieving the client email from OpenID Connect (#3103)

<!-- This change is generated by MagicModules. -->
/cc @rileykarson
This commit is contained in:
The Magician 2019-02-25 12:39:12 -08:00 committed by Riley Karson
parent 82f0251ce1
commit dff7b250c1
5 changed files with 186 additions and 0 deletions

View File

@ -0,0 +1,36 @@
package google
import (
"fmt"
"time"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourceGoogleClientOpenIDUserinfo() *schema.Resource {
return &schema.Resource{
Read: dataSourceGoogleClientOpenIDUserinfoRead,
Schema: map[string]*schema.Schema{
"email": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func dataSourceGoogleClientOpenIDUserinfoRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// See https://github.com/golang/oauth2/issues/306 for a recommendation to do this from a Go maintainer
// URL retrieved from https://accounts.google.com/.well-known/openid-configuration
res, err := sendRequest(config, "GET", "https://openidconnect.googleapis.com/v1/userinfo", nil)
if err != nil {
return fmt.Errorf("error retrieving userinfo for your provider credentials; have you enabled the 'https://www.googleapis.com/auth/userinfo.email' scope? error: %s", err)
}
d.SetId(time.Now().UTC().String())
d.Set("email", res["email"])
return nil
}

View File

@ -0,0 +1,46 @@
package google
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccDataSourceGoogleClientOpenIDUserinfo_basic(t *testing.T) {
t.Parallel()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckGoogleClientOpenIDUserinfo_basic,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.google_client_openid_userinfo.me", "email"),
),
},
},
})
}
const testAccCheckGoogleClientOpenIDUserinfo_basic = `
provider "google" {
alias = "google-scoped"
# We need to add an additional scope to test this; because our tests rely on
# every env var being set, we can just add an alias with the appropriate
# scopes. This will fail if someone uses an access token instead of creds
# unless they've configured the userinfo.email scope.
scopes = [
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/ndev.clouddns.readwrite",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/userinfo.email",
]
}
data "google_client_openid_userinfo" "me" {
provider = "google.google-scoped"
}
`

View File

@ -81,6 +81,7 @@ func Provider() terraform.ResourceProvider {
"google_billing_account": dataSourceGoogleBillingAccount(),
"google_dns_managed_zone": dataSourceDnsManagedZone(),
"google_client_config": dataSourceGoogleClientConfig(),
"google_client_openid_userinfo": dataSourceGoogleClientOpenIDUserinfo(),
"google_cloudfunctions_function": dataSourceGoogleCloudFunctionsFunction(),
"google_compute_address": dataSourceGoogleComputeAddress(),
"google_compute_backend_service": dataSourceGoogleComputeBackendService(),

View File

@ -0,0 +1,100 @@
---
layout: "google"
page_title: "Google: google_client_openid_userinfo"
sidebar_current: "docs-google-datasource-client-openid-userinfo"
description: |-
Get OpenID userinfo about the credentials used with the Google provider, specifically the email.
---
# google\_client\_openid\_userinfo
Get OpenID userinfo about the credentials used with the Google provider,
specifically the email.
When the `https://www.googleapis.com/auth/userinfo.email` scope is enabled in
your provider block, this datasource enables you to export the email of the
account you've authenticated the provider with; this can be used alongside
`data.google_client_config`'s `access_token` to perform OpenID Connect
authentication with GKE and configure an RBAC role for the email used.
~> This resource will only work as expected if the provider is configured to
use the `https://www.googleapis.com/auth/userinfo.email` scope! You will
receive an error otherwise.
## Example Usage - exporting an email
```hcl
provider "google" {
scopes = [
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/ndev.clouddns.readwrite",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/userinfo.email",
]
}
data "google_client_openid_userinfo" "me" {}
output "my-email" {
value = "${data.google_client_openid_useremail.me.email}"
}
```
## Example Usage - OpenID Connect w/ Kubernetes provider + RBAC IAM role
```hcl
provider "google" {
scopes = [
"https://www.googleapis.com/auth/compute",
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/ndev.clouddns.readwrite",
"https://www.googleapis.com/auth/devstorage.full_control",
"https://www.googleapis.com/auth/userinfo.email",
]
}
data "google_client_openid_userinfo" "provider_identity" {}
data "google_client_config" "provider" {}
data "google_container_cluster" "my_cluster" {
name = "my-cluster"
zone = "us-east1-a"
}
provider "kubernetes" {
load_config_file = false
host = "https://${data.google_container_cluster.my_cluster.endpoint}"
token = "${data.google_client_config.provider.access_token}"
cluster_ca_certificate = "${base64decode(data.google_container_cluster.my_cluster.master_auth.0.cluster_ca_certificate)}"
}
resource "kubernetes_cluster_role_binding" "user" {
metadata {
name = "provider-user-admin"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "cluster-admin"
}
subject {
kind = "User"
name = "${data.google_client_openid_useremail.provider_identity.email}"
}
}
```
## Argument Reference
There are no arguments available for this data source.
## Attributes Reference
The following attributes are exported:
* `email` - The email of the account used by the provider to authenticate with GCP.

View File

@ -39,6 +39,9 @@
<li<%= sidebar_current("docs-google-datasource-client-config") %>>
<a href="/docs/providers/google/d/datasource_client_config.html">google_client_config</a>
</li>
<li<%= sidebar_current("docs-google-datasource-google-client-openid-userinfo") %>>
<a href="/docs/providers/google/d/datasource_google_client_openid_userinfo.html">google_client_openid_userinfo</a>
</li>
<li<%= sidebar_current("docs-google-datasource-cloudfunctions-function") %>>
<a href="/docs/providers/google/d/datasource_cloudfunctions_function.html">google_cloudfunctions_function</a>
</li>