Skip to content

Commit

Permalink
add conflicts_with and enable generating firewalls in terraform (Goog…
Browse files Browse the repository at this point in the history
  • Loading branch information
danawillow authored and modular-magician committed Aug 22, 2018
1 parent 77ecb28 commit f96c83d
Show file tree
Hide file tree
Showing 13 changed files with 675 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .ci/magic-modules/generate-terraform.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bundle exec compiler -p products/resourcemanager -e terraform -o "${GOPATH}/src/
bundle exec compiler -p products/redis -e terraform -o "${GOPATH}/src/github.com/terraform-providers/terraform-provider-google/"

# Resources that were already using beta APIs before they started being autogenerated
bundle exec compiler -v beta -p products/compute -t Address,GlobalAddress,Subnetwork,ForwardingRule,RegionDisk,VpnTunnel -e terraform -o "${GOPATH}/src/github.com/terraform-providers/terraform-provider-google/"
bundle exec compiler -v beta -p products/compute -t Address,Firewall,ForwardingRule,GlobalAddress,RegionDisk,Subnetwork,VpnTunnel -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
2 changes: 1 addition & 1 deletion build/terraform
14 changes: 14 additions & 0 deletions products/compute/ansible.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ overrides: !ruby/object:Provider::ResourceOverrides
version_added: '2.7'
type: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
Firewall: !ruby/object:Provider::Ansible::ResourceOverride
properties:
denied: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
destinationRanges: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
direction: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
priority: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
sourceServiceAccounts: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
targetServiceAccounts: !ruby/object:Provider::Ansible::PropertyOverride
version_added: '2.7'
ForwardingRule: !ruby/object:Provider::Ansible::ResourceOverride
properties:
target: !ruby/object:Provider::Ansible::PropertyOverride
Expand Down
108 changes: 106 additions & 2 deletions products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,14 @@ objects:
name: 'Firewall'
kind: 'compute#firewall'
base_url: projects/{{project}}/global/firewalls
update_verb: :PATCH
exports:
- !ruby/object:Api::Type::SelfLink
name: 'selfLink'
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/vpc/docs/firewalls'
api: 'https://cloud.google.com/compute/docs/reference/latest/firewalls'
description: |
Each network has its own firewall controlling access to and from the
instances.
Expand Down Expand Up @@ -712,17 +720,74 @@ objects:
name: 'creationTimestamp'
description: 'Creation timestamp in RFC3339 text format.'
output: true
- !ruby/object:Api::Type::Array
name: 'denied'
description: |
The list of DENY rules specified by this firewall. Each rule specifies
a protocol and port-range tuple that describes a denied connection.
item_type: !ruby/object:Api::Type::NestedObject
properties:
# IPProtocol has to be string, instead of Enum because user can
# specify the protocol by number as well.
- !ruby/object:Api::Type::String
name: 'ip_protocol'
description: |
The IP protocol to which this rule applies. The protocol type is
required when creating a firewall rule. This value can either be
one of the following well known protocol strings (tcp, udp,
icmp, esp, ah, sctp), or the IP protocol number.
api_name: 'IPProtocol'
required: true
- !ruby/object:Api::Type::Array
item_type: Api::Type::String
name: 'ports'
description: |
An optional list of ports to which this rule applies. This field
is only applicable for UDP or TCP protocol. Each entry must be
either an integer or a range. If not specified, this rule
applies to connections through any port.
Example inputs include: ["22"], ["80","443"], and
["12345-12349"].
- !ruby/object:Api::Type::String
name: 'description'
description: |
An optional description of this resource. Provide this property when
you create the resource.
- !ruby/object:Api::Type::Array
name: 'destinationRanges'
description: |
If destination ranges are specified, the firewall will apply only to
traffic that has destination IP address in these ranges. These ranges
must be expressed in CIDR format. Only IPv4 is supported.
item_type: Api::Type::String
- !ruby/object:Api::Type::Enum
name: 'direction'
description: |
Direction of traffic to which this firewall applies; default is
INGRESS. Note: For INGRESS traffic, it is NOT supported to specify
destinationRanges; For EGRESS traffic, it is NOT supported to specify
sourceRanges OR sourceTags.
values:
- :INGRESS
- :EGRESS
- !ruby/object:Api::Type::Boolean
name: 'disabled'
description: |
Denotes whether the firewall rule is disabled, i.e not applied to the
network it is associated with. When set to true, the firewall rule is
not enforced and the network behaves as if it did not exist. If this
is unspecified, the firewall rule will be enabled.
min_version: beta
send_empty_value: true
- !ruby/object:Api::Type::Integer
name: 'id'
description: 'The unique identifier for the resource.'
output: true
- !ruby/object:Api::Type::String
name: 'name'
required: true
input: true
description: |
Name of the resource. Provided by the client when the resource is
created. The name must be 1-63 characters long, and comply with
Expand All @@ -731,9 +796,11 @@ objects:
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.
# TODO(nelsonjr): Convert this to a ResourceRef.
- !ruby/object:Api::Type::String
- !ruby/object:Api::Type::ResourceRef
name: 'network'
resource: 'Network'
imports: 'selfLink'
required: true
description: |
URL of the network resource for this firewall rule. If not specified
when creating a firewall rule, the default network is used:
Expand All @@ -747,6 +814,16 @@ objects:
networks/my-network
projects/myproject/global/networks/my-network
global/networks/default
- !ruby/object:Api::Type::Integer
name: 'priority'
description: |
Priority for this rule. This is an integer between 0 and 65535, both
inclusive. When not specified, the value assumed is 1000. Relative
priorities determine precedence of conflicting rules. Lower value of
priority implies higher precedence (eg, a rule with priority 0 has
higher precedence than a rule with priority 1). DENY rules take
precedence over ALLOW rules having equal priority.
default_value: 1000
- !ruby/object:Api::Type::Array
name: 'sourceRanges'
description: |
Expand All @@ -759,6 +836,22 @@ objects:
connection does not need to match both properties for the firewall to
apply. Only IPv4 is supported.
item_type: Api::Type::String
- !ruby/object:Api::Type::Array
name: 'sourceServiceAccounts'
description: |
If source service accounts are specified, the firewall will apply only
to traffic originating from an instance with a service account in this
list. Source service accounts cannot be used to control traffic to an
instance's external IP address because service accounts are associated
with an instance, not an IP address. sourceRanges can be set at the
same time as sourceServiceAccounts. If both are set, the firewall will
apply to traffic that has source IP address within sourceRanges OR the
source IP belongs to an instance with service account listed in
sourceServiceAccount. The connection does not need to match both
properties for the firewall to apply. sourceServiceAccounts cannot be
used at the same time as sourceTags or targetTags.
item_type: Api::Type::String
max_size: 1
- !ruby/object:Api::Type::Array
name: 'sourceTags'
description: |
Expand All @@ -772,6 +865,17 @@ objects:
a tag listed in the sourceTags property. The connection does not need
to match both properties for the firewall to apply.
item_type: Api::Type::String
- !ruby/object:Api::Type::Array
name: 'targetServiceAccounts'
description: |
A list of service accounts indicating sets of instances located in the
network that may make network connections as specified in allowed[].
targetServiceAccounts cannot be used at the same time as targetTags or
sourceTags. If neither targetServiceAccounts nor targetTags are
specified, the firewall rule applies to all instances on the specified
network.
item_type: Api::Type::String
max_size: 1
- !ruby/object:Api::Type::Array
name: 'targetTags'
description: |
Expand Down
79 changes: 78 additions & 1 deletion products/compute/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,84 @@ overrides: !ruby/object:Provider::ResourceOverrides
DiskType: !ruby/object:Provider::Terraform::ResourceOverride
exclude: true
Firewall: !ruby/object:Provider::Terraform::ResourceOverride
exclude: true
examples: |
```hcl
resource "google_compute_network" "default" {
name = "test-network"
}
resource "google_compute_firewall" "default" {
name = "test-firewall"
network = "${google_compute_network.default.name}"
allow {
protocol = "icmp"
}
allow {
protocol = "tcp"
ports = ["80", "8080", "1000-2000"]
}
source_tags = ["web"]
}
```
custom_code: !ruby/object:Provider::Terraform::CustomCode
constants: templates/terraform/constants/firewall.erb
resource_definition: templates/terraform/resource_definition/firewall.erb
properties:
id: !ruby/object:Provider::Terraform::PropertyOverride
exclude: true
allowed: !ruby/object:Provider::Terraform::PropertyOverride
name: 'allow'
is_set: true
set_hash_func: 'resourceComputeFirewallRuleHash'
conflicts_with:
- 'deny'
allowed.ip_protocol: !ruby/object:Provider::Terraform::PropertyOverride
name: 'protocol'
denied: !ruby/object:Provider::Terraform::PropertyOverride
name: 'deny'
is_set: true
set_hash_func: 'resourceComputeFirewallRuleHash'
conflicts_with:
- 'allow'
denied.ip_protocol: !ruby/object:Provider::Terraform::PropertyOverride
name: 'protocol'
destinationRanges: !ruby/object:Provider::Terraform::PropertyOverride
is_set: true
default_from_api: true
conflicts_with:
- source_ranges
- source_tags
direction: !ruby/object:Provider::Terraform::PropertyOverride
default_from_api: true
name: !ruby/object:Provider::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateGCPName'
network: !ruby/object:Provider::Terraform::PropertyOverride
description: |
The name or self_link of the network to attach this firewall to.
priority: !ruby/object:Provider::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validation.IntBetween(0, 65535)'
sourceRanges: !ruby/object:Provider::Terraform::PropertyOverride
is_set: true
default_from_api: true
sourceTags: !ruby/object:Provider::Terraform::PropertyOverride
is_set: true
sourceServiceAccounts: !ruby/object:Provider::Terraform::PropertyOverride
is_set: true
conflicts_with:
- source_tags
- target_tags
targetServiceAccounts: !ruby/object:Provider::Terraform::PropertyOverride
is_set: true
conflicts_with:
- source_tags
- target_tags
targetTags: !ruby/object:Provider::Terraform::PropertyOverride
is_set: true
ForwardingRule: !ruby/object:Provider::Terraform::ResourceOverride
examples: |
```hcl
Expand Down
5 changes: 5 additions & 0 deletions provider/terraform/property_override.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ module OverrideFields
# It translates to setting the field to Computed & Optional in the schema.
attr_reader :default_from_api

# Names of attributes that can't be set alongside this one
attr_reader :conflicts_with

# ===========
# Custom code
# ===========
Expand Down Expand Up @@ -99,10 +102,12 @@ def validate
@is_set ||= false
@unordered_list ||= false
@default_from_api ||= false
@conflicts_with ||= []

check_property :sensitive, :boolean
check_property :is_set, :boolean
check_property :default_from_api, :boolean
check_property_list :conflicts_with, ::String

check_optional_property :diff_suppress_func, String
check_optional_property :state_func, String
Expand Down
32 changes: 32 additions & 0 deletions templates/terraform/constants/firewall.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<% if false # the license inside this if block pertains to this file -%>
# Copyright 2017 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.
<% end -%>
func resourceComputeFirewallRuleHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%s-", m["protocol"].(string)))

// We need to make sure to sort the strings below so that we always
// generate the same hash code no matter what is in the set.
if v, ok := m["ports"]; ok {
s := convertStringArr(v.([]interface{}))
sort.Strings(s)

for _, v := range s {
buf.WriteString(fmt.Sprintf("%s-", v))
}
}

return hashcode.String(buf.String())
}
16 changes: 16 additions & 0 deletions templates/terraform/resource_definition/firewall.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<% if false # the license inside this if block pertains to this file -%>
# Copyright 2017 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.
<% end -%>
SchemaVersion: 1,
MigrateState: resourceComputeFirewallMigrateState,
3 changes: 3 additions & 0 deletions templates/terraform/schema_property.erb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@
<% unless property.default_value.nil? -%>
Default: <%= go_literal(property.default_value) -%>,
<% end -%>
<% unless property.conflicts_with.empty? -%>
ConflictsWith: []string{<%= property.conflicts_with.map{ |p| go_literal(p) }.join(', ') -%>},
<% end -%>
},
<% else -%>
// TODO: Property '<%= property.name -%>' of type <%= property.class -%> is not supported
Expand Down
Loading

0 comments on commit f96c83d

Please sign in to comment.