1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Bug fixes for gcp_compute_disk (#42806)

This commit is contained in:
Alex Stephen 2018-08-13 09:04:57 -07:00 committed by Ryan Brown
parent 146c126780
commit c8418a709b
2 changed files with 158 additions and 125 deletions

View file

@ -61,6 +61,11 @@ options:
- An optional description of this resource. Provide this property when you create - An optional description of this resource. Provide this property when you create
the resource. the resource.
required: false required: false
labels:
description:
- Labels to apply to this disk. A list of key->value pairs.
required: false
version_added: 2.7
licenses: licenses:
description: description:
- Any applicable publicly visible licenses. - Any applicable publicly visible licenses.
@ -73,7 +78,7 @@ options:
which means the first character must be a lowercase letter, and all following characters 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 must be a dash, lowercase letter, or digit, except the last character, which cannot
be a dash. be a dash.
required: false required: true
size_gb: size_gb:
description: description:
- Size of the persistent disk, specified in GB. You can specify this field when creating - Size of the persistent disk, specified in GB. You can specify this field when creating
@ -82,6 +87,12 @@ options:
- If you specify this field along with sourceImage or sourceSnapshot, the value of - If you specify this field along with sourceImage or sourceSnapshot, the value of
sizeGb must not be less than the size of the sourceImage or the size of the snapshot. sizeGb must not be less than the size of the sourceImage or the size of the snapshot.
required: false required: false
type:
description:
- URL of the disk type resource describing which disk type to use to create the disk.
Provide this when creating the disk.
required: false
version_added: 2.7
source_image: source_image:
description: description:
- The source image used to create this disk. If the source image is deleted, this - The source image used to create this disk. If the source image is deleted, this
@ -98,8 +109,24 @@ options:
required: false required: false
zone: zone:
description: description:
- A reference to Zone resource. - A reference to the zone where the disk resides.
required: true required: true
source_image_encryption_key:
description:
- The customer-supplied encryption key of the source image. Required if the source
image is protected by a customer-supplied encryption key.
required: false
suboptions:
raw_key:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
required: false
sha256:
description:
- The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key
that protects this resource.
required: false
disk_encryption_key: disk_encryption_key:
description: description:
- Encrypts the disk using a customer-supplied encryption key. - Encrypts the disk using a customer-supplied encryption key.
@ -122,30 +149,12 @@ options:
- The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key - The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key
that protects this resource. that protects this resource.
required: false required: false
source_image_encryption_key:
description:
- The customer-supplied encryption key of the source image. Required if the source
image is protected by a customer-supplied encryption key.
required: false
suboptions:
raw_key:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
required: false
sha256:
description:
- The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key
that protects this resource.
required: false
source_snapshot: source_snapshot:
description: description:
- 'The source snapshot used to create this disk. You can provide - 'The source snapshot used to create this disk. You can provide this as a partial or
this as a partial or full URL to the resource. For example, the full URL to the resource. For example, the following are valid values: *
following are valid values: * `U(https://www.googleapis.com/compute/v1/projects/project/global/snapshots/snapshot`)
U(https://www.googleapis.com/compute/v1/projects/project/global/) * `projects/project/global/snapshots/snapshot` * `global/snapshots/snapshot` .'
snapshots/snapshot * projects/project/global/snapshots/snapshot *
global/snapshots/snapshot .'
required: false required: false
source_snapshot_encryption_key: source_snapshot_encryption_key:
description: description:
@ -164,21 +173,22 @@ options:
that protects this resource. that protects this resource.
required: false required: false
extends_documentation_fragment: gcp extends_documentation_fragment: gcp
notes:
- "API Reference: U(https://cloud.google.com/compute/docs/reference/latest/disks)"
- "Adding a persistent disk: U(https://cloud.google.com/compute/docs/disks/add-persistent-disk)"
''' '''
EXAMPLES = ''' EXAMPLES = '''
- name: create a disk - name: create a disk
gcp_compute_disk: gcp_compute_disk:
name: testObject name: "test_object"
size_gb: 50 size_gb: 50
disk_encryption_key: disk_encryption_key:
raw_key: 'SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=' raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: 'us-central1-a' zone: us-central1-a
project: testProject project: "test_project"
auth_kind: service_account auth_kind: "service_account"
service_account_file: /tmp/auth.pem service_account_file: "/tmp/auth.pem"
scopes:
- https://www.googleapis.com/auth/compute
state: present state: present
''' '''
@ -209,6 +219,11 @@ RETURN = '''
- Last dettach timestamp in RFC3339 text format. - Last dettach timestamp in RFC3339 text format.
returned: success returned: success
type: str type: str
labels:
description:
- Labels to apply to this disk. A list of key->value pairs.
returned: success
type: dict
licenses: licenses:
description: description:
- Any applicable publicly visible licenses. - Any applicable publicly visible licenses.
@ -233,6 +248,18 @@ RETURN = '''
sizeGb must not be less than the size of the sourceImage or the size of the snapshot. sizeGb must not be less than the size of the sourceImage or the size of the snapshot.
returned: success returned: success
type: int 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: source_image:
description: description:
- The source image used to create this disk. If the source image is deleted, this - The source image used to create this disk. If the source image is deleted, this
@ -248,46 +275,9 @@ RETURN = '''
.' .'
returned: success returned: success
type: str type: str
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
zone: zone:
description: description:
- A reference to Zone resource. - A reference to the zone where the disk resides.
returned: success
type: str
disk_encryption_key:
description:
- Encrypts the disk using a customer-supplied encryption key.
- After you encrypt a disk with a customer-supplied key, you must provide the same
key if you use the disk later (e.g. to create a disk snapshot or an image, or to
attach the disk to a virtual machine).
- Customer-supplied encryption keys do not protect access to metadata of the disk.
- If you do not provide an encryption key when creating the disk, then the disk will
be encrypted using an automatically generated key and you do not need to provide
a key to use the disk later.
returned: success
type: complex
contains:
raw_key:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
returned: success
type: str
sha256:
description:
- The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key
that protects this resource.
returned: success returned: success
type: str type: str
source_image_encryption_key: source_image_encryption_key:
@ -318,16 +308,39 @@ RETURN = '''
was used. was used.
returned: success returned: success
type: str type: str
source_snapshot: disk_encryption_key:
description: description:
- 'The source snapshot used to create this disk. You can provide - Encrypts the disk using a customer-supplied encryption key.
this as a partial or full URL to the resource. For example, the - After you encrypt a disk with a customer-supplied key, you must provide the same
following are valid values: * key if you use the disk later (e.g. to create a disk snapshot or an image, or to
U(https://www.googleapis.com/compute/v1/projects/project/global/) attach the disk to a virtual machine).
snapshots/snapshot * projects/project/global/snapshots/snapshot * - Customer-supplied encryption keys do not protect access to metadata of the disk.
global/snapshots/snapshot .' - If you do not provide an encryption key when creating the disk, then the disk will
be encrypted using an automatically generated key and you do not need to provide
a key to use the disk later.
returned: success
type: complex
contains:
raw_key:
description:
- Specifies a 256-bit customer-supplied encryption key, encoded in RFC 4648 base64
to either encrypt or decrypt this resource.
returned: success returned: success
type: str type: str
sha256:
description:
- The RFC 4648 base64 encoded SHA-256 hash of the customer-supplied encryption key
that protects this resource.
returned: success
type: str
source_snapshot:
description:
- 'The source snapshot used to create this disk. You can provide this as a partial or
full URL to the resource. For example, the following are valid values: *
`U(https://www.googleapis.com/compute/v1/projects/project/global/snapshots/snapshot`)
* `projects/project/global/snapshots/snapshot` * `global/snapshots/snapshot` .'
returned: success
type: dict
source_snapshot_encryption_key: source_snapshot_encryption_key:
description: description:
- The customer-supplied encryption key of the source snapshot. Required if the source - The customer-supplied encryption key of the source snapshot. Required if the source
@ -364,6 +377,7 @@ RETURN = '''
from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpModule, GcpRequest, remove_nones_from_dict, 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 json
import re
import time import time
################################################################################ ################################################################################
@ -378,20 +392,22 @@ def main():
argument_spec=dict( argument_spec=dict(
state=dict(default='present', choices=['present', 'absent'], type='str'), state=dict(default='present', choices=['present', 'absent'], type='str'),
description=dict(type='str'), description=dict(type='str'),
labels=dict(type='dict'),
licenses=dict(type='list', elements='str'), licenses=dict(type='list', elements='str'),
name=dict(type='str'), name=dict(required=True, type='str'),
size_gb=dict(type='int'), size_gb=dict(type='int'),
type=dict(type='str'),
source_image=dict(type='str'), source_image=dict(type='str'),
zone=dict(required=True, type='str'), zone=dict(required=True, type='str'),
disk_encryption_key=dict(type='dict', options=dict(
raw_key=dict(type='str'),
sha256=dict(type='str')
)),
source_image_encryption_key=dict(type='dict', options=dict( source_image_encryption_key=dict(type='dict', options=dict(
raw_key=dict(type='str'), raw_key=dict(type='str'),
sha256=dict(type='str') sha256=dict(type='str')
)), )),
source_snapshot=dict(type='str'), disk_encryption_key=dict(type='dict', options=dict(
raw_key=dict(type='str'),
sha256=dict(type='str')
)),
source_snapshot=dict(type='dict'),
source_snapshot_encryption_key=dict(type='dict', options=dict( source_snapshot_encryption_key=dict(type='dict', options=dict(
raw_key=dict(type='str'), raw_key=dict(type='str'),
sha256=dict(type='str') sha256=dict(type='str')
@ -399,6 +415,9 @@ def main():
) )
) )
if not module.params['scopes']:
module.params['scopes'] = ['https://www.googleapis.com/auth/compute']
state = module.params['state'] state = module.params['state']
kind = 'compute#disk' kind = 'compute#disk'
@ -408,10 +427,10 @@ def main():
if fetch: if fetch:
if state == 'present': if state == 'present':
if is_different(module, fetch): if is_different(module, fetch):
fetch = update(module, self_link(module), kind, fetch) fetch = update(module, self_link(module), kind)
changed = True changed = True
else: else:
delete(module, self_link(module), kind, fetch) delete(module, self_link(module), kind)
fetch = {} fetch = {}
changed = True changed = True
else: else:
@ -431,11 +450,11 @@ def create(module, link, kind):
return wait_for_operation(module, auth.post(link, resource_to_request(module))) return wait_for_operation(module, auth.post(link, resource_to_request(module)))
def update(module, link, kind, fetch): def update(module, link, kind):
module.fail_json(msg="Disk cannot be edited") module.fail_json(msg="Disk cannot be edited")
def delete(module, link, kind, fetch): def delete(module, link, kind):
auth = GcpSession(module, 'compute') auth = GcpSession(module, 'compute')
return wait_for_operation(module, auth.delete(link)) return wait_for_operation(module, auth.delete(link))
@ -443,13 +462,15 @@ def delete(module, link, kind, fetch):
def resource_to_request(module): def resource_to_request(module):
request = { request = {
u'kind': 'compute#disk', u'kind': 'compute#disk',
u'diskEncryptionKey': DiskDiskEncryKey(module.params.get('disk_encryption_key', {}), module).to_request(), u'sourceImageEncryptionKey': DiskSourceImageEncryptionKey(module.params.get('source_image_encryption_key', {}), module).to_request(),
u'sourceImageEncryptionKey': DiskSourImagEncrKey(module.params.get('source_image_encryption_key', {}), module).to_request(), u'diskEncryptionKey': DiskDiskEncryptionKey(module.params.get('disk_encryption_key', {}), module).to_request(),
u'sourceSnapshotEncryptionKey': DiskSourSnapEncrKey(module.params.get('source_snapshot_encryption_key', {}), module).to_request(), u'sourceSnapshotEncryptionKey': DiskSourceSnapshotEncryptionKey(module.params.get('source_snapshot_encryption_key', {}), module).to_request(),
u'description': module.params.get('description'), u'description': module.params.get('description'),
u'labels': module.params.get('labels'),
u'licenses': module.params.get('licenses'), u'licenses': module.params.get('licenses'),
u'name': module.params.get('name'), u'name': module.params.get('name'),
u'sizeGb': module.params.get('size_gb'), u'sizeGb': module.params.get('size_gb'),
u'type': disk_type_selflink(module.params.get('type'), module.params),
u'sourceImage': module.params.get('source_image') u'sourceImage': module.params.get('source_image')
} }
return_vals = {} return_vals = {}
@ -523,15 +544,25 @@ def response_to_hash(module, response):
u'id': response.get(u'id'), u'id': response.get(u'id'),
u'lastAttachTimestamp': response.get(u'lastAttachTimestamp'), u'lastAttachTimestamp': response.get(u'lastAttachTimestamp'),
u'lastDetachTimestamp': response.get(u'lastDetachTimestamp'), u'lastDetachTimestamp': response.get(u'lastDetachTimestamp'),
u'labels': response.get(u'labels'),
u'licenses': response.get(u'licenses'), u'licenses': response.get(u'licenses'),
u'name': response.get(u'name'), u'name': module.params.get('name'),
u'sizeGb': response.get(u'sizeGb'), u'sizeGb': response.get(u'sizeGb'),
u'sourceImage': module.params.get('source_image'),
u'type': response.get(u'type'), u'type': response.get(u'type'),
u'users': response.get(u'users') u'users': response.get(u'users'),
u'sourceImage': module.params.get('source_image')
} }
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\-]*"
if not re.match(url, name):
name = "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/diskTypes/%s".format(**params) % name
return name
def async_op_url(module, extra_data=None): def async_op_url(module, extra_data=None):
if extra_data is None: if extra_data is None:
extra_data = {} extra_data = {}
@ -544,7 +575,7 @@ def async_op_url(module, extra_data=None):
def wait_for_operation(module, response): def wait_for_operation(module, response):
op_result = return_if_object(module, response, 'compute#operation') op_result = return_if_object(module, response, 'compute#operation')
if op_result is None: if op_result is None:
return None return {}
status = navigate_hash(op_result, ['status']) status = navigate_hash(op_result, ['status'])
wait_done = wait_for_completion(status, op_result, module) wait_done = wait_for_completion(status, op_result, module)
return fetch_resource(module, navigate_hash(wait_done, ['targetLink']), 'compute#disk') return fetch_resource(module, navigate_hash(wait_done, ['targetLink']), 'compute#disk')
@ -569,7 +600,7 @@ def raise_if_errors(response, err_path, module):
module.fail_json(msg=errors) module.fail_json(msg=errors)
class DiskDiskEncryKey(object): class DiskSourceImageEncryptionKey(object):
def __init__(self, request, module): def __init__(self, request, module):
self.module = module self.module = module
if request: if request:
@ -590,7 +621,7 @@ class DiskDiskEncryKey(object):
}) })
class DiskSourImagEncrKey(object): class DiskDiskEncryptionKey(object):
def __init__(self, request, module): def __init__(self, request, module):
self.module = module self.module = module
if request: if request:
@ -611,7 +642,7 @@ class DiskSourImagEncrKey(object):
}) })
class DiskSourSnapEncrKey(object): class DiskSourceSnapshotEncryptionKey(object):
def __init__(self, request, module): def __init__(self, request, module):
self.module = module self.module = module
if request: if request:

View file

@ -18,13 +18,11 @@
name: "{{ resource_name }}" name: "{{ resource_name }}"
size_gb: 50 size_gb: 50
disk_encryption_key: disk_encryption_key:
raw_key: 'SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=' raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: 'us-central1-a' zone: us-central1-a
project: "{{ gcp_project }}" project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}" auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}" service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
state: absent state: absent
#---------------------------------------------------------- #----------------------------------------------------------
- name: create a disk - name: create a disk
@ -32,13 +30,11 @@
name: "{{ resource_name }}" name: "{{ resource_name }}"
size_gb: 50 size_gb: 50
disk_encryption_key: disk_encryption_key:
raw_key: 'SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=' raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: 'us-central1-a' zone: us-central1-a
project: "{{ gcp_project }}" project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}" auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}" service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
state: present state: present
register: result register: result
- name: assert changed is true - name: assert changed is true
@ -47,26 +43,31 @@
- result.changed == true - result.changed == true
- "result.kind == 'compute#disk'" - "result.kind == 'compute#disk'"
- name: verify that disk was created - name: verify that disk was created
shell: | gcp_compute_disk_facts:
gcloud compute disks describe --project="{{ gcp_project}}" --zone="us-central1-a" "{{ resource_name }}" filters:
- name = {{ resource_name }}
zone: us-central1-a
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
register: results register: results
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results.rc == 0 - results['items'] | length == 1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: create a disk that already exists - name: create a disk that already exists
gcp_compute_disk: gcp_compute_disk:
name: "{{ resource_name }}" name: "{{ resource_name }}"
size_gb: 50 size_gb: 50
disk_encryption_key: disk_encryption_key:
raw_key: 'SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=' raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: 'us-central1-a' zone: us-central1-a
project: "{{ gcp_project }}" project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}" auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}" service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
state: present state: present
register: result register: result
- name: assert changed is false - name: assert changed is false
@ -80,13 +81,11 @@
name: "{{ resource_name }}" name: "{{ resource_name }}"
size_gb: 50 size_gb: 50
disk_encryption_key: disk_encryption_key:
raw_key: 'SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=' raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: 'us-central1-a' zone: us-central1-a
project: "{{ gcp_project }}" project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}" auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}" service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
state: absent state: absent
register: result register: result
- name: assert changed is true - name: assert changed is true
@ -95,28 +94,31 @@
- result.changed == true - result.changed == true
- result.has_key('kind') == False - result.has_key('kind') == False
- name: verify that disk was deleted - name: verify that disk was deleted
shell: | gcp_compute_disk_facts:
gcloud compute disks describe --project="{{ gcp_project}}" --zone="us-central1-a" "{{ resource_name }}" filters:
- name = {{ resource_name }}
zone: us-central1-a
project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
register: results register: results
failed_when: results.rc == 0
- name: verify that command succeeded - name: verify that command succeeded
assert: assert:
that: that:
- results.rc == 1 - results['items'] | length == 0
- "\"'projects/{{ gcp_project }}/zones/us-central1-a/disks/{{ resource_name }}' was not found\" in results.stderr"
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
- name: delete a disk that does not exist - name: delete a disk that does not exist
gcp_compute_disk: gcp_compute_disk:
name: "{{ resource_name }}" name: "{{ resource_name }}"
size_gb: 50 size_gb: 50
disk_encryption_key: disk_encryption_key:
raw_key: 'SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=' raw_key: SGVsbG8gZnJvbSBHb29nbGUgQ2xvdWQgUGxhdGZvcm0=
zone: 'us-central1-a' zone: us-central1-a
project: "{{ gcp_project }}" project: "{{ gcp_project }}"
auth_kind: "{{ gcp_cred_kind }}" auth_kind: "{{ gcp_cred_kind }}"
service_account_file: "{{ gcp_cred_file }}" service_account_file: "{{ gcp_cred_file }}"
scopes:
- https://www.googleapis.com/auth/compute
state: absent state: absent
register: result register: result
- name: assert changed is false - name: assert changed is false