mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-07-03 08:42:39 +00:00
Add support for org policies at the organization level (#523)
* Fetch latest resource manager client * Add new resource to manage Org Policy at the organization level. * Update documentation
This commit is contained in:
parent
03b11da5bb
commit
87f3a58cb2
28
google/import_google_organization_policy_test.go
Normal file
28
google/import_google_organization_policy_test.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_import(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_list_allowAll(org),
|
||||
},
|
||||
{
|
||||
ResourceName: "google_organization_policy.listAll",
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -117,6 +117,7 @@ func Provider() terraform.ResourceProvider {
|
|||
"google_sql_database": resourceSqlDatabase(),
|
||||
"google_sql_database_instance": resourceSqlDatabaseInstance(),
|
||||
"google_sql_user": resourceSqlUser(),
|
||||
"google_organization_policy": resourceGoogleOrganizationPolicy(),
|
||||
"google_project": resourceGoogleProject(),
|
||||
"google_project_iam_policy": resourceGoogleProjectIamPolicy(),
|
||||
"google_project_iam_binding": resourceGoogleProjectIamBinding(),
|
||||
|
|
|
@ -839,13 +839,9 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
|
|||
// Set the service accounts
|
||||
serviceAccounts := make([]map[string]interface{}, 0, 1)
|
||||
for _, serviceAccount := range instance.ServiceAccounts {
|
||||
scopes := make([]interface{}, len(serviceAccount.Scopes))
|
||||
for i, scope := range serviceAccount.Scopes {
|
||||
scopes[i] = scope
|
||||
}
|
||||
serviceAccounts = append(serviceAccounts, map[string]interface{}{
|
||||
"email": serviceAccount.Email,
|
||||
"scopes": schema.NewSet(stringScopeHashcode, scopes),
|
||||
"scopes": schema.NewSet(stringScopeHashcode, convertStringArrToInterface(serviceAccount.Scopes)),
|
||||
})
|
||||
}
|
||||
d.Set("service_account", serviceAccounts)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
|
||||
|
@ -75,8 +76,9 @@ func resourceGoogleFolderCreate(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
// Requires 3 successive checks for safety. Nested IFs are used to avoid 3 error statement with the same message.
|
||||
if response, ok := waitOp.Response.(map[string]interface{}); ok {
|
||||
if val, ok := response["name"]; ok {
|
||||
var responseMap map[string]interface{}
|
||||
if err := json.Unmarshal(waitOp.Response, &responseMap); err == nil {
|
||||
if val, ok := responseMap["name"]; ok {
|
||||
if name, ok := val.(string); ok {
|
||||
d.SetId(name)
|
||||
return resourceGoogleFolderRead(d, meta)
|
||||
|
|
318
google/resource_google_organization_policy.go
Normal file
318
google/resource_google_organization_policy.go
Normal file
|
@ -0,0 +1,318 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"google.golang.org/api/cloudresourcemanager/v1"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func resourceGoogleOrganizationPolicy() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceGoogleOrganizationPolicyCreate,
|
||||
Read: resourceGoogleOrganizationPolicyRead,
|
||||
Update: resourceGoogleOrganizationPolicyUpdate,
|
||||
Delete: resourceGoogleOrganizationPolicyDelete,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: resourceGoogleOrganizationPolicyImportState,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"org_id": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"constraint": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
DiffSuppressFunc: linkDiffSuppress,
|
||||
},
|
||||
"boolean_policy": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
ConflictsWith: []string{"list_policy"},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"enforced": {
|
||||
Type: schema.TypeBool,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"list_policy": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
ConflictsWith: []string{"boolean_policy"},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"allow": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
ConflictsWith: []string{"list_policy.0.deny"},
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"all": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
ConflictsWith: []string{"list_policy.0.allow.0.values"},
|
||||
},
|
||||
"values": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"deny": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"all": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
ConflictsWith: []string{"list_policy.0.deny.0.values"},
|
||||
},
|
||||
"values": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{Type: schema.TypeString},
|
||||
Set: schema.HashString,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"suggested_value": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"etag": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"update_time": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceGoogleOrganizationPolicyCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
if err := setOrganizationPolicy(d, meta); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(fmt.Sprintf("%s:%s", d.Get("org_id"), d.Get("constraint").(string)))
|
||||
|
||||
return resourceGoogleOrganizationPolicyRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceGoogleOrganizationPolicyRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
org := "organizations/" + d.Get("org_id").(string)
|
||||
|
||||
policy, err := config.clientResourceManager.Organizations.GetOrgPolicy(org, &cloudresourcemanager.GetOrgPolicyRequest{
|
||||
Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)),
|
||||
}).Do()
|
||||
|
||||
if err != nil {
|
||||
return handleNotFoundError(err, d, fmt.Sprintf("Organization policy for %s", org))
|
||||
}
|
||||
|
||||
d.Set("constraint", policy.Constraint)
|
||||
d.Set("boolean_policy", flattenBooleanOrganizationPolicy(policy.BooleanPolicy))
|
||||
d.Set("list_policy", flattenListOrganizationPolicy(policy.ListPolicy))
|
||||
d.Set("version", policy.Version)
|
||||
d.Set("etag", policy.Etag)
|
||||
d.Set("update_time", policy.UpdateTime)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGoogleOrganizationPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
if err := setOrganizationPolicy(d, meta); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceGoogleOrganizationPolicyRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceGoogleOrganizationPolicyDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
org := "organizations/" + d.Get("org_id").(string)
|
||||
|
||||
_, err := config.clientResourceManager.Organizations.ClearOrgPolicy(org, &cloudresourcemanager.ClearOrgPolicyRequest{
|
||||
Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)),
|
||||
}).Do()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGoogleOrganizationPolicyImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||
parts := strings.Split(d.Id(), ":")
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("Invalid id format. Expecting {org_id}:{constraint}, got '%s' instead.", d.Id())
|
||||
}
|
||||
|
||||
d.Set("org_id", parts[0])
|
||||
d.Set("constraint", parts[1])
|
||||
|
||||
return []*schema.ResourceData{d}, nil
|
||||
}
|
||||
|
||||
func setOrganizationPolicy(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
org := "organizations/" + d.Get("org_id").(string)
|
||||
|
||||
listPolicy, err := expandListOrganizationPolicy(d.Get("list_policy").([]interface{}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = config.clientResourceManager.Organizations.SetOrgPolicy(org, &cloudresourcemanager.SetOrgPolicyRequest{
|
||||
Policy: &cloudresourcemanager.OrgPolicy{
|
||||
Constraint: canonicalOrgPolicyConstraint(d.Get("constraint").(string)),
|
||||
BooleanPolicy: expandBooleanOrganizationPolicy(d.Get("boolean_policy").([]interface{})),
|
||||
ListPolicy: listPolicy,
|
||||
Version: int64(d.Get("version").(int)),
|
||||
Etag: d.Get("etag").(string),
|
||||
},
|
||||
}).Do()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func flattenBooleanOrganizationPolicy(policy *cloudresourcemanager.BooleanPolicy) []map[string]interface{} {
|
||||
bPolicies := make([]map[string]interface{}, 0, 1)
|
||||
|
||||
if policy == nil {
|
||||
return bPolicies
|
||||
}
|
||||
|
||||
bPolicies = append(bPolicies, map[string]interface{}{
|
||||
"enforced": policy.Enforced,
|
||||
})
|
||||
|
||||
return bPolicies
|
||||
}
|
||||
|
||||
func expandBooleanOrganizationPolicy(configured []interface{}) *cloudresourcemanager.BooleanPolicy {
|
||||
if len(configured) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
booleanPolicy := configured[0].(map[string]interface{})
|
||||
return &cloudresourcemanager.BooleanPolicy{
|
||||
Enforced: booleanPolicy["enforced"].(bool),
|
||||
}
|
||||
}
|
||||
|
||||
func flattenListOrganizationPolicy(policy *cloudresourcemanager.ListPolicy) []map[string]interface{} {
|
||||
lPolicies := make([]map[string]interface{}, 0, 1)
|
||||
|
||||
if policy == nil {
|
||||
return lPolicies
|
||||
}
|
||||
|
||||
listPolicy := map[string]interface{}{}
|
||||
switch {
|
||||
case policy.AllValues == "ALLOW":
|
||||
listPolicy["allow"] = []interface{}{map[string]interface{}{
|
||||
"all": true,
|
||||
}}
|
||||
case policy.AllValues == "DENY":
|
||||
listPolicy["deny"] = []interface{}{map[string]interface{}{
|
||||
"all": true,
|
||||
}}
|
||||
case len(policy.AllowedValues) > 0:
|
||||
listPolicy["allow"] = []interface{}{map[string]interface{}{
|
||||
"values": schema.NewSet(schema.HashString, convertStringArrToInterface(policy.AllowedValues)),
|
||||
}}
|
||||
case len(policy.DeniedValues) > 0:
|
||||
listPolicy["deny"] = []interface{}{map[string]interface{}{
|
||||
"values": schema.NewSet(schema.HashString, convertStringArrToInterface(policy.DeniedValues)),
|
||||
}}
|
||||
}
|
||||
|
||||
lPolicies = append(lPolicies, listPolicy)
|
||||
|
||||
return lPolicies
|
||||
}
|
||||
|
||||
func expandListOrganizationPolicy(configured []interface{}) (*cloudresourcemanager.ListPolicy, error) {
|
||||
if len(configured) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
listPolicyMap := configured[0].(map[string]interface{})
|
||||
|
||||
allow := listPolicyMap["allow"].([]interface{})
|
||||
deny := listPolicyMap["deny"].([]interface{})
|
||||
|
||||
var allValues string
|
||||
var allowedValues []string
|
||||
var deniedValues []string
|
||||
if len(allow) > 0 {
|
||||
allowMap := allow[0].(map[string]interface{})
|
||||
all := allowMap["all"].(bool)
|
||||
values := allowMap["values"].(*schema.Set)
|
||||
|
||||
if all {
|
||||
allValues = "ALLOW"
|
||||
} else {
|
||||
allowedValues = convertStringArr(values.List())
|
||||
}
|
||||
}
|
||||
|
||||
if len(deny) > 0 {
|
||||
denyMap := deny[0].(map[string]interface{})
|
||||
all := denyMap["all"].(bool)
|
||||
values := denyMap["values"].(*schema.Set)
|
||||
|
||||
if all {
|
||||
allValues = "DENY"
|
||||
} else {
|
||||
deniedValues = convertStringArr(values.List())
|
||||
}
|
||||
}
|
||||
|
||||
listPolicy := configured[0].(map[string]interface{})
|
||||
return &cloudresourcemanager.ListPolicy{
|
||||
AllValues: allValues,
|
||||
AllowedValues: allowedValues,
|
||||
DeniedValues: deniedValues,
|
||||
SuggestedValue: listPolicy["suggested_value"].(string),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func canonicalOrgPolicyConstraint(constraint string) string {
|
||||
if strings.HasPrefix(constraint, "constraints/") {
|
||||
return constraint
|
||||
}
|
||||
return "constraints/" + constraint
|
||||
}
|
319
google/resource_google_organization_policy_test.go
Normal file
319
google/resource_google_organization_policy_test.go
Normal file
|
@ -0,0 +1,319 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"google.golang.org/api/cloudresourcemanager/v1"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var DENIED_ORG_POLICIES = []string{
|
||||
"maps-ios-backend.googleapis.com",
|
||||
"placesios.googleapis.com",
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_boolean_enforced(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_boolean(org, true),
|
||||
Check: testAccCheckGoogleOrganizationBooleanPolicy("bool", true),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_boolean_notEnforced(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_boolean(org, false),
|
||||
Check: testAccCheckGoogleOrganizationBooleanPolicy("bool", false),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_boolean_update(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_boolean(org, true),
|
||||
Check: testAccCheckGoogleOrganizationBooleanPolicy("bool", true),
|
||||
},
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_boolean(org, false),
|
||||
Check: testAccCheckGoogleOrganizationBooleanPolicy("bool", false),
|
||||
},
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_boolean(org, true),
|
||||
Check: testAccCheckGoogleOrganizationBooleanPolicy("bool", true),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_list_allowAll(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_list_allowAll(org),
|
||||
Check: testAccCheckGoogleOrganizationListPolicyAll("listAll", "ALLOW"),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_list_allowSome(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
project := getTestProjectFromEnv()
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_list_allowSome(org, project),
|
||||
Check: testAccCheckGoogleOrganizationListPolicyAllowedValues("listSome", []string{project}),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_list_denySome(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_list_denySome(org),
|
||||
Check: testAccCheckGoogleOrganizationListPolicyDeniedValues("listSome", DENIED_ORG_POLICIES),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccGoogleOrganizationPolicy_list_update(t *testing.T) {
|
||||
skipIfEnvNotSet(t, "GOOGLE_ORG")
|
||||
org := os.Getenv("GOOGLE_ORG")
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGoogleOrganizationPolicyDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_list_allowAll(org),
|
||||
Check: testAccCheckGoogleOrganizationListPolicyAll("listAll", "ALLOW"),
|
||||
},
|
||||
{
|
||||
Config: testAccGoogleOrganizationPolicy_list_denySome(org),
|
||||
Check: testAccCheckGoogleOrganizationListPolicyDeniedValues("listSome", DENIED_ORG_POLICIES),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckGoogleOrganizationPolicyDestroy(s *terraform.State) error {
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "google_organization_policy" {
|
||||
continue
|
||||
}
|
||||
|
||||
org := "organizations/" + rs.Primary.Attributes["org_id"]
|
||||
constraint := canonicalOrgPolicyConstraint(rs.Primary.Attributes["constraint"])
|
||||
policy, err := config.clientResourceManager.Organizations.GetOrgPolicy(org, &cloudresourcemanager.GetOrgPolicyRequest{
|
||||
Constraint: constraint,
|
||||
}).Do()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if policy.ListPolicy != nil || policy.BooleanPolicy != nil {
|
||||
return fmt.Errorf("Org policy with constraint '%s' hasn't been cleared", constraint)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccCheckGoogleOrganizationBooleanPolicy(n string, enforced bool) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
policy, err := getGoogleOrganizationPolicyTestResource(s, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if policy.BooleanPolicy.Enforced != enforced {
|
||||
return fmt.Errorf("Expected boolean policy enforcement to be '%t', got '%t'", enforced, policy.BooleanPolicy.Enforced)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckGoogleOrganizationListPolicyAll(n, policyType string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
policy, err := getGoogleOrganizationPolicyTestResource(s, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(policy.ListPolicy.AllowedValues) > 0 || len(policy.ListPolicy.DeniedValues) > 0 {
|
||||
return fmt.Errorf("The `values` field shouldn't be set")
|
||||
}
|
||||
|
||||
if policy.ListPolicy.AllValues != policyType {
|
||||
return fmt.Errorf("Expected the list policy to '%s' all values, got '%s'", policyType, policy.ListPolicy.AllValues)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckGoogleOrganizationListPolicyAllowedValues(n string, values []string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
policy, err := getGoogleOrganizationPolicyTestResource(s, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(policy.ListPolicy.AllowedValues, values) {
|
||||
return fmt.Errorf("Expected the list policy to allow '%s', instead allowed '%s'", values, policy.ListPolicy.AllowedValues)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckGoogleOrganizationListPolicyDeniedValues(n string, values []string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
policy, err := getGoogleOrganizationPolicyTestResource(s, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(policy.ListPolicy.DeniedValues, values) {
|
||||
return fmt.Errorf("Expected the list policy to deny '%s', instead denied '%s'", values, policy.ListPolicy.DeniedValues)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func getGoogleOrganizationPolicyTestResource(s *terraform.State, n string) (*cloudresourcemanager.OrgPolicy, error) {
|
||||
rn := "google_organization_policy." + n
|
||||
rs, ok := s.RootModule().Resources[rn]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Not found: %s", rn)
|
||||
}
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return nil, fmt.Errorf("No ID is set")
|
||||
}
|
||||
|
||||
config := testAccProvider.Meta().(*Config)
|
||||
|
||||
return config.clientResourceManager.Organizations.GetOrgPolicy("organizations/"+rs.Primary.Attributes["org_id"], &cloudresourcemanager.GetOrgPolicyRequest{
|
||||
Constraint: rs.Primary.Attributes["constraint"],
|
||||
}).Do()
|
||||
}
|
||||
|
||||
func testAccGoogleOrganizationPolicy_boolean(org string, enforced bool) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_organization_policy" "bool" {
|
||||
org_id = "%s"
|
||||
constraint = "constraints/compute.disableSerialPortAccess"
|
||||
|
||||
boolean_policy {
|
||||
enforced = %t
|
||||
}
|
||||
}
|
||||
`, org, enforced)
|
||||
}
|
||||
|
||||
func testAccGoogleOrganizationPolicy_list_allowAll(org string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_organization_policy" "listAll" {
|
||||
org_id = "%s"
|
||||
constraint = "constraints/serviceuser.services"
|
||||
|
||||
list_policy {
|
||||
allow {
|
||||
all = true
|
||||
}
|
||||
}
|
||||
}
|
||||
`, org)
|
||||
}
|
||||
|
||||
func testAccGoogleOrganizationPolicy_list_allowSome(org, project string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_organization_policy" "listSome" {
|
||||
org_id = "%s"
|
||||
constraint = "constraints/compute.trustedImageProjects"
|
||||
|
||||
list_policy {
|
||||
allow {
|
||||
values = [
|
||||
"%s",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
`, org, project)
|
||||
}
|
||||
|
||||
func testAccGoogleOrganizationPolicy_list_denySome(org string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "google_organization_policy" "listSome" {
|
||||
org_id = "%s"
|
||||
constraint = "serviceuser.services"
|
||||
|
||||
list_policy {
|
||||
deny {
|
||||
values = [
|
||||
"maps-ios-backend.googleapis.com",
|
||||
"placesios.googleapis.com",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
`, org)
|
||||
}
|
|
@ -325,6 +325,14 @@ func convertStringArr(ifaceArr []interface{}) []string {
|
|||
return arr
|
||||
}
|
||||
|
||||
func convertStringArrToInterface(strs []string) []interface{} {
|
||||
arr := make([]interface{}, len(strs))
|
||||
for i, str := range strs {
|
||||
arr[i] = str
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
func convertStringSet(set *schema.Set) []string {
|
||||
s := make([]string, 0, set.Len())
|
||||
for _, v := range set.List() {
|
||||
|
|
2870
vendor/google.golang.org/api/cloudresourcemanager/v1/cloudresourcemanager-api.json
generated
vendored
2870
vendor/google.golang.org/api/cloudresourcemanager/v1/cloudresourcemanager-api.json
generated
vendored
File diff suppressed because it is too large
Load Diff
5467
vendor/google.golang.org/api/cloudresourcemanager/v1/cloudresourcemanager-gen.go
generated
vendored
5467
vendor/google.golang.org/api/cloudresourcemanager/v1/cloudresourcemanager-gen.go
generated
vendored
File diff suppressed because it is too large
Load Diff
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
|
@ -864,10 +864,10 @@
|
|||
"revisionTime": "2016-11-21T18:05:46Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "SIsWfZXQERRErpy9TD1ETop72uU=",
|
||||
"checksumSHA1": "9mUF072lBQeUk8vYCGZt/+KCRTI=",
|
||||
"path": "google.golang.org/api/cloudresourcemanager/v1",
|
||||
"revision": "3cc2e591b550923a2c5f0ab5a803feda924d5823",
|
||||
"revisionTime": "2016-11-27T23:54:21Z"
|
||||
"revision": "906273f42cdebd65de3a53f30dd9e23de1b55ba9",
|
||||
"revisionTime": "2017-09-30T00:03:24Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "ySd75Dknb+UV+RCkjX6ZuikRWjQ=",
|
||||
|
|
106
website/docs/r/google_organization_policy.html.markdown
Normal file
106
website/docs/r/google_organization_policy.html.markdown
Normal file
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
layout: "google"
|
||||
page_title: "Google: google_organization_policy"
|
||||
sidebar_current: "docs-google-organization-policy"
|
||||
description: |-
|
||||
Allows management of Organization policies for a Google Organization.
|
||||
---
|
||||
|
||||
# google\_organization\_policy
|
||||
|
||||
Allows management of Organization policies for a Google Organization. For more information see
|
||||
[the official
|
||||
documentation](https://cloud.google.com/resource-manager/docs/organization-policy/overview) and
|
||||
[API](https://cloud.google.com/resource-manager/reference/rest/v1/organizations/setOrgPolicy).
|
||||
|
||||
## Example Usage
|
||||
|
||||
To set policy with a [boolean constraint](https://cloud.google.com/resource-manager/docs/organization-policy/quickstart-boolean-constraints):
|
||||
|
||||
```hcl
|
||||
resource "google_folder_organization_policy" "serial_port_policy" {
|
||||
org_id = "123456789"
|
||||
constraint = "compute.disableSerialPortAccess"
|
||||
|
||||
boolean_policy {
|
||||
enforced = true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
To set a policy with a [list contraint](https://cloud.google.com/resource-manager/docs/organization-policy/quickstart-list-constraints):
|
||||
|
||||
```hcl
|
||||
resource "google_folder_organization_policy" "services_policy" {
|
||||
org_id = "123456789"
|
||||
constraint = "serviceuser.services"
|
||||
|
||||
list_policy {
|
||||
allow {
|
||||
all = true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Or to deny some services, use the following instead:
|
||||
|
||||
```hcl
|
||||
resource "google_folder_organization_policy" "services_policy" {
|
||||
org_id = "123456789"
|
||||
constraint = "serviceuser.services"
|
||||
|
||||
list_policy {
|
||||
suggested_values = "compute.googleapis.com"
|
||||
|
||||
deny {
|
||||
values = ["cloudresourcemanager.googleapis.com"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `org_id` - (Required) The numeric ID of the organization to set the policy for.
|
||||
|
||||
* `constraint` - (Required) The name of the Constraint the Policy is configuring, for example, `serviceuser.services`. Check out the [complete list of available constraints](https://cloud.google.com/resource-manager/docs/organization-policy/understanding-constraints#available_constraints).
|
||||
|
||||
- - -
|
||||
|
||||
* `version` - (Optional) Version of the Policy. Default version is 0.
|
||||
|
||||
* `boolean_policy` - (Optional) A boolean policy is a constraint that is either enforced or not. Structure is documented below.
|
||||
|
||||
* `list_policy` - (Optional) A policy that can define specific values that are allowed or denied for the given constraint. It can also be used to allow or deny all values. Structure is documented below.
|
||||
|
||||
- - -
|
||||
|
||||
The `boolean_policy` block supports:
|
||||
|
||||
* `enforced` - (Required) If true, then the Policy is enforced. If false, then any configuration is acceptable.
|
||||
|
||||
The `list_policy` block supports:
|
||||
|
||||
* `allow` or `deny` - (Optional) One or the other must be set.
|
||||
|
||||
* `suggested_values` - (Optional) The Google Cloud Console will try to default to a configuration that matches the value specified in this field.
|
||||
|
||||
The `allow` or `deny` blocks support:
|
||||
|
||||
* `all` - (Optional) The policy allows or denies all values.
|
||||
|
||||
* `values` - (Optional) The policy can define specific values that are allowed or denied.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
In addition to the arguments listed above, the following computed attributes are
|
||||
exported:
|
||||
|
||||
* `etag` - (Computed) The etag of the organization policy. `etag` is used for optimistic concurrency control as a way to help prevent simultaneous updates of a policy from overwriting each other.
|
||||
|
||||
* `update_time` - (Computed) The timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds, representing when the variable was last updated. Example: "2016-10-09T12:33:37.578138407Z".
|
Loading…
Reference in New Issue
Block a user