Skip to content

Commit

Permalink
Merge ff72c9f into 57c9075
Browse files Browse the repository at this point in the history
  • Loading branch information
nat-henderson authored Jun 15, 2018
2 parents 57c9075 + ff72c9f commit 74f999c
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 83 deletions.
1 change: 1 addition & 0 deletions .ci/magic-modules/generate-terraform.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ bundle exec compiler -p products/redis -e terraform -o "${GOPATH}/src/github.com

# Resources that were already using beta APIs before they started being autogenerated
bundle exec compiler -v beta -p products/compute -t Address -e terraform -o "${GOPATH}/src/github.com/terraform-providers/terraform-provider-google/"
bundle exec compiler -v beta -p products/compute -t Subnetwork -e terraform -o "${GOPATH}/src/github.com/terraform-providers/terraform-provider-google/"

# This command can crash - if that happens, the script should not fail.
set +e
Expand Down
70 changes: 62 additions & 8 deletions products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2709,6 +2709,7 @@ objects:
name: 'Subnetwork'
kind: 'compute#subnetwork'
base_url: projects/{{project}}/regions/{{region}}/subnetworks
input: true
exports:
- !ruby/object:Api::Type::SelfLink
name: 'selfLink'
Expand Down Expand Up @@ -2755,15 +2756,12 @@ objects:
An optional description of this resource. Provide this property when
you create the resource. This field can be set only at resource
creation time.
# TODO(nelsonjr): Update 'gatewayAddress' input:true vs. output:true
# depending on the resolution of http://b/63113897.
- !ruby/object:Api::Type::String
name: 'gatewayAddress'
description: |
The gateway address for default routes to reach destination addresses
outside this subnetwork. This field can be set only at resource
creation time.
input: true
outside this subnetwork.
output: true
- !ruby/object:Api::Type::Integer
name: 'id'
description: 'The unique identifier for the resource.'
Expand All @@ -2775,7 +2773,9 @@ objects:
Provide this property when you create the subnetwork. For example,
10.0.0.0/8 or 192.168.0.0/16. Ranges must be unique and
non-overlapping within a network. Only IPv4 is supported.
input: true
required: true
update_verb: :POST
update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}/expandIpCidrRange'
- !ruby/object:Api::Type::String
name: 'name'
description: |
Expand All @@ -2786,6 +2786,7 @@ objects:
means the first character must be a lowercase letter, and all
following characters must be a dash, lowercase letter, or digit,
except the last character, which cannot be a dash.
required: true
- !ruby/object:Api::Type::ResourceRef
name: 'network'
resource: 'Network'
Expand All @@ -2794,20 +2795,73 @@ objects:
The network this subnet belongs to.
Only networks that are in the distributed mode can have subnetworks.
input: true
required: true
- !ruby/object:Api::Type::Boolean
name: 'enableFlowLogs'
description: |
Whether to enable flow logging for this subnetwork.
min_version: beta
update_verb: :PATCH
update_url: projects/{{project}}/regions/{{region}}/subnetworks/{{name}}
- !ruby/object:Api::Type::Fingerprint
name: 'fingerprint'
description: |
Fingerprint of this resource. This field is used internally during
updates of this resource.
min_version: beta
update_verb: :PATCH
update_url: projects/{{project}}/regions/{{region}}/subnetworks/{{name}}
- !ruby/object:Api::Type::Array
name: 'secondaryIpRanges'
description: |
An array of configurations for secondary IP ranges for VM instances
contained in this subnetwork. The primary IP of such VM must belong
to the primary ipCidrRange of the subnetwork. The alias IPs may belong
to either primary or secondary ranges.
min_version: beta
update_verb: :PATCH
update_url: projects/{{project}}/regions/{{region}}/subnetworks/{{name}}
item_type: !ruby/object:Api::Type::NestedObject
properties:
- !ruby/object:Api::Type::String
name: 'rangeName'
required: true
description: |
The name associated with this subnetwork secondary range, used
when adding an alias IP range to a VM instance. The name must
be 1-63 characters long, and comply with RFC1035. The name
must be unique within the subnetwork.
- !ruby/object:Api::Type::String
name: 'ipCidrRange'
required: true
description: |
The range of IP addresses belonging to this subnetwork secondary
range. Provide this property when you create the subnetwork.
Ranges must be unique and non-overlapping with all primary and
secondary IP ranges within a network. Only IPv4 is supported.
- !ruby/object:Api::Type::Boolean
name: 'privateIpGoogleAccess'
description: |
Whether the VMs in this subnet can access Google services without
assigned external IP addresses.
update_verb: :POST
update_url: 'projects/{{project}}/regions/{{region}}/subnetworks/{{name}}/setPrivateIpGoogleAccess'
- !ruby/object:Api::Type::ResourceRef
name: 'region'
resource: 'Region'
imports: 'name'
description: |
URL of the region where the regional address resides.
This field is not applicable to global addresses.
URL of the GCP region for this subnetwork.
required: true
input: true
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Private Google Access':
'https://cloud.google.com/vpc/docs/configure-private-google-access'
'Cloud Networking':
'https://cloud.google.com/vpc/docs/using-vpc'
api: 'https://cloud.google.com/compute/docs/reference/rest/beta/subnetworks'

