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

Add org_policy_custom_constraint resource #6608

Merged
merged 8 commits into from
Sep 30, 2022
Merged
99 changes: 99 additions & 0 deletions mmv1/products/orgpolicy/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Copyright 2022 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Api::Product
name: OrgPolicy
display_name: Organization Policy
versions:
- !ruby/object:Api::Product::Version
name: beta
base_url: https://orgpolicy.googleapis.com/v2/
scopes:
- https://www.googleapis.com/auth/cloud-platform
apis_required:
- !ruby/object:Api::Product::ApiReference
name: Organization Policy API
url: https://console.cloud.google.com/apis/api/orgpolicy.googleapis.com/overview
objects:
- !ruby/object:Api::Resource
name: 'CustomConstraint'
create_url: '{{parent}}/customConstraints'
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
self_link: '{{parent}}/customConstraints/{{name}}'
base_url: '{{parent}}/customConstraints/{{name}}'
update_verb: :PATCH
min_version: beta
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation':
'https://cloud.google.com/resource-manager/docs/organization-policy/creating-managing-custom-constraints'
'Supported Services':
'https://cloud.google.com/resource-manager/docs/organization-policy/custom-constraint-supported-services'
api: 'https://cloud.google.com/resource-manager/docs/reference/orgpolicy/rest/v2/organizations.constraints'
rileykarson marked this conversation as resolved.
Show resolved Hide resolved
description: |
Custom constraints are created by administrators to provide more granular and customizable control over the specific fields that are restricted by your organization policies.
parameters:
- !ruby/object:Api::Type::String
name: parent
description: |
The parent of the resource.
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
input: true
url_param_only: true
required: true
properties:
- !ruby/object:Api::Type::String
name: 'name'
rileykarson marked this conversation as resolved.
Show resolved Hide resolved
required: true
input: true
description: |
Immutable. The name of the custom constraint. This is unique within the organization. Format of the name should be `organizations/{organization_id}/customConstraints/{custom_constraint_id}`.
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
- !ruby/object:Api::Type::String
name: 'displayName'
description: |
A human-friendly name for the constraint.
- !ruby/object:Api::Type::String
name: 'description'
description: |
A human-friendly description of the constraint to display as an error message when the policy is violated.
- !ruby/object:Api::Type::String
name: 'condition'
required: true
description: |
A CEL condition that refers to a supported service resource, for example `resource.management.autoUpgrade == false`. For details about CEL usage, see [Common Expression Language](https://cloud.google.com/resource-manager/docs/organization-policy/creating-managing-custom-constraints#common_expression_language).
- !ruby/object:Api::Type::Enum
name: 'actionType'
required: true
description: |
The action to take if the condition is met.
values:
- :ALLOW
- :DENY
- !ruby/object:Api::Type::Array
name: 'methodTypes'
min_size: 1
required: true
description: |
A list of RESTful methods for which to enforce the constraint. Can be `CREATE`, `UPDATE`, or both. Not all Google Cloud services support both methods. To see supported methods for each service, find the service in [Supported services](https://cloud.google.com/resource-manager/docs/organization-policy/custom-constraint-supported-services).
item_type: Api::Type::String
- !ruby/object:Api::Type::Array
name: 'resourceTypes'
input: true
min_size: 1
rileykarson marked this conversation as resolved.
Show resolved Hide resolved
required: true
description: |
Immutable. The fully qualified name of the Google Cloud REST resource containing the object and field you want to restrict. For example, `container.googleapis.com/NodePool`.
item_type: Api::Type::String
- !ruby/object:Api::Type::String
name: 'updateTime'
output: true
description: |
Output only. The timestamp representing when the constraint was last updated.
44 changes: 44 additions & 0 deletions mmv1/products/orgpolicy/terraform.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2022 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

--- !ruby/object:Provider::Terraform::Config
overrides: !ruby/object:Overrides::ResourceOverrides
CustomConstraint: !ruby/object:Overrides::Terraform::ResourceOverride
id_format: '{{parent}}/customConstraints/{{name}}'
import_format: ["{{%parent}}/customConstraints/{{name}}"]
custom_code: !ruby/object:Provider::Terraform::CustomCode
update_encoder: 'templates/terraform/update_encoder/org_policy_custom_constraint.go.erb'
examples:
- !ruby/object:Provider::Terraform::Examples
min_version: beta
name: "org_policy_custom_constraint_basic"
primary_resource_id: "constraint"
test_env_vars:
org_id: :ORG_ID
- !ruby/object:Provider::Terraform::Examples
min_version: beta
name: "org_policy_custom_constraint_full"
primary_resource_id: "constraint"
test_env_vars:
org_id: :ORG_TARGET
properties:
name: !ruby/object:Overrides::Terraform::PropertyOverride
custom_expand: 'templates/terraform/custom_expand/shortname_to_url.go.erb'
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'

# This is for copying files over
files: !ruby/object:Provider::Config::Files
# These files have templating (ERB) code that will be run.
# This is usually to add licensing info, autogeneration notices, etc.
compile:
<%= lines(indent(compile('provider/terraform/product~compile.yaml'), 4)) -%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resource "google_org_policy_custom_constraint" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta

name = "custom.disableGkeAutoUpgrade"
parent = "organizations/%{org_id}"
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
display_name = "Disable GKE auto upgrade"
description = "Only allow GKE NodePool resource to be created or updated if AutoUpgrade is not enabled where this custom constraint is enforced."

action_type = "ALLOW"
condition = "resource.management.autoUpgrade == false"
method_types = ["CREATE", "UPDATE"]
resource_types = ["container.googleapis.com/NodePool"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
resource "google_org_policy_custom_constraint" "<%= ctx[:primary_resource_id] %>" {
provider = google-beta

name = "custom.disableGkeAutoUpgrade"
parent = "organizations/%{org_id}"
display_name = "Disable GKE auto upgrade"
description = "Only allow GKE NodePool resource to be created or updated if AutoUpgrade is not enabled where this custom constraint is enforced."

action_type = "ALLOW"
condition = "resource.management.autoUpgrade == false"
method_types = ["CREATE", "UPDATE"]
resource_types = ["container.googleapis.com/NodePool"]
}

resource "google_org_policy_policy" "bool" {
provider = google-beta

name = "organizations/%{org_id}/policies/${google_org_policy_custom_constraint.constraint.name}"
parent = "organizations/%{org_id}"

spec {
rules {
enforce = "TRUE"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// need to send resource_types in all PATCH requests
roaks3 marked this conversation as resolved.
Show resolved Hide resolved
resourceTypesProp := d.Get("resource_types")
if v, ok := d.GetOkExists("resource_types"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, resourceTypesProp)) {
obj["resourceTypes"] = resourceTypesProp
}

return obj, nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<% autogen_exception -%>
package google
<% unless version == 'ga' -%>

import (
"testing"

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

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

context := map[string]interface{}{
"org_id": getTestOrgFromEnv(t),
"random_suffix": randString(t, 10),
}

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckOrgPolicyCustomConstraintDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccOrgPolicyCustomConstraint_v1(context),
},
{
ResourceName: "google_org_policy_custom_constraint.constraint",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"parent"},
},
{
Config: testAccOrgPolicyCustomConstraint_v2(context),
},
{
ResourceName: "google_org_policy_custom_constraint.constraint",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"parent"},
},
},
})
}

