Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* Adding external neg with fqdn

* Add decoder to fetch networkEndpoint

* Test passing, add custom import, decoder

* Fix old test

* Exclude from ansible/inspec

* networkEndpointGroup -> globalNetworkEndpointGroup for global endpoint

* Rebase, dont pre delete empty fields

* Delete unused file
  • Loading branch information
slevenick authored Apr 10, 2020
1 parent 9e82506 commit 951b487
Show file tree
Hide file tree
Showing 15 changed files with 459 additions and 2 deletions.
8 changes: 8 additions & 0 deletions products/compute/ansible.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ datasources: !ruby/object:Overrides::ResourceOverrides
exclude: true
NetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
GlobalNetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
GlobalNetworkEndpointGroup: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
ProjectInfo: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
Region: !ruby/object:Overrides::Ansible::ResourceOverride
Expand Down Expand Up @@ -307,6 +311,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides
exclude: true
NetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
GlobalNetworkEndpoint: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
GlobalNetworkEndpointGroup: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
NetworkPeeringRoutesConfig: !ruby/object:Overrides::Ansible::ResourceOverride
exclude: true
ProjectInfo: !ruby/object:Overrides::Ansible::ResourceOverride
Expand Down
146 changes: 144 additions & 2 deletions products/compute/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7356,8 +7356,7 @@ objects:
- !ruby/object:Api::Type::Enum
name: 'networkEndpointType'
description: |
Type of network endpoints in this network endpoint group. Currently
the only supported value is GCE_VM_IP_PORT.
Type of network endpoints in this network endpoint group. The only supported value is GCE_VM_IP_PORT
values:
- :GCE_VM_IP_PORT
default_value: :GCE_VM_IP_PORT
Expand All @@ -7384,6 +7383,149 @@ objects:
description: |
The default port used if the port number is not specified in the
network endpoint.
- !ruby/object:Api::Resource
name: 'GlobalNetworkEndpoint'
kind: 'compute#networkEndpoint'
base_url: 'projects/{{project}}/global/networkEndpointGroups/{{global_network_endpoint_group}}'
description: |
A Global Network endpoint represents a IP address and port combination that exists outside of GCP.
**NOTE**: Global network endpoints cannot be created outside of a
global network endpoint group.
input: true
create_verb: :POST
create_url: projects/{{project}}/global/networkEndpointGroups/{{global_network_endpoint_group}}/attachNetworkEndpoints
delete_verb: :POST
delete_url: projects/{{project}}/global/networkEndpointGroups/{{global_network_endpoint_group}}/detachNetworkEndpoints
read_verb: :POST
self_link: projects/{{project}}/global/networkEndpointGroups/{{global_network_endpoint_group}}/listNetworkEndpoints
identity:
- fqdn
- ipAddress
- port
nested_query: !ruby/object:Api::Resource::NestedQuery
keys:
- items
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/load-balancing/docs/negs/'
api: 'https://cloud.google.com/compute/docs/reference/rest/beta/networkEndpointGroups'
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
kind: 'compute#operation'
path: 'name'
base_url: 'projects/{{project}}/global/operations/{{op_id}}'
wait_ms: 1000
timeouts: !ruby/object:Api::Timeouts
insert_minutes: 6
update_minutes: 6
delete_minutes: 6
result: !ruby/object:Api::OpAsync::Result
path: 'targetLink'
status: !ruby/object:Api::OpAsync::Status
path: 'status'
complete: 'DONE'
allowed:
- 'PENDING'
- 'RUNNING'
- 'DONE'
error: !ruby/object:Api::OpAsync::Error
path: 'error/errors'
message: 'message'
parameters:
- !ruby/object:Api::Type::ResourceRef
name: 'globalNetworkEndpointGroup'
resource: 'GlobalNetworkEndpointGroup'
imports: 'name'
description: |
The global network endpoint group this endpoint is part of.
required: true
url_param_only: true
properties:
- !ruby/object:Api::Type::Integer
name: 'port'
description: |
Port number of the external endpoint.
required: true
- !ruby/object:Api::Type::String
name: 'ipAddress'
description: |
IPv4 address external endpoint.
- !ruby/object:Api::Type::String
name: 'fqdn'
at_least_one_of:
- fqdn
- ip_address
description: |
Fully qualified domain name of network endpoint.
This can only be specified when network_endpoint_type of the NEG is INTERNET_FQDN_PORT.
- !ruby/object:Api::Resource
name: 'GlobalNetworkEndpointGroup'
kind: 'compute#networkEndpointGroup'
base_url: 'projects/{{project}}/global/networkEndpointGroups'
input: true
has_self_link: true
collection_url_key: 'items'
references: !ruby/object:Api::Resource::ReferenceLinks
guides:
'Official Documentation': 'https://cloud.google.com/load-balancing/docs/negs/internet-neg-concepts'
api: 'https://cloud.google.com/compute/docs/reference/rest/beta/networkEndpointGroups'
description: |
A global network endpoint group contains endpoints that reside outside of Google Cloud.
Currently a global network endpoint group can only support a single endpoint.
async: !ruby/object:Api::OpAsync
operation: !ruby/object:Api::OpAsync::Operation
kind: 'compute#operation'
path: 'name'
base_url: 'projects/{{project}}/global/operations/{{op_id}}'
wait_ms: 1000
result: !ruby/object:Api::OpAsync::Result
path: 'targetLink'
status: !ruby/object:Api::OpAsync::Status
path: 'status'
complete: 'DONE'
allowed:
- 'PENDING'
- 'RUNNING'
- 'DONE'
error: !ruby/object:Api::OpAsync::Error
path: 'error/errors'
message: 'message'
properties:
- !ruby/object:Api::Type::Integer
name: 'id'
description: 'The unique identifier for the resource.'
output: true
- !ruby/object:Api::Type::String
name: 'name'
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
RFC1035. Specifically, the name must be 1-63 characters long and match
the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?` which 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::String
name: 'description'
description: |
An optional description of this resource. Provide this property when
you create the resource.
- !ruby/object:Api::Type::Enum
name: 'networkEndpointType'
required: true
description: |
Type of network endpoints in this network endpoint group. Supported values are:
* INTERNET_IP_PORT
* INTERNET_FQDN_PORT
values:
- :INTERNET_IP_PORT
- :INTERNET_FQDN_PORT
- !ruby/object:Api::Type::Integer
name: 'defaultPort'
description: |
The default port used if the port number is not specified in the
network endpoint.
- !ruby/object:Api::Resource
name: 'NodeGroup'
kind: 'compute#NodeGroup'
Expand Down
4 changes: 4 additions & 0 deletions products/compute/inspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides
override_name: "network_name"
NetworkEndpoint: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
GlobalNetworkEndpoint: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
GlobalNetworkEndpointGroup: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
NetworkPeeringRoutesConfig: !ruby/object:Overrides::Inspec::ResourceOverride
exclude: true
PacketMirroring: !ruby/object:Overrides::Inspec::ResourceOverride
Expand Down
46 changes: 46 additions & 0 deletions products/compute/terraform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,52 @@ overrides: !ruby/object:Overrides::ResourceOverrides
zone: !ruby/object:Overrides::Terraform::PropertyOverride
required: false
default_from_api: true
GlobalNetworkEndpoint: !ruby/object:Overrides::Terraform::ResourceOverride
id_format: "{{project}}/{{global_network_endpoint_group}}/{{ip_address}}/{{fqdn}}/{{port}}"
mutex: networkEndpoint/{{project}}/{{global_network_endpoint_group}}
# Fine-grained resources don't actually exist as standalone GCP resource
# in Cloud Asset Inventory
exclude_validator: true
examples:
- !ruby/object:Provider::Terraform::Examples
name: "global_network_endpoint"
primary_resource_id: "default-endpoint"
# Fine-grained resource need different autogenerated tests, as
# we need to check destroy during a test step where the parent resource
# still exists, rather than during CheckDestroy (when read returns
# nothing because the parent resource has then also been destroyed)
skip_test: true
vars:
neg_name: "my-lb-neg"
properties:
globalNetworkEndpointGroup: !ruby/object:Overrides::Terraform::PropertyOverride
ignore_read: true
diff_suppress_func: compareResourceNames
port: !ruby/object:Overrides::Terraform::PropertyOverride
custom_flatten: templates/terraform/custom_flatten/float64_to_int.go.erb
custom_code: !ruby/object:Provider::Terraform::CustomCode
pre_delete: templates/terraform/pre_delete/compute_global_network_endpoint.go.erb
decoder: templates/terraform/decoders/network_endpoint.go.erb
encoder: templates/terraform/encoders/compute_global_network_endpoint.go.erb
custom_import: templates/terraform/custom_import/compute_global_network_endpoint.go.erb
GlobalNetworkEndpointGroup: !ruby/object:Overrides::Terraform::ResourceOverride
examples:
- !ruby/object:Provider::Terraform::Examples
name: "global_network_endpoint_group"
primary_resource_id: "neg"
vars:
neg_name: "my-lb-neg"
- !ruby/object:Provider::Terraform::Examples
name: "global_network_endpoint_group_ip_address"
primary_resource_id: "neg"
vars:
neg_name: "my-lb-neg"
properties:
id: !ruby/object:Overrides::Terraform::PropertyOverride
exclude: true
name: !ruby/object:Overrides::Terraform::PropertyOverride
validation: !ruby/object:Provider::Terraform::Validation
function: 'validateGCPName'
NetworkPeeringRoutesConfig: !ruby/object:Overrides::Terraform::ResourceOverride
id_format: "projects/{{project}}/global/networks/{{network}}/networkPeerings/{{peering}}"
import_format: ["projects/{{project}}/global/networks/{{network}}/networkPeerings/{{peering}}"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
config := meta.(*Config)
// FQDN, port and ip_address are optional, so use * instead of + when reading the import id
if err := parseImportId([]string{
"projects/(?P<project>[^/]?)/global/networkEndpointGroups/(?P<global_network_endpoint_group>[^/]+)/(?P<ip_address>[^/]+)/(?P<fqdn>[^/]*)/(?P<port>[^/]+)",
"(?P<project>[^/]+)/(?P<global_network_endpoint_group>[^/]+)/(?P<ip_address>[^/]*)/(?P<fqdn>[^/]*)/(?P<port>[^/]*)",
"(?P<global_network_endpoint_group>[^/]+)/(?P<ip_address>[^/]*)/(?P<fqdn>[^/]*)/(?P<port>[^/]*)",
}, d, config); err != nil {
return nil, err
}

// Replace import id for the resource id
id, err := replaceVars(d, config, "{{project}}/{{global_network_endpoint_group}}/{{ip_address}}/{{fqdn}}/{{port}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)

return []*schema.ResourceData{d}, nil
20 changes: 20 additions & 0 deletions templates/terraform/decoders/network_endpoint.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<%# The license inside this block applies 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.
-%>
v, ok := res["networkEndpoint"]
if !ok || v == nil {
return res, nil
}

return v.(map[string]interface{}), nil
20 changes: 20 additions & 0 deletions templates/terraform/decoders/unwrap_global_neg.go.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<%# The license inside this block applies 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.
-%>
v, ok := res["networkEndpoint"]
if !ok || v == nil {
return res, nil
}

return v.(map[string]interface{}), nil
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<%# The license inside this block applies 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.
-%>
// Network Endpoint Group is a URL parameter only, so replace self-link/path with resource name only.
d.Set("global_network_endpoint_group", GetResourceNameFromSelfLink(d.Get("global_network_endpoint_group").(string)))

wrappedReq := map[string]interface{}{
"networkEndpoints": []interface{}{obj},
}
return wrappedReq, nil
18 changes: 18 additions & 0 deletions templates/terraform/examples/global_network_endpoint.tf.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
resource "google_compute_global_network_endpoint" "<%= ctx[:primary_resource_id] %>" {
global_network_endpoint_group = google_compute_network_endpoint_group.neg.name

fqdn = "www.example.com"
port = google_compute_network_endpoint_group.neg.default_port
ip_address = google_compute_instance.endpoint-instance.network_interface[0].network_ip
}

resource "google_compute_global_network_endpoint_group" "group" {
name = "<%= ctx[:vars]['neg_name'] %>"
network = google_compute_network.default.self_link
default_port = "90"
}

resource "google_compute_network" "default" {
name = "<%= ctx[:vars]['network_name'] %>"
auto_create_subnetworks = false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "google_compute_global_network_endpoint_group" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['neg_name'] %>"
default_port = "90"
network_endpoint_type = "INTERNET_FQDN_PORT"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resource "google_compute_global_network_endpoint_group" "<%= ctx[:primary_resource_id] %>" {
name = "<%= ctx[:vars]['neg_name'] %>"
network_endpoint_type = "INTERNET_IP_PORT"
default_port = 90
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
endpointObj := make(map[string]interface{})
if v, ok := d.GetOkExists("fqdn"); !isEmptyValue(reflect.ValueOf(fqdnProp)) && (ok || !reflect.DeepEqual(v, fqdnProp)) {
endpointObj["fqdn"] = fqdnProp
}
if v, ok := d.GetOkExists("port"); !isEmptyValue(reflect.ValueOf(portProp)) && (ok || !reflect.DeepEqual(v, portProp)) {
endpointObj["port"] = portProp
}
if v, ok := d.GetOkExists("ip_address"); !isEmptyValue(reflect.ValueOf(ipAddressProp)) && (ok || !reflect.DeepEqual(v, ipAddressProp)) {
endpointObj["ipAddress"] = ipAddressProp
}

wrappedReq := map[string]interface{}{
"networkEndpoints": []interface{}{endpointObj},
}

attachUrl, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/global/networkEndpointGroups/{{name}}/attachNetworkEndpoints")
if err != nil {
return err
}

log.Printf("[DEBUG] Creating new GlobalNetworkEndpoint: %#v", wrappedReq)
_, err = sendRequestWithTimeout(config, "POST", project, attachUrl, wrappedReq, d.Timeout(schema.TimeoutCreate))
if err != nil {
return fmt.Errorf("Error creating GlobalNetworkEndpoint: %s", err)
}
Loading

0 comments on commit 951b487

Please sign in to comment.