Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IAP brand & client #5881

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changelog/3135.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```release-note:new-resource
`google_iap_brand`
```
```release-note:new-resource
`google_iap_client`
```
6 changes: 4 additions & 2 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,9 +511,9 @@ func Provider() terraform.ResourceProvider {
return provider
}

// Generated resources: 105
// Generated resources: 107
// Generated IAM resources: 51
// Total generated resources: 156
// Total generated resources: 158
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -631,6 +631,8 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_iap_tunnel_instance_iam_binding": ResourceIamBinding(IapTunnelInstanceIamSchema, IapTunnelInstanceIamUpdaterProducer, IapTunnelInstanceIdParseFunc),
"google_iap_tunnel_instance_iam_member": ResourceIamMember(IapTunnelInstanceIamSchema, IapTunnelInstanceIamUpdaterProducer, IapTunnelInstanceIdParseFunc),
"google_iap_tunnel_instance_iam_policy": ResourceIamPolicy(IapTunnelInstanceIamSchema, IapTunnelInstanceIamUpdaterProducer, IapTunnelInstanceIdParseFunc),
"google_iap_brand": resourceIapBrand(),
"google_iap_client": resourceIapClient(),
"google_identity_platform_default_supported_idp_config": resourceIdentityPlatformDefaultSupportedIdpConfig(),
"google_identity_platform_tenant_default_supported_idp_config": resourceIdentityPlatformTenantDefaultSupportedIdpConfig(),
"google_identity_platform_inbound_saml_config": resourceIdentityPlatformInboundSamlConfig(),
Expand Down
9 changes: 9 additions & 0 deletions google/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ var orgEnvVars = []string{
"GOOGLE_ORG",
}

var orgEnvDomainVars = []string{
"GOOGLE_ORG_DOMAIN",
}

var serviceAccountEnvVars = []string{
"GOOGLE_SERVICE_ACCOUNT",
}
Expand Down Expand Up @@ -647,6 +651,11 @@ func getTestOrgFromEnv(t *testing.T) string {
return multiEnvSearch(orgEnvVars)
}

func getTestOrgDomainFromEnv(t *testing.T) string {
skipIfEnvNotSet(t, orgEnvDomainVars...)
return multiEnvSearch(orgEnvDomainVars)
}

