From 19b40a3240ce63dcc4c0adcce6b0acf86cc19254 Mon Sep 17 00:00:00 2001 From: Nathan McKinley Date: Thu, 11 Oct 2018 22:52:11 +0000 Subject: [PATCH] WIP: Add interconnect attachments. --- .../gcp_compute_interconnect_attachment.py | 393 +++++++----------- ...p_compute_interconnect_attachment_facts.py | 273 +++++------- .../tasks/main.yml | 116 ++++++ 3 files changed, 379 insertions(+), 403 deletions(-) create mode 100644 tests/integration/gcp_compute_interconnect_attachment/tasks/main.yml diff --git a/plugins/modules/gcp_compute_interconnect_attachment.py b/plugins/modules/gcp_compute_interconnect_attachment.py index 4c7d698..eb9598d 100644 --- a/plugins/modules/gcp_compute_interconnect_attachment.py +++ b/plugins/modules/gcp_compute_interconnect_attachment.py @@ -18,247 +18,162 @@ # ---------------------------------------------------------------------------- from __future__ import absolute_import, division, print_function - __metaclass__ = type ################################################################################ # Documentation ################################################################################ -ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ["preview"], 'supported_by': 'community'} +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ["preview"], + 'supported_by': 'community'} DOCUMENTATION = ''' --- module: gcp_compute_interconnect_attachment description: -- Represents an InterconnectAttachment (VLAN attachment) resource. For more information, - see Creating VLAN Attachments. + - Represents an InterconnectAttachment (VLAN attachment) resource. For more information, + see Creating VLAN Attachments. short_description: Creates a GCP InterconnectAttachment version_added: 2.8 author: Google Inc. (@googlecloudplatform) requirements: -- python >= 2.6 -- requests >= 2.18.4 -- google-auth >= 1.3.0 + - python >= 2.6 + - requests >= 2.18.4 + - google-auth >= 1.3.0 options: - state: + state: + description: + - Whether the given object should exist in GCP + choices: ['present', 'absent'] + default: 'present' + interconnect: + description: + - URL of the underlying Interconnect object that this attachment's traffic will traverse + through. + required: true description: - - Whether the given object should exist in GCP - choices: - - present - - absent - default: present - interconnect: - description: - - URL of the underlying Interconnect object that this attachment's traffic will - traverse through. Required if type is DEDICATED, must not be set if type is - PARTNER. - required: false - description: - description: - - An optional description of this resource. - required: false - edge_availability_domain: - description: - - Desired availability domain for the attachment. Only available for type PARTNER, - at creation time. For improved reliability, customers should configure a pair - of attachments with one per availability domain. The selected availability domain - will be provided to the Partner via the pairing key so that the provisioned - circuit will lie in the specified domain. If not specified, the value will default - to AVAILABILITY_DOMAIN_ANY. - required: false - type: - description: - - The type of InterconnectAttachment you wish to create. Defaults to DEDICATED. - required: false - choices: - - DEDICATED - - PARTNER - - PARTNER_PROVIDER - router: - description: - - URL of the cloud router to be used for dynamic routing. This router must be - in the same region as this InterconnectAttachment. The InterconnectAttachment - will automatically connect the Interconnect to the network & region within which - the Cloud Router is configured. - - 'This field represents a link to a Router resource in GCP. It can be specified - in two ways. First, you can place a dictionary with key ''selfLink'' and value - of your resource''s selfLink Alternatively, you can add `register: name-of-resource` - to a gcp_compute_router task and then set this router field to "{{ name-of-resource - }}"' - required: true - 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 - candidate_subnets: - description: - - Up to 16 candidate prefixes that can be used to restrict the allocation of cloudRouterIpAddress - and customerRouterIpAddress for this attachment. - - All prefixes must be within link-local address space (169.254.0.0/16) and must - be /29 or shorter (/28, /27, etc). Google will attempt to select an unused /29 - from the supplied candidate prefix(es). The request will fail if all possible - /29s are in use on Google's edge. If not supplied, Google will randomly select - an unused /29 from all of link-local space. - required: false - vlan_tag8021q: - description: - - The IEEE 802.1Q VLAN tag for this attachment, in the range 2-4094. When using - PARTNER type this will be managed upstream. - required: false - region: - description: - - Region where the regional interconnect attachment resides. - required: true + description: + - An optional description of this resource. . + required: false + router: + description: + - URL of the cloud router to be used for dynamic routing. This router must be in the + same region as this InterconnectAttachment. The InterconnectAttachment will automatically + connect the Interconnect to the network & region within which the Cloud Router is + configured. + - 'This field represents a link to a Router resource in GCP. It can be specified in + two ways. You can add `register: name-of-resource` to a gcp_compute_router task + and then set this router field to "{{ name-of-resource }}" Alternatively, you can + set this router to a dictionary with the selfLink key where the value is the selfLink + of your Router.' + required: true + 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 + region: + description: + - Region where the regional interconnect attachment resides. + required: true extends_documentation_fragment: gcp ''' EXAMPLES = ''' - name: create a interconnect attachment gcp_compute_interconnect_attachment: - name: test_object - region: us-central1 - project: test_project - auth_kind: serviceaccount - interconnect: https://googleapis.com/compute/v1/projects/test_project/global/interconnects/... - router: https://googleapis.com/compute/v1/projects/test_project/regions/us-central1/routers/... - service_account_file: "/tmp/auth.pem" - state: present + name: "test_object" + region: us-central1 + project: "test_project" + auth_kind: "serviceaccount" + interconnect: https://googleapis.com/compute/v1/projects/test_project/global/interconnects/... + router: https://googleapis.com/compute/v1/projects/test_project/regions/us-central1/routers/... + service_account_file: "/tmp/auth.pem" + state: present register: disk ''' RETURN = ''' -cloudRouterIpAddress: - description: - - IPv4 address + prefix length to be configured on Cloud Router Interface for this - interconnect attachment. - returned: success - type: str -customerRouterIpAddress: - description: - - IPv4 address + prefix length to be configured on the customer router subinterface - for this interconnect attachment. - returned: success - type: str -interconnect: - description: - - URL of the underlying Interconnect object that this attachment's traffic will - traverse through. Required if type is DEDICATED, must not be set if type is PARTNER. - returned: success - type: str -description: - description: - - An optional description of this resource. - returned: success - type: str -edgeAvailabilityDomain: - description: - - Desired availability domain for the attachment. Only available for type PARTNER, - at creation time. For improved reliability, customers should configure a pair - of attachments with one per availability domain. The selected availability domain - will be provided to the Partner via the pairing key so that the provisioned circuit - will lie in the specified domain. If not specified, the value will default to - AVAILABILITY_DOMAIN_ANY. - returned: success - type: str -pairingKey: - description: - - '[Output only for type PARTNER. Not present for DEDICATED]. The opaque identifier - of an PARTNER attachment used to initiate provisioning with a selected partner. - Of the form "XXXXX/region/domain" .' - returned: success - type: str -partnerAsn: - description: - - "[Output only for type PARTNER. Not present for DEDICATED]. Optional BGP ASN for - the router that should be supplied by a layer 3 Partner if they configured BGP - on behalf of the customer." - returned: success - type: str -privateInterconnectInfo: - description: - - Information specific to an InterconnectAttachment. This property is populated - if the interconnect that this is attached to is of type DEDICATED. - returned: success - type: complex - contains: - tag8021q: - description: - - 802.1q encapsulation tag to be used for traffic between Google and the customer, - going to and from this network and region. - returned: success - type: int -type: - description: - - The type of InterconnectAttachment you wish to create. Defaults to DEDICATED. - returned: success - type: str -state: - description: - - "[Output Only] The current state of this attachment's functionality." - returned: success - type: str -googleReferenceId: - description: - - Google reference ID, to be used when raising support tickets with Google or otherwise - to debug backend connectivity issues. - returned: success - type: str -router: - description: - - URL of the cloud router to be used for dynamic routing. This router must be in - the same region as this InterconnectAttachment. The InterconnectAttachment will - automatically connect the Interconnect to the network & region within which the - Cloud Router is configured. - returned: success - type: dict -creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str -id: - description: - - The unique identifier for the resource. This identifier is defined by the server. - returned: success - type: str -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. - returned: success - type: str -candidateSubnets: - description: - - Up to 16 candidate prefixes that can be used to restrict the allocation of cloudRouterIpAddress - and customerRouterIpAddress for this attachment. - - All prefixes must be within link-local address space (169.254.0.0/16) and must - be /29 or shorter (/28, /27, etc). Google will attempt to select an unused /29 - from the supplied candidate prefix(es). The request will fail if all possible - /29s are in use on Google's edge. If not supplied, Google will randomly select - an unused /29 from all of link-local space. - returned: success - type: list -vlanTag8021q: - description: - - The IEEE 802.1Q VLAN tag for this attachment, in the range 2-4094. When using - PARTNER type this will be managed upstream. - returned: success - type: int -region: - description: - - Region where the regional interconnect attachment resides. - returned: success - type: str + cloudRouterIpAddress: + description: + - IPv4 address + prefix length to be configured on Cloud Router Interface for this + interconnect attachment. + returned: success + type: str + customerRouterIpAddress: + description: + - IPv4 address + prefix length to be configured on the customer router subinterface + for this interconnect attachment. + returned: success + type: str + interconnect: + description: + - URL of the underlying Interconnect object that this attachment's traffic will traverse + through. + returned: success + type: str + description: + description: + - An optional description of this resource. . + returned: success + type: str + privateInterconnectInfo: + description: + - Information specific to an InterconnectAttachment. This property is populated if + the interconnect that this is attached to is of type DEDICATED. + returned: success + type: complex + contains: + tag8021q: + description: + - 802.1q encapsulation tag to be used for traffic between Google and the customer, + going to and from this network and region. + returned: success + type: int + googleReferenceId: + description: + - Google reference ID, to be used when raising support tickets with Google or otherwise + to debug backend connectivity issues. + returned: success + type: str + router: + description: + - URL of the cloud router to be used for dynamic routing. This router must be in the + same region as this InterconnectAttachment. The InterconnectAttachment will automatically + connect the Interconnect to the network & region within which the Cloud Router is + configured. + returned: success + type: dict + creationTimestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + id: + description: + - The unique identifier for the resource. This identifier is defined by the server. + returned: success + type: str + 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. + returned: success + type: str + region: + description: + - Region where the regional interconnect attachment resides. + returned: success + type: str ''' ################################################################################ @@ -281,15 +196,11 @@ def main(): module = GcpModule( argument_spec=dict( state=dict(default='present', choices=['present', 'absent'], type='str'), - interconnect=dict(type='str'), + interconnect=dict(required=True, type='str'), description=dict(type='str'), - edge_availability_domain=dict(type='str'), - type=dict(type='str', choices=['DEDICATED', 'PARTNER', 'PARTNER_PROVIDER']), router=dict(required=True, type='dict'), name=dict(required=True, type='str'), - candidate_subnets=dict(type='list', elements='str'), - vlan_tag8021q=dict(type='int'), - region=dict(required=True, type='str'), + region=dict(required=True, type='str') ) ) @@ -330,8 +241,7 @@ def create(module, link, kind): def update(module, link, kind): - delete(module, self_link(module), kind) - create(module, collection(module), kind) + module.fail_json(msg="InterconnectAttachment cannot be edited") def delete(module, link, kind): @@ -344,16 +254,12 @@ def resource_to_request(module): u'kind': 'compute#interconnectAttachment', u'interconnect': module.params.get('interconnect'), u'description': module.params.get('description'), - u'edgeAvailabilityDomain': module.params.get('edge_availability_domain'), - u'type': module.params.get('type'), u'router': replace_resource_dict(module.params.get(u'router', {}), 'selfLink'), - u'name': module.params.get('name'), - u'candidateSubnets': module.params.get('candidate_subnets'), - u'vlanTag8021q': module.params.get('vlan_tag8021q'), + u'name': module.params.get('name') } return_vals = {} for k, v in request.items(): - if v or v is False: + if v: return_vals[k] = v return return_vals @@ -384,8 +290,8 @@ def return_if_object(module, response, kind, allow_not_found=False): try: module.raise_for_status(response) result = response.json() - except getattr(json.decoder, 'JSONDecodeError', ValueError): - module.fail_json(msg="Invalid JSON response with error: %s" % response.text) + except getattr(json.decoder, 'JSONDecodeError', ValueError) as inst: + module.fail_json(msg="Invalid JSON response with error: %s" % inst) if navigate_hash(result, ['error', 'errors']): module.fail_json(msg=navigate_hash(result, ['error', 'errors'])) @@ -419,19 +325,12 @@ def response_to_hash(module, response): u'customerRouterIpAddress': response.get(u'customerRouterIpAddress'), u'interconnect': response.get(u'interconnect'), u'description': response.get(u'description'), - u'edgeAvailabilityDomain': response.get(u'edgeAvailabilityDomain'), - u'pairingKey': response.get(u'pairingKey'), - u'partnerAsn': response.get(u'partnerAsn'), - u'privateInterconnectInfo': InterconnectAttachmentPrivateinterconnectinfo(response.get(u'privateInterconnectInfo', {}), module).from_response(), - u'type': response.get(u'type'), - u'state': response.get(u'state'), + u'privateInterconnectInfo': InterconnectAttachmentPrivateInterconnectInfo(response.get(u'privateInterconnectInfo', {}), module).from_response(), u'googleReferenceId': response.get(u'googleReferenceId'), u'router': response.get(u'router'), u'creationTimestamp': response.get(u'creationTimestamp'), u'id': response.get(u'id'), - u'name': response.get(u'name'), - u'candidateSubnets': response.get(u'candidateSubnets'), - u'vlanTag8021q': response.get(u'vlanTag8021q'), + u'name': response.get(u'name') } @@ -466,9 +365,11 @@ def wait_for_completion(status, op_result, module): op_id = navigate_hash(op_result, ['name']) op_uri = async_op_url(module, {'op_id': op_id}) while status != 'DONE': - raise_if_errors(op_result, ['error', 'errors'], module) + raise_if_errors(op_result, ['error', 'errors'], 'message') time.sleep(1.0) - op_result = fetch_resource(module, op_uri, 'compute#operation', False) + if status not in ['PENDING', 'RUNNING', 'DONE']: + module.fail_json(msg="Invalid result %s" % status) + op_result = fetch_resource(module, op_uri, 'compute#operation') status = navigate_hash(op_result, ['status']) return op_result @@ -479,7 +380,7 @@ def raise_if_errors(response, err_path, module): module.fail_json(msg=errors) -class InterconnectAttachmentPrivateinterconnectinfo(object): +class InterconnectAttachmentPrivateInterconnectInfo(object): def __init__(self, request, module): self.module = module if request: @@ -488,10 +389,14 @@ class InterconnectAttachmentPrivateinterconnectinfo(object): self.request = {} def to_request(self): - return remove_nones_from_dict({}) + return remove_nones_from_dict({ + u'tag8021q': self.request.get('tag8021q') + }) def from_response(self): - return remove_nones_from_dict({}) + return remove_nones_from_dict({ + u'tag8021q': self.request.get(u'tag8021q') + }) if __name__ == '__main__': diff --git a/plugins/modules/gcp_compute_interconnect_attachment_facts.py b/plugins/modules/gcp_compute_interconnect_attachment_facts.py index 5a8b78f..2472df5 100644 --- a/plugins/modules/gcp_compute_interconnect_attachment_facts.py +++ b/plugins/modules/gcp_compute_interconnect_attachment_facts.py @@ -18,186 +18,134 @@ # ---------------------------------------------------------------------------- from __future__ import absolute_import, division, print_function - __metaclass__ = type ################################################################################ # Documentation ################################################################################ -ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ["preview"], 'supported_by': 'community'} +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ["preview"], + 'supported_by': 'community'} DOCUMENTATION = ''' --- module: gcp_compute_interconnect_attachment_facts description: -- Gather facts for GCP InterconnectAttachment + - Gather facts for GCP InterconnectAttachment short_description: Gather facts for GCP InterconnectAttachment version_added: 2.8 author: Google Inc. (@googlecloudplatform) requirements: -- python >= 2.6 -- requests >= 2.18.4 -- google-auth >= 1.3.0 + - python >= 2.6 + - requests >= 2.18.4 + - google-auth >= 1.3.0 options: - filters: - description: - - A list of filter value pairs. Available filters are listed here U(https://cloud.google.com/sdk/gcloud/reference/topic/filters.) - - Each additional filter in the list will act be added as an AND condition (filter1 - and filter2) . - region: - description: - - Region where the regional interconnect attachment resides. - required: true + filters: + description: + A list of filter value pairs. Available filters are listed here + U(https://cloud.google.com/sdk/gcloud/reference/topic/filters). + Each additional filter in the list will act be added as an AND condition + (filter1 and filter2) + region: + description: + - Region where the regional interconnect attachment resides. + required: true extends_documentation_fragment: gcp ''' EXAMPLES = ''' -- name: " a interconnect attachment facts" +- name: a interconnect attachment facts gcp_compute_interconnect_attachment_facts: - region: us-central1 - filters: - - name = test_object - project: test_project - auth_kind: serviceaccount - service_account_file: "/tmp/auth.pem" - state: facts + region: us-central1 + filters: + - name = test_object + project: test_project + auth_kind: serviceaccount + service_account_file: "/tmp/auth.pem" ''' RETURN = ''' -resources: - description: List of resources - returned: always - type: complex - contains: - cloudRouterIpAddress: - description: - - IPv4 address + prefix length to be configured on Cloud Router Interface for - this interconnect attachment. - returned: success - type: str - customerRouterIpAddress: - description: - - IPv4 address + prefix length to be configured on the customer router subinterface - for this interconnect attachment. - returned: success - type: str - interconnect: - description: - - URL of the underlying Interconnect object that this attachment's traffic will - traverse through. Required if type is DEDICATED, must not be set if type is - PARTNER. - returned: success - type: str - description: - description: - - An optional description of this resource. - returned: success - type: str - edgeAvailabilityDomain: - description: - - Desired availability domain for the attachment. Only available for type PARTNER, - at creation time. For improved reliability, customers should configure a pair - of attachments with one per availability domain. The selected availability - domain will be provided to the Partner via the pairing key so that the provisioned - circuit will lie in the specified domain. If not specified, the value will - default to AVAILABILITY_DOMAIN_ANY. - returned: success - type: str - pairingKey: - description: - - '[Output only for type PARTNER. Not present for DEDICATED]. The opaque identifier - of an PARTNER attachment used to initiate provisioning with a selected partner. - Of the form "XXXXX/region/domain" .' - returned: success - type: str - partnerAsn: - description: - - "[Output only for type PARTNER. Not present for DEDICATED]. Optional BGP ASN - for the router that should be supplied by a layer 3 Partner if they configured - BGP on behalf of the customer." - returned: success - type: str - privateInterconnectInfo: - description: - - Information specific to an InterconnectAttachment. This property is populated - if the interconnect that this is attached to is of type DEDICATED. - returned: success - type: complex - contains: - tag8021q: - description: - - 802.1q encapsulation tag to be used for traffic between Google and the - customer, going to and from this network and region. - returned: success - type: int - type: - description: - - The type of InterconnectAttachment you wish to create. Defaults to DEDICATED. - returned: success - type: str - state: - description: - - "[Output Only] The current state of this attachment's functionality." - returned: success - type: str - googleReferenceId: - description: - - Google reference ID, to be used when raising support tickets with Google or - otherwise to debug backend connectivity issues. - returned: success - type: str - router: - description: - - URL of the cloud router to be used for dynamic routing. This router must be - in the same region as this InterconnectAttachment. The InterconnectAttachment - will automatically connect the Interconnect to the network & region within - which the Cloud Router is configured. - returned: success - type: dict - creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str - id: - description: - - The unique identifier for the resource. This identifier is defined by the - server. - returned: success - type: str - 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. - returned: success - type: str - candidateSubnets: - description: - - Up to 16 candidate prefixes that can be used to restrict the allocation of - cloudRouterIpAddress and customerRouterIpAddress for this attachment. - - All prefixes must be within link-local address space (169.254.0.0/16) and - must be /29 or shorter (/28, /27, etc). Google will attempt to select an unused - /29 from the supplied candidate prefix(es). The request will fail if all possible - /29s are in use on Google's edge. If not supplied, Google will randomly select - an unused /29 from all of link-local space. - returned: success - type: list - vlanTag8021q: - description: - - The IEEE 802.1Q VLAN tag for this attachment, in the range 2-4094. When using - PARTNER type this will be managed upstream. - returned: success - type: int - region: - description: - - Region where the regional interconnect attachment resides. - returned: success - type: str +items: + description: List of items + returned: always + type: complex + contains: + cloudRouterIpAddress: + description: + - IPv4 address + prefix length to be configured on Cloud Router Interface for this + interconnect attachment. + returned: success + type: str + customerRouterIpAddress: + description: + - IPv4 address + prefix length to be configured on the customer router subinterface + for this interconnect attachment. + returned: success + type: str + interconnect: + description: + - URL of the underlying Interconnect object that this attachment's traffic will traverse + through. + returned: success + type: str + description: + description: + - An optional description of this resource. . + returned: success + type: str + privateInterconnectInfo: + description: + - Information specific to an InterconnectAttachment. This property is populated if + the interconnect that this is attached to is of type DEDICATED. + returned: success + type: complex + contains: + tag8021q: + description: + - 802.1q encapsulation tag to be used for traffic between Google and the customer, + going to and from this network and region. + returned: success + type: int + googleReferenceId: + description: + - Google reference ID, to be used when raising support tickets with Google or otherwise + to debug backend connectivity issues. + returned: success + type: str + router: + description: + - URL of the cloud router to be used for dynamic routing. This router must be in the + same region as this InterconnectAttachment. The InterconnectAttachment will automatically + connect the Interconnect to the network & region within which the Cloud Router is + configured. + returned: success + type: dict + creationTimestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + id: + description: + - The unique identifier for the resource. This identifier is defined by the server. + returned: success + type: str + 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. + returned: success + type: str + region: + description: + - Region where the regional interconnect attachment resides. + returned: success + type: str ''' ################################################################################ @@ -212,9 +160,14 @@ import json def main(): - module = GcpModule(argument_spec=dict(filters=dict(type='list', elements='str'), region=dict(required=True, type='str'))) + module = GcpModule( + argument_spec=dict( + filters=dict(type='list', elements='str'), + region=dict(required=True, type='str') + ) + ) - if not module.params['scopes']: + if 'scopes' not in module.params: module.params['scopes'] = ['https://www.googleapis.com/auth/compute'] items = fetch_list(module, collection(module), query_options(module.params['filters'])) @@ -222,7 +175,9 @@ def main(): items = items.get('items') else: items = [] - return_value = {'resources': items} + return_value = { + 'items': items + } module.exit_json(**return_value) diff --git a/tests/integration/gcp_compute_interconnect_attachment/tasks/main.yml b/tests/integration/gcp_compute_interconnect_attachment/tasks/main.yml new file mode 100644 index 0000000..2ed187a --- /dev/null +++ b/tests/integration/gcp_compute_interconnect_attachment/tasks/main.yml @@ -0,0 +1,116 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file at +# https://www.github.com/GoogleCloudPlatform/magic-modules +# +# ---------------------------------------------------------------------------- +# Pre-test setup +- name: delete a interconnect attachment + gcp_compute_interconnect_attachment: + name: "{{ resource_name }}" + region: us-central1 + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + interconnect: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/global/interconnects/... + router: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/regions/us-central1/routers/... + service_account_file: "{{ gcp_cred_file }}" + state: absent + register: disk +#---------------------------------------------------------- +- name: create a interconnect attachment + gcp_compute_interconnect_attachment: + name: "{{ resource_name }}" + region: us-central1 + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + interconnect: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/global/interconnects/... + router: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/regions/us-central1/routers/... + service_account_file: "{{ gcp_cred_file }}" + state: present + register: disk + register: result +- name: assert changed is true + assert: + that: + - result.changed == true + - "result.kind == 'compute#interconnectAttachment'" +- name: verify that interconnect_attachment was created + shell: | + gcloud compute interconnects attachments describe "{{ resource_name }}" --project="{{ gcp_project}}" --region="{{ gcp_region}}" + register: results +- name: verify that command succeeded + assert: + that: + - results.rc == 0 +# ---------------------------------------------------------------------------- +- name: create a interconnect attachment that already exists + gcp_compute_interconnect_attachment: + name: "{{ resource_name }}" + region: us-central1 + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + interconnect: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/global/interconnects/... + router: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/regions/us-central1/routers/... + service_account_file: "{{ gcp_cred_file }}" + state: present + register: disk + register: result +- name: assert changed is false + assert: + that: + - result.changed == false + - "result.kind == 'compute#interconnectAttachment'" +#---------------------------------------------------------- +- name: delete a interconnect attachment + gcp_compute_interconnect_attachment: + name: "{{ resource_name }}" + region: us-central1 + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + interconnect: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/global/interconnects/... + router: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/regions/us-central1/routers/... + service_account_file: "{{ gcp_cred_file }}" + state: absent + register: disk + register: result +- name: assert changed is true + assert: + that: + - result.changed == true + - result.has_key('kind') == False +- name: verify that interconnect_attachment was deleted + shell: | + gcloud compute interconnects attachments describe "{{ resource_name }}" --project="{{ gcp_project}}" --region="{{ gcp_region}}" + register: results + failed_when: results.rc == 0 +- name: verify that command succeeded + assert: + that: + - results.rc == 1 + - "\"'projects/{{ gcp_project }}/global/images/{{ resource_name }}' was not found\" in results.stderr" +# ---------------------------------------------------------------------------- +- name: delete a interconnect attachment that does not exist + gcp_compute_interconnect_attachment: + name: "{{ resource_name }}" + region: us-central1 + project: "{{ gcp_project }}" + auth_kind: "{{ gcp_cred_kind }}" + interconnect: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/global/interconnects/... + router: https://googleapis.com/compute/v1/projects/{{ gcp_project }}/regions/us-central1/routers/... + service_account_file: "{{ gcp_cred_file }}" + state: absent + register: disk + register: result +- name: assert changed is false + assert: + that: + - result.changed == false + - result.has_key('kind') == False