Skip to content

Commit

Permalink
Add a datasource for retrieving the client email from OpenID Connect
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
rileykarson authored and modular-magician committed Feb 21, 2019
1 parent 9b8f726 commit cdcdf21
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 0 deletions.
36 changes: 36 additions & 0 deletions google/data_source_google_client_openid_userinfo.go
Original file line number Diff line number Diff line change
@@ -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
}
46 changes: 46 additions & 0 deletions google/data_source_google_client_openid_userinfo_test.go
Original file line number Diff line number Diff line change
@@ -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"
}
`
1 change: 1 addition & 0 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
100 changes: 100 additions & 0 deletions website/docs/d/datasource_google_client_openid_userinfo.html.markdown
Original file line number Diff line number Diff line change
@@ -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.
3 changes: 3 additions & 0 deletions website/google.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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-client-openid-userinfo") %>>
<a href="/docs/providers/google/d/datasource_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>
Expand Down

0 comments on commit cdcdf21

Please sign in to comment.