diff --git a/lib/ansible/modules/cloud/google/gcp_compute_disk.py b/lib/ansible/modules/cloud/google/gcp_compute_disk.py index dbc414da5d777b..2264094405f7fa 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_disk.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_disk.py @@ -204,6 +204,12 @@ ''' RETURN = ''' + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str creation_timestamp: description: - Creation timestamp in RFC3339 text format. @@ -430,8 +436,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind, fetch) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -455,7 +460,8 @@ def create(module, link, kind): def update(module, link, kind, fetch): - update_fields(module, resource_to_request(module), response_to_hash(module, fetch)) + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) return fetch_resource(module, self_link(module), kind) @@ -469,16 +475,27 @@ def update_fields(module, request, response): def label_fingerprint_update(module, request, response): auth = GcpSession(module, 'compute') auth.post( - ''.join(["https://www.googleapis.com/compute/v1/", "projects/{project}/zones/{zone}/disks/{name}/setLabels"]).format(**module.params), - {u'labelFingerprint': response.get('labelFingerprint'), u'labels': module.params.get('labels')}, + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/zones/{zone}/disks/{name}/setLabels" + ]).format(**module.params), + { + u'labelFingerprint': response.get('labelFingerprint'), + u'labels': module.params.get('labels') + } ) def size_gb_update(module, request, response): auth = GcpSession(module, 'compute') auth.post( - ''.join(["https://www.googleapis.com/compute/v1/", "projects/{project}/zones/{zone}/disks/{name}/resize"]).format(**module.params), - {u'sizeGb': module.params.get('size_gb')}, + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/zones/{zone}/disks/{name}/resize" + ]).format(**module.params), + { + u'sizeGb': module.params.get('size_gb') + } ) diff --git a/lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py index 18922351b760c8..46070647c630a0 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py @@ -65,218 +65,193 @@ ''' RETURN = ''' -resources: - description: List of resources - returned: always - type: complex - contains: - labelFingerprint: - description: - - The fingerprint used for optimistic locking of this resource. Used internally - during updates. - returned: success - type: str - creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str - description: - description: - - An optional description of this resource. Provide this property when you create - the resource. - returned: success - type: str - id: - description: - - The unique identifier for the resource. - returned: success - type: int - lastAttachTimestamp: - description: - - Last attach timestamp in RFC3339 text format. - returned: success - type: str - lastDetachTimestamp: - description: - - Last dettach timestamp in RFC3339 text format. - returned: success - type: str - labels: - description: - - Labels to apply to this disk. A list of key->value pairs. - returned: success - type: dict - licenses: - description: - - Any applicable publicly visible licenses. - returned: success - type: list - 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 - sizeGb: - description: - - Size of the persistent disk, specified in GB. You can specify this field when - creating a persistent disk using the sourceImage or sourceSnapshot parameter, - or specify it alone to create an empty persistent disk. - - If you specify this field along with sourceImage or sourceSnapshot, the value - of sizeGb must not be less than the size of the sourceImage or the size of - the snapshot. - returned: success - type: int - users: - description: - - 'Links to the users of the disk (attached instances) in form: project/zones/zone/instances/instance - .' - returned: success - type: list - physicalBlockSizeBytes: - description: - - Physical block size of the persistent disk, in bytes. If not present in a - request, a default value is used. Currently supported sizes are 4096 and 16384, - other sizes may be added in the future. - - If an unsupported value is requested, the error message will list the supported - values for the caller's project. - returned: success - type: int - type: - description: - - URL of the disk type resource describing which disk type to use to create - the disk. Provide this when creating the disk. - returned: success - type: str - sourceImage: - description: - - The source image used to create this disk. If the source image is deleted, - this field will not be set. - - 'To create a disk with one of the public operating system images, specify - the image by its family name. For example, specify family/debian-8 to use - the latest Debian 8 image: projects/debian-cloud/global/images/family/debian-8 - Alternatively, use a specific version of a public operating system image: - projects/debian-cloud/global/images/debian-8-jessie-vYYYYMMDD To create a - disk with a private image that you created, specify the image name in the - following format: global/images/my-private-image You can also specify a private - image by its image family, which returns the latest version of the image in - that family. Replace the image name with family/family-name: global/images/family/my-private-family - .' - returned: success - type: str - zone: - description: - - A reference to the zone where the disk resides. - returned: success - type: str - sourceImageEncryptionKey: - description: - - The customer-supplied encryption key of the source image. Required if the - source image is protected by a customer-supplied encryption key. - returned: success - type: complex - contains: - rawKey: - description: - - Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 - base64 to either encrypt or decrypt this resource. - returned: success - type: str - sha256: - description: - - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption - key that protects this resource. - returned: success - type: str - kmsKeyName: - description: - - The name of the encryption key that is stored in Google Cloud KMS. - returned: success - type: str - sourceImageId: - description: - - The ID value of the image used to create this disk. This value identifies - the exact image that was used to create this persistent disk. For example, - if you created the persistent disk from an image that was later deleted and - recreated under the same name, the source image ID would identify the exact - version of the image that was used. - returned: success - type: str - diskEncryptionKey: - description: - - Encrypts the disk using a customer-supplied encryption key. - - After you encrypt a disk with a customer-supplied key, you must provide the - same key if you use the disk later (e.g. to create a disk snapshot or an image, - or to attach the disk to a virtual machine). - - Customer-supplied encryption keys do not protect access to metadata of the - disk. - - If you do not provide an encryption key when creating the disk, then the disk - will be encrypted using an automatically generated key and you do not need - to provide a key to use the disk later. - returned: success - type: complex - contains: - rawKey: - description: - - Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 - base64 to either encrypt or decrypt this resource. - returned: success - type: str - sha256: - description: - - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption - key that protects this resource. - returned: success - type: str - kmsKeyName: - description: - - The name of the encryption key that is stored in Google Cloud KMS. - returned: success - type: str - sourceSnapshot: - description: - - The source snapshot used to create this disk. You can provide this as a partial - or full URL to the resource. - returned: success - type: dict - sourceSnapshotEncryptionKey: - description: - - The customer-supplied encryption key of the source snapshot. Required if the - source snapshot is protected by a customer-supplied encryption key. - returned: success - type: complex - contains: - rawKey: - description: - - Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 - base64 to either encrypt or decrypt this resource. - returned: success - type: str - kmsKeyName: - description: - - The name of the encryption key that is stored in Google Cloud KMS. - returned: success - type: str - sha256: - description: - - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption - key that protects this resource. - returned: success - type: str - sourceSnapshotId: - description: - - The unique ID of the snapshot used to create this disk. This value identifies - the exact snapshot that was used to create this persistent disk. For example, - if you created the persistent disk from a snapshot that was later deleted - and recreated under the same name, the source snapshot ID would identify the - exact version of the snapshot that was used. - returned: success - type: str +items: + description: List of items + returned: always + type: complex + contains: + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + description: + description: + - An optional description of this resource. Provide this property when you create + the resource. + returned: success + type: str + id: + description: + - The unique identifier for the resource. + returned: success + type: int + last_attach_timestamp: + description: + - Last attach timestamp in RFC3339 text format. + returned: success + type: str + last_detach_timestamp: + description: + - Last dettach timestamp in RFC3339 text format. + returned: success + type: str + labels: + description: + - Labels to apply to this disk. A list of key->value pairs. + returned: success + type: dict + licenses: + description: + - Any applicable publicly visible licenses. + returned: success + type: list + 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 + size_gb: + description: + - Size of the persistent disk, specified in GB. You can specify this field when creating + a persistent disk using the sourceImage or sourceSnapshot parameter, or specify + it alone to create an empty persistent disk. + - If you specify this field along with sourceImage or sourceSnapshot, the value of + sizeGb must not be less than the size of the sourceImage or the size of the snapshot. + returned: success + type: int + users: + description: + - 'Links to the users of the disk (attached instances) in form: project/zones/zone/instances/instance + .' + returned: success + type: list + type: + description: + - URL of the disk type resource describing which disk type to use to create the disk. + Provide this when creating the disk. + returned: success + type: str + source_image: + description: + - The source image used to create this disk. If the source image is deleted, this + field will not be set. + - 'To create a disk with one of the public operating system images, specify the image + by its family name. For example, specify family/debian-8 to use the latest Debian + 8 image: projects/debian-cloud/global/images/family/debian-8 Alternatively, use + a specific version of a public operating system image: projects/debian-cloud/global/images/debian-8-jessie-vYYYYMMDD To + create a disk with a private image that you created, specify the image name in the + following format: global/images/my-private-image You can also specify a private + image by its image family, which returns the latest version of the image in that + family. Replace the image name with family/family-name: global/images/family/my-private-family + .' + returned: success + type: str + zone: + description: + - A reference to the zone where the disk resides. + returned: success + type: str + source_image_encryption_key: + description: + - The customer-supplied encryption key of the source image. Required if the source + image is protected by a customer-supplied encryption key. + returned: success + type: complex + contains: + raw_key: + description: + - Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64 + to either encrypt or decrypt this resource. + returned: success + type: str + sha256: + description: + - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key + that protects this resource. + returned: success + type: str + source_image_id: + description: + - The ID value of the image used to create this disk. This value identifies the exact + image that was used to create this persistent disk. For example, if you created + the persistent disk from an image that was later deleted and recreated under the + same name, the source image ID would identify the exact version of the image that + was used. + returned: success + type: str + disk_encryption_key: + description: + - Encrypts the disk using a customer-supplied encryption key. + - After you encrypt a disk with a customer-supplied key, you must provide the same + key if you use the disk later (e.g. to create a disk snapshot or an image, or to + attach the disk to a virtual machine). + - Customer-supplied encryption keys do not protect access to metadata of the disk. + - If you do not provide an encryption key when creating the disk, then the disk will + be encrypted using an automatically generated key and you do not need to provide + a key to use the disk later. + returned: success + type: complex + contains: + raw_key: + description: + - Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64 + to either encrypt or decrypt this resource. + returned: success + type: str + sha256: + description: + - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key + that protects this resource. + returned: success + type: str + source_snapshot: + description: + - 'The source snapshot used to create this disk. You can provide this as a partial + or full URL to the resource. For example, the following are valid values: * + `U(https://www.googleapis.com/compute/v1/projects/project/global/snapshots/snapshot`) + * `projects/project/global/snapshots/snapshot` * `global/snapshots/snapshot` .' + returned: success + type: dict + source_snapshot_encryption_key: + description: + - The customer-supplied encryption key of the source snapshot. Required if the source + snapshot is protected by a customer-supplied encryption key. + returned: success + type: complex + contains: + raw_key: + description: + - Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64 + to either encrypt or decrypt this resource. + returned: success + type: str + sha256: + description: + - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key + that protects this resource. + returned: success + type: str + source_snapshot_id: + description: + - The unique ID of the snapshot used to create this disk. This value identifies the + exact snapshot that was used to create this persistent disk. For example, if you + created the persistent disk from a snapshot that was later deleted and recreated + under the same name, the source snapshot ID would identify the exact version of + the snapshot that was used. + returned: success + type: str ''' ################################################################################ diff --git a/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py b/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py index 1f9eafc82618ed..6a743a2ef443dd 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py @@ -263,168 +263,145 @@ ''' RETURN = ''' -creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str -description: - description: - - An optional description of this resource. Provide this property when you create - the resource. - returned: success - type: str -id: - description: - - The unique identifier for the resource. - returned: success - type: int -IPAddress: - description: - - The IP address that this forwarding rule is serving on behalf of. - - Addresses are restricted based on the forwarding rule's load balancing scheme - (EXTERNAL or INTERNAL) and scope (global or regional). - - When the load balancing scheme is EXTERNAL, for global forwarding rules, the address - must be a global IP, and for regional forwarding rules, the address must live - in the same region as the forwarding rule. If this field is empty, an ephemeral - IPv4 address from the same scope (global or regional) will be assigned. A regional - forwarding rule supports IPv4 only. A global forwarding rule supports either IPv4 - or IPv6. - - When the load balancing scheme is INTERNAL, this can only be an RFC 1918 IP address - belonging to the network/subnet configured for the forwarding rule. By default, - if this field is empty, an ephemeral internal IP address will be automatically - allocated from the IP range of the subnet or network configured for this forwarding - rule. - - 'An address can be specified either by a literal IP address or a URL reference - to an existing Address resource. The following examples are all valid: * 100.1.2.3 - * U(https://www.googleapis.com/compute/v1/projects/project/regions/region/addresses/address) - * projects/project/regions/region/addresses/address * regions/region/addresses/address - * global/addresses/address * address .' - returned: success - type: str -IPProtocol: - description: - - The IP protocol to which this rule applies. Valid options are TCP, UDP, ESP, AH, - SCTP or ICMP. - - When the load balancing scheme is INTERNAL, only TCP and UDP are valid. - returned: success - type: str -backendService: - description: - - A BackendService to receive the matched traffic. This is used only for INTERNAL - load balancing. - returned: success - type: dict -ipVersion: - description: - - ipVersion is not a valid field for regional forwarding rules. - returned: success - type: str -loadBalancingScheme: - description: - - 'This signifies what the ForwardingRule will be used for and can only take the - following values: INTERNAL, EXTERNAL The value of INTERNAL means that this will - be used for Internal Network Load Balancing (TCP, UDP). The value of EXTERNAL - means that this will be used for External Load Balancing (HTTP(S) LB, External - TCP/UDP LB, SSL Proxy) .' - 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 -network: - description: - - For internal load balancing, this field identifies the network that the load balanced - IP should belong to for this Forwarding Rule. If this field is not specified, - the default network will be used. - - This field is only used for INTERNAL load balancing. - returned: success - type: dict -portRange: - description: - - This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy, - TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance. - - Applicable only when IPProtocol is TCP, UDP, or SCTP, only packets addressed to - ports in the specified range will be forwarded to target. - - Forwarding rules with the same [IPAddress, IPProtocol] pair must have disjoint - port ranges. - - 'Some types of forwarding target have constraints on the acceptable ports: * TargetHttpProxy: - 80, 8080 * TargetHttpsProxy: 443 * TargetTcpProxy: 25, 43, 110, 143, 195, 443, - 465, 587, 700, 993, 995, 1883, 5222 * TargetSslProxy: 25, 43, 110, 143, 195, 443, - 465, 587, 700, 993, 995, 1883, 5222 * TargetVpnGateway: 500, 4500 .' - returned: success - type: str -ports: - description: - - This field is used along with the backend_service field for internal load balancing. - - When the load balancing scheme is INTERNAL, a single port or a comma separated - list of ports can be configured. Only packets addressed to these ports will be - forwarded to the backends configured with this forwarding rule. - - You may specify a maximum of up to 5 ports. - returned: success - type: list -subnetwork: - description: - - The subnetwork that the load balanced IP should belong to for this Forwarding - Rule. This field is only used for INTERNAL load balancing. - - If the network specified is in auto subnet mode, this field is optional. However, - if the network is in custom subnet mode, a subnetwork must be specified. - returned: success - type: dict -target: - description: - - This field is only used for EXTERNAL load balancing. - - A reference to a TargetPool resource to receive the matched traffic. - - This target must live in the same region as the forwarding rule. - - The forwarded traffic must be of a type appropriate to the target object. - returned: success - type: dict -allPorts: - description: - - For internal TCP/UDP load balancing (i.e. load balancing scheme is INTERNAL and - protocol is TCP/UDP), set this to true to allow packets addressed to any ports - to be forwarded to the backends configured with this forwarding rule. Used with - backend service. Cannot be set if port or portRange are set. - returned: success - type: bool -networkTier: - description: - - 'The networking tier used for configuring this address. This field can take the - following values: PREMIUM or STANDARD. If this field is not specified, it is assumed - to be PREMIUM.' - returned: success - type: str -serviceLabel: - description: - - An optional prefix to the service name for this Forwarding Rule. - - If specified, will be the first label of the fully qualified service name. - - The label must be 1-63 characters long, and comply with RFC1035. - - Specifically, the label 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. - - This field is only used for INTERNAL load balancing. - returned: success - type: str -serviceName: - description: - - The internal fully qualified service name for this Forwarding Rule. - - This field is only used for INTERNAL load balancing. - returned: success - type: str -region: - description: - - A reference to the region where the regional forwarding rule resides. - - This field is not applicable to global forwarding rules. - returned: success - type: str + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + description: + description: + - An optional description of this resource. Provide this property when you create + the resource. + returned: success + type: str + id: + description: + - The unique identifier for the resource. + returned: success + type: int + ip_address: + description: + - The IP address that this forwarding rule is serving on behalf of. + - Addresses are restricted based on the forwarding rule's load balancing scheme (EXTERNAL + or INTERNAL) and scope (global or regional). + - When the load balancing scheme is EXTERNAL, for global forwarding rules, the address + must be a global IP, and for regional forwarding rules, the address must live in + the same region as the forwarding rule. If this field is empty, an ephemeral IPv4 + address from the same scope (global or regional) will be assigned. A regional forwarding + rule supports IPv4 only. A global forwarding rule supports either IPv4 or IPv6. + - When the load balancing scheme is INTERNAL, this can only be an RFC 1918 IP address + belonging to the network/subnet configured for the forwarding rule. By default, + if this field is empty, an ephemeral internal IP address will be automatically allocated + from the IP range of the subnet or network configured for this forwarding rule. + - 'An address can be specified either by a literal IP address or a URL reference to + an existing Address resource. The following examples are all valid: * 100.1.2.3 + * U(https://www.googleapis.com/compute/v1/projects/project/regions/region/addresses/address) + * projects/project/regions/region/addresses/address * regions/region/addresses/address + * global/addresses/address * address .' + returned: success + type: str + ip_protocol: + description: + - The IP protocol to which this rule applies. Valid options are TCP, UDP, ESP, AH, + SCTP or ICMP. + - When the load balancing scheme is INTERNAL, only TCP and UDP are valid. + returned: success + type: str + backend_service: + description: + - A reference to a BackendService to receive the matched traffic. + - This is used for internal load balancing. + - "(not used for external load balancing) ." + returned: success + type: dict + ip_version: + description: + - The IP Version that will be used by this forwarding rule. Valid options are IPV4 + or IPV6. This can only be specified for a global forwarding rule. + returned: success + type: str + load_balancing_scheme: + description: + - 'This signifies what the ForwardingRule will be used for and can only take the following + values: INTERNAL, EXTERNAL The value of INTERNAL means that this will be used for + Internal Network Load Balancing (TCP, UDP). The value of EXTERNAL means that this + will be used for External Load Balancing (HTTP(S) LB, External TCP/UDP LB, SSL Proxy) + .' + 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 + network: + description: + - For internal load balancing, this field identifies the network that the load balanced + IP should belong to for this Forwarding Rule. If this field is not specified, the + default network will be used. + - This field is not used for external load balancing. + returned: success + type: dict + port_range: + description: + - This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy, + TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance. + - Applicable only when IPProtocol is TCP, UDP, or SCTP, only packets addressed to + ports in the specified range will be forwarded to target. + - Forwarding rules with the same [IPAddress, IPProtocol] pair must have disjoint port + ranges. + - 'Some types of forwarding target have constraints on the acceptable ports: * TargetHttpProxy: + 80, 8080 * TargetHttpsProxy: 443 * TargetTcpProxy: 25, 43, 110, 143, 195, 443, 465, + 587, 700, 993, 995, 1883, 5222 * TargetSslProxy: 25, 43, 110, + 143, 195, 443, 465, 587, 700, 993, 995, 1883, 5222 * TargetVpnGateway: + 500, 4500 .' + returned: success + type: str + ports: + description: + - This field is used along with the backend_service field for internal load balancing. + - When the load balancing scheme is INTERNAL, a single port or a comma separated list + of ports can be configured. Only packets addressed to these ports will be forwarded + to the backends configured with this forwarding rule. + - You may specify a maximum of up to 5 ports. + returned: success + type: list + subnetwork: + description: + - A reference to a subnetwork. + - For internal load balancing, this field identifies the subnetwork that the load + balanced IP should belong to for this Forwarding Rule. + - If the network specified is in auto subnet mode, this field is optional. However, + if the network is in custom subnet mode, a subnetwork must be specified. + - This field is not used for external load balancing. + returned: success + type: dict + target: + description: + - A reference to a TargetPool resource to receive the matched traffic. + - For regional forwarding rules, this target must live in the same region as the forwarding + rule. For global forwarding rules, this target must be a global load balancing resource. + The forwarded traffic must be of a type appropriate to the target object. + - This field is not used for internal load balancing. + returned: success + type: dict + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + region: + description: + - A reference to the region where the regional forwarding rule resides. + - This field is not applicable to global forwarding rules. + returned: success + type: str ''' ################################################################################ @@ -477,7 +454,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - fetch = update(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -500,8 +477,41 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="ForwardingRule cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('target') != request.get('target'): + target_update(module, request, response) + + +def target_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/regions/{region}/forwardingRules/{name}/setTarget" + ]).format(**module.params), + { + u'target': replace_resource_dict(module.params.get(u'target', {}), 'selfLink') + } + ) + + +def label_fingerprint_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/regions/{region}/forwardingRules/{name}/setLabels" + ]).format(**module.params), + { + u'labelFingerprint': response.get('labelFingerprint') + } + ) def delete(module, link, kind): @@ -606,10 +616,7 @@ def response_to_hash(module, response): u'ports': response.get(u'ports'), u'subnetwork': response.get(u'subnetwork'), u'target': response.get(u'target'), - u'allPorts': response.get(u'allPorts'), - u'networkTier': module.params.get('network_tier'), - u'serviceLabel': response.get(u'serviceLabel'), - u'serviceName': response.get(u'serviceName'), + u'labelFingerprint': response.get(u'labelFingerprint') } diff --git a/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule_facts.py index 892581f6d08154..d7d5ba370a69af 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule_facts.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule_facts.py @@ -66,175 +66,150 @@ ''' RETURN = ''' -resources: - description: List of resources - returned: always - type: complex - contains: - creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str - description: - description: - - An optional description of this resource. Provide this property when you create - the resource. - returned: success - type: str - id: - description: - - The unique identifier for the resource. - returned: success - type: int - IPAddress: - description: - - The IP address that this forwarding rule is serving on behalf of. - - Addresses are restricted based on the forwarding rule's load balancing scheme - (EXTERNAL or INTERNAL) and scope (global or regional). - - When the load balancing scheme is EXTERNAL, for global forwarding rules, the - address must be a global IP, and for regional forwarding rules, the address - must live in the same region as the forwarding rule. If this field is empty, - an ephemeral IPv4 address from the same scope (global or regional) will be - assigned. A regional forwarding rule supports IPv4 only. A global forwarding - rule supports either IPv4 or IPv6. - - When the load balancing scheme is INTERNAL, this can only be an RFC 1918 IP - address belonging to the network/subnet configured for the forwarding rule. - By default, if this field is empty, an ephemeral internal IP address will - be automatically allocated from the IP range of the subnet or network configured - for this forwarding rule. - - 'An address can be specified either by a literal IP address or a URL reference - to an existing Address resource. The following examples are all valid: * 100.1.2.3 - * U(https://www.googleapis.com/compute/v1/projects/project/regions/region/addresses/address) - * projects/project/regions/region/addresses/address * regions/region/addresses/address - * global/addresses/address * address .' - returned: success - type: str - IPProtocol: - description: - - The IP protocol to which this rule applies. Valid options are TCP, UDP, ESP, - AH, SCTP or ICMP. - - When the load balancing scheme is INTERNAL, only TCP and UDP are valid. - returned: success - type: str - backendService: - description: - - A BackendService to receive the matched traffic. This is used only for INTERNAL - load balancing. - returned: success - type: dict - ipVersion: - description: - - ipVersion is not a valid field for regional forwarding rules. - returned: success - type: str - loadBalancingScheme: - description: - - 'This signifies what the ForwardingRule will be used for and can only take - the following values: INTERNAL, EXTERNAL The value of INTERNAL means that - this will be used for Internal Network Load Balancing (TCP, UDP). The value - of EXTERNAL means that this will be used for External Load Balancing (HTTP(S) - LB, External TCP/UDP LB, SSL Proxy) .' - 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 - network: - description: - - For internal load balancing, this field identifies the network that the load - balanced IP should belong to for this Forwarding Rule. If this field is not - specified, the default network will be used. - - This field is only used for INTERNAL load balancing. - returned: success - type: dict - portRange: - description: - - This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy, - TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance. - - Applicable only when IPProtocol is TCP, UDP, or SCTP, only packets addressed - to ports in the specified range will be forwarded to target. - - Forwarding rules with the same [IPAddress, IPProtocol] pair must have disjoint - port ranges. - - 'Some types of forwarding target have constraints on the acceptable ports: - * TargetHttpProxy: 80, 8080 * TargetHttpsProxy: 443 * TargetTcpProxy: 25, - 43, 110, 143, 195, 443, 465, 587, 700, 993, 995, 1883, 5222 * TargetSslProxy: - 25, 43, 110, 143, 195, 443, 465, 587, 700, 993, 995, 1883, 5222 * TargetVpnGateway: - 500, 4500 .' - returned: success - type: str - ports: - description: - - This field is used along with the backend_service field for internal load - balancing. - - When the load balancing scheme is INTERNAL, a single port or a comma separated - list of ports can be configured. Only packets addressed to these ports will - be forwarded to the backends configured with this forwarding rule. - - You may specify a maximum of up to 5 ports. - returned: success - type: list - subnetwork: - description: - - The subnetwork that the load balanced IP should belong to for this Forwarding - Rule. This field is only used for INTERNAL load balancing. - - If the network specified is in auto subnet mode, this field is optional. However, - if the network is in custom subnet mode, a subnetwork must be specified. - returned: success - type: dict - target: - description: - - This field is only used for EXTERNAL load balancing. - - A reference to a TargetPool resource to receive the matched traffic. - - This target must live in the same region as the forwarding rule. - - The forwarded traffic must be of a type appropriate to the target object. - returned: success - type: dict - allPorts: - description: - - For internal TCP/UDP load balancing (i.e. load balancing scheme is INTERNAL - and protocol is TCP/UDP), set this to true to allow packets addressed to any - ports to be forwarded to the backends configured with this forwarding rule. - Used with backend service. Cannot be set if port or portRange are set. - returned: success - type: bool - networkTier: - description: - - 'The networking tier used for configuring this address. This field can take - the following values: PREMIUM or STANDARD. If this field is not specified, - it is assumed to be PREMIUM.' - returned: success - type: str - serviceLabel: - description: - - An optional prefix to the service name for this Forwarding Rule. - - If specified, will be the first label of the fully qualified service name. - - The label must be 1-63 characters long, and comply with RFC1035. - - Specifically, the label 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. - - This field is only used for INTERNAL load balancing. - returned: success - type: str - serviceName: - description: - - The internal fully qualified service name for this Forwarding Rule. - - This field is only used for INTERNAL load balancing. - returned: success - type: str - region: - description: - - A reference to the region where the regional forwarding rule resides. - - This field is not applicable to global forwarding rules. - returned: success - type: str +items: + description: List of items + returned: always + type: complex + contains: + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + description: + description: + - An optional description of this resource. Provide this property when you create + the resource. + returned: success + type: str + id: + description: + - The unique identifier for the resource. + returned: success + type: int + ip_address: + description: + - The IP address that this forwarding rule is serving on behalf of. + - Addresses are restricted based on the forwarding rule's load balancing scheme (EXTERNAL + or INTERNAL) and scope (global or regional). + - When the load balancing scheme is EXTERNAL, for global forwarding rules, the address + must be a global IP, and for regional forwarding rules, the address must live in + the same region as the forwarding rule. If this field is empty, an ephemeral IPv4 + address from the same scope (global or regional) will be assigned. A regional forwarding + rule supports IPv4 only. A global forwarding rule supports either IPv4 or IPv6. + - When the load balancing scheme is INTERNAL, this can only be an RFC 1918 IP address + belonging to the network/subnet configured for the forwarding rule. By default, + if this field is empty, an ephemeral internal IP address will be automatically allocated + from the IP range of the subnet or network configured for this forwarding rule. + - 'An address can be specified either by a literal IP address or a URL reference to + an existing Address resource. The following examples are all valid: * 100.1.2.3 + * U(https://www.googleapis.com/compute/v1/projects/project/regions/region/addresses/address) + * projects/project/regions/region/addresses/address * regions/region/addresses/address + * global/addresses/address * address .' + returned: success + type: str + ip_protocol: + description: + - The IP protocol to which this rule applies. Valid options are TCP, UDP, ESP, AH, + SCTP or ICMP. + - When the load balancing scheme is INTERNAL, only TCP and UDP are valid. + returned: success + type: str + backend_service: + description: + - A reference to a BackendService to receive the matched traffic. + - This is used for internal load balancing. + - "(not used for external load balancing) ." + returned: success + type: dict + ip_version: + description: + - The IP Version that will be used by this forwarding rule. Valid options are IPV4 + or IPV6. This can only be specified for a global forwarding rule. + returned: success + type: str + load_balancing_scheme: + description: + - 'This signifies what the ForwardingRule will be used for and can only take the following + values: INTERNAL, EXTERNAL The value of INTERNAL means that this will be used for + Internal Network Load Balancing (TCP, UDP). The value of EXTERNAL means that this + will be used for External Load Balancing (HTTP(S) LB, External TCP/UDP LB, SSL Proxy) + .' + 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 + network: + description: + - For internal load balancing, this field identifies the network that the load balanced + IP should belong to for this Forwarding Rule. If this field is not specified, the + default network will be used. + - This field is not used for external load balancing. + returned: success + type: dict + port_range: + description: + - This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy, + TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance. + - Applicable only when IPProtocol is TCP, UDP, or SCTP, only packets addressed to + ports in the specified range will be forwarded to target. + - Forwarding rules with the same [IPAddress, IPProtocol] pair must have disjoint port + ranges. + - 'Some types of forwarding target have constraints on the acceptable ports: * TargetHttpProxy: + 80, 8080 * TargetHttpsProxy: 443 * TargetTcpProxy: 25, 43, 110, 143, 195, 443, 465, + 587, 700, 993, 995, 1883, 5222 * TargetSslProxy: 25, 43, 110, + 143, 195, 443, 465, 587, 700, 993, 995, 1883, 5222 * TargetVpnGateway: + 500, 4500 .' + returned: success + type: str + ports: + description: + - This field is used along with the backend_service field for internal load balancing. + - When the load balancing scheme is INTERNAL, a single port or a comma separated list + of ports can be configured. Only packets addressed to these ports will be forwarded + to the backends configured with this forwarding rule. + - You may specify a maximum of up to 5 ports. + returned: success + type: list + subnetwork: + description: + - A reference to a subnetwork. + - For internal load balancing, this field identifies the subnetwork that the load + balanced IP should belong to for this Forwarding Rule. + - If the network specified is in auto subnet mode, this field is optional. However, + if the network is in custom subnet mode, a subnetwork must be specified. + - This field is not used for external load balancing. + returned: success + type: dict + target: + description: + - A reference to a TargetPool resource to receive the matched traffic. + - For regional forwarding rules, this target must live in the same region as the forwarding + rule. For global forwarding rules, this target must be a global load balancing resource. + The forwarded traffic must be of a type appropriate to the target object. + - This field is not used for internal load balancing. + returned: success + type: dict + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + region: + description: + - A reference to the region where the regional forwarding rule resides. + - This field is not applicable to global forwarding rules. + returned: success + type: str ''' ################################################################################ diff --git a/lib/ansible/modules/cloud/google/gcp_compute_global_address.py b/lib/ansible/modules/cloud/google/gcp_compute_global_address.py index 00bc1af38511d1..00a1d3e3f178f7 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_global_address.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_global_address.py @@ -102,54 +102,54 @@ ''' RETURN = ''' -address: - description: - - The static external IP address represented by this resource. - returned: success - type: str -creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str -description: - description: - - An optional description of this resource. - returned: success - type: str -id: - description: - - The unique identifier for the resource. This identifier is defined by the server. - returned: success - type: int -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 -ipVersion: - description: - - The IP Version that will be used by this address. Valid options are `IPV4` or - `IPV6`. The default value is `IPV4`. - returned: success - type: str -region: - description: - - A reference to the region where the regional address resides. - returned: success - type: str -addressType: - description: - - The type of the address to reserve, default is EXTERNAL. - - "* EXTERNAL indicates public/external single IP address." - - "* INTERNAL indicates internal IP ranges belonging to some network." - returned: success - type: str + address: + description: + - The static external IP address represented by this resource. + returned: success + type: str + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + description: + description: + - An optional description of this resource. + - Provide this property when you create the resource. + returned: success + type: str + id: + description: + - The unique identifier for the resource. This identifier is defined by the server. + returned: success + type: int + 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 + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + ip_version: + description: + - The IP Version that will be used by this address. Valid options are IPV4 or IPV6. + The default value is IPV4. + returned: success + type: str + region: + description: + - A reference to the region where the regional address resides. + returned: success + type: str ''' ################################################################################ @@ -192,8 +192,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -216,8 +215,27 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="GlobalAddress cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + pass + + +def label_fingerprint_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/addresses/{name}/setLabels" + ]).format(**module.params), + { + u'labelFingerprint': response.get('labelFingerprint') + } + ) def delete(module, link, kind): @@ -303,6 +321,7 @@ def response_to_hash(module, response): u'description': response.get(u'description'), u'id': response.get(u'id'), u'name': response.get(u'name'), + u'labelFingerprint': response.get(u'labelFingerprint'), u'ipVersion': response.get(u'ipVersion'), u'region': response.get(u'region'), u'addressType': response.get(u'addressType'), diff --git a/lib/ansible/modules/cloud/google/gcp_compute_global_address_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_global_address_facts.py index 1f4f45d576e01a..18f2507b8a790f 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_global_address_facts.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_global_address_facts.py @@ -60,60 +60,59 @@ ''' RETURN = ''' -resources: - description: List of resources - returned: always - type: complex - contains: - address: - description: - - The static external IP address represented by this resource. - returned: success - type: str - creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str - description: - description: - - An optional description of this resource. - returned: success - type: str - id: - description: - - The unique identifier for the resource. This identifier is defined by the - server. - returned: success - type: int - 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 - ipVersion: - description: - - The IP Version that will be used by this address. Valid options are `IPV4` - or `IPV6`. The default value is `IPV4`. - returned: success - type: str - region: - description: - - A reference to the region where the regional address resides. - returned: success - type: str - addressType: - description: - - The type of the address to reserve, default is EXTERNAL. - - "* EXTERNAL indicates public/external single IP address." - - "* INTERNAL indicates internal IP ranges belonging to some network." - returned: success - type: str +items: + description: List of items + returned: always + type: complex + contains: + address: + description: + - The static external IP address represented by this resource. + returned: success + type: str + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + description: + description: + - An optional description of this resource. + - Provide this property when you create the resource. + returned: success + type: str + id: + description: + - The unique identifier for the resource. This identifier is defined by the server. + returned: success + type: int + 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 + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + ip_version: + description: + - The IP Version that will be used by this address. Valid options are IPV4 or IPV6. + The default value is IPV4. + returned: success + type: str + region: + description: + - A reference to the region where the regional address resides. + returned: success + type: str ''' ################################################################################ diff --git a/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py b/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py index 7b51c29c756014..6244552790c61f 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py @@ -299,8 +299,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind, fetch) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -323,8 +322,43 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="Subnetwork cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('ipCidrRange') != request.get('ipCidrRange'): + ip_cidr_range_update(module, request, response) + if response.get('privateIpGoogleAccess') != request.get('privateIpGoogleAccess'): + private_ip_google_access_update(module, request, response) + + +def ip_cidr_range_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/regions/{region}/subnetworks/{name}/expandIpCidrRange" + ]).format(**module.params), + { + u'ipCidrRange': module.params.get('ip_cidr_range') + } + ) + + +def private_ip_google_access_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/regions/{region}/subnetworks/{name}/setPrivateIpGoogleAccess" + ]).format(**module.params), + { + u'privateIpGoogleAccess': module.params.get('private_ip_google_access') + } + ) def delete(module, link, kind): diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy.py b/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy.py index 16c7533b1ed99c..0ff470169d4416 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy.py @@ -205,8 +205,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind, fetch) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -229,8 +228,28 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="TargetHttpProxy cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('urlMap') != request.get('urlMap'): + url_map_update(module, request, response) + + +def url_map_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/targetHttpProxies/{name}/setUrlMap" + ]).format(**module.params), + { + u'urlMap': replace_resource_dict(module.params.get(u'url_map', {}), 'selfLink') + } + ) def delete(module, link, kind): diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy.py b/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy.py index 4a554172d8e78d..f7641965dc77a1 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy.py @@ -285,8 +285,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind, fetch) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -309,8 +308,58 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="TargetHttpsProxy cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('quicOverride') != request.get('quicOverride'): + quic_override_update(module, request, response) + if response.get('sslCertificates') != request.get('sslCertificates'): + ssl_certificates_update(module, request, response) + if response.get('urlMap') != request.get('urlMap'): + url_map_update(module, request, response) + + +def quic_override_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/targetHttpsProxies/{name}/setQuicOverride" + ]).format(**module.params), + { + u'quicOverride': module.params.get('quic_override') + } + ) + + +def ssl_certificates_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/targetHttpsProxies/{name}/setSslCertificates" + ]).format(**module.params), + { + u'sslCertificates': replace_resource_dict(module.params.get('ssl_certificates', []), 'selfLink') + } + ) + + +def url_map_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/targetHttpsProxies/{name}/setUrlMap" + ]).format(**module.params), + { + u'urlMap': replace_resource_dict(module.params.get(u'url_map', {}), 'selfLink') + } + ) def delete(module, link, kind): diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy.py b/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy.py index 3e57836f677ccf..061300901bbd20 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy.py @@ -270,8 +270,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind, fetch) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -294,8 +293,58 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="TargetSslProxy cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('proxyHeader') != request.get('proxyHeader'): + proxy_header_update(module, request, response) + if response.get('service') != request.get('service'): + service_update(module, request, response) + if response.get('sslCertificates') != request.get('sslCertificates'): + ssl_certificates_update(module, request, response) + + +def proxy_header_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/targetSslProxies/{name}/setProxyHeader" + ]).format(**module.params), + { + u'proxyHeader': module.params.get('proxy_header') + } + ) + + +def service_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/targetSslProxies/{name}/setBackendService" + ]).format(**module.params), + { + u'service': replace_resource_dict(module.params.get(u'service', {}), 'selfLink') + } + ) + + +def ssl_certificates_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/targetSslProxies/{name}/setSslCertificates" + ]).format(**module.params), + { + u'sslCertificates': replace_resource_dict(module.params.get('ssl_certificates', []), 'selfLink') + } + ) def delete(module, link, kind): diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy.py b/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy.py index 68954460dd7e78..16e100ddae21f1 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy.py @@ -214,7 +214,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - fetch = update(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -237,8 +237,43 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="TargetTcpProxy cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('proxyHeader') != request.get('proxyHeader'): + proxy_header_update(module, request, response) + if response.get('service') != request.get('service'): + service_update(module, request, response) + + +def proxy_header_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/targetTcpProxies/{name}/setProxyHeader" + ]).format(**module.params), + { + u'proxyHeader': module.params.get('proxy_header') + } + ) + + +def service_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/global/targetTcpProxies/{name}/setBackendService" + ]).format(**module.params), + { + u'service': replace_resource_dict(module.params.get(u'service', {}), 'selfLink') + } + ) def delete(module, link, kind): diff --git a/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py b/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py index ec7be3db0500e5..a23cee5fa833b1 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py @@ -171,78 +171,89 @@ ''' RETURN = ''' -creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str -name: - description: - - Name of the resource. 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 -description: - description: - - An optional description of this resource. - returned: success - type: str -targetVpnGateway: - description: - - URL of the Target VPN gateway with which this VPN tunnel is associated. - returned: success - type: dict -router: - description: - - URL of router resource to be used for dynamic routing. - returned: success - type: dict -peerIp: - description: - - IP address of the peer VPN gateway. Only IPv4 is supported. - returned: success - type: str -sharedSecret: - description: - - Shared secret used to set the secure session between the Cloud VPN gateway and - the peer VPN gateway. - returned: success - type: str -sharedSecretHash: - description: - - Hash of the shared secret. - returned: success - type: str -ikeVersion: - description: - - IKE protocol version to use when establishing the VPN tunnel with peer VPN gateway. - - Acceptable IKE versions are 1 or 2. Default version is 2. - returned: success - type: int -localTrafficSelector: - description: - - Local traffic selector to use when establishing the VPN tunnel with peer VPN gateway. - The value should be a CIDR formatted string, for example `192.168.0.0/16`. The - ranges should be disjoint. - - Only IPv4 is supported. - returned: success - type: list -remoteTrafficSelector: - description: - - Remote traffic selector to use when establishing the VPN tunnel with peer VPN - gateway. The value should be a CIDR formatted string, for example `192.168.0.0/16`. - The ranges should be disjoint. - - Only IPv4 is supported. - returned: success - type: list -region: - description: - - The region where the tunnel is located. - returned: success - type: str + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + name: + description: + - Name of the resource. 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 + description: + description: + - An optional description of this resource. + returned: success + type: str + target_vpn_gateway: + description: + - URL of the Target VPN gateway with which this VPN tunnel is associated. + returned: success + type: dict + router: + description: + - URL of router resource to be used for dynamic routing. + returned: success + type: str + peer_ip: + description: + - IP address of the peer VPN gateway. Only IPv4 is supported. + returned: success + type: str + shared_secret: + description: + - Shared secret used to set the secure session between the Cloud VPN gateway and the + peer VPN gateway. + returned: success + type: str + shared_secret_hash: + description: + - Hash of the shared secret. + returned: success + type: str + ike_version: + description: + - IKE protocol version to use when establishing the VPN tunnel with peer VPN gateway. + - Acceptable IKE versions are 1 or 2. Default version is 2. + returned: success + type: int + local_traffic_selector: + description: + - Local traffic selector to use when establishing the VPN tunnel with peer VPN gateway. + The value should be a CIDR formatted string, for example `192.168.0.0/16`. The ranges + should be disjoint. + - Only IPv4 is supported. + returned: success + type: list + remote_traffic_selector: + description: + - Remote traffic selector to use when establishing the VPN tunnel with peer VPN gateway. + The value should be a CIDR formatted string, for example `192.168.0.0/16`. The ranges + should be disjoint. + - Only IPv4 is supported. + returned: success + type: list + labels: + description: + - Labels to apply to this VpnTunnel. + returned: success + type: dict + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + region: + description: + - The region where the tunnel is located. + returned: success + type: str ''' ################################################################################ @@ -289,8 +300,7 @@ def main(): if fetch: if state == 'present': if is_different(module, fetch): - update(module, self_link(module), kind) - fetch = fetch_resource(module, self_link(module), kind) + fetch = update(module, self_link(module), kind, fetch) changed = True else: delete(module, self_link(module), kind) @@ -299,6 +309,7 @@ def main(): else: if state == 'present': fetch = create(module, collection(module), kind) + labels_update(module, module.params, fetch) changed = True else: fetch = {} @@ -313,8 +324,29 @@ def create(module, link, kind): return wait_for_operation(module, auth.post(link, resource_to_request(module))) -def update(module, link, kind): - module.fail_json(msg="VpnTunnel cannot be edited") +def update(module, link, kind, fetch): + update_fields(module, resource_to_request(module), + response_to_hash(module, fetch)) + return fetch_resource(module, self_link(module), kind) + + +def update_fields(module, request, response): + if response.get('labels') != request.get('labels'): + labels_update(module, request, response) + + +def labels_update(module, request, response): + auth = GcpSession(module, 'compute') + auth.post( + ''.join([ + "https://www.googleapis.com/compute/v1/", + "projects/{project}/regions/{region}/vpnTunnels/{name}/setLabels" + ]).format(**module.params), + { + u'labels': module.params.get('labels'), + u'labelFingerprint': response.get('labelFingerprint') + } + ) def delete(module, link, kind): @@ -410,6 +442,8 @@ def response_to_hash(module, response): u'ikeVersion': response.get(u'ikeVersion'), u'localTrafficSelector': response.get(u'localTrafficSelector'), u'remoteTrafficSelector': response.get(u'remoteTrafficSelector'), + u'labels': response.get(u'labels'), + u'labelFingerprint': response.get(u'labelFingerprint') } diff --git a/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel_facts.py index e67c1b4e0402f6..1348de133ef3ea 100644 --- a/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel_facts.py +++ b/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel_facts.py @@ -66,83 +66,93 @@ RETURN = ''' items: - description: List of items - returned: always - type: complex - contains: - creationTimestamp: - description: - - Creation timestamp in RFC3339 text format. - returned: success - type: str - name: - description: - - Name of the resource. 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 - description: - description: - - An optional description of this resource. - returned: success - type: str - targetVpnGateway: - description: - - URL of the Target VPN gateway with which this VPN tunnel is associated. - returned: success - type: dict - router: - description: - - URL of router resource to be used for dynamic routing. - returned: success - type: dict - peerIp: - description: - - IP address of the peer VPN gateway. Only IPv4 is supported. - returned: success - type: str - sharedSecret: - description: - - Shared secret used to set the secure session between the Cloud VPN gateway - and the peer VPN gateway. - returned: success - type: str - sharedSecretHash: - description: - - Hash of the shared secret. - returned: success - type: str - ikeVersion: - description: - - IKE protocol version to use when establishing the VPN tunnel with peer VPN - gateway. - - Acceptable IKE versions are 1 or 2. Default version is 2. - returned: success - type: int - localTrafficSelector: - description: - - Local traffic selector to use when establishing the VPN tunnel with peer VPN - gateway. The value should be a CIDR formatted string, for example `192.168.0.0/16`. - The ranges should be disjoint. - - Only IPv4 is supported. - returned: success - type: list - remoteTrafficSelector: - description: - - Remote traffic selector to use when establishing the VPN tunnel with peer - VPN gateway. The value should be a CIDR formatted string, for example `192.168.0.0/16`. - The ranges should be disjoint. - - Only IPv4 is supported. - returned: success - type: list - region: - description: - - The region where the tunnel is located. - returned: success - type: str + description: List of items + returned: always + type: complex + contains: + creation_timestamp: + description: + - Creation timestamp in RFC3339 text format. + returned: success + type: str + name: + description: + - Name of the resource. 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 + description: + description: + - An optional description of this resource. + returned: success + type: str + target_vpn_gateway: + description: + - URL of the Target VPN gateway with which this VPN tunnel is associated. + returned: success + type: dict + router: + description: + - URL of router resource to be used for dynamic routing. + returned: success + type: str + peer_ip: + description: + - IP address of the peer VPN gateway. Only IPv4 is supported. + returned: success + type: str + shared_secret: + description: + - Shared secret used to set the secure session between the Cloud VPN gateway and the + peer VPN gateway. + returned: success + type: str + shared_secret_hash: + description: + - Hash of the shared secret. + returned: success + type: str + ike_version: + description: + - IKE protocol version to use when establishing the VPN tunnel with peer VPN gateway. + - Acceptable IKE versions are 1 or 2. Default version is 2. + returned: success + type: int + local_traffic_selector: + description: + - Local traffic selector to use when establishing the VPN tunnel with peer VPN gateway. + The value should be a CIDR formatted string, for example `192.168.0.0/16`. The ranges + should be disjoint. + - Only IPv4 is supported. + returned: success + type: list + remote_traffic_selector: + description: + - Remote traffic selector to use when establishing the VPN tunnel with peer VPN gateway. + The value should be a CIDR formatted string, for example `192.168.0.0/16`. The ranges + should be disjoint. + - Only IPv4 is supported. + returned: success + type: list + labels: + description: + - Labels to apply to this VpnTunnel. + returned: success + type: dict + label_fingerprint: + description: + - The fingerprint used for optimistic locking of this resource. Used internally during + updates. + returned: success + type: str + region: + description: + - The region where the tunnel is located. + returned: success + type: str ''' ################################################################################