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

AD Domain resource added #3735

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
107 changes: 107 additions & 0 deletions products/activedirectory/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copyright 2020 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: ActiveDirectory
display_name: Managed Microsoft Active Directory
versions:
- !ruby/object:Api::Product::Version
name: ga
base_url: https://managedidentities.googleapis.com/v1/
scopes:
- https://www.googleapis.com/auth/cloud-platform
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
path: 'name'
base_url: '{{op_id}}'
wait_ms: 1000
# It takes about 35-40 mins to get the resource created
timeouts: !ruby/object:Api::Timeouts
venkykuberan marked this conversation as resolved.
Show resolved Hide resolved
insert_minutes: 60
update_minutes: 60
delete_minutes: 60
result: !ruby/object:Api::OpAsync::Result
path: 'response'
resource_inside_response: true
status: !ruby/object:Api::OpAsync::Status
path: 'done'
complete: true
allowed:
- true
- false
error: !ruby/object:Api::OpAsync::Error
path: 'error'
message: 'message'
objects:
- !ruby/object:Api::Resource
name: 'Domain'
kind: 'activedirectory#domain'
base_url : projects/{{project}}/locations/global/domains?domainName={{domain_name}}
update_verb: :PATCH
update_mask: true
self_link: '{{name}}'
description: Creates a Microsoft AD domain
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Managed Microsoft Active Directory Quickstart': 'https://cloud.google.com/managed-microsoft-ad/docs/quickstarts'
api: 'https://cloud.google.com/managed-microsoft-ad/reference/rest/v1/projects.locations.global.domains'
parameters:
- !ruby/object:Api::Type::String
name: domainName
required: true
url_param_only: true
input: true
description: |
The fully qualified domain name. e.g. mydomain.myorganization.com, with the restrictions,
https://cloud.google.com/managed-microsoft-ad/reference/rest/v1/projects.locations.global.domains.
venkykuberan marked this conversation as resolved.
Show resolved Hide resolved
properties:
- !ruby/object:Api::Type::String
name: 'name'
venkykuberan marked this conversation as resolved.
Show resolved Hide resolved
output: true
description: 'The unique name of the domain using the format: `projects/{project}/locations/global/domains/{domainName}`.'
- !ruby/object:Api::Type::KeyValuePairs
name: 'labels'
description: 'Resource labels that can contain user-provided metadata'
- !ruby/object:Api::Type::Array
name: 'authorizedNetworks'
venkykuberan marked this conversation as resolved.
Show resolved Hide resolved
item_type: Api::Type::String
description: |
The full names of the Google Compute Engine networks the domain instance is connected to. The domain is only available on networks listed in authorizedNetworks.
If CIDR subnets overlap between networks, domain creation will fail.
- !ruby/object:Api::Type::String
name: 'reservedIpRange'
required: true
input: true
description: |
The CIDR range of internal addresses that are reserved for this domain. Reserved networks must be /24 or larger.
Ranges must be unique and non-overlapping with existing subnets in authorizedNetworks
- !ruby/object:Api::Type::Array
name: 'locations'
required: true
item_type: Api::Type::String
description: |
Locations where domain needs to be provisioned. [regions][compute/docs/regions-zones/]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is some failed markdown from the cloud docs generator. Can you change it to what you think it should be?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^

e.g. us-west1 or us-east4 Service supports up to 4 locations at once. Each location will use a /26 block.
- !ruby/object:Api::Type::String
name: 'admin'
default_value: 'setupadmin'
input: true
description: |
The name of delegated administrator account used to perform Active Directory operations.
If not specified, setupadmin will be used.
- !ruby/object:Api::Type::String
name: 'fqdn'
output: true
description: |
The fully-qualified domain name of the exposed domain used by clients to connect to the service.
Similar to what would be chosen for an Active Directory set up on an internal network.
39 changes: 39 additions & 0 deletions products/activedirectory/terraform.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2020 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
Domain: !ruby/object:Overrides::Terraform::ResourceOverride
id_format: "{{name}}"
import_format: ["{{name}}"]
venkykuberan marked this conversation as resolved.
Show resolved Hide resolved
autogen_async: true
properties:
authorizedNetworks: !ruby/object:Overrides::Terraform::PropertyOverride
is_set: true
domainName: !ruby/object:Overrides::Terraform::PropertyOverride
required: true
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateADDomainName()'
custom_code: !ruby/object:Provider::Terraform::CustomCode
custom_import: templates/terraform/custom_import/self_link_as_name.erb
examples:
- !ruby/object:Provider::Terraform::Examples
name: "active_directory_domain_basic"
primary_resource_id: "ad-domain"
vars:
name: "myorg"
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,5 @@
resource "google_active_directory_domain" "ad-domain" {
domain_name = "mydomain.org.com"
locations = ["us-central1"]
reserved_ip_range = "192.168.255.0/24"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package google

import (
"testing"

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

func TestAccActiveDirectoryDomain_update(t *testing.T) {
venkykuberan marked this conversation as resolved.
Show resolved Hide resolved
t.Parallel()

context := map[string]interface{}{
"domain": "mydomain.org1.com",
"resource_name": "ad-domain",
}

resourceName := Nprintf("google_active_directory_domain.%{resource_name}", context)

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckActiveDirectoryDomainDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccADDomainBasic(context),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"domain_name"},
},
{
Config: testAccADDomainUpdate(context),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"domain_name"},
},
{
Config: testAccADDomainBasic(context),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"domain_name"},
},
},
})
}

func testAccADDomainBasic(context map[string]interface{}) string {

return Nprintf(`
resource "google_active_directory_domain" "%{resource_name}" {
domain_name = "%{domain}"
locations = ["us-central1"]
reserved_ip_range = "192.168.255.0/24"
}
`, context)
}

func testAccADDomainUpdate(context map[string]interface{}) string {
return Nprintf(`
resource "google_active_directory_domain" "%{resource_name}" {
domain_name = "%{domain}"
locations = ["us-central1", "us-west1"]
reserved_ip_range = "192.168.255.0/24"
labels = {
env = "test"
}
}
`, context)

}
15 changes: 15 additions & 0 deletions third_party/terraform/utils/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const (

// https://cloud.google.com/iam/docs/understanding-custom-roles#naming_the_role
IAMCustomRoleIDRegex = "^[a-zA-Z0-9_\\.]{3,64}$"

// https://cloud.google.com/managed-microsoft-ad/reference/rest/v1/projects.locations.global.domains/create#query-parameters
ADDomainNameRegex = "^[a-z][a-z0-9-]{0,14}\\.[a-z0-9-\\.]*[a-z]+[a-z0-9]*$"
)

var (
Expand Down Expand Up @@ -311,3 +314,15 @@ func validateRFC3339Date(v interface{}, k string) (warnings []string, errors []e
}
return
}

func validateADDomainName() schema.SchemaValidateFunc {
return func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

if len(value) > 64 || !regexp.MustCompile(ADDomainNameRegex).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q (%q) doesn't match regexp %q, domain_name must be 2 to 64 with lowercase letters, digits, hyphens, dots and start with a letter", k, value, ADDomainNameRegex))
}
return
}
}