func testAccOrgPolicyCustomConstraint_v1(context map[string]interface{}) string {
return Nprintf(`
resource "google_org_policy_custom_constraint" "constraint" {
name = "custom.tfTest%{random_suffix}"
parent = "organizations/%{org_id}"
display_name = "Disable GKE auto upgrade"
description = "Only allow GKE NodePool resource to be created or updated if AutoUpgrade is not enabled where this custom constraint is enforced."

action_type = "ALLOW"
condition = "resource.management.autoUpgrade == false"
method_types = ["CREATE", "UPDATE"]
resource_types = ["container.googleapis.com/NodePool"]
}
`, context)
}

func testAccOrgPolicyCustomConstraint_v2(context map[string]interface{}) string {
return Nprintf(`
resource "google_org_policy_custom_constraint" "constraint" {
name = "custom.tfTest%{random_suffix}"
parent = "organizations/%{org_id}"
display_name = "Updated"
description = "Updated"

action_type = "DENY"
condition = "resource.management.autoUpgrade == true"
method_types = ["CREATE"]
resource_types = ["container.googleapis.com/NodePool"]
}
`, context)
}

<% end -%>
5 changes: 5 additions & 0 deletions tpgtools/overrides/orgpolicy/beta/tpgtools_product.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## product level overrides

- type: PRODUCT_BASE_PATH
details:
skip: true