summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/cloud/google
diff options
context:
space:
mode:
authorRyan Brown <sb@ryansb.com>2018-10-18 10:55:42 -0400
committerGitHub <noreply@github.com>2018-10-18 10:55:42 -0400
commit18a088c64e4dc27955d18128a9978a9e24f63fb1 (patch)
tree3574d12d9994a1a6113c68132e6328c4d2150eed /lib/ansible/modules/cloud/google
parent3b5471a7348d16bff24aa376285b5d1cbbd88ec9 (diff)
downloadansible-18a088c64e4dc27955d18128a9978a9e24f63fb1.tar.gz
GCP MagicModules bug fixes (#47285)
Closes: #46930 #46929 #46928 #46927 #46926 #46925 #46924 #46923 #46922 #46921 #46920 #46919 #46918 #46917 #46916 #46915 #46914 #46913 #46912 #46911 #46910 #46909 #46908 #46907 #46906 #46905 #46903 #46902 #46901 #46900 #46899 #46898 #46897 #46896 #46895 #46894 #46893 #46892 #46891 #46890 #46889 #46888 #46887 #46886 #46885 #46884 #46883 #46882 #46881 #46880 #46879 #46878 #46877 #46876 #46875 #46874 #46873 #46872 #46871 #46870 #46869 #46868 #46867 #46866 #46865 #46864 #46863 #46862 #46861 #46860 #46859 #46858 #46857 #46856 #46855 #46854 #46853 #46852
Diffstat (limited to 'lib/ansible/modules/cloud/google')
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_address.py45
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_address_facts.py13
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_backend_bucket.py21
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_backend_bucket_facts.py10
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_backend_service.py72
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_backend_service_facts.py83
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_disk.py111
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py36
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_firewall.py253
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_firewall_facts.py89
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py114
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule_facts.py29
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_global_address.py73
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_global_address_facts.py21
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule.py44
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule_facts.py18
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_health_check.py98
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_health_check_facts.py42
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_http_health_check.py27
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_http_health_check_facts.py16
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_https_health_check.py27
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_https_health_check_facts.py16
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_image.py48
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_image_facts.py32
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance.py128
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_facts.py66
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_group.py117
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_group_facts.py15
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager.py38
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager_facts.py20
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_template.py100
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_instance_template_facts.py60
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_network.py140
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_network_facts.py23
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_route.py35
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_route_facts.py16
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_router.py28
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_router_facts.py10
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate.py42
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate_facts.py10
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_ssl_policy.py23
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_ssl_policy_facts.py12
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py189
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_subnetwork_facts.py44
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy.py47
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy_facts.py8
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy.py81
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy_facts.py12
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_pool.py35
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_pool_facts.py12
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy_facts.py10
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy.py62
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy_facts.py8
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway.py27
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway_facts.py6
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_url_map.py94
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_url_map_facts.py24
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py83
-rw-r--r--lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel_facts.py26
-rw-r--r--lib/ansible/modules/cloud/google/gcp_container_cluster.py65
-rw-r--r--lib/ansible/modules/cloud/google/gcp_container_node_pool.py44
-rw-r--r--lib/ansible/modules/cloud/google/gcp_dns_managed_zone.py23
-rw-r--r--lib/ansible/modules/cloud/google/gcp_dns_resource_record_set.py26
-rw-r--r--lib/ansible/modules/cloud/google/gcp_pubsub_subscription.py26
-rw-r--r--lib/ansible/modules/cloud/google/gcp_pubsub_topic.py13
-rw-r--r--lib/ansible/modules/cloud/google/gcp_spanner_database.py20
-rw-r--r--lib/ansible/modules/cloud/google/gcp_spanner_instance.py17
-rw-r--r--lib/ansible/modules/cloud/google/gcp_sql_database.py16
-rw-r--r--lib/ansible/modules/cloud/google/gcp_sql_instance.py91
-rw-r--r--lib/ansible/modules/cloud/google/gcp_sql_user.py16
-rw-r--r--lib/ansible/modules/cloud/google/gcp_storage_bucket.py73
-rw-r--r--lib/ansible/modules/cloud/google/gcp_storage_bucket_access_control.py26
72 files changed, 2378 insertions, 1067 deletions
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_address.py b/lib/ansible/modules/cloud/google/gcp_compute_address.py
index c7d40c9838..7ac0cbec69 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_address.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_address.py
@@ -81,11 +81,24 @@ options:
letter, and all following characters must be a dash, lowercase letter, or digit,
except the last character, which cannot be a dash.
required: true
+ network_tier:
+ 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.'
+ required: false
+ version_added: 2.8
+ choices: ['PREMIUM', 'STANDARD']
subnetwork:
description:
- The URL of the subnetwork in which to reserve the address. If an IP address is specified,
it must be within the subnetwork's IP range.
- This field can only be used with INTERNAL type with GCE_ENDPOINT/DNS_RESOLVER purposes.
+ - 'This field represents a link to a Subnetwork resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_subnetwork
+ task and then set this subnetwork field to "{{ name-of-resource }}" Alternatively,
+ you can set this subnetwork to a dictionary with the selfLink key where the value
+ is the selfLink of your Subnetwork.'
required: false
version_added: 2.7
region:
@@ -106,7 +119,7 @@ EXAMPLES = '''
name: test-address1
region: us-west1
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -119,13 +132,13 @@ RETURN = '''
be inside the specified subnetwork, if any.
returned: success
type: str
- address_type:
+ addressType:
description:
- The type of address to reserve, either INTERNAL or EXTERNAL.
- If unspecified, defaults to EXTERNAL.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -149,6 +162,13 @@ RETURN = '''
except the last character, which cannot be a dash.
returned: success
type: str
+ 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
subnetwork:
description:
- The URL of the subnetwork in which to reserve the address. If an IP address is specified,
@@ -192,6 +212,7 @@ def main():
address_type=dict(default='EXTERNAL', type='str', choices=['INTERNAL', 'EXTERNAL']),
description=dict(type='str'),
name=dict(required=True, type='str'),
+ network_tier=dict(type='str', choices=['PREMIUM', 'STANDARD']),
subnetwork=dict(type='dict'),
region=dict(required=True, type='str')
)
@@ -209,7 +230,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -233,8 +255,7 @@ def create(module, link, kind):
def update(module, link, kind):
- auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ module.fail_json(msg="Address cannot be edited")
def delete(module, link, kind):
@@ -249,6 +270,7 @@ def resource_to_request(module):
u'addressType': module.params.get('address_type'),
u'description': module.params.get('description'),
u'name': module.params.get('name'),
+ u'networkTier': module.params.get('network_tier'),
u'subnetwork': replace_resource_dict(module.params.get(u'subnetwork', {}), 'selfLink')
}
return_vals = {}
@@ -259,9 +281,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -272,9 +294,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/addresses".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -289,8 +311,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -323,6 +343,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'networkTier': response.get(u'networkTier'),
u'subnetwork': response.get(u'subnetwork'),
u'users': response.get(u'users')
}
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_address_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_address_facts.py
index a011ffc904..4e6ed2792d 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_address_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_address_facts.py
@@ -62,7 +62,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -79,13 +79,13 @@ items:
be inside the specified subnetwork, if any.
returned: success
type: str
- address_type:
+ addressType:
description:
- The type of address to reserve, either INTERNAL or EXTERNAL.
- If unspecified, defaults to EXTERNAL.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -109,6 +109,13 @@ items:
except the last character, which cannot be a dash.
returned: success
type: str
+ 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
subnetwork:
description:
- The URL of the subnetwork in which to reserve the address. If an IP address is specified,
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket.py b/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket.py
index 8cd3e41955..0ef41ad3c8 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket.py
@@ -96,18 +96,18 @@ EXAMPLES = '''
description: A BackendBucket to connect LNB w/ Storage Bucket
enable_cdn: true
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- bucket_name:
+ bucketName:
description:
- Cloud Storage bucket name.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -118,7 +118,7 @@ RETURN = '''
resource is created.
returned: success
type: str
- enable_cdn:
+ enableCdn:
description:
- If true, enable Cloud CDN for this BackendBucket.
returned: success
@@ -178,7 +178,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -227,9 +228,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -240,9 +241,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/backendBuckets".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -257,8 +258,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket_facts.py
index 6686db14d9..29a7dea603 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_backend_bucket_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,12 +66,12 @@ items:
returned: always
type: complex
contains:
- bucket_name:
+ bucketName:
description:
- Cloud Storage bucket name.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -82,7 +82,7 @@ items:
resource is created.
returned: success
type: str
- enable_cdn:
+ enableCdn:
description:
- If true, enable Cloud CDN for this BackendBucket.
returned: success
@@ -118,7 +118,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_backend_service.py b/lib/ansible/modules/cloud/google/gcp_compute_backend_service.py
index e5a796f3f3..56c77ac556 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_backend_service.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_backend_service.py
@@ -89,6 +89,11 @@ options:
- No two backends in a backend service are allowed to use same Instance Group resource.
- When the BackendService has load balancing scheme INTERNAL, the instance group must
be in a zone within the same region as the BackendService.
+ - 'This field represents a link to a InstanceGroup resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_instance_group
+ task and then set this group field to "{{ name-of-resource }}" Alternatively, you
+ can set this group to a dictionary with the selfLink key where the value is the
+ selfLink of your InstanceGroup.'
required: false
max_connections:
description:
@@ -305,13 +310,13 @@ EXAMPLES = '''
- "{{ healthcheck.selfLink }}"
enable_cdn: true
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- affinity_cookie_ttl_sec:
+ affinityCookieTtlSec:
description:
- Lifetime of cookies in seconds if session_affinity is GENERATED_COOKIE. If set to
0, the cookie is non-persistent and lasts only until the end of the browser session
@@ -325,7 +330,7 @@ RETURN = '''
returned: success
type: complex
contains:
- balancing_mode:
+ balancingMode:
description:
- Specifies the balancing mode for this backend.
- For global HTTP(S) or TCP/SSL load balancing, the default is UTILIZATION. Valid
@@ -333,7 +338,7 @@ RETURN = '''
- This cannot be used for internal load balancing.
returned: success
type: str
- capacity_scaler:
+ capacityScaler:
description:
- A multiplier applied to the group's maximum servicing capacity (based on UTILIZATION,
RATE or CONNECTION).
@@ -359,7 +364,7 @@ RETURN = '''
be in a zone within the same region as the BackendService.
returned: success
type: dict
- max_connections:
+ maxConnections:
description:
- The max number of simultaneous connections for the group. Can be used with either
CONNECTION or UTILIZATION balancing modes.
@@ -368,7 +373,7 @@ RETURN = '''
- This cannot be used for internal load balancing.
returned: success
type: int
- max_connections_per_instance:
+ maxConnectionsPerInstance:
description:
- The max number of simultaneous connections that a single backend instance can handle.
This is used to calculate the capacity of the group. Can be used in either CONNECTION
@@ -378,7 +383,7 @@ RETURN = '''
- This cannot be used for internal load balancing.
returned: success
type: int
- max_rate:
+ maxRate:
description:
- The max requests per second (RPS) of the group.
- Can be used with either RATE or UTILIZATION balancing modes, but required if RATE
@@ -386,7 +391,7 @@ RETURN = '''
- This cannot be used for internal load balancing.
returned: success
type: int
- max_rate_per_instance:
+ maxRatePerInstance:
description:
- The max requests per second (RPS) that a single backend instance can handle. This
is used to calculate the capacity of the group. Can be used in either balancing
@@ -394,43 +399,43 @@ RETURN = '''
- This cannot be used for internal load balancing.
returned: success
type: str
- max_utilization:
+ maxUtilization:
description:
- Used when balancingMode is UTILIZATION. This ratio defines the CPU utilization target
for the group. The default is 0.8. Valid range is [0.0, 1.0].
- This cannot be used for internal load balancing.
returned: success
type: str
- cdn_policy:
+ cdnPolicy:
description:
- Cloud CDN configuration for this BackendService.
returned: success
type: complex
contains:
- cache_key_policy:
+ cacheKeyPolicy:
description:
- The CacheKeyPolicy for this CdnPolicy.
returned: success
type: complex
contains:
- include_host:
+ includeHost:
description:
- If true requests to different hosts will be cached separately.
returned: success
type: bool
- include_protocol:
+ includeProtocol:
description:
- If true, http and https requests will be cached separately.
returned: success
type: bool
- include_query_string:
+ includeQueryString:
description:
- If true, include query string parameters in the cache key according to query_string_whitelist
and query_string_blacklist. If neither is set, the entire query string will be included.
- If false, the query string will be excluded from the cache key entirely.
returned: success
type: bool
- query_string_blacklist:
+ queryStringBlacklist:
description:
- Names of query string parameters to exclude in cache keys.
- All other parameters will be included. Either specify query_string_whitelist or
@@ -438,7 +443,7 @@ RETURN = '''
- "'&' and '=' will be percent encoded and not treated as delimiters."
returned: success
type: list
- query_string_whitelist:
+ queryStringWhitelist:
description:
- Names of query string parameters to include in cache keys.
- All other parameters will be excluded. Either specify query_string_whitelist or
@@ -446,19 +451,19 @@ RETURN = '''
- "'&' and '=' will be percent encoded and not treated as delimiters."
returned: success
type: list
- connection_draining:
+ connectionDraining:
description:
- Settings for connection draining.
returned: success
type: complex
contains:
- draining_timeout_sec:
+ drainingTimeoutSec:
description:
- Time for which instance will be drained (not accept new connections, but still work
to finish started).
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -468,13 +473,13 @@ RETURN = '''
- An optional description of this resource.
returned: success
type: str
- enable_cdn:
+ enableCDN:
description:
- If true, enable Cloud CDN for this BackendService.
- When the load balancing scheme is INTERNAL, this field is not used.
returned: success
type: bool
- health_checks:
+ healthChecks:
description:
- The list of URLs to the HttpHealthCheck or HttpsHealthCheck resource for health
checking this BackendService. Currently at most one health check can be specified,
@@ -498,22 +503,22 @@ RETURN = '''
- Enables IAP.
returned: success
type: bool
- oauth2_client_id:
+ oauth2ClientId:
description:
- OAuth2 Client ID for IAP.
returned: success
type: str
- oauth2_client_secret:
+ oauth2ClientSecret:
description:
- OAuth2 Client Secret for IAP.
returned: success
type: str
- oauth2_client_secret_sha256:
+ oauth2ClientSecretSha256:
description:
- OAuth2 Client Secret SHA-256 for IAP.
returned: success
type: str
- load_balancing_scheme:
+ loadBalancingScheme:
description:
- Indicates whether the backend service will be used with internal or external load
balancing. A backend service created for one type of load balancing cannot be used
@@ -530,7 +535,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- port_name:
+ portName:
description:
- Name of backend port. The same name should appear in the instance groups referenced
by this service. Required when the load balancing scheme is EXTERNAL.
@@ -551,7 +556,7 @@ RETURN = '''
- This field is not applicable to global backend services.
returned: success
type: str
- session_affinity:
+ sessionAffinity:
description:
- Type of session affinity to use. The default is NONE.
- When the load balancing scheme is EXTERNAL, can be NONE, CLIENT_IP, or GENERATED_COOKIE.
@@ -560,7 +565,7 @@ RETURN = '''
- When the protocol is UDP, this field is not used.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How many seconds to wait for the backend before considering it a failed request.
Default is 30 seconds. Valid range is [1, 86400].
@@ -643,7 +648,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -703,9 +709,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -716,9 +722,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/backendServices".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_backend_service_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_backend_service_facts.py
index 614f4f2d7a..c303c75686 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_backend_service_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_backend_service_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- affinity_cookie_ttl_sec:
+ affinityCookieTtlSec:
description:
- Lifetime of cookies in seconds if session_affinity is GENERATED_COOKIE. If set to
0, the cookie is non-persistent and lasts only until the end of the browser session
@@ -80,7 +80,7 @@ items:
returned: success
type: complex
contains:
- balancing_mode:
+ balancingMode:
description:
- Specifies the balancing mode for this backend.
- For global HTTP(S) or TCP/SSL load balancing, the default is UTILIZATION. Valid
@@ -88,7 +88,7 @@ items:
- This cannot be used for internal load balancing.
returned: success
type: str
- capacity_scaler:
+ capacityScaler:
description:
- A multiplier applied to the group's maximum servicing capacity (based on UTILIZATION,
RATE or CONNECTION).
@@ -114,7 +114,7 @@ items:
be in a zone within the same region as the BackendService.
returned: success
type: dict
- max_connections:
+ maxConnections:
description:
- The max number of simultaneous connections for the group. Can be used with either
CONNECTION or UTILIZATION balancing modes.
@@ -123,7 +123,7 @@ items:
- This cannot be used for internal load balancing.
returned: success
type: int
- max_connections_per_instance:
+ maxConnectionsPerInstance:
description:
- The max number of simultaneous connections that a single backend instance can handle.
This is used to calculate the capacity of the group. Can be used in either CONNECTION
@@ -133,7 +133,7 @@ items:
- This cannot be used for internal load balancing.
returned: success
type: int
- max_rate:
+ maxRate:
description:
- The max requests per second (RPS) of the group.
- Can be used with either RATE or UTILIZATION balancing modes, but required if RATE
@@ -141,7 +141,7 @@ items:
- This cannot be used for internal load balancing.
returned: success
type: int
- max_rate_per_instance:
+ maxRatePerInstance:
description:
- The max requests per second (RPS) that a single backend instance can handle. This
is used to calculate the capacity of the group. Can be used in either balancing
@@ -149,43 +149,43 @@ items:
- This cannot be used for internal load balancing.
returned: success
type: str
- max_utilization:
+ maxUtilization:
description:
- Used when balancingMode is UTILIZATION. This ratio defines the CPU utilization target
for the group. The default is 0.8. Valid range is [0.0, 1.0].
- This cannot be used for internal load balancing.
returned: success
type: str
- cdn_policy:
+ cdnPolicy:
description:
- Cloud CDN configuration for this BackendService.
returned: success
type: complex
contains:
- cache_key_policy:
+ cacheKeyPolicy:
description:
- The CacheKeyPolicy for this CdnPolicy.
returned: success
type: complex
contains:
- include_host:
+ includeHost:
description:
- If true requests to different hosts will be cached separately.
returned: success
type: bool
- include_protocol:
+ includeProtocol:
description:
- If true, http and https requests will be cached separately.
returned: success
type: bool
- include_query_string:
+ includeQueryString:
description:
- If true, include query string parameters in the cache key according to query_string_whitelist
and query_string_blacklist. If neither is set, the entire query string will be included.
- If false, the query string will be excluded from the cache key entirely.
returned: success
type: bool
- query_string_blacklist:
+ queryStringBlacklist:
description:
- Names of query string parameters to exclude in cache keys.
- All other parameters will be included. Either specify query_string_whitelist or
@@ -193,7 +193,7 @@ items:
- "'&' and '=' will be percent encoded and not treated as delimiters."
returned: success
type: list
- query_string_whitelist:
+ queryStringWhitelist:
description:
- Names of query string parameters to include in cache keys.
- All other parameters will be excluded. Either specify query_string_whitelist or
@@ -201,19 +201,19 @@ items:
- "'&' and '=' will be percent encoded and not treated as delimiters."
returned: success
type: list
- connection_draining:
+ connectionDraining:
description:
- Settings for connection draining.
returned: success
type: complex
contains:
- draining_timeout_sec:
+ drainingTimeoutSec:
description:
- Time for which instance will be drained (not accept new connections, but still work
to finish started).
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -223,13 +223,13 @@ items:
- An optional description of this resource.
returned: success
type: str
- enable_cdn:
+ enableCDN:
description:
- If true, enable Cloud CDN for this BackendService.
- When the load balancing scheme is INTERNAL, this field is not used.
returned: success
type: bool
- health_checks:
+ healthChecks:
description:
- The list of URLs to the HttpHealthCheck or HttpsHealthCheck resource for health
checking this BackendService. Currently at most one health check can be specified,
@@ -242,6 +242,39 @@ items:
- The unique identifier for the resource.
returned: success
type: int
+ iap:
+ description:
+ - Settings for enabling Cloud Identity Aware Proxy.
+ returned: success
+ type: complex
+ contains:
+ enabled:
+ description:
+ - Enables IAP.
+ returned: success
+ type: bool
+ oauth2ClientId:
+ description:
+ - OAuth2 Client ID for IAP.
+ returned: success
+ type: str
+ oauth2ClientSecret:
+ description:
+ - OAuth2 Client Secret for IAP.
+ returned: success
+ type: str
+ oauth2ClientSecretSha256:
+ description:
+ - OAuth2 Client Secret SHA-256 for IAP.
+ returned: success
+ type: str
+ loadBalancingScheme:
+ description:
+ - Indicates whether the backend service will be used with internal or external load
+ balancing. A backend service created for one type of load balancing cannot be used
+ with the other.
+ returned: success
+ type: str
name:
description:
- Name of the resource. Provided by the client when the resource is created. The name
@@ -252,7 +285,7 @@ items:
be a dash.
returned: success
type: str
- port_name:
+ portName:
description:
- Name of backend port. The same name should appear in the instance groups referenced
by this service. Required when the load balancing scheme is EXTERNAL.
@@ -273,7 +306,7 @@ items:
- This field is not applicable to global backend services.
returned: success
type: str
- session_affinity:
+ sessionAffinity:
description:
- Type of session affinity to use. The default is NONE.
- When the load balancing scheme is EXTERNAL, can be NONE, CLIENT_IP, or GENERATED_COOKIE.
@@ -282,7 +315,7 @@ items:
- When the protocol is UDP, this field is not used.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How many seconds to wait for the backend before considering it a failed request.
Default is 30 seconds. Valid range is [1, 86400].
@@ -304,7 +337,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_disk.py b/lib/ansible/modules/cloud/google/gcp_compute_disk.py
index 8dfc0d1ed1..ff840386d2 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_disk.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_disk.py
@@ -155,6 +155,11 @@ options:
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` .'
+ - 'This field represents a link to a Snapshot resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_snapshot
+ task and then set this source_snapshot field to "{{ name-of-resource }}" Alternatively,
+ you can set this source_snapshot to a dictionary with the selfLink key where the
+ value is the selfLink of your Snapshot.'
required: false
source_snapshot_encryption_key:
description:
@@ -187,13 +192,19 @@ EXAMPLES = '''
raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: us-central1-a
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ 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
@@ -209,12 +220,12 @@ RETURN = '''
- The unique identifier for the resource.
returned: success
type: int
- last_attach_timestamp:
+ lastAttachTimestamp:
description:
- Last attach timestamp in RFC3339 text format.
returned: success
type: str
- last_detach_timestamp:
+ lastDetachTimestamp:
description:
- Last dettach timestamp in RFC3339 text format.
returned: success
@@ -239,7 +250,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- size_gb:
+ 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
@@ -248,19 +259,19 @@ RETURN = '''
sizeGb must not be less than the size of the sourceImage or the size of the snapshot.
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
users:
description:
- 'Links to the users of the disk (attached instances) in form: project/zones/zone/instances/instance
.'
returned: success
type: list
- source_image:
+ 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.
@@ -280,14 +291,14 @@ RETURN = '''
- A reference to the zone where the disk resides.
returned: success
type: str
- source_image_encryption_key:
+ 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:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -299,7 +310,7 @@ RETURN = '''
that protects this resource.
returned: success
type: str
- source_image_id:
+ 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
@@ -308,7 +319,7 @@ RETURN = '''
was used.
returned: success
type: str
- disk_encryption_key:
+ 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
@@ -321,7 +332,7 @@ RETURN = '''
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -333,7 +344,7 @@ RETURN = '''
that protects this resource.
returned: success
type: str
- source_snapshot:
+ sourceSnapshot:
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: *
@@ -341,14 +352,14 @@ RETURN = '''
* `projects/project/global/snapshots/snapshot` * `global/snapshots/snapshot` .'
returned: success
type: dict
- source_snapshot_encryption_key:
+ 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:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -360,7 +371,7 @@ RETURN = '''
that protects this resource.
returned: success
type: str
- source_snapshot_id:
+ 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
@@ -427,7 +438,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -450,8 +462,44 @@ 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="Disk 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'):
+ label_fingerprint_update(module, request, response)
+ if response.get('sizeGb') != request.get('sizeGb'):
+ size_gb_update(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')
+ }
+ )
+
+
+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')
+ }
+ )
def delete(module, link, kind):
@@ -481,9 +529,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -494,9 +542,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/disks".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -511,8 +559,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -539,6 +585,7 @@ def is_different(module, response):
# This is for doing comparisons with Ansible's current parameters.
def response_to_hash(module, response):
return {
+ u'labelFingerprint': response.get(u'labelFingerprint'),
u'creationTimestamp': response.get(u'creationTimestamp'),
u'description': response.get(u'description'),
u'id': response.get(u'id'),
@@ -548,8 +595,8 @@ def response_to_hash(module, response):
u'licenses': response.get(u'licenses'),
u'name': module.params.get('name'),
u'sizeGb': response.get(u'sizeGb'),
- u'type': response.get(u'type'),
u'users': response.get(u'users'),
+ u'type': response.get(u'type'),
u'sourceImage': module.params.get('source_image')
}
@@ -557,7 +604,7 @@ def response_to_hash(module, response):
def disk_type_selflink(name, params):
if name is None:
return
- url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/{zone}/diskTypes/[a-z1-9\-]*"
+ url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/[a-z1-9\-]*/diskTypes/[a-z1-9\-]*"
if not re.match(url, name):
name = "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/diskTypes/%s".format(**params) % name
return name
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 13f01c8d88..5c7795d013 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_disk_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,13 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ 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
@@ -87,12 +93,12 @@ items:
- The unique identifier for the resource.
returned: success
type: int
- last_attach_timestamp:
+ lastAttachTimestamp:
description:
- Last attach timestamp in RFC3339 text format.
returned: success
type: str
- last_detach_timestamp:
+ lastDetachTimestamp:
description:
- Last dettach timestamp in RFC3339 text format.
returned: success
@@ -117,7 +123,7 @@ items:
be a dash.
returned: success
type: str
- size_gb:
+ 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
@@ -138,7 +144,7 @@ items:
Provide this when creating the disk.
returned: success
type: str
- source_image:
+ sourceImage:
description:
- The source image used to create this disk. If the source image is deleted, this
field will not be set.
@@ -158,14 +164,14 @@ items:
- A reference to the zone where the disk resides.
returned: success
type: str
- source_image_encryption_key:
+ 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:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -177,7 +183,7 @@ items:
that protects this resource.
returned: success
type: str
- source_image_id:
+ 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
@@ -186,7 +192,7 @@ items:
was used.
returned: success
type: str
- disk_encryption_key:
+ 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
@@ -199,7 +205,7 @@ items:
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -211,7 +217,7 @@ items:
that protects this resource.
returned: success
type: str
- source_snapshot:
+ sourceSnapshot:
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: *
@@ -219,14 +225,14 @@ items:
* `projects/project/global/snapshots/snapshot` * `global/snapshots/snapshot` .'
returned: success
type: dict
- source_snapshot_encryption_key:
+ 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:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -238,7 +244,7 @@ items:
that protects this resource.
returned: success
type: str
- source_snapshot_id:
+ 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
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_firewall.py b/lib/ansible/modules/cloud/google/gcp_compute_firewall.py
index 747ea290ae..09fcadb93f 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_firewall.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_firewall.py
@@ -72,11 +72,55 @@ options:
specified, this rule applies to connections through any port.
- 'Example inputs include: ["22"], ["80","443"], and ["12345-12349"].'
required: false
+ denied:
+ description:
+ - The list of DENY rules specified by this firewall. Each rule specifies a protocol
+ and port-range tuple that describes a denied connection.
+ required: false
+ version_added: 2.8
+ suboptions:
+ ip_protocol:
+ description:
+ - The IP protocol to which this rule applies. The protocol type is required when creating
+ a firewall rule. This value can either be one of the following well known protocol
+ strings (tcp, udp, icmp, esp, ah, sctp), or the IP protocol number.
+ required: true
+ ports:
+ description:
+ - An optional list of ports to which this rule applies. This field is only applicable
+ for UDP or TCP protocol. Each entry must be either an integer or a range. If not
+ specified, this rule applies to connections through any port.
+ - 'Example inputs include: ["22"], ["80","443"], and ["12345-12349"].'
+ required: false
description:
description:
- An optional description of this resource. Provide this property when you create
the resource.
required: false
+ destination_ranges:
+ description:
+ - If destination ranges are specified, the firewall will apply only to traffic that
+ has destination IP address in these ranges. These ranges must be expressed in CIDR
+ format. Only IPv4 is supported.
+ required: false
+ version_added: 2.8
+ direction:
+ description:
+ - 'Direction of traffic to which this firewall applies; default is INGRESS. Note:
+ For INGRESS traffic, it is NOT supported to specify destinationRanges; For EGRESS
+ traffic, it is NOT supported to specify sourceRanges OR sourceTags.'
+ required: false
+ version_added: 2.8
+ choices: ['INGRESS', 'EGRESS']
+ disabled:
+ description:
+ - Denotes whether the firewall rule is disabled, i.e not applied to the network it
+ is associated with. When set to true, the firewall rule is not enforced and the
+ network behaves as if it did not exist. If this is unspecified, the firewall rule
+ will be enabled.
+ required: false
+ type: bool
+ version_added: 2.8
name:
description:
- Name of the resource. Provided by the client when the resource is created. The name
@@ -85,7 +129,7 @@ options:
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: false
+ required: true
network:
description:
- 'URL of the network resource for this firewall rule. If not specified when creating
@@ -95,7 +139,22 @@ options:
U(https://www.googleapis.com/compute/v1/projects/myproject/global/)
networks/my-network projects/myproject/global/networks/my-network
global/networks/default .'
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
+ required: true
+ priority:
+ description:
+ - Priority for this rule. This is an integer between 0 and 65535, both inclusive.
+ When not specified, the value assumed is 1000. Relative priorities determine precedence
+ of conflicting rules. Lower value of priority implies higher precedence (eg, a rule
+ with priority 0 has higher precedence than a rule with priority 1). DENY rules take
+ precedence over ALLOW rules having equal priority.
required: false
+ default: 1000
+ version_added: 2.8
source_ranges:
description:
- If source ranges are specified, the firewall will apply only to traffic that has
@@ -105,6 +164,19 @@ options:
OR the source IP that belongs to a tag listed in the sourceTags property. The connection
does not need to match both properties for the firewall to apply. Only IPv4 is supported.
required: false
+ source_service_accounts:
+ description:
+ - If source service accounts are specified, the firewall will apply only to traffic
+ originating from an instance with a service account in this list. Source service
+ accounts cannot be used to control traffic to an instance's external IP address
+ because service accounts are associated with an instance, not an IP address. sourceRanges
+ can be set at the same time as sourceServiceAccounts. If both are set, the firewall
+ will apply to traffic that has source IP address within sourceRanges OR the source
+ IP belongs to an instance with service account listed in sourceServiceAccount. The
+ connection does not need to match both properties for the firewall to apply. sourceServiceAccounts
+ cannot be used at the same time as sourceTags or targetTags.
+ required: false
+ version_added: 2.8
source_tags:
description:
- If source tags are specified, the firewall will apply only to traffic with source
@@ -116,6 +188,15 @@ options:
sourceTags property. The connection does not need to match both properties for the
firewall to apply.
required: false
+ target_service_accounts:
+ description:
+ - A list of service accounts indicating sets of instances located in the network that
+ may make network connections as specified in allowed[].
+ - targetServiceAccounts cannot be used at the same time as targetTags or sourceTags.
+ If neither targetServiceAccounts nor targetTags are specified, the firewall rule
+ applies to all instances on the specified network.
+ required: false
+ version_added: 2.8
target_tags:
description:
- A list of instance tags indicating sets of instances located in the network that
@@ -124,6 +205,9 @@ options:
specified network.
required: false
extends_documentation_fragment: gcp
+notes:
+ - "API Reference: U(https://cloud.google.com/compute/docs/reference/latest/firewalls)"
+ - "Official Documentation: U(https://cloud.google.com/vpc/docs/firewalls)"
'''
EXAMPLES = '''
@@ -140,7 +224,7 @@ EXAMPLES = '''
source_tags:
- test-ssh-clients
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -168,17 +252,61 @@ RETURN = '''
- 'Example inputs include: ["22"], ["80","443"], and ["12345-12349"].'
returned: success
type: list
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
type: str
+ denied:
+ description:
+ - The list of DENY rules specified by this firewall. Each rule specifies a protocol
+ and port-range tuple that describes a denied connection.
+ returned: success
+ type: complex
+ contains:
+ ip_protocol:
+ description:
+ - The IP protocol to which this rule applies. The protocol type is required when creating
+ a firewall rule. This value can either be one of the following well known protocol
+ strings (tcp, udp, icmp, esp, ah, sctp), or the IP protocol number.
+ returned: success
+ type: str
+ ports:
+ description:
+ - An optional list of ports to which this rule applies. This field is only applicable
+ for UDP or TCP protocol. Each entry must be either an integer or a range. If not
+ specified, this rule applies to connections through any port.
+ - 'Example inputs include: ["22"], ["80","443"], and ["12345-12349"].'
+ returned: success
+ type: list
description:
description:
- An optional description of this resource. Provide this property when you create
the resource.
returned: success
type: str
+ destinationRanges:
+ description:
+ - If destination ranges are specified, the firewall will apply only to traffic that
+ has destination IP address in these ranges. These ranges must be expressed in CIDR
+ format. Only IPv4 is supported.
+ returned: success
+ type: list
+ direction:
+ description:
+ - 'Direction of traffic to which this firewall applies; default is INGRESS. Note:
+ For INGRESS traffic, it is NOT supported to specify destinationRanges; For EGRESS
+ traffic, it is NOT supported to specify sourceRanges OR sourceTags.'
+ returned: success
+ type: str
+ disabled:
+ description:
+ - Denotes whether the firewall rule is disabled, i.e not applied to the network it
+ is associated with. When set to true, the firewall rule is not enforced and the
+ network behaves as if it did not exist. If this is unspecified, the firewall rule
+ will be enabled.
+ returned: success
+ type: bool
id:
description:
- The unique identifier for the resource.
@@ -204,8 +332,17 @@ RETURN = '''
networks/my-network projects/myproject/global/networks/my-network
global/networks/default .'
returned: success
- type: str
- source_ranges:
+ type: dict
+ priority:
+ description:
+ - Priority for this rule. This is an integer between 0 and 65535, both inclusive.
+ When not specified, the value assumed is 1000. Relative priorities determine precedence
+ of conflicting rules. Lower value of priority implies higher precedence (eg, a rule
+ with priority 0 has higher precedence than a rule with priority 1). DENY rules take
+ precedence over ALLOW rules having equal priority.
+ returned: success
+ type: int
+ sourceRanges:
description:
- If source ranges are specified, the firewall will apply only to traffic that has
source IP address in these ranges. These ranges must be expressed in CIDR format.
@@ -215,7 +352,20 @@ RETURN = '''
does not need to match both properties for the firewall to apply. Only IPv4 is supported.
returned: success
type: list
- source_tags:
+ sourceServiceAccounts:
+ description:
+ - If source service accounts are specified, the firewall will apply only to traffic
+ originating from an instance with a service account in this list. Source service
+ accounts cannot be used to control traffic to an instance's external IP address
+ because service accounts are associated with an instance, not an IP address. sourceRanges
+ can be set at the same time as sourceServiceAccounts. If both are set, the firewall
+ will apply to traffic that has source IP address within sourceRanges OR the source
+ IP belongs to an instance with service account listed in sourceServiceAccount. The
+ connection does not need to match both properties for the firewall to apply. sourceServiceAccounts
+ cannot be used at the same time as sourceTags or targetTags.
+ returned: success
+ type: list
+ sourceTags:
description:
- If source tags are specified, the firewall will apply only to traffic with source
IP that belongs to a tag listed in source tags. Source tags cannot be used to control
@@ -227,7 +377,16 @@ RETURN = '''
firewall to apply.
returned: success
type: list
- target_tags:
+ targetServiceAccounts:
+ description:
+ - A list of service accounts indicating sets of instances located in the network that
+ may make network connections as specified in allowed[].
+ - targetServiceAccounts cannot be used at the same time as targetTags or sourceTags.
+ If neither targetServiceAccounts nor targetTags are specified, the firewall rule
+ applies to all instances on the specified network.
+ returned: success
+ type: list
+ targetTags:
description:
- A list of instance tags indicating sets of instances located in the network that
may make network connections as specified in allowed[].
@@ -260,11 +419,21 @@ def main():
ip_protocol=dict(required=True, type='str'),
ports=dict(type='list', elements='str')
)),
+ denied=dict(type='list', elements='dict', options=dict(
+ ip_protocol=dict(required=True, type='str'),
+ ports=dict(type='list', elements='str')
+ )),
description=dict(type='str'),
- name=dict(type='str'),
- network=dict(type='str'),
+ destination_ranges=dict(type='list', elements='str'),
+ direction=dict(type='str', choices=['INGRESS', 'EGRESS']),
+ disabled=dict(type='bool'),
+ name=dict(required=True, type='str'),
+ network=dict(required=True, type='dict'),
+ priority=dict(default=1000, type='int'),
source_ranges=dict(type='list', elements='str'),
+ source_service_accounts=dict(type='list', elements='str'),
source_tags=dict(type='list', elements='str'),
+ target_service_accounts=dict(type='list', elements='str'),
target_tags=dict(type='list', elements='str')
)
)
@@ -281,7 +450,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -306,7 +476,7 @@ def create(module, link, kind):
def update(module, link, kind):
auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ return wait_for_operation(module, auth.patch(link, resource_to_request(module)))
def delete(module, link, kind):
@@ -318,11 +488,18 @@ def resource_to_request(module):
request = {
u'kind': 'compute#firewall',
u'allowed': FirewallAllowedArray(module.params.get('allowed', []), module).to_request(),
+ u'denied': FirewallDeniedArray(module.params.get('denied', []), module).to_request(),
u'description': module.params.get('description'),
+ u'destinationRanges': module.params.get('destination_ranges'),
+ u'direction': module.params.get('direction'),
+ u'disabled': module.params.get('disabled'),
u'name': module.params.get('name'),
- u'network': module.params.get('network'),
+ u'network': replace_resource_dict(module.params.get(u'network', {}), 'selfLink'),
+ u'priority': module.params.get('priority'),
u'sourceRanges': module.params.get('source_ranges'),
+ u'sourceServiceAccounts': module.params.get('source_service_accounts'),
u'sourceTags': module.params.get('source_tags'),
+ u'targetServiceAccounts': module.params.get('target_service_accounts'),
u'targetTags': module.params.get('target_tags')
}
return_vals = {}
@@ -333,9 +510,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -346,9 +523,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/firewalls".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -363,8 +540,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -393,12 +568,19 @@ def response_to_hash(module, response):
return {
u'allowed': FirewallAllowedArray(response.get(u'allowed', []), module).from_response(),
u'creationTimestamp': response.get(u'creationTimestamp'),
+ u'denied': FirewallDeniedArray(response.get(u'denied', []), module).from_response(),
u'description': response.get(u'description'),
+ u'destinationRanges': response.get(u'destinationRanges'),
+ u'direction': response.get(u'direction'),
+ u'disabled': response.get(u'disabled'),
u'id': response.get(u'id'),
- u'name': response.get(u'name'),
+ u'name': module.params.get('name'),
u'network': response.get(u'network'),
+ u'priority': response.get(u'priority'),
u'sourceRanges': response.get(u'sourceRanges'),
+ u'sourceServiceAccounts': response.get(u'sourceServiceAccounts'),
u'sourceTags': response.get(u'sourceTags'),
+ u'targetServiceAccounts': response.get(u'targetServiceAccounts'),
u'targetTags': response.get(u'targetTags')
}
@@ -473,5 +655,38 @@ class FirewallAllowedArray(object):
})
+class FirewallDeniedArray(object):
+ def __init__(self, request, module):
+ self.module = module
+ if request:
+ self.request = request
+ else:
+ self.request = []
+
+ def to_request(self):
+ items = []
+ for item in self.request:
+ items.append(self._request_for_item(item))
+ return items
+
+ def from_response(self):
+ items = []
+ for item in self.request:
+ items.append(self._response_from_item(item))
+ return items
+
+ def _request_for_item(self, item):
+ return remove_nones_from_dict({
+ u'IPProtocol': item.get('ip_protocol'),
+ u'ports': item.get('ports')
+ })
+
+ def _response_from_item(self, item):
+ return remove_nones_from_dict({
+ u'IPProtocol': item.get(u'ip_protocol'),
+ u'ports': item.get(u'ports')
+ })
+
+
if __name__ == '__main__':
main()
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_firewall_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_firewall_facts.py
index 1ad88378ff..5fce2e9fba 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_firewall_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_firewall_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -88,17 +88,61 @@ items:
- 'Example inputs include: ["22"], ["80","443"], and ["12345-12349"].'
returned: success
type: list
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
type: str
+ denied:
+ description:
+ - The list of DENY rules specified by this firewall. Each rule specifies a protocol
+ and port-range tuple that describes a denied connection.
+ returned: success
+ type: complex
+ contains:
+ ip_protocol:
+ description:
+ - The IP protocol to which this rule applies. The protocol type is required when creating
+ a firewall rule. This value can either be one of the following well known protocol
+ strings (tcp, udp, icmp, esp, ah, sctp), or the IP protocol number.
+ returned: success
+ type: str
+ ports:
+ description:
+ - An optional list of ports to which this rule applies. This field is only applicable
+ for UDP or TCP protocol. Each entry must be either an integer or a range. If not
+ specified, this rule applies to connections through any port.
+ - 'Example inputs include: ["22"], ["80","443"], and ["12345-12349"].'
+ returned: success
+ type: list
description:
description:
- An optional description of this resource. Provide this property when you create
the resource.
returned: success
type: str
+ destinationRanges:
+ description:
+ - If destination ranges are specified, the firewall will apply only to traffic that
+ has destination IP address in these ranges. These ranges must be expressed in CIDR
+ format. Only IPv4 is supported.
+ returned: success
+ type: list
+ direction:
+ description:
+ - 'Direction of traffic to which this firewall applies; default is INGRESS. Note:
+ For INGRESS traffic, it is NOT supported to specify destinationRanges; For EGRESS
+ traffic, it is NOT supported to specify sourceRanges OR sourceTags.'
+ returned: success
+ type: str
+ disabled:
+ description:
+ - Denotes whether the firewall rule is disabled, i.e not applied to the network it
+ is associated with. When set to true, the firewall rule is not enforced and the
+ network behaves as if it did not exist. If this is unspecified, the firewall rule
+ will be enabled.
+ returned: success
+ type: bool
id:
description:
- The unique identifier for the resource.
@@ -124,8 +168,17 @@ items:
networks/my-network projects/myproject/global/networks/my-network
global/networks/default .'
returned: success
- type: str
- source_ranges:
+ type: dict
+ priority:
+ description:
+ - Priority for this rule. This is an integer between 0 and 65535, both inclusive.
+ When not specified, the value assumed is 1000. Relative priorities determine precedence
+ of conflicting rules. Lower value of priority implies higher precedence (eg, a rule
+ with priority 0 has higher precedence than a rule with priority 1). DENY rules take
+ precedence over ALLOW rules having equal priority.
+ returned: success
+ type: int
+ sourceRanges:
description:
- If source ranges are specified, the firewall will apply only to traffic that has
source IP address in these ranges. These ranges must be expressed in CIDR format.
@@ -135,7 +188,20 @@ items:
does not need to match both properties for the firewall to apply. Only IPv4 is supported.
returned: success
type: list
- source_tags:
+ sourceServiceAccounts:
+ description:
+ - If source service accounts are specified, the firewall will apply only to traffic
+ originating from an instance with a service account in this list. Source service
+ accounts cannot be used to control traffic to an instance's external IP address
+ because service accounts are associated with an instance, not an IP address. sourceRanges
+ can be set at the same time as sourceServiceAccounts. If both are set, the firewall
+ will apply to traffic that has source IP address within sourceRanges OR the source
+ IP belongs to an instance with service account listed in sourceServiceAccount. The
+ connection does not need to match both properties for the firewall to apply. sourceServiceAccounts
+ cannot be used at the same time as sourceTags or targetTags.
+ returned: success
+ type: list
+ sourceTags:
description:
- If source tags are specified, the firewall will apply only to traffic with source
IP that belongs to a tag listed in source tags. Source tags cannot be used to control
@@ -147,7 +213,16 @@ items:
firewall to apply.
returned: success
type: list
- target_tags:
+ targetServiceAccounts:
+ description:
+ - A list of service accounts indicating sets of instances located in the network that
+ may make network connections as specified in allowed[].
+ - targetServiceAccounts cannot be used at the same time as targetTags or sourceTags.
+ If neither targetServiceAccounts nor targetTags are specified, the firewall rule
+ applies to all instances on the specified network.
+ returned: success
+ type: list
+ targetTags:
description:
- A list of instance tags indicating sets of instances located in the network that
may make network connections as specified in allowed[].
@@ -171,7 +246,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='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 500482d5f3..a712c5e709 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_forwarding_rule.py
@@ -85,6 +85,11 @@ options:
- A reference to a BackendService to receive the matched traffic.
- This is used for internal load balancing.
- "(not used for external load balancing) ."
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this backend_service field to "{{ name-of-resource }}" Alternatively,
+ you can set this backend_service to a dictionary with the selfLink key where the
+ value is the selfLink of your BackendService.'
required: false
ip_version:
description:
@@ -116,6 +121,11 @@ options:
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.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: false
port_range:
description:
@@ -147,6 +157,11 @@ options:
- 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.
+ - 'This field represents a link to a Subnetwork resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_subnetwork
+ task and then set this subnetwork field to "{{ name-of-resource }}" Alternatively,
+ you can set this subnetwork to a dictionary with the selfLink key where the value
+ is the selfLink of your Subnetwork.'
required: false
target:
description:
@@ -155,8 +170,21 @@ options:
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.
+ - 'This field represents a link to a TargetPool resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_target_pool
+ task and then set this target field to "{{ name-of-resource }}" Alternatively, you
+ can set this target to a dictionary with the selfLink key where the value is the
+ selfLink of your TargetPool.'
required: false
version_added: 2.7
+ network_tier:
+ 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.'
+ required: false
+ version_added: 2.8
+ choices: ['PREMIUM', 'STANDARD']
region:
description:
- A reference to the region where the regional forwarding rule resides.
@@ -198,13 +226,13 @@ EXAMPLES = '''
port_range: 80-80
ip_address: "{{ address.address }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -220,7 +248,7 @@ RETURN = '''
- The unique identifier for the resource.
returned: success
type: int
- ip_address:
+ 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
@@ -241,27 +269,27 @@ RETURN = '''
* global/addresses/address * address .'
returned: success
type: str
- ip_protocol:
+ 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
- backend_service:
+ backendService:
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:
+ ipVersion:
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:
+ 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
@@ -288,7 +316,7 @@ RETURN = '''
- This field is not used for external load balancing.
returned: success
type: dict
- port_range:
+ portRange:
description:
- This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy,
TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance.
@@ -331,6 +359,19 @@ RETURN = '''
- This field is not used for internal load balancing.
returned: success
type: dict
+ labelFingerprint:
+ description:
+ - The fingerprint used for optimistic locking of this resource. Used internally during
+ updates.
+ returned: success
+ type: str
+ 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
region:
description:
- A reference to the region where the regional forwarding rule resides.
@@ -370,6 +411,7 @@ def main():
ports=dict(type='list', elements='str'),
subnetwork=dict(type='dict'),
target=dict(type='dict'),
+ network_tier=dict(type='str', choices=['PREMIUM', 'STANDARD']),
region=dict(required=True, type='str')
)
)
@@ -386,7 +428,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -409,9 +452,41 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ 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):
@@ -433,7 +508,8 @@ def resource_to_request(module):
u'portRange': module.params.get('port_range'),
u'ports': module.params.get('ports'),
u'subnetwork': replace_resource_dict(module.params.get(u'subnetwork', {}), 'selfLink'),
- u'target': replace_resource_dict(module.params.get(u'target', {}), 'selfLink')
+ u'target': replace_resource_dict(module.params.get(u'target', {}), 'selfLink'),
+ u'networkTier': module.params.get('network_tier')
}
return_vals = {}
for k, v in request.items():
@@ -443,9 +519,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -456,9 +532,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/forwardingRules".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -473,8 +549,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -514,7 +588,9 @@ def response_to_hash(module, response):
u'portRange': response.get(u'portRange'),
u'ports': response.get(u'ports'),
u'subnetwork': response.get(u'subnetwork'),
- u'target': response.get(u'target')
+ u'target': response.get(u'target'),
+ u'labelFingerprint': response.get(u'labelFingerprint'),
+ u'networkTier': module.params.get('network_tier')
}
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 2be21b9ec5..a56710298a 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
@@ -62,7 +62,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -72,7 +72,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -88,7 +88,7 @@ items:
- The unique identifier for the resource.
returned: success
type: int
- ip_address:
+ 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
@@ -109,27 +109,27 @@ items:
* global/addresses/address * address .'
returned: success
type: str
- ip_protocol:
+ 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
- backend_service:
+ backendService:
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:
+ ipVersion:
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:
+ 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
@@ -156,7 +156,7 @@ items:
- This field is not used for external load balancing.
returned: success
type: dict
- port_range:
+ portRange:
description:
- This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy,
TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance.
@@ -199,6 +199,19 @@ items:
- This field is not used for internal load balancing.
returned: success
type: dict
+ labelFingerprint:
+ description:
+ - The fingerprint used for optimistic locking of this resource. Used internally during
+ updates.
+ returned: success
+ type: str
+ 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
region:
description:
- A reference to the region where the regional forwarding rule resides.
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 3402fd96e1..f8cc7eaea9 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_global_address.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_global_address.py
@@ -67,6 +67,15 @@ options:
The default value is IPV4.
required: false
choices: ['IPV4', 'IPV6']
+ address_type:
+ 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."
+ required: false
+ default: EXTERNAL
+ version_added: 2.8
+ choices: ['EXTERNAL', 'INTERNAL']
extends_documentation_fragment: gcp
notes:
- "API Reference: U(https://cloud.google.com/compute/docs/reference/latest/globalAddresses)"
@@ -78,7 +87,7 @@ EXAMPLES = '''
gcp_compute_global_address:
name: "test_object"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -89,7 +98,7 @@ RETURN = '''
- The static external IP address represented by this resource.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -115,7 +124,13 @@ RETURN = '''
be a dash.
returned: success
type: str
- ip_version:
+ labelFingerprint:
+ description:
+ - The fingerprint used for optimistic locking of this resource. Used internally during
+ updates.
+ 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.
@@ -126,6 +141,13 @@ RETURN = '''
- 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
'''
################################################################################
@@ -150,7 +172,8 @@ def main():
state=dict(default='present', choices=['present', 'absent'], type='str'),
description=dict(type='str'),
name=dict(required=True, type='str'),
- ip_version=dict(type='str', choices=['IPV4', 'IPV6'])
+ ip_version=dict(type='str', choices=['IPV4', 'IPV6']),
+ address_type=dict(default='EXTERNAL', type='str', choices=['EXTERNAL', 'INTERNAL'])
)
)
@@ -166,7 +189,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -189,9 +213,27 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ 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):
@@ -204,7 +246,8 @@ def resource_to_request(module):
u'kind': 'compute#address',
u'description': module.params.get('description'),
u'name': module.params.get('name'),
- u'ipVersion': module.params.get('ip_version')
+ u'ipVersion': module.params.get('ip_version'),
+ u'addressType': module.params.get('address_type')
}
return_vals = {}
for k, v in request.items():
@@ -214,9 +257,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -227,9 +270,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/addresses".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -244,8 +287,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -277,8 +318,10 @@ 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'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 69cdab4f81..cd91bc0a27 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
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
- The static external IP address represented by this resource.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -97,7 +97,13 @@ items:
be a dash.
returned: success
type: str
- ip_version:
+ labelFingerprint:
+ description:
+ - The fingerprint used for optimistic locking of this resource. Used internally during
+ updates.
+ 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.
@@ -108,6 +114,13 @@ items:
- 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
'''
################################################################################
@@ -124,7 +137,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule.py b/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule.py
index 27b65d5c62..09e563396c 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule.py
@@ -87,6 +87,11 @@ options:
- A reference to a BackendService to receive the matched traffic.
- This is used for internal load balancing.
- "(not used for external load balancing) ."
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this backend_service field to "{{ name-of-resource }}" Alternatively,
+ you can set this backend_service to a dictionary with the selfLink key where the
+ value is the selfLink of your BackendService.'
required: false
ip_version:
description:
@@ -118,6 +123,11 @@ options:
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.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: false
port_range:
description:
@@ -149,6 +159,11 @@ options:
- 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.
+ - 'This field represents a link to a Subnetwork resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_subnetwork
+ task and then set this subnetwork field to "{{ name-of-resource }}" Alternatively,
+ you can set this subnetwork to a dictionary with the selfLink key where the value
+ is the selfLink of your Subnetwork.'
required: false
target:
description:
@@ -234,13 +249,13 @@ EXAMPLES = '''
port_range: 80-80
target: "{{ httpproxy.selfLink }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -256,7 +271,7 @@ RETURN = '''
- The unique identifier for the resource.
returned: success
type: int
- ip_address:
+ 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
@@ -277,27 +292,27 @@ RETURN = '''
* global/addresses/address * address .'
returned: success
type: str
- ip_protocol:
+ 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
- backend_service:
+ backendService:
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:
+ ipVersion:
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:
+ 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
@@ -324,7 +339,7 @@ RETURN = '''
- This field is not used for external load balancing.
returned: success
type: dict
- port_range:
+ portRange:
description:
- This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy,
TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance.
@@ -419,7 +434,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -476,9 +492,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -489,9 +505,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/forwardingRules".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -506,8 +522,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule_facts.py
index e8693d9375..3c25d67d00 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_global_forwarding_rule_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -82,7 +82,7 @@ items:
- The unique identifier for the resource.
returned: success
type: int
- ip_address:
+ 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
@@ -103,27 +103,27 @@ items:
* global/addresses/address * address .'
returned: success
type: str
- ip_protocol:
+ 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
- backend_service:
+ backendService:
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:
+ ipVersion:
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:
+ 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
@@ -150,7 +150,7 @@ items:
- This field is not used for external load balancing.
returned: success
type: dict
- port_range:
+ portRange:
description:
- This field is used along with the target field for TargetHttpProxy, TargetHttpsProxy,
TargetSslProxy, TargetTcpProxy, TargetVpnGateway, TargetPool, TargetInstance.
@@ -213,7 +213,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_health_check.py b/lib/ansible/modules/cloud/google/gcp_compute_health_check.py
index a07c5d1030..a7c2f4a330 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_health_check.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_health_check.py
@@ -32,8 +32,15 @@ DOCUMENTATION = '''
---
module: gcp_compute_health_check
description:
- - An HealthCheck resource. This resource defines a template for how individual virtual
- machines should be checked for health, via one of the supported protocols.
+ - Health Checks determine whether instances are responsive and able to do work.
+ - They are an important part of a comprehensive load balancing configuration, as they
+ enable monitoring instances behind load balancers.
+ - Health Checks poll instances at a specified interval. Instances that do not respond
+ successfully to some number of probes in a row are marked as unhealthy. No new connections
+ are sent to unhealthy instances, though existing connections will continue. The
+ health check will continue to poll unhealthy instances. If an instance later responds
+ successfully to some number of consecutive probes, it is marked healthy again and
+ can receive new connections.
short_description: Creates a GCP HealthCheck
version_added: 2.6
author: Google Inc. (@googlecloudplatform)
@@ -62,6 +69,7 @@ options:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
required: false
+ default: 2
name:
description:
- Name of the resource. Provided by the client when the resource is created. The name
@@ -70,7 +78,7 @@ options:
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: false
+ required: true
timeout_sec:
description:
- How long (in seconds) to wait before claiming failure.
@@ -91,7 +99,7 @@ options:
the default is TCP. Exactly one of the protocol-specific health check field must
be specified, which must match type field.
required: false
- choices: ['TCP', 'SSL', 'HTTP']
+ choices: ['TCP', 'SSL', 'HTTP', 'HTTPS']
http_health_check:
description:
- A nested object resource.
@@ -108,6 +116,7 @@ options:
- The request path of the HTTP health check request.
- The default value is /.
required: false
+ default: /
port:
description:
- The TCP port number for the HTTP health check request.
@@ -123,6 +132,7 @@ options:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
required: false
+ default: NONE
choices: ['NONE', 'PROXY_V1']
https_health_check:
description:
@@ -140,6 +150,7 @@ options:
- The request path of the HTTPS health check request.
- The default value is /.
required: false
+ default: /
port:
description:
- The TCP port number for the HTTPS health check request.
@@ -155,6 +166,7 @@ options:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
required: false
+ default: NONE
choices: ['NONE', 'PROXY_V1']
tcp_health_check:
description:
@@ -188,6 +200,7 @@ options:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
required: false
+ default: NONE
choices: ['NONE', 'PROXY_V1']
ssl_health_check:
description:
@@ -221,8 +234,12 @@ options:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
required: false
+ default: NONE
choices: ['NONE', 'PROXY_V1']
extends_documentation_fragment: gcp
+notes:
+ - "API Reference: U(https://cloud.google.com/compute/docs/reference/rest/latest/healthChecks)"
+ - "Official Documentation: U(https://cloud.google.com/load-balancing/docs/health-checks)"
'''
EXAMPLES = '''
@@ -238,18 +255,18 @@ EXAMPLES = '''
timeout_sec: 2
unhealthy_threshold: 5
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- check_interval_sec:
+ checkIntervalSec:
description:
- How often (in seconds) to send a health check. The default value is 5 seconds.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -260,7 +277,7 @@ RETURN = '''
the resource.
returned: success
type: str
- healthy_threshold:
+ healthyThreshold:
description:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
@@ -281,14 +298,14 @@ RETURN = '''
be a dash.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How long (in seconds) to wait before claiming failure.
- The default value is 5 seconds. It is invalid for timeoutSec to have greater value
than checkIntervalSec.
returned: success
type: int
- unhealthy_threshold:
+ unhealthyThreshold:
description:
- A so-far healthy instance will be marked unhealthy after this many consecutive failures.
The default value is 2.
@@ -301,7 +318,7 @@ RETURN = '''
be specified, which must match type field.
returned: success
type: str
- http_health_check:
+ httpHealthCheck:
description:
- A nested object resource.
returned: success
@@ -314,7 +331,7 @@ RETURN = '''
is performed will be used.
returned: success
type: str
- request_path:
+ requestPath:
description:
- The request path of the HTTP health check request.
- The default value is /.
@@ -326,19 +343,19 @@ RETURN = '''
- The default value is 80.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
returned: success
type: str
- https_health_check:
+ httpsHealthCheck:
description:
- A nested object resource.
returned: success
@@ -351,7 +368,7 @@ RETURN = '''
is performed will be used.
returned: success
type: str
- request_path:
+ requestPath:
description:
- The request path of the HTTPS health check request.
- The default value is /.
@@ -363,19 +380,19 @@ RETURN = '''
- The default value is 443.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
returned: success
type: str
- tcp_health_check:
+ tcpHealthCheck:
description:
- A nested object resource.
returned: success
@@ -401,19 +418,19 @@ RETURN = '''
- The default value is 443.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
returned: success
type: str
- ssl_health_check:
+ sslHealthCheck:
description:
- A nested object resource.
returned: success
@@ -439,13 +456,13 @@ RETURN = '''
- The default value is 443.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
@@ -474,38 +491,38 @@ def main():
state=dict(default='present', choices=['present', 'absent'], type='str'),
check_interval_sec=dict(default=5, type='int'),
description=dict(type='str'),
- healthy_threshold=dict(type='int'),
- name=dict(type='str'),
+ healthy_threshold=dict(default=2, type='int'),
+ name=dict(required=True, type='str'),
timeout_sec=dict(default=5, type='int', aliases=['timeout_seconds']),
unhealthy_threshold=dict(default=2, type='int'),
- type=dict(type='str', choices=['TCP', 'SSL', 'HTTP']),
+ type=dict(type='str', choices=['TCP', 'SSL', 'HTTP', 'HTTPS']),
http_health_check=dict(type='dict', options=dict(
host=dict(type='str'),
- request_path=dict(type='str'),
+ request_path=dict(default='/', type='str'),
port=dict(type='int'),
port_name=dict(type='str'),
- proxy_header=dict(type='str', choices=['NONE', 'PROXY_V1'])
+ proxy_header=dict(default='NONE', type='str', choices=['NONE', 'PROXY_V1'])
)),
https_health_check=dict(type='dict', options=dict(
host=dict(type='str'),
- request_path=dict(type='str'),
+ request_path=dict(default='/', type='str'),
port=dict(type='int'),
port_name=dict(type='str'),
- proxy_header=dict(type='str', choices=['NONE', 'PROXY_V1'])
+ proxy_header=dict(default='NONE', type='str', choices=['NONE', 'PROXY_V1'])
)),
tcp_health_check=dict(type='dict', options=dict(
request=dict(type='str'),
response=dict(type='str'),
port=dict(type='int'),
port_name=dict(type='str'),
- proxy_header=dict(type='str', choices=['NONE', 'PROXY_V1'])
+ proxy_header=dict(default='NONE', type='str', choices=['NONE', 'PROXY_V1'])
)),
ssl_health_check=dict(type='dict', options=dict(
request=dict(type='str'),
response=dict(type='str'),
port=dict(type='int'),
port_name=dict(type='str'),
- proxy_header=dict(type='str', choices=['NONE', 'PROXY_V1'])
+ proxy_header=dict(default='NONE', type='str', choices=['NONE', 'PROXY_V1'])
))
)
)
@@ -522,7 +539,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -578,9 +596,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -591,9 +609,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/healthChecks".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -608,8 +626,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -641,7 +657,7 @@ def response_to_hash(module, response):
u'description': response.get(u'description'),
u'healthyThreshold': response.get(u'healthyThreshold'),
u'id': response.get(u'id'),
- u'name': response.get(u'name'),
+ u'name': module.params.get('name'),
u'timeoutSec': response.get(u'timeoutSec'),
u'unhealthyThreshold': response.get(u'unhealthyThreshold'),
u'type': response.get(u'type'),
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_health_check_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_health_check_facts.py
index e3d4480a06..4fb8fc5e43 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_health_check_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_health_check_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,12 +66,12 @@ items:
returned: always
type: complex
contains:
- check_interval_sec:
+ checkIntervalSec:
description:
- How often (in seconds) to send a health check. The default value is 5 seconds.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -82,7 +82,7 @@ items:
the resource.
returned: success
type: str
- healthy_threshold:
+ healthyThreshold:
description:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
@@ -103,14 +103,14 @@ items:
be a dash.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How long (in seconds) to wait before claiming failure.
- The default value is 5 seconds. It is invalid for timeoutSec to have greater value
than checkIntervalSec.
returned: success
type: int
- unhealthy_threshold:
+ unhealthyThreshold:
description:
- A so-far healthy instance will be marked unhealthy after this many consecutive failures.
The default value is 2.
@@ -123,7 +123,7 @@ items:
be specified, which must match type field.
returned: success
type: str
- http_health_check:
+ httpHealthCheck:
description:
- A nested object resource.
returned: success
@@ -136,7 +136,7 @@ items:
is performed will be used.
returned: success
type: str
- request_path:
+ requestPath:
description:
- The request path of the HTTP health check request.
- The default value is /.
@@ -148,19 +148,19 @@ items:
- The default value is 80.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
returned: success
type: str
- https_health_check:
+ httpsHealthCheck:
description:
- A nested object resource.
returned: success
@@ -173,7 +173,7 @@ items:
is performed will be used.
returned: success
type: str
- request_path:
+ requestPath:
description:
- The request path of the HTTPS health check request.
- The default value is /.
@@ -185,19 +185,19 @@ items:
- The default value is 443.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
returned: success
type: str
- tcp_health_check:
+ tcpHealthCheck:
description:
- A nested object resource.
returned: success
@@ -223,19 +223,19 @@ items:
- The default value is 443.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
returned: success
type: str
- ssl_health_check:
+ sslHealthCheck:
description:
- A nested object resource.
returned: success
@@ -261,13 +261,13 @@ items:
- The default value is 443.
returned: success
type: int
- port_name:
+ portName:
description:
- Port name as defined in InstanceGroup#NamedPort#name. If both port and port_name
are defined, port takes precedence.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
@@ -289,7 +289,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_http_health_check.py b/lib/ansible/modules/cloud/google/gcp_compute_http_health_check.py
index d22962a468..df8c7f6758 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_http_health_check.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_http_health_check.py
@@ -115,18 +115,18 @@ EXAMPLES = '''
timeout_sec: 2
unhealthy_threshold: 5
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- check_interval_sec:
+ checkIntervalSec:
description:
- How often (in seconds) to send a health check. The default value is 5 seconds.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -137,7 +137,7 @@ RETURN = '''
the resource.
returned: success
type: str
- healthy_threshold:
+ healthyThreshold:
description:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
@@ -171,20 +171,20 @@ RETURN = '''
- The default value is 80.
returned: success
type: int
- request_path:
+ requestPath:
description:
- The request path of the HTTP health check request.
- The default value is /.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How long (in seconds) to wait before claiming failure.
- The default value is 5 seconds. It is invalid for timeoutSec to have greater value
than checkIntervalSec.
returned: success
type: int
- unhealthy_threshold:
+ unhealthyThreshold:
description:
- A so-far healthy instance will be marked unhealthy after this many consecutive failures.
The default value is 2.
@@ -235,7 +235,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -289,9 +290,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -302,9 +303,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/httpHealthChecks".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -319,8 +320,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_http_health_check_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_http_health_check_facts.py
index e4f9096920..6fc063d023 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_http_health_check_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_http_health_check_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,12 +66,12 @@ items:
returned: always
type: complex
contains:
- check_interval_sec:
+ checkIntervalSec:
description:
- How often (in seconds) to send a health check. The default value is 5 seconds.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -82,7 +82,7 @@ items:
the resource.
returned: success
type: str
- healthy_threshold:
+ healthyThreshold:
description:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
@@ -116,20 +116,20 @@ items:
- The default value is 80.
returned: success
type: int
- request_path:
+ requestPath:
description:
- The request path of the HTTP health check request.
- The default value is /.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How long (in seconds) to wait before claiming failure.
- The default value is 5 seconds. It is invalid for timeoutSec to have greater value
than checkIntervalSec.
returned: success
type: int
- unhealthy_threshold:
+ unhealthyThreshold:
description:
- A so-far healthy instance will be marked unhealthy after this many consecutive failures.
The default value is 2.
@@ -151,7 +151,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_https_health_check.py b/lib/ansible/modules/cloud/google/gcp_compute_https_health_check.py
index 2cf4962cce..96e0101bab 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_https_health_check.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_https_health_check.py
@@ -113,18 +113,18 @@ EXAMPLES = '''
timeout_sec: 2
unhealthy_threshold: 5
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- check_interval_sec:
+ checkIntervalSec:
description:
- How often (in seconds) to send a health check. The default value is 5 seconds.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -135,7 +135,7 @@ RETURN = '''
the resource.
returned: success
type: str
- healthy_threshold:
+ healthyThreshold:
description:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
@@ -169,20 +169,20 @@ RETURN = '''
- The default value is 80.
returned: success
type: int
- request_path:
+ requestPath:
description:
- The request path of the HTTPS health check request.
- The default value is /.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How long (in seconds) to wait before claiming failure.
- The default value is 5 seconds. It is invalid for timeoutSec to have greater value
than checkIntervalSec.
returned: success
type: int
- unhealthy_threshold:
+ unhealthyThreshold:
description:
- A so-far healthy instance will be marked unhealthy after this many consecutive failures.
The default value is 2.
@@ -233,7 +233,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -287,9 +288,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -300,9 +301,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/httpsHealthChecks".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -317,8 +318,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_https_health_check_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_https_health_check_facts.py
index 9599e30190..5a599f764d 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_https_health_check_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_https_health_check_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,12 +66,12 @@ items:
returned: always
type: complex
contains:
- check_interval_sec:
+ checkIntervalSec:
description:
- How often (in seconds) to send a health check. The default value is 5 seconds.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -82,7 +82,7 @@ items:
the resource.
returned: success
type: str
- healthy_threshold:
+ healthyThreshold:
description:
- A so-far unhealthy instance will be marked healthy after this many consecutive successes.
The default value is 2.
@@ -116,20 +116,20 @@ items:
- The default value is 80.
returned: success
type: int
- request_path:
+ requestPath:
description:
- The request path of the HTTPS health check request.
- The default value is /.
returned: success
type: str
- timeout_sec:
+ timeoutSec:
description:
- How long (in seconds) to wait before claiming failure.
- The default value is 5 seconds. It is invalid for timeoutSec to have greater value
than checkIntervalSec.
returned: success
type: int
- unhealthy_threshold:
+ unhealthyThreshold:
description:
- A so-far healthy instance will be marked unhealthy after this many consecutive failures.
The default value is 2.
@@ -151,7 +151,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_image.py b/lib/ansible/modules/cloud/google/gcp_compute_image.py
index be56da41a4..bf3307b985 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_image.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_image.py
@@ -148,6 +148,11 @@ options:
description:
- Refers to a gcompute_disk object You must provide either this property or the rawDisk.source
property but not both to create an image.
+ - 'This field represents a link to a Disk resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_compute_disk task and
+ then set this source_disk field to "{{ name-of-resource }}" Alternatively, you can
+ set this source_disk to a dictionary with the selfLink key where the value is the
+ selfLink of your Disk.'
required: false
source_disk_encryption_key:
description:
@@ -196,18 +201,18 @@ EXAMPLES = '''
name: "test_object"
source_disk: "{{ disk }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- archive_size_bytes:
+ archiveSizeBytes:
description:
- Size of the image tar.gz archive stored in Google Cloud Storage (in bytes).
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -261,7 +266,7 @@ RETURN = '''
the resource.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Size of the image when restored onto a persistent disk (in GB).
returned: success
@@ -274,7 +279,7 @@ RETURN = '''
comply with RFC1035.
returned: success
type: str
- guest_os_features:
+ guestOsFeatures:
description:
- A list of features to enable on the guest OS. Applicable for bootable images only.
Currently, only one feature can be enabled, VIRTIO_SCSI_MULTIQUEUE, which allows
@@ -300,7 +305,7 @@ RETURN = '''
- The unique identifier for the resource. This identifier is defined by the server.
returned: success
type: int
- image_encryption_key:
+ imageEncryptionKey:
description:
- Encrypts the image using a customer-supplied encryption key.
- After you encrypt an image with a customer-supplied key, you must provide the same
@@ -308,7 +313,7 @@ RETURN = '''
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -335,20 +340,20 @@ RETURN = '''
be a dash.
returned: success
type: str
- raw_disk:
+ rawDisk:
description:
- The parameters of the raw disk image.
returned: success
type: complex
contains:
- container_type:
+ containerType:
description:
- The format used to encode and transmit the block device, which should be TAR. This
is just a container and transmission format and not a runtime format. Provided by
the client when the disk image is created.
returned: success
type: str
- sha1_checksum:
+ sha1Checksum:
description:
- An optional SHA1 checksum of the disk image before unpackaging.
- This is provided by the client when the disk image is created.
@@ -360,20 +365,20 @@ RETURN = '''
either this property or the sourceDisk property but not both.
returned: success
type: str
- source_disk:
+ sourceDisk:
description:
- Refers to a gcompute_disk object You must provide either this property or the rawDisk.source
property but not both to create an image.
returned: success
type: dict
- source_disk_encryption_key:
+ sourceDiskEncryptionKey:
description:
- The customer-supplied encryption key of the source disk. Required if the source
disk is protected by a customer-supplied encryption key.
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -385,14 +390,14 @@ RETURN = '''
that protects this resource.
returned: success
type: str
- source_disk_id:
+ sourceDiskId:
description:
- The ID value of the disk used to create this image. This value may be used to determine
whether the image was taken from the current or a previous instance of a given disk
name.
returned: success
type: str
- source_type:
+ sourceType:
description:
- The type of the image used to create this disk. The default and only value is RAW
.
@@ -458,7 +463,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -515,9 +521,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -528,9 +534,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/images".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -545,8 +551,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_image_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_image_facts.py
index 516315890f..17ecd7a8d0 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_image_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_image_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,12 +66,12 @@ items:
returned: always
type: complex
contains:
- archive_size_bytes:
+ archiveSizeBytes:
description:
- Size of the image tar.gz archive stored in Google Cloud Storage (in bytes).
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -125,7 +125,7 @@ items:
the resource.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Size of the image when restored onto a persistent disk (in GB).
returned: success
@@ -138,7 +138,7 @@ items:
comply with RFC1035.
returned: success
type: str
- guest_os_features:
+ guestOsFeatures:
description:
- A list of features to enable on the guest OS. Applicable for bootable images only.
Currently, only one feature can be enabled, VIRTIO_SCSI_MULTIQUEUE, which allows
@@ -164,7 +164,7 @@ items:
- The unique identifier for the resource. This identifier is defined by the server.
returned: success
type: int
- image_encryption_key:
+ imageEncryptionKey:
description:
- Encrypts the image using a customer-supplied encryption key.
- After you encrypt an image with a customer-supplied key, you must provide the same
@@ -172,7 +172,7 @@ items:
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -199,20 +199,20 @@ items:
be a dash.
returned: success
type: str
- raw_disk:
+ rawDisk:
description:
- The parameters of the raw disk image.
returned: success
type: complex
contains:
- container_type:
+ containerType:
description:
- The format used to encode and transmit the block device, which should be TAR. This
is just a container and transmission format and not a runtime format. Provided by
the client when the disk image is created.
returned: success
type: str
- sha1_checksum:
+ sha1Checksum:
description:
- An optional SHA1 checksum of the disk image before unpackaging.
- This is provided by the client when the disk image is created.
@@ -224,20 +224,20 @@ items:
either this property or the sourceDisk property but not both.
returned: success
type: str
- source_disk:
+ sourceDisk:
description:
- Refers to a gcompute_disk object You must provide either this property or the rawDisk.source
property but not both to create an image.
returned: success
type: dict
- source_disk_encryption_key:
+ sourceDiskEncryptionKey:
description:
- The customer-supplied encryption key of the source disk. Required if the source
disk is protected by a customer-supplied encryption key.
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -249,14 +249,14 @@ items:
that protects this resource.
returned: success
type: str
- source_disk_id:
+ sourceDiskId:
description:
- The ID value of the disk used to create this image. This value may be used to determine
whether the image was taken from the current or a previous instance of a given disk
name.
returned: success
type: str
- source_type:
+ sourceType:
description:
- The type of the image used to create this disk. The default and only value is RAW
.
@@ -278,7 +278,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance.py b/lib/ansible/modules/cloud/google/gcp_compute_instance.py
index 5ac79538a3..4c52273d07 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance.py
@@ -171,6 +171,11 @@ options:
or disks.source is required.
- If desired, you can also attach existing non-root persistent disks using this property.
This field is only applicable for persistent disks.
+ - 'This field represents a link to a Disk resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_compute_disk task and
+ then set this source field to "{{ name-of-resource }}" Alternatively, you can set
+ this source to a dictionary with the selfLink key where the value is the selfLink
+ of your Disk.'
required: false
type:
description:
@@ -249,6 +254,11 @@ options:
field undefined to use an IP from a shared ephemeral IP address pool. If you specify
a static external IP address, it must live in the same region as the zone of the
instance.
+ - 'This field represents a link to a Address resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_address task
+ and then set this nat_ip field to "{{ name-of-resource }}" Alternatively, you can
+ set this nat_ip to a dictionary with the address key where the value is the address
+ of your Address.'
required: false
type:
description:
@@ -286,6 +296,11 @@ options:
if neither the network nor the subnetwork is specified, the default network global/networks/default
is used; if the network is not specified but the subnetwork is specified, the network
is inferred.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: false
network_ip:
description:
@@ -298,6 +313,11 @@ options:
- If the network resource is in legacy mode, do not provide this property. If the
network is in auto subnet mode, providing the subnetwork is optional. If the network
is in custom subnet mode, then this field should be specified.
+ - 'This field represents a link to a Subnetwork resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_subnetwork
+ task and then set this subnetwork field to "{{ name-of-resource }}" Alternatively,
+ you can set this subnetwork to a dictionary with the selfLink key where the value
+ is the selfLink of your Subnetwork.'
required: false
scheduling:
description:
@@ -417,24 +437,24 @@ EXAMPLES = '''
type: ONE_TO_ONE_NAT
zone: us-central1-a
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- can_ip_forward:
+ canIpForward:
description:
- Allows this instance to send and receive packets with non-matching destination or
source IPs. This is required if you plan to use this instance to forward routes.
returned: success
type: bool
- cpu_platform:
+ cpuPlatform:
description:
- The CPU platform used by this instance.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -446,7 +466,7 @@ RETURN = '''
returned: success
type: complex
contains:
- auto_delete:
+ autoDelete:
description:
- Specifies whether the disk will be auto-deleted when the instance is deleted (but
not when the disk is detached from the instance).
@@ -460,26 +480,26 @@ RETURN = '''
of the disk for its root filesystem.
returned: success
type: bool
- device_name:
+ deviceName:
description:
- Specifies a unique device name of your choice that is reflected into the /dev/disk/by-id/google-*
tree of a Linux operating system running within the instance. This name can be used
to reference the device for mounting, resizing, and so on, from within the instance.
returned: success
type: str
- disk_encryption_key:
+ diskEncryptionKey:
description:
- Encrypts or decrypts a disk using a customer-supplied encryption key.
returned: success
type: complex
contains:
- raw_key:
+ 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
- rsa_encrypted_key:
+ rsaEncryptedKey:
description:
- Specifies an RFC 4648 base64 encoded, RSA-wrapped 2048-bit customer-supplied encryption
key to either encrypt or decrypt this resource.
@@ -498,7 +518,7 @@ RETURN = '''
a unique index number. If not specified, the server will choose an appropriate value.
returned: success
type: int
- initialize_params:
+ initializeParams:
description:
- Specifies the parameters for a new disk that will be created alongside the new instance.
Use initialization parameters to create boot disks or local SSDs attached to the
@@ -506,32 +526,32 @@ RETURN = '''
returned: success
type: complex
contains:
- disk_name:
+ diskName:
description:
- Specifies the disk name. If not specified, the default is to use the name of the
instance.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Specifies the size of the disk in base-2 GB.
returned: success
type: int
- disk_type:
+ diskType:
description:
- Reference to a gcompute_disk_type resource.
- Specifies the disk type to use to create the instance.
- If not specified, the default is pd-standard.
returned: success
type: str
- source_image:
+ sourceImage:
description:
- The source image to create this disk. When creating a new instance, one of initializeParams.sourceImage
or disks.source is required. To create a disk with one of the public operating
system images, specify the image by its family name.
returned: success
type: str
- source_image_encryption_key:
+ sourceImageEncryptionKey:
description:
- The customer-supplied encryption key of the source image. Required if the source
image is protected by a customer-supplied encryption key.
@@ -541,7 +561,7 @@ RETURN = '''
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -581,18 +601,18 @@ RETURN = '''
the default is PERSISTENT.
returned: success
type: str
- guest_accelerators:
+ guestAccelerators:
description:
- List of the type and count of accelerator cards attached to the instance .
returned: success
type: complex
contains:
- accelerator_count:
+ acceleratorCount:
description:
- The number of the guest accelerator cards exposed to this instance.
returned: success
type: int
- accelerator_type:
+ acceleratorType:
description:
- Full or partial URL of the accelerator type resource to expose to this instance.
returned: success
@@ -602,7 +622,7 @@ RETURN = '''
- The unique identifier for the resource. This identifier is defined by the server.
returned: success
type: int
- label_fingerprint:
+ labelFingerprint:
description:
- A fingerprint for this request, which is essentially a hash of the metadata's contents
and used for optimistic locking. The fingerprint is initially generated by Compute
@@ -616,12 +636,12 @@ RETURN = '''
These pairs can consist of custom metadata or predefined keys.
returned: success
type: dict
- machine_type:
+ machineType:
description:
- A reference to a machine type which defines VM kind.
returned: success
type: str
- min_cpu_platform:
+ minCpuPlatform:
description:
- Specifies a minimum CPU platform for the VM instance. Applicable values are the
friendly names of CPU platforms .
@@ -637,7 +657,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- network_interfaces:
+ networkInterfaces:
description:
- An array of configurations for this interface. This specifies how this interface
is configured to interact with other network services, such as connecting to the
@@ -645,7 +665,7 @@ RETURN = '''
returned: success
type: complex
contains:
- access_configs:
+ accessConfigs:
description:
- An array of configurations for this interface. Currently, only one access config,
ONE_TO_ONE_NAT, is supported. If there are no accessConfigs specified, then this
@@ -660,7 +680,7 @@ RETURN = '''
IP or Network Access.
returned: success
type: str
- nat_ip:
+ natIP:
description:
- Specifies the title of a gcompute_address.
- An external IP address associated with this instance.
@@ -675,14 +695,14 @@ RETURN = '''
- The type of configuration. The default and only option is ONE_TO_ONE_NAT.
returned: success
type: str
- alias_ip_ranges:
+ aliasIpRanges:
description:
- An array of alias IP ranges for this network interface. Can only be specified for
network interfaces on subnet-mode networks.
returned: success
type: complex
contains:
- ip_cidr_range:
+ ipCidrRange:
description:
- The IP CIDR range represented by this alias IP range.
- This IP CIDR range must belong to the specified subnetwork and cannot contain IP
@@ -691,7 +711,7 @@ RETURN = '''
(e.g. 10.1.2.0/24).
returned: success
type: str
- subnetwork_range_name:
+ subnetworkRangeName:
description:
- Optional subnetwork secondary range name specifying the secondary range from which
to allocate the IP CIDR range for this alias IP range. If left unspecified, the
@@ -712,7 +732,7 @@ RETURN = '''
is inferred.
returned: success
type: dict
- network_ip:
+ networkIP:
description:
- An IPv4 internal network address to assign to the instance for this network interface.
If not specified by the user, an unused internal IP is assigned by the system.
@@ -732,7 +752,7 @@ RETURN = '''
returned: success
type: complex
contains:
- automatic_restart:
+ automaticRestart:
description:
- Specifies whether the instance should be automatically restarted if it is terminated
by Compute Engine (not terminated by a user).
@@ -740,7 +760,7 @@ RETURN = '''
instances cannot be automatically restarted.
returned: success
type: bool
- on_host_maintenance:
+ onHostMaintenance:
description:
- Defines the maintenance behavior for this instance. For standard instances, the
default behavior is MIGRATE. For preemptible instances, the default and only possible
@@ -754,7 +774,7 @@ RETURN = '''
creation, it cannot be set or changed after the instance has been created.
returned: success
type: bool
- service_accounts:
+ serviceAccounts:
description:
- A list of service accounts, with their specified scopes, authorized for this instance.
Only one service account per VM instance is supported.
@@ -777,7 +797,7 @@ RETURN = '''
RUNNING, STOPPING, SUSPENDING, SUSPENDED, and TERMINATED.'
returned: success
type: str
- status_message:
+ statusMessage:
description:
- An optional, human-readable explanation of the status.
returned: success
@@ -911,7 +931,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -934,9 +955,28 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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('machineType') != request.get('machineType'):
+ machine_type_update(module, request, response)
+
+
+def machine_type_update(module, request, response):
auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ auth.post(
+ ''.join([
+ "https://www.googleapis.com/compute/v1/",
+ "projdcts/{project}/zones/{zone}/instances/{name}/setMachineType"
+ ]).format(**module.params),
+ {
+ u'machineType': machine_type_selflink(module.params.get('machine_type'), module.params)
+ }
+ )
def delete(module, link, kind):
@@ -969,9 +1009,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -982,9 +1022,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instances".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -1001,8 +1041,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -1053,7 +1091,7 @@ def response_to_hash(module, response):
def disk_type_selflink(name, params):
if name is None:
return
- url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/{zone}/diskTypes/[a-z1-9\-]*"
+ url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/[a-z1-9\-]*/diskTypes/[a-z1-9\-]*"
if not re.match(url, name):
name = "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/diskTypes/%s".format(**params) % name
return name
@@ -1062,7 +1100,7 @@ def disk_type_selflink(name, params):
def machine_type_selflink(name, params):
if name is None:
return
- url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/{zone}/machineTypes/[a-z1-9\-]*"
+ url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/[a-z1-9\-]*/machineTypes/[a-z1-9\-]*"
if not re.match(url, name):
name = "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/machineTypes/%s".format(**params) % name
return name
@@ -1112,7 +1150,7 @@ def encode_request(request, module):
def decode_response(response, module):
- if 'metadata' in response:
+ if 'metadata' in response and response['metadata'] is not None:
response['metadata'] = metadata_decoder(response['metadata'])
return response
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_facts.py
index a8fc1d5050..1d1096b8c3 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,18 +71,18 @@ items:
returned: always
type: complex
contains:
- can_ip_forward:
+ canIpForward:
description:
- Allows this instance to send and receive packets with non-matching destination or
source IPs. This is required if you plan to use this instance to forward routes.
returned: success
type: bool
- cpu_platform:
+ cpuPlatform:
description:
- The CPU platform used by this instance.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -94,7 +94,7 @@ items:
returned: success
type: complex
contains:
- auto_delete:
+ autoDelete:
description:
- Specifies whether the disk will be auto-deleted when the instance is deleted (but
not when the disk is detached from the instance).
@@ -108,26 +108,26 @@ items:
of the disk for its root filesystem.
returned: success
type: bool
- device_name:
+ deviceName:
description:
- Specifies a unique device name of your choice that is reflected into the /dev/disk/by-id/google-*
tree of a Linux operating system running within the instance. This name can be used
to reference the device for mounting, resizing, and so on, from within the instance.
returned: success
type: str
- disk_encryption_key:
+ diskEncryptionKey:
description:
- Encrypts or decrypts a disk using a customer-supplied encryption key.
returned: success
type: complex
contains:
- raw_key:
+ 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
- rsa_encrypted_key:
+ rsaEncryptedKey:
description:
- Specifies an RFC 4648 base64 encoded, RSA-wrapped 2048-bit customer-supplied encryption
key to either encrypt or decrypt this resource.
@@ -146,7 +146,7 @@ items:
a unique index number. If not specified, the server will choose an appropriate value.
returned: success
type: int
- initialize_params:
+ initializeParams:
description:
- Specifies the parameters for a new disk that will be created alongside the new instance.
Use initialization parameters to create boot disks or local SSDs attached to the
@@ -154,32 +154,32 @@ items:
returned: success
type: complex
contains:
- disk_name:
+ diskName:
description:
- Specifies the disk name. If not specified, the default is to use the name of the
instance.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Specifies the size of the disk in base-2 GB.
returned: success
type: int
- disk_type:
+ diskType:
description:
- Reference to a gcompute_disk_type resource.
- Specifies the disk type to use to create the instance.
- If not specified, the default is pd-standard.
returned: success
type: str
- source_image:
+ sourceImage:
description:
- The source image to create this disk. When creating a new instance, one of initializeParams.sourceImage
or disks.source is required. To create a disk with one of the public operating
system images, specify the image by its family name.
returned: success
type: str
- source_image_encryption_key:
+ sourceImageEncryptionKey:
description:
- The customer-supplied encryption key of the source image. Required if the source
image is protected by a customer-supplied encryption key.
@@ -189,7 +189,7 @@ items:
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -229,18 +229,18 @@ items:
the default is PERSISTENT.
returned: success
type: str
- guest_accelerators:
+ guestAccelerators:
description:
- List of the type and count of accelerator cards attached to the instance .
returned: success
type: complex
contains:
- accelerator_count:
+ acceleratorCount:
description:
- The number of the guest accelerator cards exposed to this instance.
returned: success
type: int
- accelerator_type:
+ acceleratorType:
description:
- Full or partial URL of the accelerator type resource to expose to this instance.
returned: success
@@ -250,7 +250,7 @@ items:
- The unique identifier for the resource. This identifier is defined by the server.
returned: success
type: int
- label_fingerprint:
+ labelFingerprint:
description:
- A fingerprint for this request, which is essentially a hash of the metadata's contents
and used for optimistic locking. The fingerprint is initially generated by Compute
@@ -264,12 +264,12 @@ items:
These pairs can consist of custom metadata or predefined keys.
returned: success
type: dict
- machine_type:
+ machineType:
description:
- A reference to a machine type which defines VM kind.
returned: success
type: str
- min_cpu_platform:
+ minCpuPlatform:
description:
- Specifies a minimum CPU platform for the VM instance. Applicable values are the
friendly names of CPU platforms .
@@ -285,7 +285,7 @@ items:
be a dash.
returned: success
type: str
- network_interfaces:
+ networkInterfaces:
description:
- An array of configurations for this interface. This specifies how this interface
is configured to interact with other network services, such as connecting to the
@@ -293,7 +293,7 @@ items:
returned: success
type: complex
contains:
- access_configs:
+ accessConfigs:
description:
- An array of configurations for this interface. Currently, only one access config,
ONE_TO_ONE_NAT, is supported. If there are no accessConfigs specified, then this
@@ -308,7 +308,7 @@ items:
IP or Network Access.
returned: success
type: str
- nat_ip:
+ natIP:
description:
- Specifies the title of a gcompute_address.
- An external IP address associated with this instance.
@@ -323,14 +323,14 @@ items:
- The type of configuration. The default and only option is ONE_TO_ONE_NAT.
returned: success
type: str
- alias_ip_ranges:
+ aliasIpRanges:
description:
- An array of alias IP ranges for this network interface. Can only be specified for
network interfaces on subnet-mode networks.
returned: success
type: complex
contains:
- ip_cidr_range:
+ ipCidrRange:
description:
- The IP CIDR range represented by this alias IP range.
- This IP CIDR range must belong to the specified subnetwork and cannot contain IP
@@ -339,7 +339,7 @@ items:
(e.g. 10.1.2.0/24).
returned: success
type: str
- subnetwork_range_name:
+ subnetworkRangeName:
description:
- Optional subnetwork secondary range name specifying the secondary range from which
to allocate the IP CIDR range for this alias IP range. If left unspecified, the
@@ -360,7 +360,7 @@ items:
is inferred.
returned: success
type: dict
- network_ip:
+ networkIP:
description:
- An IPv4 internal network address to assign to the instance for this network interface.
If not specified by the user, an unused internal IP is assigned by the system.
@@ -380,7 +380,7 @@ items:
returned: success
type: complex
contains:
- automatic_restart:
+ automaticRestart:
description:
- Specifies whether the instance should be automatically restarted if it is terminated
by Compute Engine (not terminated by a user).
@@ -388,7 +388,7 @@ items:
instances cannot be automatically restarted.
returned: success
type: bool
- on_host_maintenance:
+ onHostMaintenance:
description:
- Defines the maintenance behavior for this instance. For standard instances, the
default behavior is MIGRATE. For preemptible instances, the default and only possible
@@ -402,7 +402,7 @@ items:
creation, it cannot be set or changed after the instance has been created.
returned: success
type: bool
- service_accounts:
+ serviceAccounts:
description:
- A list of service accounts, with their specified scopes, authorized for this instance.
Only one service account per VM instance is supported.
@@ -425,7 +425,7 @@ items:
RUNNING, STOPPING, SUSPENDING, SUSPENDED, and TERMINATED.'
returned: success
type: str
- status_message:
+ statusMessage:
description:
- An optional, human-readable explanation of the status.
returned: success
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_group.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_group.py
index 276798dcc8..f1b711e03f 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_group.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_group.py
@@ -81,6 +81,11 @@ options:
network:
description:
- The network to which all instances in the instance group belong.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: false
region:
description:
@@ -89,11 +94,25 @@ options:
subnetwork:
description:
- The subnetwork to which all instances in the instance group belong.
+ - 'This field represents a link to a Subnetwork resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_subnetwork
+ task and then set this subnetwork field to "{{ name-of-resource }}" Alternatively,
+ you can set this subnetwork to a dictionary with the selfLink key where the value
+ is the selfLink of your Subnetwork.'
required: false
zone:
description:
- A reference to the zone where the instance group resides.
required: true
+ instances:
+ description:
+ - The list of instances associated with this InstanceGroup.
+ - All instances must be created before being added to an InstanceGroup.
+ - All instances not in this list will be removed from the InstanceGroup and will not
+ be deleted.
+ - Only the full identifier of the instance will be returned.
+ required: false
+ version_added: 2.8
extends_documentation_fragment: gcp
'''
@@ -116,13 +135,13 @@ EXAMPLES = '''
network: "{{ network }}"
zone: us-central1-a
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -144,7 +163,7 @@ RETURN = '''
- The name must be 1-63 characters long, and comply with RFC1035.
returned: success
type: str
- named_ports:
+ namedPorts:
description:
- Assigns a name to a port number.
- 'For example: {name: "http", port: 80}.'
@@ -186,6 +205,15 @@ RETURN = '''
- A reference to the zone where the instance group resides.
returned: success
type: str
+ instances:
+ description:
+ - The list of instances associated with this InstanceGroup.
+ - All instances must be created before being added to an InstanceGroup.
+ - All instances not in this list will be removed from the InstanceGroup and will not
+ be deleted.
+ - Only the full identifier of the instance will be returned.
+ returned: success
+ type: list
'''
################################################################################
@@ -217,7 +245,8 @@ def main():
network=dict(type='dict'),
region=dict(type='str'),
subnetwork=dict(type='dict'),
- zone=dict(required=True, type='str')
+ zone=dict(required=True, type='str'),
+ instances=dict(type='list', elements='dict')
)
)
@@ -233,7 +262,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -246,6 +276,10 @@ def main():
else:
fetch = {}
+ if fetch:
+ instance = InstanceLogic(module)
+ instance.run()
+ fetch.update({'instances': instance.list_instances()})
fetch.update({'changed': changed})
module.exit_json(**fetch)
@@ -257,7 +291,8 @@ def create(module, link, kind):
def update(module, link, kind):
- module.fail_json(msg="InstanceGroup cannot be edited")
+ instance = InstanceLogic(module)
+ instance.run()
def delete(module, link, kind):
@@ -283,9 +318,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -296,9 +331,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -313,8 +348,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -398,6 +431,66 @@ def raise_if_errors(response, err_path, module):
module.fail_json(msg=errors)
+class InstanceLogic(object):
+ def __init__(self, module):
+ self.module = module
+ self.current_instances = self.list_instances()
+ self.module_instances = []
+
+ # Transform module list of instances (dicts of instance responses) into a list of selfLinks.
+ instances = self.module.params.get('instances')
+ if instances:
+ for instance in instances:
+ self.module_instances.append(replace_resource_dict(instance, 'selfLink'))
+
+ def run(self):
+ # Find all instances to add and add them
+ instances_to_add = list(set(self.module_instances) - set(self.current_instances))
+ if instances_to_add:
+ self.add_instances(instances_to_add)
+
+ # Find all instances to remove and remove them
+ instances_to_remove = list(set(self.current_instances) - set(self.module_instances))
+ if instances_to_remove:
+ self.remove_instances(instances_to_remove)
+
+ def list_instances(self):
+ auth = GcpSession(self.module, 'compute')
+ response = return_if_object(self.module, auth.post(self._list_instances_url(), {'instanceState': 'ALL'}),
+ 'compute#instanceGroupsListInstances')
+
+ # Transform instance list into a list of selfLinks for diffing with module parameters
+ instances = []
+ for instance in response.get('items', []):
+ instances.append(instance['instance'])
+ return instances
+
+ def add_instances(self, instances):
+ auth = GcpSession(self.module, 'compute')
+ wait_for_operation(self.module, auth.post(self._add_instances_url(), self._build_request(instances)))
+
+ def remove_instances(self, instances):
+ auth = GcpSession(self.module, 'compute')
+ wait_for_operation(self.module, auth.post(self._remove_instances_url(), self._build_request(instances)))
+
+ def _list_instances_url(self):
+ return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups/{name}/listInstances".format(**self.module.params)
+
+ def _remove_instances_url(self):
+ return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups/{name}/removeInstances".format(**self.module.params)
+
+ def _add_instances_url(self):
+ return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups/{name}/addInstances".format(**self.module.params)
+
+ def _build_request(self, instances):
+ request = {
+ 'instances': []
+ }
+ for instance in instances:
+ request['instances'].append({'instance': instance})
+ return request
+
+
class InstanceGroupNamedPortsArray(object):
def __init__(self, request, module):
self.module = module
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_group_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_group_facts.py
index 9ffccbf34c..952363ec5a 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_group_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_group_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -93,7 +93,7 @@ items:
- The name must be 1-63 characters long, and comply with RFC1035.
returned: success
type: str
- named_ports:
+ namedPorts:
description:
- Assigns a name to a port number.
- 'For example: {name: "http", port: 80}.'
@@ -135,6 +135,15 @@ items:
- A reference to the zone where the instance group resides.
returned: success
type: str
+ instances:
+ description:
+ - The list of instances associated with this InstanceGroup.
+ - All instances must be created before being added to an InstanceGroup.
+ - All instances not in this list will be removed from the InstanceGroup and will not
+ be deleted.
+ - Only the full identifier of the instance will be returned.
+ returned: success
+ type: list
'''
################################################################################
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager.py
index c3e39d3d53..f48f8c2d69 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager.py
@@ -67,6 +67,11 @@ options:
description:
- The instance template that is specified for this managed instance group. The group
uses this template to create all new instances in the managed instance group.
+ - 'This field represents a link to a InstanceTemplate resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_instance_template
+ task and then set this instance_template field to "{{ name-of-resource }}" Alternatively,
+ you can set this instance_template to a dictionary with the selfLink key where the
+ value is the selfLink of your InstanceTemplate.'
required: true
name:
description:
@@ -156,13 +161,13 @@ EXAMPLES = '''
target_size: 3
zone: us-west1-a
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- base_instance_name:
+ baseInstanceName:
description:
- The base instance name to use for instances in this group. The value must be 1-58
characters long. Instances are named by appending a hyphen and a random four-character
@@ -170,12 +175,12 @@ RETURN = '''
- The base instance name must comply with RFC1035.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- The creation timestamp for this managed instance group in RFC3339 text format.
returned: success
type: str
- current_actions:
+ currentActions:
description:
- The list of instance actions and the number of instances in this managed instance
group that are scheduled for each of those actions.
@@ -198,7 +203,7 @@ RETURN = '''
the creatingWithoutRetries field will be populated.
returned: success
type: int
- creating_without_retries:
+ creatingWithoutRetries:
description:
- The number of instances that the managed instance group will attempt to create.
The group attempts to create each instance only once. If the group fails to create
@@ -249,12 +254,12 @@ RETURN = '''
- A unique identifier for this resource.
returned: success
type: int
- instance_group:
+ instanceGroup:
description:
- The instance group being managed.
returned: success
type: dict
- instance_template:
+ instanceTemplate:
description:
- The instance template that is specified for this managed instance group. The group
uses this template to create all new instances in the managed instance group.
@@ -266,7 +271,7 @@ RETURN = '''
comply with RFC1035.
returned: success
type: str
- named_ports:
+ namedPorts:
description:
- Named ports configured for the Instance Groups complementary to this Instance Group
Manager.
@@ -289,14 +294,14 @@ RETURN = '''
- The region this managed instance group resides (for regional resources).
returned: success
type: str
- target_pools:
+ targetPools:
description:
- TargetPool resources to which instances in the instanceGroup field are added. The
target pools automatically apply to all of the instances in the managed instance
group.
returned: success
type: list
- target_size:
+ targetSize:
description:
- The target number of running instances for this managed instance group. Deleting
or abandoning instances reduces this number. Resizing the group changes this number.
@@ -355,7 +360,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -407,9 +413,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -420,9 +426,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroupManagers".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -437,8 +443,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager_facts.py
index 2d8928b6e9..5db47bbdb1 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_group_manager_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
returned: always
type: complex
contains:
- base_instance_name:
+ baseInstanceName:
description:
- The base instance name to use for instances in this group. The value must be 1-58
characters long. Instances are named by appending a hyphen and a random four-character
@@ -79,12 +79,12 @@ items:
- The base instance name must comply with RFC1035.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- The creation timestamp for this managed instance group in RFC3339 text format.
returned: success
type: str
- current_actions:
+ currentActions:
description:
- The list of instance actions and the number of instances in this managed instance
group that are scheduled for each of those actions.
@@ -107,7 +107,7 @@ items:
the creatingWithoutRetries field will be populated.
returned: success
type: int
- creating_without_retries:
+ creatingWithoutRetries:
description:
- The number of instances that the managed instance group will attempt to create.
The group attempts to create each instance only once. If the group fails to create
@@ -158,12 +158,12 @@ items:
- A unique identifier for this resource.
returned: success
type: int
- instance_group:
+ instanceGroup:
description:
- The instance group being managed.
returned: success
type: dict
- instance_template:
+ instanceTemplate:
description:
- The instance template that is specified for this managed instance group. The group
uses this template to create all new instances in the managed instance group.
@@ -175,7 +175,7 @@ items:
comply with RFC1035.
returned: success
type: str
- named_ports:
+ namedPorts:
description:
- Named ports configured for the Instance Groups complementary to this Instance Group
Manager.
@@ -198,14 +198,14 @@ items:
- The region this managed instance group resides (for regional resources).
returned: success
type: str
- target_pools:
+ targetPools:
description:
- TargetPool resources to which instances in the instanceGroup field are added. The
target pools automatically apply to all of the instances in the managed instance
group.
returned: success
type: list
- target_size:
+ targetSize:
description:
- The target number of running instances for this managed instance group. Deleting
or abandoning instances reduces this number. Resizing the group changes this number.
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_template.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_template.py
index a3b4919e7f..519f965f15 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_template.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_template.py
@@ -200,6 +200,11 @@ options:
- If desired, you can also attach existing non-root persistent disks using this property.
This field is only applicable for persistent disks.
- Note that for InstanceTemplate, specify the disk name, not the URL for the disk.
+ - 'This field represents a link to a Disk resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_compute_disk task and
+ then set this source field to "{{ name-of-resource }}" Alternatively, you can set
+ this source to a dictionary with the name key where the value is the name of your
+ Disk.'
required: false
type:
description:
@@ -257,6 +262,11 @@ options:
field undefined to use an IP from a shared ephemeral IP address pool. If you specify
a static external IP address, it must live in the same region as the zone of the
instance.
+ - 'This field represents a link to a Address resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_address task
+ and then set this nat_ip field to "{{ name-of-resource }}" Alternatively, you can
+ set this nat_ip to a dictionary with the address key where the value is the address
+ of your Address.'
required: false
type:
description:
@@ -294,6 +304,11 @@ options:
if neither the network nor the subnetwork is specified, the default network global/networks/default
is used; if the network is not specified but the subnetwork is specified, the network
is inferred.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: false
network_ip:
description:
@@ -306,6 +321,11 @@ options:
- If the network resource is in legacy mode, do not provide this property. If the
network is in auto subnet mode, providing the subnetwork is optional. If the network
is in custom subnet mode, then this field should be specified.
+ - 'This field represents a link to a Subnetwork resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_subnetwork
+ task and then set this subnetwork field to "{{ name-of-resource }}" Alternatively,
+ you can set this subnetwork to a dictionary with the selfLink key where the value
+ is the selfLink of your Subnetwork.'
required: false
scheduling:
description:
@@ -407,13 +427,13 @@ EXAMPLES = '''
type: ONE_TO_ONE_NAT
nat_ip: "{{ address }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -440,7 +460,7 @@ RETURN = '''
returned: success
type: complex
contains:
- can_ip_forward:
+ canIpForward:
description:
- Enables instances created based on this template to send packets with source IP
addresses other than their own and receive packets with destination IP addresses
@@ -462,7 +482,7 @@ RETURN = '''
returned: success
type: complex
contains:
- auto_delete:
+ autoDelete:
description:
- Specifies whether the disk will be auto-deleted when the instance is deleted (but
not when the disk is detached from the instance).
@@ -476,26 +496,26 @@ RETURN = '''
of the disk for its root filesystem.
returned: success
type: bool
- device_name:
+ deviceName:
description:
- Specifies a unique device name of your choice that is reflected into the /dev/disk/by-id/google-*
tree of a Linux operating system running within the instance. This name can be used
to reference the device for mounting, resizing, and so on, from within the instance.
returned: success
type: str
- disk_encryption_key:
+ diskEncryptionKey:
description:
- Encrypts or decrypts a disk using a customer-supplied encryption key.
returned: success
type: complex
contains:
- raw_key:
+ 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
- rsa_encrypted_key:
+ rsaEncryptedKey:
description:
- Specifies an RFC 4648 base64 encoded, RSA-wrapped 2048-bit customer-supplied encryption
key to either encrypt or decrypt this resource.
@@ -514,7 +534,7 @@ RETURN = '''
a unique index number. If not specified, the server will choose an appropriate value.
returned: success
type: int
- initialize_params:
+ initializeParams:
description:
- Specifies the parameters for a new disk that will be created alongside the new instance.
Use initialization parameters to create boot disks or local SSDs attached to the
@@ -522,32 +542,32 @@ RETURN = '''
returned: success
type: complex
contains:
- disk_name:
+ diskName:
description:
- Specifies the disk name. If not specified, the default is to use the name of the
instance.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Specifies the size of the disk in base-2 GB.
returned: success
type: int
- disk_type:
+ diskType:
description:
- Reference to a gcompute_disk_type resource.
- Specifies the disk type to use to create the instance.
- If not specified, the default is pd-standard.
returned: success
type: str
- source_image:
+ sourceImage:
description:
- The source image to create this disk. When creating a new instance, one of initializeParams.sourceImage
or disks.source is required. To create a disk with one of the public operating
system images, specify the image by its family name.
returned: success
type: str
- source_image_encryption_key:
+ sourceImageEncryptionKey:
description:
- The customer-supplied encryption key of the source image. Required if the source
image is protected by a customer-supplied encryption key.
@@ -557,7 +577,7 @@ RETURN = '''
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -598,7 +618,7 @@ RETURN = '''
the default is PERSISTENT.
returned: success
type: str
- machine_type:
+ machineType:
description:
- Reference to a gcompute_machine_type resource.
returned: success
@@ -609,23 +629,23 @@ RETURN = '''
These pairs can consist of custom metadata or predefined keys.
returned: success
type: dict
- guest_accelerators:
+ guestAccelerators:
description:
- List of the type and count of accelerator cards attached to the instance .
returned: success
type: complex
contains:
- accelerator_count:
+ acceleratorCount:
description:
- The number of the guest accelerator cards exposed to this instance.
returned: success
type: int
- accelerator_type:
+ acceleratorType:
description:
- Full or partial URL of the accelerator type resource to expose to this instance.
returned: success
type: str
- network_interfaces:
+ networkInterfaces:
description:
- An array of configurations for this interface. This specifies how this interface
is configured to interact with other network services, such as connecting to the
@@ -633,7 +653,7 @@ RETURN = '''
returned: success
type: complex
contains:
- access_configs:
+ accessConfigs:
description:
- An array of configurations for this interface. Currently, only one access config,
ONE_TO_ONE_NAT, is supported. If there are no accessConfigs specified, then this
@@ -648,7 +668,7 @@ RETURN = '''
IP or Network Access.
returned: success
type: str
- nat_ip:
+ natIP:
description:
- Specifies the title of a gcompute_address.
- An external IP address associated with this instance.
@@ -663,14 +683,14 @@ RETURN = '''
- The type of configuration. The default and only option is ONE_TO_ONE_NAT.
returned: success
type: str
- alias_ip_ranges:
+ aliasIpRanges:
description:
- An array of alias IP ranges for this network interface. Can only be specified for
network interfaces on subnet-mode networks.
returned: success
type: complex
contains:
- ip_cidr_range:
+ ipCidrRange:
description:
- The IP CIDR range represented by this alias IP range.
- This IP CIDR range must belong to the specified subnetwork and cannot contain IP
@@ -679,7 +699,7 @@ RETURN = '''
(e.g. 10.1.2.0/24).
returned: success
type: str
- subnetwork_range_name:
+ subnetworkRangeName:
description:
- Optional subnetwork secondary range name specifying the secondary range from which
to allocate the IP CIDR range for this alias IP range. If left unspecified, the
@@ -700,7 +720,7 @@ RETURN = '''
is inferred.
returned: success
type: dict
- network_ip:
+ networkIP:
description:
- An IPv4 internal network address to assign to the instance for this network interface.
If not specified by the user, an unused internal IP is assigned by the system.
@@ -720,7 +740,7 @@ RETURN = '''
returned: success
type: complex
contains:
- automatic_restart:
+ automaticRestart:
description:
- Specifies whether the instance should be automatically restarted if it is terminated
by Compute Engine (not terminated by a user).
@@ -728,7 +748,7 @@ RETURN = '''
instances cannot be automatically restarted.
returned: success
type: bool
- on_host_maintenance:
+ onHostMaintenance:
description:
- Defines the maintenance behavior for this instance. For standard instances, the
default behavior is MIGRATE. For preemptible instances, the default and only possible
@@ -742,7 +762,7 @@ RETURN = '''
creation, it cannot be set or changed after the instance has been created.
returned: success
type: bool
- service_accounts:
+ serviceAccounts:
description:
- A list of service accounts, with their specified scopes, authorized for this instance.
Only one service account per VM instance is supported.
@@ -884,7 +904,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -908,8 +929,7 @@ def create(module, link, kind):
def update(module, link, kind):
- auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ module.fail_json(msg="InstanceTemplate cannot be edited")
def delete(module, link, kind):
@@ -933,9 +953,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -946,9 +966,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/instanceTemplates".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -965,8 +985,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -1005,7 +1023,7 @@ def response_to_hash(module, response):
def disk_type_selflink(name, params):
if name is None:
return
- url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/{zone}/diskTypes/[a-z1-9\-]*"
+ url = r"https://www.googleapis.com/compute/v1/projects/.*/zones/[a-z1-9\-]*/diskTypes/[a-z1-9\-]*"
if not re.match(url, name):
name = "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/diskTypes/%s".format(**params) % name
return name
@@ -1049,13 +1067,13 @@ def raise_if_errors(response, err_path, module):
def encode_request(request, module):
- if 'metadata' in request:
+ if 'metadata' in request and request['metadata'] is not None:
request['metadata'] = metadata_encoder(request['metadata'])
return request
def decode_response(response, module):
- if 'metadata' in response:
+ if 'metadata' in response and response['metadata'] is not None:
response['metadata'] = metadata_decoder(response['metadata'])
return response
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_instance_template_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_instance_template_facts.py
index aca57a632c..5d687b9d92 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_instance_template_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_instance_template_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -93,7 +93,7 @@ items:
returned: success
type: complex
contains:
- can_ip_forward:
+ canIpForward:
description:
- Enables instances created based on this template to send packets with source IP
addresses other than their own and receive packets with destination IP addresses
@@ -115,7 +115,7 @@ items:
returned: success
type: complex
contains:
- auto_delete:
+ autoDelete:
description:
- Specifies whether the disk will be auto-deleted when the instance is deleted (but
not when the disk is detached from the instance).
@@ -129,26 +129,26 @@ items:
of the disk for its root filesystem.
returned: success
type: bool
- device_name:
+ deviceName:
description:
- Specifies a unique device name of your choice that is reflected into the /dev/disk/by-id/google-*
tree of a Linux operating system running within the instance. This name can be used
to reference the device for mounting, resizing, and so on, from within the instance.
returned: success
type: str
- disk_encryption_key:
+ diskEncryptionKey:
description:
- Encrypts or decrypts a disk using a customer-supplied encryption key.
returned: success
type: complex
contains:
- raw_key:
+ 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
- rsa_encrypted_key:
+ rsaEncryptedKey:
description:
- Specifies an RFC 4648 base64 encoded, RSA-wrapped 2048-bit customer-supplied encryption
key to either encrypt or decrypt this resource.
@@ -167,7 +167,7 @@ items:
a unique index number. If not specified, the server will choose an appropriate value.
returned: success
type: int
- initialize_params:
+ initializeParams:
description:
- Specifies the parameters for a new disk that will be created alongside the new instance.
Use initialization parameters to create boot disks or local SSDs attached to the
@@ -175,32 +175,32 @@ items:
returned: success
type: complex
contains:
- disk_name:
+ diskName:
description:
- Specifies the disk name. If not specified, the default is to use the name of the
instance.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Specifies the size of the disk in base-2 GB.
returned: success
type: int
- disk_type:
+ diskType:
description:
- Reference to a gcompute_disk_type resource.
- Specifies the disk type to use to create the instance.
- If not specified, the default is pd-standard.
returned: success
type: str
- source_image:
+ sourceImage:
description:
- The source image to create this disk. When creating a new instance, one of initializeParams.sourceImage
or disks.source is required. To create a disk with one of the public operating
system images, specify the image by its family name.
returned: success
type: str
- source_image_encryption_key:
+ sourceImageEncryptionKey:
description:
- The customer-supplied encryption key of the source image. Required if the source
image is protected by a customer-supplied encryption key.
@@ -210,7 +210,7 @@ items:
returned: success
type: complex
contains:
- raw_key:
+ rawKey:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
@@ -251,7 +251,7 @@ items:
the default is PERSISTENT.
returned: success
type: str
- machine_type:
+ machineType:
description:
- Reference to a gcompute_machine_type resource.
returned: success
@@ -262,23 +262,23 @@ items:
These pairs can consist of custom metadata or predefined keys.
returned: success
type: dict
- guest_accelerators:
+ guestAccelerators:
description:
- List of the type and count of accelerator cards attached to the instance .
returned: success
type: complex
contains:
- accelerator_count:
+ acceleratorCount:
description:
- The number of the guest accelerator cards exposed to this instance.
returned: success
type: int
- accelerator_type:
+ acceleratorType:
description:
- Full or partial URL of the accelerator type resource to expose to this instance.
returned: success
type: str
- network_interfaces:
+ networkInterfaces:
description:
- An array of configurations for this interface. This specifies how this interface
is configured to interact with other network services, such as connecting to the
@@ -286,7 +286,7 @@ items:
returned: success
type: complex
contains:
- access_configs:
+ accessConfigs:
description:
- An array of configurations for this interface. Currently, only one access config,
ONE_TO_ONE_NAT, is supported. If there are no accessConfigs specified, then this
@@ -301,7 +301,7 @@ items:
IP or Network Access.
returned: success
type: str
- nat_ip:
+ natIP:
description:
- Specifies the title of a gcompute_address.
- An external IP address associated with this instance.
@@ -316,14 +316,14 @@ items:
- The type of configuration. The default and only option is ONE_TO_ONE_NAT.
returned: success
type: str
- alias_ip_ranges:
+ aliasIpRanges:
description:
- An array of alias IP ranges for this network interface. Can only be specified for
network interfaces on subnet-mode networks.
returned: success
type: complex
contains:
- ip_cidr_range:
+ ipCidrRange:
description:
- The IP CIDR range represented by this alias IP range.
- This IP CIDR range must belong to the specified subnetwork and cannot contain IP
@@ -332,7 +332,7 @@ items:
(e.g. 10.1.2.0/24).
returned: success
type: str
- subnetwork_range_name:
+ subnetworkRangeName:
description:
- Optional subnetwork secondary range name specifying the secondary range from which
to allocate the IP CIDR range for this alias IP range. If left unspecified, the
@@ -353,7 +353,7 @@ items:
is inferred.
returned: success
type: dict
- network_ip:
+ networkIP:
description:
- An IPv4 internal network address to assign to the instance for this network interface.
If not specified by the user, an unused internal IP is assigned by the system.
@@ -373,7 +373,7 @@ items:
returned: success
type: complex
contains:
- automatic_restart:
+ automaticRestart:
description:
- Specifies whether the instance should be automatically restarted if it is terminated
by Compute Engine (not terminated by a user).
@@ -381,7 +381,7 @@ items:
instances cannot be automatically restarted.
returned: success
type: bool
- on_host_maintenance:
+ onHostMaintenance:
description:
- Defines the maintenance behavior for this instance. For standard instances, the
default behavior is MIGRATE. For preemptible instances, the default and only possible
@@ -395,7 +395,7 @@ items:
creation, it cannot be set or changed after the instance has been created.
returned: success
type: bool
- service_accounts:
+ serviceAccounts:
description:
- A list of service accounts, with their specified scopes, authorized for this instance.
Only one service account per VM instance is supported.
@@ -451,7 +451,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_network.py b/lib/ansible/modules/cloud/google/gcp_compute_network.py
index f5cda92606..4eccbc5fc1 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_network.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_network.py
@@ -62,12 +62,6 @@ options:
- An optional description of this resource. Provide this property when you create
the resource.
required: false
- gateway_ipv4:
- description:
- - A gateway address for default routing to other networks. This value is read only
- and is selected by the Google Compute Engine, typically as the first usable address
- in the IPv4Range.
- required: false
ipv4_range:
description:
- 'The range of internal addresses that are legal on this network. This range is a
@@ -82,7 +76,7 @@ options:
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: false
+ required: true
auto_create_subnetworks:
description:
- When set to true, the network is created in "auto subnet mode". When set to false,
@@ -91,7 +85,25 @@ options:
and it automatically creates one subnetwork per region.
required: false
type: bool
+ routing_config:
+ description:
+ - The network-level routing configuration for this network. Used by Cloud Router to
+ determine what type of network-wide routing behavior to enforce.
+ required: false
+ version_added: 2.8
+ suboptions:
+ routing_mode:
+ description:
+ - The network-wide routing mode to use. If set to REGIONAL, this network's cloud routers
+ will only advertise routes with subnetworks of this network in the same region as
+ the router. If set to GLOBAL, this network's cloud routers will advertise routes
+ with all subnetworks of this network, across regions.
+ required: true
+ choices: ['REGIONAL', 'GLOBAL']
extends_documentation_fragment: gcp
+notes:
+ - "API Reference: U(https://cloud.google.com/compute/docs/reference/rest/v1/networks)"
+ - "Official Documentation: U(https://cloud.google.com/vpc/docs/vpc)"
'''
EXAMPLES = '''
@@ -100,7 +112,7 @@ EXAMPLES = '''
name: "test_object"
auto_create_subnetworks: true
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -146,7 +158,7 @@ RETURN = '''
- Server-defined fully-qualified URLs for all subnetworks in this network.
returned: success
type: list
- auto_create_subnetworks:
+ autoCreateSubnetworks:
description:
- When set to true, the network is created in "auto subnet mode". When set to false,
the network is in "custom subnet mode".
@@ -154,18 +166,33 @@ RETURN = '''
and it automatically creates one subnetwork per region.
returned: success
type: bool
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
type: str
+ routingConfig:
+ description:
+ - The network-level routing configuration for this network. Used by Cloud Router to
+ determine what type of network-wide routing behavior to enforce.
+ returned: success
+ type: complex
+ contains:
+ routingMode:
+ description:
+ - The network-wide routing mode to use. If set to REGIONAL, this network's cloud routers
+ will only advertise routes with subnetworks of this network in the same region as
+ the router. If set to GLOBAL, this network's cloud routers will advertise routes
+ with all subnetworks of this network, across regions.
+ returned: success
+ type: str
'''
################################################################################
# Imports
################################################################################
-from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, replace_resource_dict
+from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, remove_nones_from_dict, replace_resource_dict
import json
import time
@@ -181,10 +208,12 @@ def main():
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'),
description=dict(type='str'),
- gateway_ipv4=dict(type='str'),
ipv4_range=dict(type='str'),
- name=dict(type='str'),
- auto_create_subnetworks=dict(type='bool')
+ name=dict(required=True, type='str'),
+ auto_create_subnetworks=dict(type='bool'),
+ routing_config=dict(type='list', elements='dict', options=dict(
+ routing_mode=dict(required=True, type='str', choices=['REGIONAL', 'GLOBAL'])
+ ))
)
)
@@ -200,7 +229,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -223,9 +253,29 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+def update(module, link, kind, fetch):
+ update_fields(module, resource_to_request(module),
+ response_to_hash(module, fetch))
auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ return wait_for_operation(module, auth.patch(link, resource_to_request(module)))
+
+
+def update_fields(module, request, response):
+ if response.get('routingConfig') != request.get('routingConfig'):
+ routing_config_update(module, request, response)
+
+
+def routing_config_update(module, request, response):
+ auth = GcpSession(module, 'compute')
+ auth.patch(
+ ''.join([
+ "https://www.googleapis.com/compute/v1/",
+ "projects/{project}/regions/{region}/subnetworks/{name}"
+ ]).format(**module.params),
+ {
+ u'routingConfig': NetworkRoutingConfigArray(module.params.get('routing_config', []), module).to_request()
+ }
+ )
def delete(module, link, kind):
@@ -237,10 +287,10 @@ def resource_to_request(module):
request = {
u'kind': 'compute#network',
u'description': module.params.get('description'),
- u'gatewayIPv4': module.params.get('gateway_ipv4'),
u'IPv4Range': module.params.get('ipv4_range'),
u'name': module.params.get('name'),
- u'autoCreateSubnetworks': module.params.get('auto_create_subnetworks')
+ u'autoCreateSubnetworks': module.params.get('auto_create_subnetworks'),
+ u'routingConfig': NetworkRoutingConfigArray(module.params.get('routing_config', []), module).to_request()
}
return_vals = {}
for k, v in request.items():
@@ -250,9 +300,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -263,9 +313,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/networks".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -280,8 +330,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -308,14 +356,15 @@ def is_different(module, response):
# This is for doing comparisons with Ansible's current parameters.
def response_to_hash(module, response):
return {
- u'description': response.get(u'description'),
+ u'description': module.params.get('description'),
u'gatewayIPv4': response.get(u'gateway_ipv4'),
u'id': response.get(u'id'),
- u'IPv4Range': response.get(u'ipv4_range'),
- u'name': response.get(u'name'),
+ u'IPv4Range': module.params.get('ipv4_range'),
+ u'name': module.params.get('name'),
u'subnetworks': response.get(u'subnetworks'),
- u'autoCreateSubnetworks': response.get(u'autoCreateSubnetworks'),
- u'creationTimestamp': response.get(u'creationTimestamp')
+ u'autoCreateSubnetworks': module.params.get('auto_create_subnetworks'),
+ u'creationTimestamp': response.get(u'creationTimestamp'),
+ u'routingConfig': NetworkRoutingConfigArray(response.get(u'routingConfig', []), module).from_response()
}
@@ -356,5 +405,36 @@ def raise_if_errors(response, err_path, module):
module.fail_json(msg=errors)
+class NetworkRoutingConfigArray(object):
+ def __init__(self, request, module):
+ self.module = module
+ if request:
+ self.request = request
+ else:
+ self.request = []
+
+ def to_request(self):
+ items = []
+ for item in self.request:
+ items.append(self._request_for_item(item))
+ return items
+
+ def from_response(self):
+ items = []
+ for item in self.request:
+ items.append(self._response_from_item(item))
+ return items
+
+ def _request_for_item(self, item):
+ return remove_nones_from_dict({
+ u'routingMode': item.get('routing_mode')
+ })
+
+ def _response_from_item(self, item):
+ return remove_nones_from_dict({
+ u'routingMode': item.get(u'routingMode')
+ })
+
+
if __name__ == '__main__':
main()
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_network_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_network_facts.py
index 22a32ffeb0..f7c87a316c 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_network_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_network_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -106,7 +106,7 @@ items:
- Server-defined fully-qualified URLs for all subnetworks in this network.
returned: success
type: list
- auto_create_subnetworks:
+ autoCreateSubnetworks:
description:
- When set to true, the network is created in "auto subnet mode". When set to false,
the network is in "custom subnet mode".
@@ -114,11 +114,26 @@ items:
and it automatically creates one subnetwork per region.
returned: success
type: bool
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
type: str
+ routingConfig:
+ description:
+ - The network-level routing configuration for this network. Used by Cloud Router to
+ determine what type of network-wide routing behavior to enforce.
+ returned: success
+ type: complex
+ contains:
+ routingMode:
+ description:
+ - The network-wide routing mode to use. If set to REGIONAL, this network's cloud routers
+ will only advertise routes with subnetworks of this network in the same region as
+ the router. If set to GLOBAL, this network's cloud routers will advertise routes
+ with all subnetworks of this network, across regions.
+ returned: success
+ type: str
'''
################################################################################
@@ -135,7 +150,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_route.py b/lib/ansible/modules/cloud/google/gcp_compute_route.py
index 1a61e098b6..bbda85c765 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_route.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_route.py
@@ -84,6 +84,11 @@ options:
network:
description:
- The network that this route applies to.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: true
priority:
description:
@@ -146,13 +151,13 @@ EXAMPLES = '''
- backends
- databases
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- dest_range:
+ destRange:
description:
- The destination range of outgoing packets that this route applies to.
- Only IPv4 is supported.
@@ -193,7 +198,7 @@ RETURN = '''
- A list of instance tags to which this route applies.
returned: success
type: list
- next_hop_gateway:
+ nextHopGateway:
description:
- URL to a gateway that should handle matching packets.
- 'Currently, you can only specify the internet gateway, using a full or partial valid
@@ -202,7 +207,7 @@ RETURN = '''
.'
returned: success
type: str
- next_hop_instance:
+ nextHopInstance:
description:
- URL to an instance that should handle matching packets.
- 'You can specify this as a full or partial URL. For example: * U(https://www.googleapis.com/compute/v1/projects/project/zones/zone/)
@@ -210,17 +215,17 @@ RETURN = '''
.'
returned: success
type: str
- next_hop_ip:
+ nextHopIp:
description:
- Network IP address of an instance that should handle matching packets.
returned: success
type: str
- next_hop_vpn_tunnel:
+ nextHopVpnTunnel:
description:
- URL to a VpnTunnel that should handle matching packets.
returned: success
type: str
- next_hop_network:
+ nextHopNetwork:
description:
- URL to a Network that should handle matching packets.
returned: success
@@ -271,7 +276,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -295,8 +301,7 @@ def create(module, link, kind):
def update(module, link, kind):
- auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ module.fail_json(msg="Route cannot be edited")
def delete(module, link, kind):
@@ -326,9 +331,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -339,9 +344,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/routes".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -356,8 +361,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_route_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_route_facts.py
index e9b1a43856..312d9af00c 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_route_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_route_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- dest_range:
+ destRange:
description:
- The destination range of outgoing packets that this route applies to.
- Only IPv4 is supported.
@@ -107,7 +107,7 @@ items:
- A list of instance tags to which this route applies.
returned: success
type: list
- next_hop_gateway:
+ nextHopGateway:
description:
- URL to a gateway that should handle matching packets.
- 'Currently, you can only specify the internet gateway, using a full or partial valid
@@ -116,7 +116,7 @@ items:
.'
returned: success
type: str
- next_hop_instance:
+ nextHopInstance:
description:
- URL to an instance that should handle matching packets.
- 'You can specify this as a full or partial URL. For example: * U(https://www.googleapis.com/compute/v1/projects/project/zones/zone/)
@@ -124,17 +124,17 @@ items:
.'
returned: success
type: str
- next_hop_ip:
+ nextHopIp:
description:
- Network IP address of an instance that should handle matching packets.
returned: success
type: str
- next_hop_vpn_tunnel:
+ nextHopVpnTunnel:
description:
- URL to a VpnTunnel that should handle matching packets.
returned: success
type: str
- next_hop_network:
+ nextHopNetwork:
description:
- URL to a Network that should handle matching packets.
returned: success
@@ -155,7 +155,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_router.py b/lib/ansible/modules/cloud/google/gcp_compute_router.py
index e35f67f5cf..40d88a7d9e 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_router.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_router.py
@@ -61,6 +61,11 @@ options:
network:
description:
- A reference to the network to which this router belongs.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: true
bgp:
description:
@@ -138,7 +143,7 @@ EXAMPLES = '''
- range: 6.7.0.0/16
region: us-central1
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -149,7 +154,7 @@ RETURN = '''
- The unique identifier for the resource.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -186,13 +191,13 @@ RETURN = '''
that link to this router will have the same local ASN.
returned: success
type: int
- advertise_mode:
+ advertiseMode:
description:
- User-specified flag to indicate which mode to use for advertisement.
- 'Valid values of this enum field are: DEFAULT, CUSTOM .'
returned: success
type: str
- advertised_groups:
+ advertisedGroups:
description:
- User-specified list of prefix groups to advertise in custom mode.
- This field can only be populated if advertiseMode is CUSTOM and is advertised to
@@ -201,7 +206,7 @@ RETURN = '''
- 'This enum field has the one valid value: ALL_SUBNETS .'
returned: success
type: list
- advertised_ip_ranges:
+ advertisedIpRanges:
description:
- User-specified list of individual IP ranges to advertise in custom mode. This field
can only be populated if advertiseMode is CUSTOM and is advertised to all peers
@@ -274,7 +279,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -324,9 +330,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -337,9 +343,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/routers".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -354,8 +360,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_router_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_router_facts.py
index 81d7f1fb23..ae9057d727 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_router_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_router_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -76,7 +76,7 @@ items:
- The unique identifier for the resource.
returned: success
type: int
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -113,13 +113,13 @@ items:
that link to this router will have the same local ASN.
returned: success
type: int
- advertise_mode:
+ advertiseMode:
description:
- User-specified flag to indicate which mode to use for advertisement.
- 'Valid values of this enum field are: DEFAULT, CUSTOM .'
returned: success
type: str
- advertised_groups:
+ advertisedGroups:
description:
- User-specified list of prefix groups to advertise in custom mode.
- This field can only be populated if advertiseMode is CUSTOM and is advertised to
@@ -128,7 +128,7 @@ items:
- 'This enum field has the one valid value: ALL_SUBNETS .'
returned: success
type: list
- advertised_ip_ranges:
+ advertisedIpRanges:
description:
- User-specified list of individual IP ranges to advertise in custom mode. This field
can only be populated if advertiseMode is CUSTOM and is advertised to all peers
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate.py b/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate.py
index 2f64ca6167..5fdd494b04 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate.py
@@ -32,8 +32,9 @@ DOCUMENTATION = '''
---
module: gcp_compute_ssl_certificate
description:
- - An SslCertificate resource. This resource provides a mechanism to upload an SSL
- key and certificate to the load balancer to serve secure connections from the user.
+ - An SslCertificate resource, used for HTTPS load balancing. This resource provides
+ a mechanism to upload an SSL key and certificate to the load balancer to serve secure
+ connections from the user.
short_description: Creates a GCP SslCertificate
version_added: 2.6
author: Google Inc. (@googlecloudplatform)
@@ -52,7 +53,7 @@ options:
- The certificate in PEM format.
- The certificate chain must be no greater than 5 certs long.
- The chain must include at least one intermediate cert.
- required: false
+ required: true
description:
description:
- An optional description of this resource.
@@ -68,9 +69,12 @@ options:
required: false
private_key:
description:
- - The private key in PEM format.
- required: false
+ - The write-only private key in PEM format.
+ required: true
extends_documentation_fragment: gcp
+notes:
+ - "API Reference: U(https://cloud.google.com/compute/docs/reference/rest/v1/sslCertificates)"
+ - "Official Documentation: U(https://cloud.google.com/load-balancing/docs/ssl-certificates)"
'''
EXAMPLES = '''
@@ -103,7 +107,7 @@ EXAMPLES = '''
OGN02HtkpBOZzzvUARTR10JQoSe2/5PIwQ==
-----END EC PRIVATE KEY-----
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -116,7 +120,7 @@ RETURN = '''
- The chain must include at least one intermediate cert.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -141,9 +145,9 @@ RETURN = '''
be a dash.
returned: success
type: str
- private_key:
+ privateKey:
description:
- - The private key in PEM format.
+ - The write-only private key in PEM format.
returned: success
type: str
'''
@@ -167,10 +171,10 @@ def main():
module = GcpModule(
argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'),
- certificate=dict(type='str'),
+ certificate=dict(required=True, type='str'),
description=dict(type='str'),
name=dict(type='str'),
- private_key=dict(type='str')
+ private_key=dict(required=True, type='str')
)
)
@@ -186,7 +190,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -210,8 +215,7 @@ def create(module, link, kind):
def update(module, link, kind):
- auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ module.fail_json(msg="SslCertificate cannot be edited")
def delete(module, link, kind):
@@ -235,9 +239,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -248,9 +252,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/sslCertificates".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -265,8 +269,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate_facts.py
index 10dcc20f09..4fc37c9483 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_ssl_certificate_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -73,7 +73,7 @@ items:
- The chain must include at least one intermediate cert.
returned: success
type: str
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -98,9 +98,9 @@ items:
be a dash.
returned: success
type: str
- private_key:
+ privateKey:
description:
- - The private key in PEM format.
+ - The write-only private key in PEM format.
returned: success
type: str
'''
@@ -119,7 +119,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy.py b/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy.py
index bb7ab24d73..003eaf34eb 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy.py
@@ -96,13 +96,13 @@ EXAMPLES = '''
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -135,18 +135,18 @@ RETURN = '''
in the `customFeatures` field.
returned: success
type: str
- min_tls_version:
+ minTlsVersion:
description:
- The minimum version of SSL protocol that can be used by the clients to establish
a connection with the load balancer. This can be one of `TLS_1_0`, `TLS_1_1`, `TLS_1_2`.
returned: success
type: str
- enabled_features:
+ enabledFeatures:
description:
- The list of features enabled in the SSL policy.
returned: success
type: list
- custom_features:
+ customFeatures:
description:
- A list of features enabled when the selected profile is CUSTOM. The method returns
the set of features that can be specified in this list. This field must be empty
@@ -217,7 +217,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -267,9 +268,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -280,9 +281,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/sslPolicies".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -297,8 +298,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy_facts.py
index 3b638b9c66..80de3606b9 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_ssl_policy_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -99,18 +99,18 @@ items:
in the `customFeatures` field.
returned: success
type: str
- min_tls_version:
+ minTlsVersion:
description:
- The minimum version of SSL protocol that can be used by the clients to establish
a connection with the load balancer. This can be one of `TLS_1_0`, `TLS_1_1`, `TLS_1_2`.
returned: success
type: str
- enabled_features:
+ enabledFeatures:
description:
- The list of features enabled in the SSL policy.
returned: success
type: list
- custom_features:
+ customFeatures:
description:
- A list of features enabled when the selected profile is CUSTOM. The method returns
the set of features that can be specified in this list. This field must be empty
@@ -156,7 +156,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py b/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py
index e2cca99239..9348fb6293 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_subnetwork.py
@@ -87,7 +87,39 @@ options:
description:
- The network this subnet belongs to.
- Only networks that are in the distributed mode can have subnetworks.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: true
+ enable_flow_logs:
+ description:
+ - Whether to enable flow logging for this subnetwork.
+ required: false
+ type: bool
+ version_added: 2.8
+ secondary_ip_ranges:
+ description:
+ - An array of configurations for secondary IP ranges for VM instances contained in
+ this subnetwork. The primary IP of such VM must belong to the primary ipCidrRange
+ of the subnetwork. The alias IPs may belong to either primary or secondary ranges.
+ required: false
+ version_added: 2.8
+ suboptions:
+ range_name:
+ description:
+ - The name associated with this subnetwork secondary range, used when adding an alias
+ IP range to a VM instance. The name must be 1-63 characters long, and comply with
+ RFC1035. The name must be unique within the subnetwork.
+ required: true
+ ip_cidr_range:
+ description:
+ - The range of IP addresses belonging to this subnetwork secondary range. Provide
+ this property when you create the subnetwork.
+ - Ranges must be unique and non-overlapping with all primary and secondary IP ranges
+ within a network. Only IPv4 is supported.
+ required: true
private_ip_google_access:
description:
- Whether the VMs in this subnet can access Google services without assigned external
@@ -123,13 +155,13 @@ EXAMPLES = '''
network: "{{ network }}"
ip_cidr_range: 172.16.0.0/16
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -140,7 +172,7 @@ RETURN = '''
the resource. This field can be set only at resource creation time.
returned: success
type: str
- gateway_address:
+ gatewayAddress:
description:
- The gateway address for default routes to reach destination addresses outside this
subnetwork.
@@ -151,7 +183,7 @@ RETURN = '''
- The unique identifier for the resource.
returned: success
type: int
- ip_cidr_range:
+ ipCidrRange:
description:
- The range of internal addresses that are owned by this subnetwork.
- Provide this property when you create the subnetwork. For example, 10.0.0.0/8 or
@@ -175,7 +207,41 @@ RETURN = '''
- Only networks that are in the distributed mode can have subnetworks.
returned: success
type: dict
- private_ip_google_access:
+ enableFlowLogs:
+ description:
+ - Whether to enable flow logging for this subnetwork.
+ returned: success
+ type: bool
+ fingerprint:
+ description:
+ - Fingerprint of this resource. This field is used internally during updates of this
+ resource.
+ returned: success
+ type: str
+ secondaryIpRanges:
+ description:
+ - An array of configurations for secondary IP ranges for VM instances contained in
+ this subnetwork. The primary IP of such VM must belong to the primary ipCidrRange
+ of the subnetwork. The alias IPs may belong to either primary or secondary ranges.
+ returned: success
+ type: complex
+ contains:
+ rangeName:
+ description:
+ - The name associated with this subnetwork secondary range, used when adding an alias
+ IP range to a VM instance. The name must be 1-63 characters long, and comply with
+ RFC1035. The name must be unique within the subnetwork.
+ returned: success
+ type: str
+ ipCidrRange:
+ description:
+ - The range of IP addresses belonging to this subnetwork secondary range. Provide
+ this property when you create the subnetwork.
+ - Ranges must be unique and non-overlapping with all primary and secondary IP ranges
+ within a network. Only IPv4 is supported.
+ returned: success
+ type: str
+ privateIpGoogleAccess:
description:
- Whether the VMs in this subnet can access Google services without assigned external
IP addresses.
@@ -192,7 +258,7 @@ RETURN = '''
# Imports
################################################################################
-from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, replace_resource_dict
+from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, remove_nones_from_dict, replace_resource_dict
import json
import time
@@ -211,6 +277,11 @@ def main():
ip_cidr_range=dict(required=True, type='str'),
name=dict(required=True, type='str'),
network=dict(required=True, type='dict'),
+ enable_flow_logs=dict(type='bool'),
+ secondary_ip_ranges=dict(type='list', elements='dict', options=dict(
+ range_name=dict(required=True, type='str'),
+ ip_cidr_range=dict(required=True, type='str')
+ )),
private_ip_google_access=dict(type='bool'),
region=dict(required=True, type='str')
)
@@ -228,7 +299,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -251,9 +323,60 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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('enableFlowLogs') != request.get('enableFlowLogs') or response.get('secondaryIpRanges') != request.get('secondaryIpRanges'):
+ enable_flow_logs_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 enable_flow_logs_update(module, request, response):
auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ auth.patch(
+ ''.join([
+ "https://www.googleapis.com/compute/v1/",
+ "projects/{project}/regions/{region}/subnetworks/{name}"
+ ]).format(**module.params),
+ {
+ u'enableFlowLogs': module.params.get('enable_flow_logs'),
+ u'fingerprint': response.get('fingerprint'),
+ u'secondaryIpRanges': SubnetworkSecondaryIpRangesArray(module.params.get('secondary_ip_ranges', []), module).to_request()
+ }
+ )
+
+
+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):
@@ -268,6 +391,8 @@ def resource_to_request(module):
u'ipCidrRange': module.params.get('ip_cidr_range'),
u'name': module.params.get('name'),
u'network': replace_resource_dict(module.params.get(u'network', {}), 'selfLink'),
+ u'enableFlowLogs': module.params.get('enable_flow_logs'),
+ u'secondaryIpRanges': SubnetworkSecondaryIpRangesArray(module.params.get('secondary_ip_ranges', []), module).to_request(),
u'privateIpGoogleAccess': module.params.get('private_ip_google_access'),
u'region': module.params.get('region')
}
@@ -279,9 +404,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -292,9 +417,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/subnetworks".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -309,8 +434,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -344,6 +467,9 @@ def response_to_hash(module, response):
u'ipCidrRange': response.get(u'ipCidrRange'),
u'name': response.get(u'name'),
u'network': replace_resource_dict(module.params.get(u'network', {}), 'selfLink'),
+ u'enableFlowLogs': response.get(u'enableFlowLogs'),
+ u'fingerprint': response.get(u'fingerprint'),
+ u'secondaryIpRanges': SubnetworkSecondaryIpRangesArray(response.get(u'secondaryIpRanges', []), module).from_response(),
u'privateIpGoogleAccess': response.get(u'privateIpGoogleAccess'),
u'region': module.params.get('region')
}
@@ -386,5 +512,38 @@ def raise_if_errors(response, err_path, module):
module.fail_json(msg=errors)
+class SubnetworkSecondaryIpRangesArray(object):
+ def __init__(self, request, module):
+ self.module = module
+ if request:
+ self.request = request
+ else:
+ self.request = []
+
+ def to_request(self):
+ items = []
+ for item in self.request:
+ items.append(self._request_for_item(item))
+ return items
+
+ def from_response(self):
+ items = []
+ for item in self.request:
+ items.append(self._response_from_item(item))
+ return items
+
+ def _request_for_item(self, item):
+ return remove_nones_from_dict({
+ u'rangeName': item.get('range_name'),
+ u'ipCidrRange': item.get('ip_cidr_range')
+ })
+
+ def _response_from_item(self, item):
+ return remove_nones_from_dict({
+ u'rangeName': item.get(u'rangeName'),
+ u'ipCidrRange': item.get(u'ipCidrRange')
+ })
+
+
if __name__ == '__main__':
main()
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_subnetwork_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_subnetwork_facts.py
index aa05e1d4d1..2952d3a151 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_subnetwork_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_subnetwork_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -82,7 +82,7 @@ items:
the resource. This field can be set only at resource creation time.
returned: success
type: str
- gateway_address:
+ gatewayAddress:
description:
- The gateway address for default routes to reach destination addresses outside this
subnetwork.
@@ -93,7 +93,7 @@ items:
- The unique identifier for the resource.
returned: success
type: int
- ip_cidr_range:
+ ipCidrRange:
description:
- The range of internal addresses that are owned by this subnetwork.
- Provide this property when you create the subnetwork. For example, 10.0.0.0/8 or
@@ -117,7 +117,41 @@ items:
- Only networks that are in the distributed mode can have subnetworks.
returned: success
type: dict
- private_ip_google_access:
+ enableFlowLogs:
+ description:
+ - Whether to enable flow logging for this subnetwork.
+ returned: success
+ type: bool
+ fingerprint:
+ description:
+ - Fingerprint of this resource. This field is used internally during updates of this
+ resource.
+ returned: success
+ type: str
+ secondaryIpRanges:
+ description:
+ - An array of configurations for secondary IP ranges for VM instances contained in
+ this subnetwork. The primary IP of such VM must belong to the primary ipCidrRange
+ of the subnetwork. The alias IPs may belong to either primary or secondary ranges.
+ returned: success
+ type: complex
+ contains:
+ rangeName:
+ description:
+ - The name associated with this subnetwork secondary range, used when adding an alias
+ IP range to a VM instance. The name must be 1-63 characters long, and comply with
+ RFC1035. The name must be unique within the subnetwork.
+ returned: success
+ type: str
+ ipCidrRange:
+ description:
+ - The range of IP addresses belonging to this subnetwork secondary range. Provide
+ this property when you create the subnetwork.
+ - Ranges must be unique and non-overlapping with all primary and secondary IP ranges
+ within a network. Only IPv4 is supported.
+ returned: success
+ type: str
+ privateIpGoogleAccess:
description:
- Whether the VMs in this subnet can access Google services without assigned external
IP addresses.
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 ae62cd29d3..808d4d3c28 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
@@ -63,6 +63,11 @@ options:
url_map:
description:
- A reference to the UrlMap resource that defines the mapping from URL to the BackendService.
+ - 'This field represents a link to a UrlMap resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_compute_url_map task
+ and then set this url_map field to "{{ name-of-resource }}" Alternatively, you can
+ set this url_map to a dictionary with the selfLink key where the value is the selfLink
+ of your UrlMap.'
required: true
extends_documentation_fragment: gcp
notes:
@@ -123,13 +128,13 @@ EXAMPLES = '''
name: "test_object"
url_map: "{{ urlmap }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -154,7 +159,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- url_map:
+ urlMap:
description:
- A reference to the UrlMap resource that defines the mapping from URL to the BackendService.
returned: success
@@ -198,7 +203,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -221,9 +227,28 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ 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):
@@ -246,9 +271,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -259,9 +284,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/targetHttpProxies".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -276,8 +301,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy_facts.py
index f5f276e083..0506a929ca 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_http_proxy_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -91,7 +91,7 @@ items:
be a dash.
returned: success
type: str
- url_map:
+ urlMap:
description:
- A reference to the UrlMap resource that defines the mapping from URL to the BackendService.
returned: success
@@ -112,7 +112,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
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 c3e4cb2343..fc298bdc89 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
@@ -78,6 +78,11 @@ options:
url_map:
description:
- A reference to the UrlMap resource that defines the mapping from URL to the BackendService.
+ - 'This field represents a link to a UrlMap resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_compute_url_map task
+ and then set this url_map field to "{{ name-of-resource }}" Alternatively, you can
+ set this url_map to a dictionary with the selfLink key where the value is the selfLink
+ of your UrlMap.'
required: true
extends_documentation_fragment: gcp
notes:
@@ -174,13 +179,13 @@ EXAMPLES = '''
- "{{ sslcert }}"
url_map: "{{ urlmap }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -205,7 +210,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- quic_override:
+ quicOverride:
description:
- Specifies the QUIC override policy for this resource. This determines whether the
load balancer will attempt to negotiate QUIC with clients or not. Can specify one
@@ -214,13 +219,13 @@ RETURN = '''
to specifying NONE.
returned: success
type: str
- ssl_certificates:
+ sslCertificates:
description:
- A list of SslCertificate resources that are used to authenticate connections between
users and the load balancer. Currently, exactly one SSL certificate must be specified.
returned: success
type: list
- url_map:
+ urlMap:
description:
- A reference to the UrlMap resource that defines the mapping from URL to the BackendService.
returned: success
@@ -266,7 +271,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -289,9 +295,58 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ 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):
@@ -316,9 +371,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -329,9 +384,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/targetHttpsProxies".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -346,8 +401,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy_facts.py
index 2b33efa3d8..1b536b643b 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_https_proxy_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -91,7 +91,7 @@ items:
be a dash.
returned: success
type: str
- quic_override:
+ quicOverride:
description:
- Specifies the QUIC override policy for this resource. This determines whether the
load balancer will attempt to negotiate QUIC with clients or not. Can specify one
@@ -100,13 +100,13 @@ items:
to specifying NONE.
returned: success
type: str
- ssl_certificates:
+ sslCertificates:
description:
- A list of SslCertificate resources that are used to authenticate connections between
users and the load balancer. Currently, exactly one SSL certificate must be specified.
returned: success
type: list
- url_map:
+ urlMap:
description:
- A reference to the UrlMap resource that defines the mapping from URL to the BackendService.
returned: success
@@ -127,7 +127,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_pool.py b/lib/ansible/modules/cloud/google/gcp_compute_target_pool.py
index dac771de36..b6fab8bb0f 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_pool.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_pool.py
@@ -59,6 +59,11 @@ options:
the backup pool are unhealthy, the traffic will be directed back to the primary
pool in the "force" mode, where traffic will be spread to the healthy instances
with the best effort, or to all instances when no instance is healthy.
+ - 'This field represents a link to a TargetPool resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_target_pool
+ task and then set this backup_pool field to "{{ name-of-resource }}" Alternatively,
+ you can set this backup_pool to a dictionary with the selfLink key where the value
+ is the selfLink of your TargetPool.'
required: false
description:
description:
@@ -84,6 +89,11 @@ options:
- A member instance in this pool is considered healthy if and only if the health checks
pass. If not specified it means all member instances will be considered healthy
at all times.
+ - 'This field represents a link to a HttpHealthCheck resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_http_health_check
+ task and then set this health_check field to "{{ name-of-resource }}" Alternatively,
+ you can set this health_check to a dictionary with the selfLink key where the value
+ is the selfLink of your HttpHealthCheck.'
required: false
instances:
description:
@@ -125,13 +135,13 @@ EXAMPLES = '''
name: "test_object"
region: us-west1
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- backup_pool:
+ backupPool:
description:
- This field is applicable only when the containing target pool is serving a forwarding
rule as the primary pool, and its failoverRatio field is properly set to a value
@@ -146,7 +156,7 @@ RETURN = '''
with the best effort, or to all instances when no instance is healthy.
returned: success
type: dict
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -156,7 +166,7 @@ RETURN = '''
- An optional description of this resource.
returned: success
type: str
- failover_ratio:
+ failoverRatio:
description:
- This field is applicable only when the containing target pool is serving a forwarding
rule as the primary pool (i.e., not as a backup pool to some other target pool).
@@ -171,7 +181,7 @@ RETURN = '''
or to all instances when no instance is healthy.
returned: success
type: str
- health_check:
+ healthCheck:
description:
- A reference to a HttpHealthCheck resource.
- A member instance in this pool is considered healthy if and only if the health checks
@@ -200,7 +210,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- session_affinity:
+ sessionAffinity:
description:
- 'Session affinity option. Must be one of these values: - NONE: Connections from
the same client IP may go to any instance in the pool.'
@@ -259,7 +269,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -312,9 +323,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -325,9 +336,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/targetPools".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -344,8 +355,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_pool_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_target_pool_facts.py
index b8c65f740d..a738329041 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_pool_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_pool_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
returned: always
type: complex
contains:
- backup_pool:
+ backupPool:
description:
- This field is applicable only when the containing target pool is serving a forwarding
rule as the primary pool, and its failoverRatio field is properly set to a value
@@ -86,7 +86,7 @@ items:
with the best effort, or to all instances when no instance is healthy.
returned: success
type: dict
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -96,7 +96,7 @@ items:
- An optional description of this resource.
returned: success
type: str
- failover_ratio:
+ failoverRatio:
description:
- This field is applicable only when the containing target pool is serving a forwarding
rule as the primary pool (i.e., not as a backup pool to some other target pool).
@@ -111,7 +111,7 @@ items:
or to all instances when no instance is healthy.
returned: success
type: str
- health_check:
+ healthCheck:
description:
- A reference to a HttpHealthCheck resource.
- A member instance in this pool is considered healthy if and only if the health checks
@@ -140,7 +140,7 @@ items:
be a dash.
returned: success
type: str
- session_affinity:
+ sessionAffinity:
description:
- 'Session affinity option. Must be one of these values: - NONE: Connections from
the same client IP may go to any instance in the pool.'
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy_facts.py
index 8a41381db9..47c4a707ff 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_ssl_proxy_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -91,7 +91,7 @@ items:
be a dash.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
@@ -102,7 +102,7 @@ items:
- A reference to the BackendService resource.
returned: success
type: dict
- ssl_certificates:
+ sslCertificates:
description:
- A list of SslCertificate resources that are used to authenticate connections between
users and the load balancer. Currently, exactly one SSL certificate must be specified.
@@ -124,7 +124,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
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 f8fea56040..fe805985a9 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
@@ -69,6 +69,11 @@ options:
service:
description:
- A reference to the BackendService resource.
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this service field to "{{ name-of-resource }}" Alternatively,
+ you can set this service to a dictionary with the selfLink key where the value is
+ the selfLink of your BackendService.'
required: true
extends_documentation_fragment: gcp
notes:
@@ -124,13 +129,13 @@ EXAMPLES = '''
proxy_header: PROXY_V1
service: "{{ backendservice }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -155,7 +160,7 @@ RETURN = '''
be a dash.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
@@ -206,7 +211,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -229,9 +235,43 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ 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):
@@ -255,9 +295,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -268,9 +308,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/targetTcpProxies".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -285,8 +325,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy_facts.py
index 34e885d4a7..158198ced7 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_tcp_proxy_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,7 +66,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -91,7 +91,7 @@ items:
be a dash.
returned: success
type: str
- proxy_header:
+ proxyHeader:
description:
- Specifies the type of proxy header to append before sending data to the backend,
either NONE or PROXY_V1. The default is NONE.
@@ -118,7 +118,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway.py b/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway.py
index a68d32f446..480c2f02ed 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway.py
@@ -63,6 +63,11 @@ options:
network:
description:
- The network this VPN gateway is accepting traffic for.
+ - 'This field represents a link to a Network resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_network task
+ and then set this network field to "{{ name-of-resource }}" Alternatively, you can
+ set this network to a dictionary with the selfLink key where the value is the selfLink
+ of your Network.'
required: true
region:
description:
@@ -99,13 +104,13 @@ EXAMPLES = '''
region: us-west1
network: "{{ network }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -140,7 +145,7 @@ RETURN = '''
- A list of references to VpnTunnel resources associated to this VPN gateway.
returned: success
type: list
- forwarding_rules:
+ forwardingRules:
description:
- A list of references to the ForwardingRule resources associated to this VPN gateway.
returned: success
@@ -190,7 +195,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -214,8 +220,7 @@ def create(module, link, kind):
def update(module, link, kind):
- auth = GcpSession(module, 'compute')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ module.fail_json(msg="TargetVpnGateway cannot be edited")
def delete(module, link, kind):
@@ -238,9 +243,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -251,9 +256,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/targetVpnGateways".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -268,8 +273,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway_facts.py
index 23d1a4b892..f2d65dca94 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_target_vpn_gateway_facts.py
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -106,7 +106,7 @@ items:
- A list of references to VpnTunnel resources associated to this VPN gateway.
returned: success
type: list
- forwarding_rules:
+ forwardingRules:
description:
- A list of references to the ForwardingRule resources associated to this VPN gateway.
returned: success
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_url_map.py b/lib/ansible/modules/cloud/google/gcp_compute_url_map.py
index f39d002aee..60753392d9 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_url_map.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_url_map.py
@@ -50,6 +50,11 @@ options:
default_service:
description:
- A reference to BackendService resource if none of the hostRules match.
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this default_service field to "{{ name-of-resource }}" Alternatively,
+ you can set this default_service to a dictionary with the selfLink key where the
+ value is the selfLink of your BackendService.'
required: true
description:
description:
@@ -71,12 +76,12 @@ options:
- The list of host patterns to match. They must be valid hostnames, except * will
match any string of ([a-z0-9-.]*). In that case, * must be the first character and
must be followed in the pattern by either - or .
- required: false
+ required: true
path_matcher:
description:
- The name of the PathMatcher to use to match the path portion of the URL if the hostRule
matches the URL's host portion.
- required: false
+ required: true
name:
description:
- Name of the resource. Provided by the client when the resource is created. The name
@@ -85,7 +90,7 @@ options:
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: false
+ required: true
path_matchers:
description:
- The list of named PathMatchers to use against the URL.
@@ -95,7 +100,12 @@ options:
description:
- A reference to a BackendService resource. This will be used if none of the pathRules
defined by this PathMatcher is matched by the URL's path portion.
- required: false
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this default_service field to "{{ name-of-resource }}" Alternatively,
+ you can set this default_service to a dictionary with the selfLink key where the
+ value is the selfLink of your BackendService.'
+ required: true
description:
description:
- An optional description of this resource.
@@ -103,7 +113,7 @@ options:
name:
description:
- The name to which this PathMatcher is referred by the HostRule.
- required: false
+ required: true
path_rules:
description:
- The list of path rules.
@@ -118,7 +128,12 @@ options:
service:
description:
- A reference to the BackendService resource if this rule is matched.
- required: false
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this service field to "{{ name-of-resource }}" Alternatively,
+ you can set this service to a dictionary with the selfLink key where the value is
+ the selfLink of your BackendService.'
+ required: true
tests:
description:
- The list of expected URL mappings. Request to update this UrlMap will succeed only
@@ -132,15 +147,20 @@ options:
host:
description:
- Host portion of the URL.
- required: false
+ required: true
path:
description:
- Path portion of the URL.
- required: false
+ required: true
service:
description:
- A reference to expected BackendService resource the given URL should be mapped to.
- required: false
+ - 'This field represents a link to a BackendService resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_backend_service
+ task and then set this service field to "{{ name-of-resource }}" Alternatively,
+ you can set this service to a dictionary with the selfLink key where the value is
+ the selfLink of your BackendService.'
+ required: true
extends_documentation_fragment: gcp
'''
@@ -187,18 +207,18 @@ EXAMPLES = '''
name: "test_object"
default_service: "{{ backendservice }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
type: str
- default_service:
+ defaultService:
description:
- A reference to BackendService resource if none of the hostRules match.
returned: success
@@ -209,7 +229,7 @@ RETURN = '''
the resource.
returned: success
type: str
- host_rules:
+ hostRules:
description:
- The list of HostRules to use against the URL.
returned: success
@@ -228,7 +248,7 @@ RETURN = '''
must be followed in the pattern by either - or .
returned: success
type: list
- path_matcher:
+ pathMatcher:
description:
- The name of the PathMatcher to use to match the path portion of the URL if the hostRule
matches the URL's host portion.
@@ -239,6 +259,12 @@ RETURN = '''
- The unique identifier for the resource.
returned: success
type: int
+ fingerprint:
+ description:
+ - Fingerprint of this resource. This field is used internally during updates of this
+ resource.
+ returned: success
+ type: str
name:
description:
- Name of the resource. Provided by the client when the resource is created. The name
@@ -249,13 +275,13 @@ RETURN = '''
be a dash.
returned: success
type: str
- path_matchers:
+ pathMatchers:
description:
- The list of named PathMatchers to use against the URL.
returned: success
type: complex
contains:
- default_service:
+ defaultService:
description:
- A reference to a BackendService resource. This will be used if none of the pathRules
defined by this PathMatcher is matched by the URL's path portion.
@@ -271,7 +297,7 @@ RETURN = '''
- The name to which this PathMatcher is referred by the HostRule.
returned: success
type: str
- path_rules:
+ pathRules:
description:
- The list of path rules.
returned: success
@@ -341,24 +367,24 @@ def main():
description=dict(type='str'),
host_rules=dict(type='list', elements='dict', options=dict(
description=dict(type='str'),
- hosts=dict(type='list', elements='str'),
- path_matcher=dict(type='str')
+ hosts=dict(required=True, type='list', elements='str'),
+ path_matcher=dict(required=True, type='str')
)),
- name=dict(type='str'),
+ name=dict(required=True, type='str'),
path_matchers=dict(type='list', elements='dict', options=dict(
- default_service=dict(type='dict'),
+ default_service=dict(required=True, type='dict'),
description=dict(type='str'),
- name=dict(type='str'),
+ name=dict(required=True, type='str'),
path_rules=dict(type='list', elements='dict', options=dict(
paths=dict(type='list', elements='str'),
- service=dict(type='dict')
+ service=dict(required=True, type='dict')
))
)),
tests=dict(type='list', elements='dict', options=dict(
description=dict(type='str'),
- host=dict(type='str'),
- path=dict(type='str'),
- service=dict(type='dict')
+ host=dict(required=True, type='str'),
+ path=dict(required=True, type='str'),
+ service=dict(required=True, type='dict')
))
)
)
@@ -375,7 +401,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -426,9 +453,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -439,9 +466,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/global/urlMaps".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -456,8 +483,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -489,7 +514,8 @@ def response_to_hash(module, response):
u'description': response.get(u'description'),
u'hostRules': UrlMapHostRulesArray(response.get(u'hostRules', []), module).from_response(),
u'id': response.get(u'id'),
- u'name': response.get(u'name'),
+ u'fingerprint': response.get(u'fingerprint'),
+ u'name': module.params.get('name'),
u'pathMatchers': UrlMapPathMatchersArray(response.get(u'pathMatchers', []), module).from_response(),
u'tests': UrlMapTestsArray(response.get(u'tests', []), module).from_response()
}
diff --git a/lib/ansible/modules/cloud/google/gcp_compute_url_map_facts.py b/lib/ansible/modules/cloud/google/gcp_compute_url_map_facts.py
index 515e4031c8..55d114e58c 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_url_map_facts.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_url_map_facts.py
@@ -56,7 +56,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -66,12 +66,12 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
type: str
- default_service:
+ defaultService:
description:
- A reference to BackendService resource if none of the hostRules match.
returned: success
@@ -82,7 +82,7 @@ items:
the resource.
returned: success
type: str
- host_rules:
+ hostRules:
description:
- The list of HostRules to use against the URL.
returned: success
@@ -101,7 +101,7 @@ items:
must be followed in the pattern by either - or .
returned: success
type: list
- path_matcher:
+ pathMatcher:
description:
- The name of the PathMatcher to use to match the path portion of the URL if the hostRule
matches the URL's host portion.
@@ -112,6 +112,12 @@ items:
- The unique identifier for the resource.
returned: success
type: int
+ fingerprint:
+ description:
+ - Fingerprint of this resource. This field is used internally during updates of this
+ resource.
+ returned: success
+ type: str
name:
description:
- Name of the resource. Provided by the client when the resource is created. The name
@@ -122,13 +128,13 @@ items:
be a dash.
returned: success
type: str
- path_matchers:
+ pathMatchers:
description:
- The list of named PathMatchers to use against the URL.
returned: success
type: complex
contains:
- default_service:
+ defaultService:
description:
- A reference to a BackendService resource. This will be used if none of the pathRules
defined by this PathMatcher is matched by the URL's path portion.
@@ -144,7 +150,7 @@ items:
- The name to which this PathMatcher is referred by the HostRule.
returned: success
type: str
- path_rules:
+ pathRules:
description:
- The list of path rules.
returned: success
@@ -205,7 +211,7 @@ import json
def main():
module = GcpModule(
argument_spec=dict(
- filters=dict(type='list', elements='str'),
+ filters=dict(type='list', elements='str')
)
)
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 0697ab9002..1a5ea665d0 100644
--- a/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py
+++ b/lib/ansible/modules/cloud/google/gcp_compute_vpn_tunnel.py
@@ -61,10 +61,20 @@ options:
target_vpn_gateway:
description:
- URL of the Target VPN gateway with which this VPN tunnel is associated.
+ - 'This field represents a link to a TargetVpnGateway resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_compute_target_vpn_gateway
+ task and then set this target_vpn_gateway field to "{{ name-of-resource }}" Alternatively,
+ you can set this target_vpn_gateway to a dictionary with the selfLink key where
+ the value is the selfLink of your TargetVpnGateway.'
required: true
router:
description:
- URL of router resource to be used for dynamic routing.
+ - '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: false
peer_ip:
description:
@@ -158,13 +168,13 @@ EXAMPLES = '''
router: "{{ router }}"
shared_secret: super secret
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -183,7 +193,7 @@ RETURN = '''
- An optional description of this resource.
returned: success
type: str
- target_vpn_gateway:
+ targetVpnGateway:
description:
- URL of the Target VPN gateway with which this VPN tunnel is associated.
returned: success
@@ -192,30 +202,30 @@ RETURN = '''
description:
- URL of router resource to be used for dynamic routing.
returned: success
- type: str
- peer_ip:
+ type: dict
+ peerIp:
description:
- IP address of the peer VPN gateway. Only IPv4 is supported.
returned: success
type: str
- shared_secret:
+ sharedSecret:
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:
+ sharedSecretHash:
description:
- Hash of the shared secret.
returned: success
type: str
- ike_version:
+ 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
- local_traffic_selector:
+ 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
@@ -223,7 +233,7 @@ RETURN = '''
- Only IPv4 is supported.
returned: success
type: list
- remote_traffic_selector:
+ 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
@@ -236,6 +246,12 @@ RETURN = '''
- Labels to apply to this VpnTunnel.
returned: success
type: dict
+ labelFingerprint:
+ 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.
@@ -265,7 +281,7 @@ def main():
name=dict(required=True, type='str'),
description=dict(type='str'),
target_vpn_gateway=dict(required=True, type='dict'),
- router=dict(type='str'),
+ router=dict(type='dict'),
peer_ip=dict(required=True, type='str'),
shared_secret=dict(required=True, type='str'),
ike_version=dict(default=2, type='int'),
@@ -288,7 +304,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind, fetch)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -297,6 +314,7 @@ def main():
else:
if state == 'present':
fetch = create(module, collection(module), kind)
+ labels_update(module, module.params, fetch)
changed = True
else:
fetch = {}
@@ -311,9 +329,29 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module)))
-def update(module, link, kind):
+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')
- return wait_for_operation(module, auth.put(link, resource_to_request(module)))
+ 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):
@@ -327,7 +365,7 @@ def resource_to_request(module):
u'name': module.params.get('name'),
u'description': module.params.get('description'),
u'targetVpnGateway': replace_resource_dict(module.params.get(u'target_vpn_gateway', {}), 'selfLink'),
- u'router': module.params.get('router'),
+ u'router': replace_resource_dict(module.params.get(u'router', {}), 'selfLink'),
u'peerIp': module.params.get('peer_ip'),
u'sharedSecret': module.params.get('shared_secret'),
u'ikeVersion': module.params.get('ike_version'),
@@ -343,9 +381,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'compute')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -356,9 +394,9 @@ def collection(module):
return "https://www.googleapis.com/compute/v1/projects/{project}/regions/{region}/vpnTunnels".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -373,8 +411,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -405,14 +441,15 @@ def response_to_hash(module, response):
u'name': response.get(u'name'),
u'description': module.params.get('description'),
u'targetVpnGateway': replace_resource_dict(module.params.get(u'target_vpn_gateway', {}), 'selfLink'),
- u'router': module.params.get('router'),
+ u'router': replace_resource_dict(module.params.get(u'router', {}), 'selfLink'),
u'peerIp': response.get(u'peerIp'),
u'sharedSecret': response.get(u'sharedSecret'),
u'sharedSecretHash': response.get(u'sharedSecretHash'),
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'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 24a0142a24..f1f479205d 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
@@ -61,7 +61,7 @@ EXAMPLES = '''
filters:
- name = test_object
project: test_project
- auth_kind: service_account
+ auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
'''
@@ -71,7 +71,7 @@ items:
returned: always
type: complex
contains:
- creation_timestamp:
+ creationTimestamp:
description:
- Creation timestamp in RFC3339 text format.
returned: success
@@ -90,7 +90,7 @@ items:
- An optional description of this resource.
returned: success
type: str
- target_vpn_gateway:
+ targetVpnGateway:
description:
- URL of the Target VPN gateway with which this VPN tunnel is associated.
returned: success
@@ -99,30 +99,30 @@ items:
description:
- URL of router resource to be used for dynamic routing.
returned: success
- type: str
- peer_ip:
+ type: dict
+ peerIp:
description:
- IP address of the peer VPN gateway. Only IPv4 is supported.
returned: success
type: str
- shared_secret:
+ sharedSecret:
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:
+ sharedSecretHash:
description:
- Hash of the shared secret.
returned: success
type: str
- ike_version:
+ 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
- local_traffic_selector:
+ 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
@@ -130,7 +130,7 @@ items:
- Only IPv4 is supported.
returned: success
type: list
- remote_traffic_selector:
+ 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
@@ -143,6 +143,12 @@ items:
- Labels to apply to this VpnTunnel.
returned: success
type: dict
+ labelFingerprint:
+ 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.
diff --git a/lib/ansible/modules/cloud/google/gcp_container_cluster.py b/lib/ansible/modules/cloud/google/gcp_container_cluster.py
index 1998155c60..d0677315eb 100644
--- a/lib/ansible/modules/cloud/google/gcp_container_cluster.py
+++ b/lib/ansible/modules/cloud/google/gcp_container_cluster.py
@@ -268,7 +268,7 @@ EXAMPLES = '''
disk_size_gb: 500
zone: us-central1-a
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -286,7 +286,7 @@ RETURN = '''
- An optional description of this cluster.
returned: success
type: str
- initial_node_count:
+ initialNodeCount:
description:
- The number of nodes to create in this cluster. You must ensure that your Compute
Engine resource quota is sufficient for this number of instances. You must also
@@ -296,7 +296,7 @@ RETURN = '''
this and a nodePool at the same time.
returned: success
type: int
- node_config:
+ nodeConfig:
description:
- Parameters used in creating the cluster's nodes.
- For requests, this field should only be used in lieu of a "nodePool" object, since
@@ -307,19 +307,19 @@ RETURN = '''
returned: success
type: complex
contains:
- machine_type:
+ machineType:
description:
- The name of a Google Compute Engine machine type (e.g.
- n1-standard-1). If unspecified, the default machine type is n1-standard-1.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Size of the disk attached to each node, specified in GB. The smallest allowed disk
size is 10GB. If unspecified, the default disk size is 100GB.
returned: success
type: int
- oauth_scopes:
+ oauthScopes:
description:
- The set of Google API scopes to be made available on all of the node VMs under the
"default" service account.
@@ -332,7 +332,7 @@ RETURN = '''
enabled, in which case their required scopes will be added.
returned: success
type: list
- service_account:
+ serviceAccount:
description:
- The Google Cloud Platform Service Account to be used by the node VMs. If no Service
Account is specified, the "default" service account is used.
@@ -353,7 +353,7 @@ RETURN = '''
- 'Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.'
returned: success
type: dict
- image_type:
+ imageType:
description:
- The image type to use for this node. Note that for a given image type, the latest
version of it will be used.
@@ -371,7 +371,7 @@ RETURN = '''
- 'Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.'
returned: success
type: dict
- local_ssd_count:
+ localSsdCount:
description:
- The number of local SSD disks to be attached to the node.
- 'The limit for this value is dependant upon the maximum number of disks available
@@ -392,7 +392,7 @@ RETURN = '''
for more inforamtion about preemptible VM instances.'
returned: success
type: bool
- master_auth:
+ masterAuth:
description:
- The authentication information for accessing the master endpoint.
returned: success
@@ -409,23 +409,23 @@ RETURN = '''
the master endpoint is open to the Internet, you should create a strong password.
returned: success
type: str
- cluster_ca_certificate:
+ clusterCaCertificate:
description:
- Base64-encoded public certificate that is the root of trust for the cluster.
returned: success
type: str
- client_certificate:
+ clientCertificate:
description:
- Base64-encoded public certificate used by clients to authenticate to the cluster
endpoint.
returned: success
type: str
- client_key:
+ clientKey:
description:
- Base64-encoded private key used by clients to authenticate to the cluster endpoint.
returned: success
type: str
- logging_service:
+ loggingService:
description:
- 'The logging service the cluster should use to write logs. Currently available options: logging.googleapis.com
- the Google Cloud Logging service.'
@@ -433,7 +433,7 @@ RETURN = '''
- if left as an empty string,logging.googleapis.com will be used.
returned: success
type: str
- monitoring_service:
+ monitoringService:
description:
- The monitoring service the cluster should use to write metrics.
- 'Currently available options: monitoring.googleapis.com - the Google Cloud Monitoring
@@ -450,20 +450,20 @@ RETURN = '''
resource.
returned: success
type: str
- cluster_ipv4_cidr:
+ clusterIpv4Cidr:
description:
- The IP address range of the container pods in this cluster, in CIDR notation (e.g.
10.96.0.0/14). Leave blank to have one automatically chosen or specify a /14 block
in 10.0.0.0/8.
returned: success
type: str
- addons_config:
+ addonsConfig:
description:
- Configurations for the various addons available to run in the cluster.
returned: success
type: complex
contains:
- http_load_balancing:
+ httpLoadBalancing:
description:
- Configuration for the HTTP (L7) load balancing controller addon, which makes it
easy to set up HTTP load balancers for services in a cluster.
@@ -476,7 +476,7 @@ RETURN = '''
it runs a small pod in the cluster that manages the load balancers.
returned: success
type: bool
- horizontal_pod_autoscaling:
+ horizontalPodAutoscaling:
description:
- Configuration for the horizontal pod autoscaling feature, which increases or decreases
the number of replica pods a replication controller has based on the resource usage
@@ -509,48 +509,48 @@ RETURN = '''
the masterAuth property of this resource for username and password information.
returned: success
type: str
- initial_cluster_version:
+ initialClusterVersion:
description:
- The software version of the master endpoint and kubelets used in the cluster when
it was first created. The version can be upgraded over time.
returned: success
type: str
- current_master_version:
+ currentMasterVersion:
description:
- The current software version of the master endpoint.
returned: success
type: str
- current_node_version:
+ currentNodeVersion:
description:
- The current version of the node software components. If they are currently at multiple
versions because they're in the process of being upgraded, this reflects the minimum
version of all nodes.
returned: success
type: str
- create_time:
+ createTime:
description:
- The time the cluster was created, in RFC3339 text format.
returned: success
type: str
- node_ipv4_cidr_size:
+ nodeIpv4CidrSize:
description:
- The size of the address space on each node for hosting containers.
- This is provisioned from within the container_ipv4_cidr range.
returned: success
type: int
- services_ipv4_cidr:
+ servicesIpv4Cidr:
description:
- The IP address range of the Kubernetes services in this cluster, in CIDR notation
(e.g. 1.2.3.4/29). Service addresses are typically put in the last /16 from the
container CIDR.
returned: success
type: str
- current_node_count:
+ currentNodeCount:
description:
- The number of nodes currently in the cluster.
returned: success
type: int
- expire_time:
+ expireTime:
description:
- The time the cluster will be automatically deleted in RFC3339 text format.
returned: success
@@ -632,7 +632,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module))
+ update(module, self_link(module))
+ fetch = fetch_resource(module, self_link(module))
changed = True
else:
delete(module, self_link(module))
@@ -689,9 +690,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link):
+def fetch_resource(module, link, allow_not_found=True):
auth = GcpSession(module, 'container')
- return return_if_object(module, auth.get(link))
+ return return_if_object(module, auth.get(link), allow_not_found)
def self_link(module):
@@ -702,9 +703,9 @@ def collection(module):
return "https://container.googleapis.com/v1/projects/{project}/zones/{zone}/clusters".format(**module.params)
-def return_if_object(module, response):
+def return_if_object(module, response, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
diff --git a/lib/ansible/modules/cloud/google/gcp_container_node_pool.py b/lib/ansible/modules/cloud/google/gcp_container_node_pool.py
index dffe9b3229..68b267a133 100644
--- a/lib/ansible/modules/cloud/google/gcp_container_node_pool.py
+++ b/lib/ansible/modules/cloud/google/gcp_container_node_pool.py
@@ -198,6 +198,11 @@ options:
cluster:
description:
- The cluster this node pool belongs to.
+ - 'This field represents a link to a Cluster resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_container_cluster
+ task and then set this cluster field to "{{ name-of-resource }}" Alternatively,
+ you can set this cluster to a dictionary with the name key where the value is the
+ name of your Cluster.'
required: true
zone:
description:
@@ -225,7 +230,7 @@ EXAMPLES = '''
cluster: "{{ cluster }}"
zone: us-central1-a
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -242,19 +247,19 @@ RETURN = '''
returned: success
type: complex
contains:
- machine_type:
+ machineType:
description:
- The name of a Google Compute Engine machine type (e.g.
- n1-standard-1). If unspecified, the default machine type is n1-standard-1.
returned: success
type: str
- disk_size_gb:
+ diskSizeGb:
description:
- Size of the disk attached to each node, specified in GB. The smallest allowed disk
size is 10GB. If unspecified, the default disk size is 100GB.
returned: success
type: int
- oauth_scopes:
+ oauthScopes:
description:
- The set of Google API scopes to be made available on all of the node VMs under the
"default" service account.
@@ -267,7 +272,7 @@ RETURN = '''
enabled, in which case their required scopes will be added.
returned: success
type: list
- service_account:
+ serviceAccount:
description:
- The Google Cloud Platform Service Account to be used by the node VMs. If no Service
Account is specified, the "default" service account is used.
@@ -288,7 +293,7 @@ RETURN = '''
- 'Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.'
returned: success
type: dict
- image_type:
+ imageType:
description:
- The image type to use for this node. Note that for a given image type, the latest
version of it will be used.
@@ -306,7 +311,7 @@ RETURN = '''
- 'Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.'
returned: success
type: dict
- local_ssd_count:
+ localSsdCount:
description:
- The number of local SSD disks to be attached to the node.
- 'The limit for this value is dependant upon the maximum number of disks available
@@ -327,7 +332,7 @@ RETURN = '''
for more inforamtion about preemptible VM instances.'
returned: success
type: bool
- initial_node_count:
+ initialNodeCount:
description:
- The initial node count for the pool. You must ensure that your Compute Engine resource
quota is sufficient for this number of instances. You must also have available firewall
@@ -351,12 +356,12 @@ RETURN = '''
- Is autoscaling enabled for this node pool.
returned: success
type: bool
- min_node_count:
+ minNodeCount:
description:
- Minimum number of nodes in the NodePool. Must be >= 1 and <= maxNodeCount.
returned: success
type: int
- max_node_count:
+ maxNodeCount:
description:
- Maximum number of nodes in the NodePool. Must be >= minNodeCount.
- There has to enough quota to scale up the cluster.
@@ -368,27 +373,27 @@ RETURN = '''
returned: success
type: complex
contains:
- auto_upgrade:
+ autoUpgrade:
description:
- A flag that specifies whether node auto-upgrade is enabled for the node pool. If
enabled, node auto-upgrade helps keep the nodes in your node pool up to date with
the latest release version of Kubernetes.
returned: success
type: bool
- auto_repair:
+ autoRepair:
description:
- A flag that specifies whether the node auto-repair is enabled for the node pool.
If enabled, the nodes in this node pool will be monitored and, if they fail health
checks too many times, an automatic repair action will be triggered.
returned: success
type: bool
- upgrade_options:
+ upgradeOptions:
description:
- Specifies the Auto Upgrade knobs for the node pool.
returned: success
type: complex
contains:
- auto_upgrade_start_time:
+ autoUpgradeStartTime:
description:
- This field is set when upgrades are about to commence with the approximate start
time for the upgrades, in RFC3339 text format.
@@ -474,7 +479,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module))
+ update(module, self_link(module))
+ fetch = fetch_resource(module, self_link(module))
changed = True
else:
delete(module, self_link(module))
@@ -524,9 +530,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link):
+def fetch_resource(module, link, allow_not_found=True):
auth = GcpSession(module, 'container')
- return return_if_object(module, auth.get(link))
+ return return_if_object(module, auth.get(link), allow_not_found)
def self_link(module):
@@ -548,9 +554,9 @@ def collection(module):
return "https://container.googleapis.com/v1/projects/{project}/zones/{zone}/clusters/{cluster}/nodePools".format(**res)
-def return_if_object(module, response):
+def return_if_object(module, response, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
diff --git a/lib/ansible/modules/cloud/google/gcp_dns_managed_zone.py b/lib/ansible/modules/cloud/google/gcp_dns_managed_zone.py
index 9965a31506..08fdc31ead 100644
--- a/lib/ansible/modules/cloud/google/gcp_dns_managed_zone.py
+++ b/lib/ansible/modules/cloud/google/gcp_dns_managed_zone.py
@@ -77,7 +77,7 @@ EXAMPLES = '''
dns_name: test.somewild2.example.com.
description: test zone
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -89,7 +89,7 @@ RETURN = '''
user's convenience. Has no effect on the managed zone's function.
returned: success
type: str
- dns_name:
+ dnsName:
description:
- The DNS name of this managed zone, for instance "example.com.".
returned: success
@@ -105,20 +105,20 @@ RETURN = '''
- Must be unique within the project.
returned: success
type: str
- name_servers:
+ nameServers:
description:
- Delegate your managed_zone to these virtual name servers; defined by the server
.
returned: success
type: list
- name_server_set:
+ nameServerSet:
description:
- Optionally specifies the NameServerSet for this ManagedZone. A NameServerSet is
a set of DNS name servers that all host the same ManagedZones. Most users will leave
this field unset.
returned: success
type: list
- creation_time:
+ creationTime:
description:
- The time that this resource was created on the server.
- This is in RFC3339 text format.
@@ -163,7 +163,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -211,9 +212,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'dns')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -224,9 +225,9 @@ def collection(module):
return "https://www.googleapis.com/dns/v1/projects/{project}/managedZones".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -241,8 +242,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_dns_resource_record_set.py b/lib/ansible/modules/cloud/google/gcp_dns_resource_record_set.py
index 1e4050108c..2b0491534b 100644
--- a/lib/ansible/modules/cloud/google/gcp_dns_resource_record_set.py
+++ b/lib/ansible/modules/cloud/google/gcp_dns_resource_record_set.py
@@ -71,6 +71,11 @@ options:
description:
- Identifies the managed zone addressed by this request.
- Can be the managed zone name or id.
+ - 'This field represents a link to a ManagedZone resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_dns_managed_zone
+ task and then set this managed_zone field to "{{ name-of-resource }}" Alternatively,
+ you can set this managed_zone to a dictionary with the name key where the value
+ is the name of your ManagedZone.'
required: true
extends_documentation_fragment: gcp
'''
@@ -97,7 +102,7 @@ EXAMPLES = '''
- 10.1.2.3
- 40.5.6.7
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -174,7 +179,8 @@ 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)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind, fetch)
@@ -238,9 +244,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'dns')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def fetch_wrapped_resource(module, kind, wrap_kind, wrap_path):
@@ -269,17 +275,17 @@ def self_link(module):
return "https://www.googleapis.com/dns/v1/projects/{project}/managedZones/{managed_zone}/rrsets?name={name}&type={type}".format(**res)
-def collection(module, extra_url=''):
+def collection(module):
res = {
'project': module.params['project'],
'managed_zone': replace_resource_dict(module.params['managed_zone'], 'name')
}
- return "https://www.googleapis.com/dns/v1/projects/{project}/managedZones/{managed_zone}/changes".format(**res) + extra_url
+ return "https://www.googleapis.com/dns/v1/projects/{project}/managedZones/{managed_zone}/changes".format(**res)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -294,8 +300,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
@@ -436,7 +440,7 @@ def wait_for_change_to_complete(change_id, module):
def get_change_status(change_id, module):
auth = GcpSession(module, 'dns')
- link = collection(module, "/%s" % change_id)
+ link = collection(module) + "/%s" % change_id
return return_if_change_object(module, auth.get(link))['status']
diff --git a/lib/ansible/modules/cloud/google/gcp_pubsub_subscription.py b/lib/ansible/modules/cloud/google/gcp_pubsub_subscription.py
index 5f7c2807c5..d5eeeee253 100644
--- a/lib/ansible/modules/cloud/google/gcp_pubsub_subscription.py
+++ b/lib/ansible/modules/cloud/google/gcp_pubsub_subscription.py
@@ -54,6 +54,11 @@ options:
topic:
description:
- A reference to a Topic resource.
+ - 'This field represents a link to a Topic resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_pubsub_topic task and
+ then set this topic field to "{{ name-of-resource }}" Alternatively, you can set
+ this topic to a dictionary with the name key where the value is the name of your
+ Topic.'
required: false
push_config:
description:
@@ -105,7 +110,7 @@ EXAMPLES = '''
push_endpoint: https://myapp.graphite.cloudnativeapp.com/webhook/sub1
ack_deadline_seconds: 300
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -121,7 +126,7 @@ RETURN = '''
- A reference to a Topic resource.
returned: success
type: dict
- push_config:
+ pushConfig:
description:
- If push delivery is used with this subscription, this field is used to configure
it. An empty pushConfig signifies that the subscriber will pull and ack messages
@@ -129,13 +134,13 @@ RETURN = '''
returned: success
type: complex
contains:
- push_endpoint:
+ pushEndpoint:
description:
- A URL locating the endpoint to which messages should be pushed.
- For example, a Webhook endpoint might use "U(https://example.com/push".)
returned: success
type: str
- ack_deadline_seconds:
+ ackDeadlineSeconds:
description:
- This value is the maximum time after a subscriber receives a message before the
subscriber should acknowledge the message. After message delivery but before the
@@ -193,7 +198,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module))
+ update(module, self_link(module))
+ fetch = fetch_resource(module, self_link(module))
changed = True
else:
delete(module, self_link(module))
@@ -241,9 +247,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link):
+def fetch_resource(module, link, allow_not_found=True):
auth = GcpSession(module, 'pubsub')
- return return_if_object(module, auth.get(link))
+ return return_if_object(module, auth.get(link), allow_not_found)
def self_link(module):
@@ -254,9 +260,9 @@ def collection(module):
return "https://pubsub.googleapis.com/v1/projects/{project}/subscriptions".format(**module.params)
-def return_if_object(module, response):
+def return_if_object(module, response, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -319,7 +325,7 @@ def decode_request(response, module):
def encode_request(request, module):
request['topic'] = '/'.join(['projects', module.params['project'],
- 'topics', module.params['topic']])
+ 'topics', module.params['topic']['name']])
request['name'] = '/'.join(['projects', module.params['project'],
'subscriptions', module.params['name']])
diff --git a/lib/ansible/modules/cloud/google/gcp_pubsub_topic.py b/lib/ansible/modules/cloud/google/gcp_pubsub_topic.py
index 863c9f39f6..1a266d46eb 100644
--- a/lib/ansible/modules/cloud/google/gcp_pubsub_topic.py
+++ b/lib/ansible/modules/cloud/google/gcp_pubsub_topic.py
@@ -58,7 +58,7 @@ EXAMPLES = '''
gcp_pubsub_topic:
name: test-topic1
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -104,7 +104,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module))
+ update(module, self_link(module))
+ fetch = fetch_resource(module, self_link(module))
changed = True
else:
delete(module, self_link(module))
@@ -150,9 +151,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link):
+def fetch_resource(module, link, allow_not_found=True):
auth = GcpSession(module, 'pubsub')
- return return_if_object(module, auth.get(link))
+ return return_if_object(module, auth.get(link), allow_not_found)
def self_link(module):
@@ -163,9 +164,9 @@ def collection(module):
return "https://pubsub.googleapis.com/v1/projects/{project}/topics".format(**module.params)
-def return_if_object(module, response):
+def return_if_object(module, response, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
diff --git a/lib/ansible/modules/cloud/google/gcp_spanner_database.py b/lib/ansible/modules/cloud/google/gcp_spanner_database.py
index 702dddd355..3b23cef1dc 100644
--- a/lib/ansible/modules/cloud/google/gcp_spanner_database.py
+++ b/lib/ansible/modules/cloud/google/gcp_spanner_database.py
@@ -61,6 +61,11 @@ options:
instance:
description:
- The instance to create the database on.
+ - 'This field represents a link to a Instance resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_spanner_instance
+ task and then set this instance field to "{{ name-of-resource }}" Alternatively,
+ you can set this instance to a dictionary with the name key where the value is the
+ name of your Instance.'
required: true
extends_documentation_fragment: gcp
'''
@@ -85,7 +90,7 @@ EXAMPLES = '''
name: webstore
instance: "{{ instance }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -98,7 +103,7 @@ RETURN = '''
The final segment of the name must be between 6 and 30 characters in length.
returned: success
type: str
- extra_statements:
+ extraStatements:
description:
- 'An optional list of DDL statements to run inside the newly created database. Statements
can create tables, indexes, etc. These statements execute atomically with the creation
@@ -147,7 +152,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module))
+ update(module, self_link(module))
+ fetch = fetch_resource(module, self_link(module))
changed = True
else:
delete(module, self_link(module))
@@ -194,9 +200,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link):
+def fetch_resource(module, link, allow_not_found=True):
auth = GcpSession(module, 'spanner')
- return return_if_object(module, auth.get(link))
+ return return_if_object(module, auth.get(link), allow_not_found)
def self_link(module):
@@ -216,9 +222,9 @@ def collection(module):
return "https://spanner.googleapis.com/v1/projects/{project}/instances/{instance}/databases".format(**res)
-def return_if_object(module, response):
+def return_if_object(module, response, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
diff --git a/lib/ansible/modules/cloud/google/gcp_spanner_instance.py b/lib/ansible/modules/cloud/google/gcp_spanner_instance.py
index bd5dbb3e6d..dcac37f969 100644
--- a/lib/ansible/modules/cloud/google/gcp_spanner_instance.py
+++ b/lib/ansible/modules/cloud/google/gcp_spanner_instance.py
@@ -99,7 +99,7 @@ EXAMPLES = '''
cost_center: ti-1700004
config: regional-us-central1
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -117,13 +117,13 @@ RETURN = '''
- A reference to the instance configuration.
returned: success
type: str
- display_name:
+ displayName:
description:
- The descriptive name for this instance as it appears in UIs. Must be unique per
project and between 4 and 30 characters in length.
returned: success
type: str
- node_count:
+ nodeCount:
description:
- The number of nodes allocated to this instance.
returned: success
@@ -189,7 +189,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module))
+ update(module, self_link(module))
+ fetch = fetch_resource(module, self_link(module))
changed = True
else:
delete(module, self_link(module))
@@ -238,9 +239,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link):
+def fetch_resource(module, link, allow_not_found=True):
auth = GcpSession(module, 'spanner')
- return return_if_object(module, auth.get(link))
+ return return_if_object(module, auth.get(link), allow_not_found)
def self_link(module):
@@ -251,9 +252,9 @@ def collection(module):
return "https://spanner.googleapis.com/v1/projects/{project}/instances".format(**module.params)
-def return_if_object(module, response):
+def return_if_object(module, response, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
diff --git a/lib/ansible/modules/cloud/google/gcp_sql_database.py b/lib/ansible/modules/cloud/google/gcp_sql_database.py
index 574c00112b..2069aeded4 100644
--- a/lib/ansible/modules/cloud/google/gcp_sql_database.py
+++ b/lib/ansible/modules/cloud/google/gcp_sql_database.py
@@ -62,6 +62,11 @@ options:
instance:
description:
- The name of the Cloud SQL instance. This does not include the project ID.
+ - 'This field represents a link to a Instance resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_sql_instance task
+ and then set this instance field to "{{ name-of-resource }}" Alternatively, you
+ can set this instance to a dictionary with the name key where the value is the name
+ of your Instance.'
required: true
extends_documentation_fragment: gcp
'''
@@ -89,7 +94,7 @@ EXAMPLES = '''
charset: utf8
instance: "{{ instance }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -156,7 +161,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -204,9 +210,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'sql')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -226,7 +232,7 @@ def collection(module):
return "https://www.googleapis.com/sql/v1beta4/projects/{project}/instances/{instance}/databases".format(**res)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
if response.status_code == 404:
return None
diff --git a/lib/ansible/modules/cloud/google/gcp_sql_instance.py b/lib/ansible/modules/cloud/google/gcp_sql_instance.py
index 373e1bf0ed..e298130935 100644
--- a/lib/ansible/modules/cloud/google/gcp_sql_instance.py
+++ b/lib/ansible/modules/cloud/google/gcp_sql_instance.py
@@ -246,6 +246,12 @@ options:
instances, this field determines whether the instance is Second Generation (recommended)
or First Generation.
required: false
+ settings_version:
+ description:
+ - The version of instance settings. This is a required field for update method to
+ make sure concurrent updates are handled properly. During update, use the most
+ recent settingsVersion value for this instance and do not try to update this value.
+ required: false
extends_documentation_fragment: gcp
'''
@@ -261,25 +267,25 @@ EXAMPLES = '''
tier: db-n1-standard-1
region: us-central1
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
RETURN = '''
- backend_type:
+ backendType:
description:
- "* FIRST_GEN: First Generation instance. MySQL only."
- "* SECOND_GEN: Second Generation instance or PostgreSQL instance."
- "* EXTERNAL: A database server that is not managed by Google."
returned: success
type: str
- connection_name:
+ connectionName:
description:
- Connection name of the Cloud SQL instance used in connection strings.
returned: success
type: str
- database_version:
+ databaseVersion:
description:
- The database engine type and version. For First Generation instances, can be MYSQL_5_5,
or MYSQL_5_6. For Second Generation instances, can be MYSQL_5_6 or MYSQL_5_7. Defaults
@@ -288,7 +294,7 @@ RETURN = '''
after instance creation.'
returned: success
type: str
- failover_replica:
+ failoverReplica:
description:
- The name and status of the failover replica. This property is applicable only to
Second Generation instances.
@@ -309,7 +315,7 @@ RETURN = '''
property is applicable only to Second Generation instances.
returned: success
type: str
- instance_type:
+ instanceType:
description:
- The instance type. This can be one of the following.
- "* CLOUD_SQL_INSTANCE: A Cloud SQL instance that is not replicating from a master."
@@ -317,18 +323,18 @@ RETURN = '''
- "* READ_REPLICA_INSTANCE: A Cloud SQL instance configured as a read-replica."
returned: success
type: str
- ip_addresses:
+ ipAddresses:
description:
- The assigned IP addresses for the instance.
returned: success
type: complex
contains:
- ip_address:
+ ipAddress:
description:
- The IP address assigned.
returned: success
type: str
- time_to_retire:
+ timeToRetire:
description:
- The due time for this IP to be retired in RFC 3339 format, for example 2012-11-15T16:19:00.094Z.
This field is only available when the IP is scheduled to be retired.
@@ -341,18 +347,18 @@ RETURN = '''
from the instance, if supported.
returned: success
type: str
- ipv6_address:
+ ipv6Address:
description:
- The IPv6 address assigned to the instance. This property is applicable only to First
Generation instances.
returned: success
type: str
- master_instance_name:
+ masterInstanceName:
description:
- The name of the instance which will act as master in the replication setup.
returned: success
type: str
- max_disk_size:
+ maxDiskSize:
description:
- The maximum disk size of the instance in bytes.
returned: success
@@ -368,13 +374,13 @@ RETURN = '''
instance type (First Generation or Second Generation/PostgreSQL).
returned: success
type: str
- replica_configuration:
+ replicaConfiguration:
description:
- Configuration specific to failover replicas and read replicas.
returned: success
type: complex
contains:
- failover_target:
+ failoverTarget:
description:
- Specifies if the replica is the failover target. If the field is set to true the
replica will be designated as a failover replica.
@@ -384,7 +390,7 @@ RETURN = '''
in different zone with the master instance.
returned: success
type: bool
- mysql_replica_configuration:
+ mysqlReplicaConfiguration:
description:
- MySQL specific configuration when replicating from a MySQL on-premises master. Replication
configuration information such as the username, password, certificates, and keys
@@ -394,28 +400,28 @@ RETURN = '''
returned: success
type: complex
contains:
- ca_certificate:
+ caCertificate:
description:
- PEM representation of the trusted CA's x509 certificate.
returned: success
type: str
- client_certificate:
+ clientCertificate:
description:
- PEM representation of the slave's x509 certificate .
returned: success
type: str
- client_key:
+ clientKey:
description:
- PEM representation of the slave's private key. The corresponsing public key is encoded
in the client's asf asd certificate.
returned: success
type: str
- connect_retry_interval:
+ connectRetryInterval:
description:
- Seconds to wait between connect retries. MySQL's default is 60 seconds.
returned: success
type: int
- dump_file_path:
+ dumpFilePath:
description:
- Path to a SQL dump file in Google Cloud Storage from which the slave instance is
to be created. The URI is in the form gs://bucketName/fileName. Compressed gzip
@@ -424,7 +430,7 @@ RETURN = '''
when using mysqldump.
returned: success
type: str
- master_heartbeat_period:
+ masterHeartbeatPeriod:
description:
- Interval in milliseconds between replication heartbeats.
returned: success
@@ -434,7 +440,7 @@ RETURN = '''
- The password for the replication connection.
returned: success
type: str
- ssl_cipher:
+ sslCipher:
description:
- A list of permissible ciphers to use for SSL encryption.
returned: success
@@ -444,18 +450,18 @@ RETURN = '''
- The username for the replication connection.
returned: success
type: str
- verify_server_certificate:
+ verifyServerCertificate:
description:
- Whether or not to check the master's Common Name value in the certificate that it
sends during the SSL handshake.
returned: success
type: bool
- replica_names:
+ replicaNames:
description:
- The replicas of the instance.
returned: success
type: list
- service_account_email_address:
+ serviceAccountEmailAddress:
description:
- The service account email address assigned to the instance. This property is applicable
only to Second Generation instances.
@@ -467,7 +473,7 @@ RETURN = '''
returned: success
type: complex
contains:
- ip_configuration:
+ ipConfiguration:
description:
- The settings for IP Management. This allows to enable or disable the instance IP
and manage which external networks can connect to the instance. The IPv4 address
@@ -475,19 +481,19 @@ RETURN = '''
returned: success
type: complex
contains:
- ipv4_enabled:
+ ipv4Enabled:
description:
- Whether the instance should be assigned an IP address or not.
returned: success
type: bool
- authorized_networks:
+ authorizedNetworks:
description:
- The list of external networks that are allowed to connect to the instance using
the IP. In CIDR notation, also known as 'slash' notation (e.g. 192.168.100.0/24).
returned: success
type: complex
contains:
- expiration_time:
+ expirationTime:
description:
- The time when this access control entry expires in RFC 3339 format, for example
2012-11-15T16:19:00.094Z.
@@ -505,7 +511,7 @@ RETURN = '''
or subnet here.
returned: success
type: str
- require_ssl:
+ requireSsl:
description:
- Whether the mysqld should default to 'REQUIRE X509' for users connecting over IP.
returned: success
@@ -517,6 +523,13 @@ RETURN = '''
or First Generation.
returned: success
type: str
+ settingsVersion:
+ description:
+ - The version of instance settings. This is a required field for update method to
+ make sure concurrent updates are handled properly. During update, use the most
+ recent settingsVersion value for this instance and do not try to update this value.
+ returned: success
+ type: int
'''
################################################################################
@@ -578,7 +591,8 @@ def main():
)),
require_ssl=dict(type='bool')
)),
- tier=dict(type='str')
+ tier=dict(type='str'),
+ settings_version=dict(type='int')
))
)
)
@@ -595,7 +609,8 @@ 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)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind, fetch)
@@ -652,9 +667,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'sql')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -665,7 +680,7 @@ def collection(module):
return "https://www.googleapis.com/sql/v1beta4/projects/{project}/instances".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
if response.status_code == 404:
return None
@@ -895,13 +910,15 @@ class InstanceSettings(object):
def to_request(self):
return remove_nones_from_dict({
u'ipConfiguration': InstanceIpConfiguration(self.request.get('ip_configuration', {}), self.module).to_request(),
- u'tier': self.request.get('tier')
+ u'tier': self.request.get('tier'),
+ u'settingsVersion': self.request.get('settings_version')
})
def from_response(self):
return remove_nones_from_dict({
u'ipConfiguration': InstanceIpConfiguration(self.request.get(u'ipConfiguration', {}), self.module).from_response(),
- u'tier': self.request.get(u'tier')
+ u'tier': self.request.get(u'tier'),
+ u'settingsVersion': self.request.get(u'settingsVersion')
})
diff --git a/lib/ansible/modules/cloud/google/gcp_sql_user.py b/lib/ansible/modules/cloud/google/gcp_sql_user.py
index b913722210..d0ab9e7ac1 100644
--- a/lib/ansible/modules/cloud/google/gcp_sql_user.py
+++ b/lib/ansible/modules/cloud/google/gcp_sql_user.py
@@ -59,6 +59,11 @@ options:
instance:
description:
- The name of the Cloud SQL instance. This does not include the project ID.
+ - 'This field represents a link to a Instance resource in GCP. It can be specified
+ in two ways. You can add `register: name-of-resource` to a gcp_sql_instance task
+ and then set this instance field to "{{ name-of-resource }}" Alternatively, you
+ can set this instance to a dictionary with the name key where the value is the name
+ of your Instance.'
required: true
password:
description:
@@ -91,7 +96,7 @@ EXAMPLES = '''
password: secret-password
instance: "{{ instance }}"
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -161,7 +166,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -231,9 +237,9 @@ def unwrap_resource(result, module):
return None
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'sql')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def fetch_wrapped_resource(module, kind, wrap_kind, wrap_path):
@@ -270,7 +276,7 @@ def collection(module):
return "https://www.googleapis.com/sql/v1beta4/projects/{project}/instances/{instance}/users".format(**res)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
if response.status_code == 404:
return None
diff --git a/lib/ansible/modules/cloud/google/gcp_storage_bucket.py b/lib/ansible/modules/cloud/google/gcp_storage_bucket.py
index 0f47994284..644f6a8d02 100644
--- a/lib/ansible/modules/cloud/google/gcp_storage_bucket.py
+++ b/lib/ansible/modules/cloud/google/gcp_storage_bucket.py
@@ -59,6 +59,11 @@ options:
bucket:
description:
- The name of the bucket.
+ - 'This field represents a link to a Bucket resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_storage_bucket task
+ and then set this bucket field to "{{ name-of-resource }}" Alternatively, you can
+ set this bucket to a dictionary with the name key where the value is the name of
+ your Bucket.'
required: true
domain:
description:
@@ -139,6 +144,11 @@ options:
bucket:
description:
- The name of the bucket.
+ - 'This field represents a link to a Bucket resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_storage_bucket task
+ and then set this bucket field to "{{ name-of-resource }}" Alternatively, you can
+ set this bucket to a dictionary with the name key where the value is the name of
+ your Bucket.'
required: true
domain:
description:
@@ -358,7 +368,7 @@ EXAMPLES = '''
gcp_storage_bucket:
name: ansible-storage-module
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -396,7 +406,7 @@ RETURN = '''
entity would be domain-example.com.
returned: success
type: str
- entity_id:
+ entityId:
description:
- The ID for the entity.
returned: success
@@ -406,13 +416,13 @@ RETURN = '''
- The ID of the access-control entry.
returned: success
type: str
- project_team:
+ projectTeam:
description:
- The project team associated with the entity.
returned: success
type: complex
contains:
- project_number:
+ projectNumber:
description:
- The project team associated with the entity.
returned: success
@@ -433,7 +443,7 @@ RETURN = '''
returned: success
type: complex
contains:
- max_age_seconds:
+ maxAgeSeconds:
description:
- The value, in seconds, to return in the Access-Control-Max-Age header used in preflight
responses.
@@ -451,13 +461,13 @@ RETURN = '''
- 'Note: "*" is permitted in the list of origins, and means "any Origin".'
returned: success
type: list
- response_header:
+ responseHeader:
description:
- The list of HTTP headers other than the simple response headers to give permission
for the user-agent to share across domains.
returned: success
type: list
- default_object_acl:
+ defaultObjectAcl:
description:
- Default access controls to apply to new objects when no ACL is provided.
returned: success
@@ -489,7 +499,7 @@ RETURN = '''
entity would be domain-example.com.
returned: success
type: str
- entity_id:
+ entityId:
description:
- The ID for the entity.
returned: success
@@ -509,13 +519,13 @@ RETURN = '''
- The name of the object, if applied to an object.
returned: success
type: str
- project_team:
+ projectTeam:
description:
- The project team associated with the entity.
returned: success
type: complex
contains:
- project_number:
+ projectNumber:
description:
- The project team associated with the entity.
returned: success
@@ -555,7 +565,7 @@ RETURN = '''
returned: success
type: complex
contains:
- storage_class:
+ storageClass:
description:
- Target storage class. Required iff the type of the action is SetStorageClass.
returned: success
@@ -571,32 +581,32 @@ RETURN = '''
returned: success
type: complex
contains:
- age_days:
+ ageDays:
description:
- Age of an object (in days). This condition is satisfied when an object reaches the
specified age.
returned: success
type: int
- created_before:
+ createdBefore:
description:
- A date in RFC 3339 format with only the date part (for instance, "2013-01-15").
This condition is satisfied when an object is created before midnight of the specified
date in UTC.
returned: success
type: str
- is_live:
+ isLive:
description:
- Relevant only for versioned objects. If the value is true, this condition matches
live objects; if the value is false, it matches archived objects.
returned: success
type: bool
- matches_storage_class:
+ matchesStorageClass:
description:
- Objects having any of the storage classes specified by this condition will be matched.
Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, STANDARD, and DURABLE_REDUCED_AVAILABILITY.
returned: success
type: list
- num_newer_versions:
+ numNewerVersions:
description:
- Relevant only for versioned objects. If the value is N, this condition is satisfied
when there are at least N versions (including the live version) newer than this
@@ -617,12 +627,12 @@ RETURN = '''
returned: success
type: complex
contains:
- log_bucket:
+ logBucket:
description:
- The destination bucket where the current bucket's logs should be placed.
returned: success
type: str
- log_object_prefix:
+ logObjectPrefix:
description:
- A prefix for log object names.
returned: success
@@ -648,17 +658,17 @@ RETURN = '''
- The entity, in the form project-owner-projectId.
returned: success
type: str
- entity_id:
+ entityId:
description:
- The ID for the entity.
returned: success
type: str
- project_number:
+ projectNumber:
description:
- The project number of the project the bucket belongs to.
returned: success
type: int
- storage_class:
+ storageClass:
description:
- The bucket's default storage class, used whenever no storageClass is specified for
a newly-created object. This defines how objects in the bucket are stored and determines
@@ -668,7 +678,7 @@ RETURN = '''
For more information, see storage classes.
returned: success
type: str
- time_created:
+ timeCreated:
description:
- The creation time of the bucket in RFC 3339 format.
returned: success
@@ -696,14 +706,14 @@ RETURN = '''
returned: success
type: complex
contains:
- main_page_suffix:
+ mainPageSuffix:
description:
- If the requested object path is missing, the service will ensure the path has a
trailing '/', append this suffix, and attempt to retrieve the resulting object.
This allows the creation of index.html objects to represent directory pages.
returned: success
type: str
- not_found_page:
+ notFoundPage:
description:
- If the requested object path is missing, and any mainPageSuffix object is missing,
if applicable, the service will return the named object from this bucket as the
@@ -715,7 +725,7 @@ RETURN = '''
- A valid API project identifier.
returned: success
type: str
- predefined_default_object_acl:
+ predefinedDefaultObjectAcl:
description:
- Apply a predefined set of default object access controls to this bucket.
- 'Acceptable values are: - "authenticatedRead": Object owner gets OWNER access,
@@ -840,7 +850,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -899,9 +910,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'storage')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -912,9 +923,9 @@ def collection(module):
return "https://www.googleapis.com/storage/v1/b?project={project}".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -929,8 +940,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result
diff --git a/lib/ansible/modules/cloud/google/gcp_storage_bucket_access_control.py b/lib/ansible/modules/cloud/google/gcp_storage_bucket_access_control.py
index 586ba93202..0f48f4aaf3 100644
--- a/lib/ansible/modules/cloud/google/gcp_storage_bucket_access_control.py
+++ b/lib/ansible/modules/cloud/google/gcp_storage_bucket_access_control.py
@@ -58,6 +58,11 @@ options:
bucket:
description:
- The name of the bucket.
+ - 'This field represents a link to a Bucket resource in GCP. It can be specified in
+ two ways. You can add `register: name-of-resource` to a gcp_storage_bucket task
+ and then set this bucket field to "{{ name-of-resource }}" Alternatively, you can
+ set this bucket to a dictionary with the name key where the value is the name of
+ your Bucket.'
required: true
entity:
description:
@@ -111,7 +116,7 @@ EXAMPLES = '''
entity: user-alexstephen@google.com
role: WRITER
project: "test_project"
- auth_kind: "service_account"
+ auth_kind: "serviceaccount"
service_account_file: "/tmp/auth.pem"
state: present
'''
@@ -143,7 +148,7 @@ RETURN = '''
entity would be domain-example.com.
returned: success
type: str
- entity_id:
+ entityId:
description:
- The ID for the entity.
returned: success
@@ -153,13 +158,13 @@ RETURN = '''
- The ID of the access-control entry.
returned: success
type: str
- project_team:
+ projectTeam:
description:
- The project team associated with the entity.
returned: success
type: complex
contains:
- project_number:
+ projectNumber:
description:
- The project team associated with the entity.
returned: success
@@ -217,7 +222,8 @@ def main():
if fetch:
if state == 'present':
if is_different(module, fetch):
- fetch = update(module, self_link(module), kind)
+ update(module, self_link(module), kind)
+ fetch = fetch_resource(module, self_link(module), kind)
changed = True
else:
delete(module, self_link(module), kind)
@@ -267,9 +273,9 @@ def resource_to_request(module):
return return_vals
-def fetch_resource(module, link, kind):
+def fetch_resource(module, link, kind, allow_not_found=True):
auth = GcpSession(module, 'storage')
- return return_if_object(module, auth.get(link), kind)
+ return return_if_object(module, auth.get(link), kind, allow_not_found)
def self_link(module):
@@ -280,9 +286,9 @@ def collection(module):
return "https://www.googleapis.com/storage/v1/b/{bucket}/acl".format(**module.params)
-def return_if_object(module, response, kind):
+def return_if_object(module, response, kind, allow_not_found=False):
# If not found, return nothing.
- if response.status_code == 404:
+ if allow_not_found and response.status_code == 404:
return None
# If no content, return nothing.
@@ -297,8 +303,6 @@ def return_if_object(module, response, kind):
if navigate_hash(result, ['error', 'errors']):
module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
- if result['kind'] != kind:
- module.fail_json(msg="Incorrect result: {kind}".format(**result))
return result