- !ruby/object:Api::Resource
name: 'TargetHttpProxy'
kind: 'compute#targetHttpProxy'
Expand Down
40 changes: 39 additions & 1 deletion products/compute/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -469,13 +469,51 @@ overrides: !ruby/object:Provider::ResourceOverrides
exclude: true
Subnetwork: !ruby/object:Provider::Terraform::ResourceOverride
id_format: "{{region}}/{{name}}"
exclude: true
properties:
id: !ruby/object:Provider::Terraform::PropertyOverride
exclude: true
name: !ruby/object:Provider::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateGCPName'
secondaryIpRanges: !ruby/object:Provider::Terraform::PropertyOverride
name: secondaryIpRange
secondaryIpRanges.rangeName: !ruby/object:Provider::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateGCPName'
secondaryIpRanges.ipCidrRange: !ruby/object:Provider::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateIpCidrRange'
fingerprint: !ruby/object:Provider::Terraform::PropertyOverride
exclude: false
ipCidrRange: !ruby/object:Provider::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateIpCidrRange'
region: !ruby/object:Provider::Terraform::PropertyOverride
required: false
input: false
default_from_api: true
custom_flatten: 'templates/terraform/custom_flatten/name_from_self_link.erb'
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/subnetwork.erb
resource_definition: templates/terraform/resource_definition/subnetwork.erb
examples: |
```hcl
resource "google_compute_network" "custom-test" {
name = "test-network"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" {
name = "test-subnetwork"
ip_cidr_range = "10.2.0.0/16"
region = "us-central1"
network = "${google_compute_network.custom-test.self_link}"
secondary_ip_range {
range_name = "tf-test-secondary-range-update1"
ip_cidr_range = "192.168.10.0/24"
}
}
```
TargetHttpProxy: !ruby/object:Provider::Terraform::ResourceOverride
examples: |
```hcl
Expand Down
8 changes: 7 additions & 1 deletion provider/resource_overrides.rb
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,13 @@ def override_objects
end

def override_properties(api_object, override)
override.properties.each do |property_path, property_override|
# We apply property overrides in reverse order of level of nesting.
# This helps us avoid a problem where we change the name of a property
# before we have applied the overrides to its child properties (and
# therefore can no longer find the child property, since the
# parent name has changed)
sorted_props = override.properties.sort_by { |path, _| -path.count('.') }
sorted_props.each do |property_path, property_override|
check_property_value "properties['#{property_path}']",
property_override, Provider::PropertyOverride
api_property = find_property api_object, property_path.split('.')
Expand Down
4 changes: 3 additions & 1 deletion provider/terraform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ def updatable?(resource, properties)

def force_new?(property, resource)
!property.output &&
(property.input || (resource.input && property.update_url.nil?))
(property.input || (resource.input && property.update_url.nil? &&
(property.parent.nil? ||
force_new?(property.parent, resource))))
end

# Puts together the links to use to make API calls for a given resource type
Expand Down
6 changes: 6 additions & 0 deletions provider/terraform/import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module Import
# c) short id w/o defaults: {{name}}
#
# Fields with default values are `project`, `region` and `zone`.
# rubocop:disable Metrics/AbcSize
def import_id_formats(resource)
if resource.import_format.nil? || resource.import_format.empty?
underscored_base_url = resource.base_url.gsub(
Expand All @@ -40,6 +41,10 @@ def import_id_formats(resource)
id_formats = resource.import_format
end

unless resource.id_format.nil? || resource.id_format == '{{name}}'
id_formats << resource.id_format
end

# short id: {{project}}/{{zone}}/{{name}}
field_markers = id_formats[0].scan(/{{[[:word:]]+}}/)
short_id_format = field_markers.join('/')
Expand All @@ -50,6 +55,7 @@ def import_id_formats(resource)

(id_formats + [short_id_format, short_id_default_format]).uniq
end
# rubocop:enable Metrics/AbcSize
end
end
end
27 changes: 27 additions & 0 deletions templates/terraform/constants/subnetwork.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Whether the IP CIDR change shrinks the block.
func isShrinkageIpCidr(old, new, _ interface{}) bool {
_, oldCidr, oldErr := net.ParseCIDR(old.(string))
_, newCidr, newErr := net.ParseCIDR(new.(string))

if oldErr != nil || newErr != nil {
// This should never happen. The ValidateFunc on the field ensures it.
return false
}

oldStart, oldEnd := cidr.AddressRange(oldCidr)

if newCidr.Contains(oldStart) && newCidr.Contains(oldEnd) {
// This is a CIDR range expansion, no need to ForceNew, we have an update method for it.
return false
}

return true
}


func splitSubnetID(id string) (region string, name string) {
parts := strings.Split(id, "/")
region = parts[0]
name = parts[1]
return
}
3 changes: 3 additions & 0 deletions templates/terraform/flatten_property_method.erb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ func flatten<%= prefix -%><%= titlelize_property(property) -%>(v interface{}) in
<% end -%>
return []interface{}{transformed}
<% elsif property.is_a?(Api::Type::Array) && property.item_type.is_a?(Api::Type::NestedObject) -%>
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
Expand Down
41 changes: 17 additions & 24 deletions templates/terraform/resource.erb
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,16 @@ func resource<%= resource_name -%>Create(d *schema.ResourceData, meta interface{
}
<% end -%>

obj := make(map[string]interface{})
<% settable_properties.each do |prop| -%>
<%= prop.api_name -%>Prop, err := expand<%= resource_name -%><%= titlelize_property(prop) -%>(d.Get("<%= Google::StringUtils.underscore(prop.name) -%>"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("<%= Google::StringUtils.underscore(prop.name) -%>"); ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop) {
obj["<%= prop.api_name -%>"] = <%= prop.api_name -%>Prop
}
<% end -%>

obj := map[string]interface{}{
<% settable_properties.each do |prop| -%>
"<%= prop.api_name -%>": <%= prop.api_name -%>Prop,
<% end -%>
}
<% if object.custom_code.encoder -%>
obj, err = resource<%= resource_name -%>Encoder(d, meta, obj)
if err != nil {
Expand Down Expand Up @@ -217,7 +215,6 @@ func resource<%= resource_name -%>Update(d *schema.ResourceData, meta interface{
<% end -%>

<% if object.input -%>
var obj map[string]interface{}
var url string
var res map[string]interface{}
op := &<%= api_name_lower -%>.Operation{}
Expand All @@ -226,28 +223,27 @@ func resource<%= resource_name -%>Update(d *schema.ResourceData, meta interface{

<% properties_by_custom_update(properties).each do |key, props| -%>
if <%= props.map { |prop| "d.HasChange(\"#{Google::StringUtils.underscore(prop.name)}\")" }.join ' || ' -%> {
obj := make(map[string]interface{})
<% props.each do |prop| -%>
<% if settable_properties.include? prop -%>
<%= prop.api_name -%>Prop, err := expand<%= resource_name -%><%= titlelize_property(prop) -%>(d.Get("<%= Google::StringUtils.underscore(prop.name) -%>"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("<%= Google::StringUtils.underscore(prop.name) -%>"); ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop) || d.HasChange("<%= Google::StringUtils.underscore(prop.name) -%>") {
<% if prop.update_statement -%>
obj["<%= prop.api_name -%>"] = <%= compile_template(prop.update_statement,
prefix: resource_name,
property: prop) -%>
<% else -%>
obj["<%= prop.api_name -%>"] = <%= prop.api_name -%>Prop
<% end -%>
}
<% else -%>
<%= prop.api_name -%>Prop := d.Get("<%= Google::StringUtils.underscore(prop.name) -%>")
obj["<%= prop.api_name -%>"] = <%= prop.api_name -%>Prop
<% end -%>
<% end -%>

obj = map[string]interface{}{
<% props.each do |prop| -%>
<% if prop.update_statement -%>
"<%= prop.api_name -%>": <%= compile_template(prop.update_statement,
prefix: resource_name,
property: prop) -%>
<% else -%>
"<%= prop.api_name -%>": <%= prop.api_name -%>Prop,
<% end -%>
<% end -%>
}
url, err = replaceVars(d, config, "<%= update_url(object, key[:update_url]) -%>")
if err != nil {
return err
Expand Down Expand Up @@ -281,19 +277,16 @@ func resource<%= resource_name -%>Update(d *schema.ResourceData, meta interface{

d.Partial(false)
<% else # if object.input -%>
obj := make(map[string]interface{})
<% settable_properties.each do |prop| -%>
<%= prop.api_name -%>Prop, err := expand<%= resource_name -%><%= titlelize_property(prop) -%>(d.Get("<%= Google::StringUtils.underscore(prop.name) -%>"), d, config)
if err != nil {
return err
return err
} else if v, ok := d.GetOkExists("<%= Google::StringUtils.underscore(prop.name) -%>"); ok || !reflect.DeepEqual(v, <%= prop.api_name -%>Prop) {
obj["<%= prop.api_name -%>"] = <%= prop.api_name -%>Prop
}
<% end -%>

obj := map[string]interface{}{
<% settable_properties.each do |prop| -%>
"<%= prop.api_name -%>": <%= prop.api_name -%>Prop,
<% end -%>
}

<%# We need to decide what encoder to use here - if there's an update encoder, use that! -%>
<% if object.custom_code.update_encoder -%>
obj, err = resource<%= resource_name -%>UpdateEncoder(d, meta, obj)
Expand Down
3 changes: 3 additions & 0 deletions templates/terraform/resource_definition/subnetwork.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CustomizeDiff: customdiff.All(
customdiff.ForceNewIfChange("ip_cidr_range", isShrinkageIpCidr),
),
Loading

0 comments on commit 74f999c

Please sign in to comment.