func getTestOrgTargetFromEnv(t *testing.T) string {
skipIfEnvNotSet(t, orgTargetEnvVars...)
return multiEnvSearch(orgTargetEnvVars)
Expand Down
223 changes: 223 additions & 0 deletions google/resource_iap_brand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------

package google

import (
"fmt"
"log"
"reflect"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)

func resourceIapBrand() *schema.Resource {
return &schema.Resource{
Create: resourceIapBrandCreate,
Read: resourceIapBrandRead,
Delete: resourceIapBrandDelete,

Importer: &schema.ResourceImporter{
State: resourceIapBrandImport,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(4 * time.Minute),
Delete: schema.DefaultTimeout(4 * time.Minute),
},

Schema: map[string]*schema.Schema{
"application_title": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `Application name displayed on OAuth consent screen.`,
},
"support_email": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: `Support email displayed on the OAuth consent screen. Can be either a
user or group email. When a user email is specified, the caller must
be the user with the associated email address. When a group email is
specified, the caller can be either a user or a service account which
is an owner of the specified group in Cloud Identity.`,
},
"name": {
Type: schema.TypeString,
Computed: true,
Description: `Output only. Identifier of the brand, in the format
'projects/{project_number}/brands/{brand_id}'. NOTE: The brand
identification corresponds to the project number as only one
brand per project can be created.`,
},
"org_internal_only": {
Type: schema.TypeBool,
Computed: true,
Description: `Whether the brand is only intended for usage inside the GSuite organization only.`,
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
}

func resourceIapBrandCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

obj := make(map[string]interface{})
supportEmailProp, err := expandIapBrandSupportEmail(d.Get("support_email"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("support_email"); !isEmptyValue(reflect.ValueOf(supportEmailProp)) && (ok || !reflect.DeepEqual(v, supportEmailProp)) {
obj["supportEmail"] = supportEmailProp
}
applicationTitleProp, err := expandIapBrandApplicationTitle(d.Get("application_title"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("application_title"); !isEmptyValue(reflect.ValueOf(applicationTitleProp)) && (ok || !reflect.DeepEqual(v, applicationTitleProp)) {
obj["applicationTitle"] = applicationTitleProp
}

url, err := replaceVars(d, config, "{{IapBasePath}}projects/{{project}}/brands")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new Brand: %#v", obj)
project, err := getProject(d, config)
if err != nil {
return err
}
res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating Brand: %s", err)
}

// Store the ID now
id, err := replaceVars(d, config, "{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

log.Printf("[DEBUG] Finished creating Brand %q: %#v", d.Id(), res)

// `name` is autogenerated from the api so needs to be set post-create
name, ok := res["name"]
if !ok {
return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
}
d.Set("name", name.(string))
d.SetId(name.(string))

return resourceIapBrandRead(d, meta)
}

func resourceIapBrandRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)

url, err := replaceVars(d, config, "{{IapBasePath}}{{name}}")
if err != nil {
return err
}

project, err := getProject(d, config)
if err != nil {
return err
}
res, err := sendRequest(config, "GET", project, url, nil)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("IapBrand %q", d.Id()))
}

if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading Brand: %s", err)
}

if err := d.Set("support_email", flattenIapBrandSupportEmail(res["supportEmail"], d, config)); err != nil {
return fmt.Errorf("Error reading Brand: %s", err)
}
if err := d.Set("application_title", flattenIapBrandApplicationTitle(res["applicationTitle"], d, config)); err != nil {
return fmt.Errorf("Error reading Brand: %s", err)
}
if err := d.Set("org_internal_only", flattenIapBrandOrgInternalOnly(res["orgInternalOnly"], d, config)); err != nil {
return fmt.Errorf("Error reading Brand: %s", err)
}
if err := d.Set("name", flattenIapBrandName(res["name"], d, config)); err != nil {
return fmt.Errorf("Error reading Brand: %s", err)
}

return nil
}

func resourceIapBrandDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[WARNING] Iap Brand resources"+
" cannot be deleted from GCP. The resource %s will be removed from Terraform"+
" state, but will still be present on the server.", d.Id())
d.SetId("")

return nil
}

func resourceIapBrandImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)

// current import_formats can't import fields with forward slashes in their value
if err := parseImportId([]string{"(?P<name>.+)"}, d, config); err != nil {
return nil, err
}

nameParts := strings.Split(d.Get("name").(string), "/")
if len(nameParts) != 4 {
return nil, fmt.Errorf(
"Saw %s when the name is expected to have shape %s",
d.Get("name"),
"projects/{{project}}/brands/{{name}}",
)
}

d.Set("project", nameParts[1])
return []*schema.ResourceData{d}, nil
}

func flattenIapBrandSupportEmail(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenIapBrandApplicationTitle(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenIapBrandOrgInternalOnly(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func flattenIapBrandName(v interface{}, d *schema.ResourceData, config *Config) interface{} {
return v
}

func expandIapBrandSupportEmail(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}

func expandIapBrandApplicationTitle(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
return v, nil
}
55 changes: 55 additions & 0 deletions google/resource_iap_brand_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package google

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
)

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

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

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccIapBrand_iapBrandExample(context),
},
{
ResourceName: "google_iap_brand.project_brand",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"project"},
},
},
})
}

func testAccIapBrand_iapBrandExample(context map[string]interface{}) string {
return Nprintf(`
resource "google_project" "project" {
project_id = "tf-test%{random_suffix}"
name = "tf-test%{random_suffix}"
org_id = "%{org_id}"
}

resource "google_project_service" "project_service" {
project = google_project.project.project_id
service = "iap.googleapis.com"
}

resource "google_iap_brand" "project_brand" {
support_email = "support@%{org_domain}"
application_title = "Cloud IAP protected Application"
project = google_project_service.project_service.project
}
`, context)
}
Loading