Skip to content

Commit

Permalink
Additional target keys support (hashicorp#4)
Browse files Browse the repository at this point in the history
* add chrome policy test case: schema_value correctly contains multiple values of different types

* Do not iterate over and validate against all schema field definitions during validation. Instead, access only the relevant def from schemaFields map.

* make fmt

* rename test case for clarity

* fix test name in invocation

* first pass at AdditionalTargetKeys

* dry additionalTargetKey handling with new func expandChromePoliciesAdditionalTargetKeys

* test case for additional target keys

* whitespace cleanup
  • Loading branch information
w0de authored Dec 7, 2023
1 parent 2d50b07 commit decb74b
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 2 deletions.
80 changes: 78 additions & 2 deletions internal/provider/resource_chrome_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import (
func resourceChromePolicy() *schema.Resource {
return &schema.Resource{
Description: "Chrome Policy resource in the Terraform Googleworkspace provider. " +
"Currently only supports policies not requiring additionalTargetKeys. Chrome Policy Schema " +
"resides under the `https://www.googleapis.com/auth/chrome.management.policy` client scope.",
"Chrome Policy Schema resides under the `https://www.googleapis.com/auth/chrome.management.policy` client scope.",

CreateContext: resourceChromePolicyCreate,
UpdateContext: resourceChromePolicyUpdate,
Expand All @@ -35,6 +34,25 @@ func resourceChromePolicy() *schema.Resource {
ForceNew: true,
DiffSuppressFunc: diffSuppressOrgUnitId,
},
"additional_target_keys": {
Description: "Additional target keys for policies.",
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"target_key": {
Description: "The target key name.",
Type: schema.TypeString,
Required: true,
},
"target_value": {
Description: "The target key value.",
Type: schema.TypeString,
Required: true,
},
},
},
},
"policies": {
Description: "Policies to set for the org unit",
Type: schema.TypeList,
Expand Down Expand Up @@ -86,6 +104,10 @@ func resourceChromePolicyCreate(ctx context.Context, d *schema.ResourceData, met
TargetResource: "orgunits/" + orgUnitId,
}

if _, ok := d.GetOk("additional_target_keys"); ok {
policyTargetKey.AdditionalTargetKeys = expandChromePoliciesAdditionalTargetKeys(d.Get("additional_target_keys").([]interface{}))
}

diags = validateChromePolicies(ctx, d, client)
if diags.HasError() {
return diags
Expand Down Expand Up @@ -147,6 +169,10 @@ func resourceChromePolicyUpdate(ctx context.Context, d *schema.ResourceData, met
TargetResource: "orgunits/" + d.Id(),
}

if _, ok := d.GetOk("additional_target_keys"); ok {
policyTargetKey.AdditionalTargetKeys = expandChromePoliciesAdditionalTargetKeys(d.Get("additional_target_keys").([]interface{}))
}

// Update is achieved by inheriting defaults for the previous policySchemas, and then applying the new set
old, _ := d.GetChange("policies")

Expand Down Expand Up @@ -200,6 +226,10 @@ func resourceChromePolicyRead(ctx context.Context, d *schema.ResourceData, meta
TargetResource: "orgunits/" + d.Id(),
}

if _, ok := d.GetOk("additional_target_keys"); ok {
policyTargetKey.AdditionalTargetKeys = expandChromePoliciesAdditionalTargetKeys(d.Get("additional_target_keys").([]interface{}))
}

policiesObj := []*chromepolicy.GoogleChromePolicyV1PolicyValue{}
for _, p := range d.Get("policies").([]interface{}) {
policy := p.(map[string]interface{})
Expand Down Expand Up @@ -262,6 +292,10 @@ func resourceChromePolicyDelete(ctx context.Context, d *schema.ResourceData, met
TargetResource: "orgunits/" + d.Id(),
}

if _, ok := d.GetOk("additional_target_keys"); ok {
policyTargetKey.AdditionalTargetKeys = expandChromePoliciesAdditionalTargetKeys(d.Get("additional_target_keys").([]interface{}))
}

var requests []*chromepolicy.GoogleChromePolicyV1InheritOrgUnitPolicyRequest
for _, p := range d.Get("policies").([]interface{}) {
policy := p.(map[string]interface{})
Expand Down Expand Up @@ -384,6 +418,35 @@ func validateChromePolicies(ctx context.Context, d *schema.ResourceData, client
}
}
}

if _, ok := d.GetOk("additional_target_keys"); ok {
if schemaDef.AdditionalTargetKeyNames == nil {
return append(diags, diag.Diagnostic{
Summary: fmt.Sprintf("schema defintion (%s) does not support additional target key names", schemaName),
Severity: diag.Error,
})
}

additionalTargetKeyNames := map[string]string{}
for _, targetKeyName := range schemaDef.AdditionalTargetKeyNames {
additionalTargetKeyNames[targetKeyName.Key] = targetKeyName.KeyDescription
}

additionalTargetKeys := expandChromePoliciesAdditionalTargetKeys(d.Get("additional_target_keys").([]interface{}))
for additionalTargetKeyName := range additionalTargetKeys {
if _, ok := additionalTargetKeyNames[additionalTargetKeyName]; !ok {
return append(diags, diag.Diagnostic{
Summary: fmt.Sprintf("additional target key name (%s) is not found in this schema definition (%s)", additionalTargetKeyName, schemaName),
Severity: diag.Error,
})
}
}
} else if schemaDef.AdditionalTargetKeyNames != nil {
return append(diags, diag.Diagnostic{
Summary: fmt.Sprintf("additional target key names are required by this schema definition (%s)", schemaName),
Severity: diag.Error,
})
}
}

return nil
Expand Down Expand Up @@ -531,6 +594,19 @@ func expandChromePoliciesValues(policies []interface{}) ([]*chromepolicy.GoogleC
return result, diags
}

func expandChromePoliciesAdditionalTargetKeys(keys []interface{}) map[string]string {
result := map[string]string{}

for _, k := range keys {
targetKeyDef := k.(map[string]interface{})
targetKeyName := targetKeyDef["target_key"].(string)
targetKeyValue := targetKeyDef["target_value"].(string)
result[targetKeyName] = targetKeyValue
}

return result
}

func flattenChromePolicies(ctx context.Context, policiesObj []*chromepolicy.GoogleChromePolicyV1PolicyValue, client *apiClient) ([]map[string]interface{}, diag.Diagnostics) {
var policies []map[string]interface{}

Expand Down
47 changes: 47 additions & 0 deletions internal/provider/resource_chrome_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,30 @@ func TestAccResourceChromePolicy_typeMessage(t *testing.T) {
})
}

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

ouName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: providerFactories,
Steps: []resource.TestStep{
{
Config: testAccResourceChromePolicy_additionalTargetKey(ouName, "chrome:glnpjglilkicbckjpbgcfkogebgllemb", "ALLOWED"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("googleworkspace_chrome_policy.test", "policies.#", "1"),
resource.TestCheckResourceAttr("googleworkspace_chrome_policy.test", "policies.0.schema_name", "chrome.users.apps.InstallType"),
resource.TestCheckResourceAttr("googleworkspace_chrome_policy.test", "policies.0.schema_values.appInstallType", encode("ALLOWED")),
resource.TestCheckResourceAttr("googleworkspace_chrome_policy.test", "additional_target_keys.#", "1"),
resource.TestCheckResourceAttr("googleworkspace_chrome_policy.test", "additional_target_keys.0.target_key", "app_id"),
resource.TestCheckResourceAttr("googleworkspace_chrome_policy.test", "additional_target_keys.0.target_value", "chrome:glnpjglilkicbckjpbgcfkogebgllemb"),
),
},
},
})
}

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

Expand Down Expand Up @@ -320,3 +344,26 @@ resource "googleworkspace_chrome_policy" "test" {
}
`, ouName)
}

func testAccResourceChromePolicy_additionalTargetKey(ouName string, app_id string, install_type string) string {
return fmt.Sprintf(`
resource "googleworkspace_org_unit" "test" {
name = "%s"
parent_org_unit_path = "/"
}
resource "googleworkspace_chrome_policy" "test" {
org_unit_id = googleworkspace_org_unit.test.id
additional_target_keys {
target_key = "app_id"
target_value = "%s"
}
policies {
schema_name = "chrome.users.apps.InstallType"
schema_values = {
appInstallType = jsonencode("%s")
}
}
}
`, ouName, app_id, install_type)
}

0 comments on commit decb74b

Please sign in to comment.