Cloudscale Regions and Zones Support (#67165)

This commit is contained in:
Denis Krienbühl 2020-02-12 14:06:41 +01:00 committed by GitHub
parent 7c8c53de20
commit a4ec18d8a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 169 additions and 22 deletions

View file

@ -26,7 +26,9 @@ notes:
- This module requires the ipaddress python library. This library is included in Python since version 3.3. It is available as a
module on PyPI for earlier versions.
version_added: "2.5"
author: "Gaudenz Steinlin (@gaudenz)"
author:
- Gaudenz Steinlin (@gaudenz)
- Denis Krienbühl (@href)
options:
state:
description:
@ -50,6 +52,20 @@ options:
- UUID of the server assigned to this floating IP.
- Required unless I(state) is absent.
type: str
type:
description:
- The type of the floating IP.
choices: [ regional, global ]
type: str
default: regional
version_added: '2.10'
region:
description:
- Region in which the floating IP resides (e.g. C(lgp) or C(rma)).
If omitted, the region of the project default zone is used.
This parameter must be omitted if I(type) is set to C(global).
type: str
version_added: '2.10'
prefix_length:
description:
- Only valid if I(ip_version) is 6.
@ -89,6 +105,7 @@ EXAMPLES = '''
prefix_length: 56
server: 47cec963-fcd2-482f-bdb6-24461b2d47b1
api_token: xxxxxx
region: lpg1
register: floating_ip
# Assign an existing floating network to a different server
@ -137,6 +154,12 @@ ip:
returned: success
type: str
sample: 185.98.122.176
region:
description: The region of the floating IP.
returned: success when state == present
type: dict
sample: {'slug': 'lpg'}
version_added: '2.10'
state:
description: The current status of the floating IP.
returned: success
@ -210,10 +233,9 @@ class AnsibleCloudscaleFloatingIP(AnsibleCloudscaleBase):
data = {'ip_version': params['ip_version'],
'server': params['server']}
if params['prefix_length']:
data['prefix_length'] = params['prefix_length']
if params['reverse_ptr']:
data['reverse_ptr'] = params['reverse_ptr']
for p in ('prefix_length', 'reverse_ptr', 'type', 'region'):
if params[p]:
data[p] = params[p]
self.info = self._resp2info(self._post('floating-ips', data))
@ -235,6 +257,8 @@ def main():
ip=dict(aliases=('network', ), type='str'),
ip_version=dict(choices=(4, 6), type='int'),
server=dict(type='str'),
type=dict(type='str', choices=('regional', 'global'), default='regional'),
region=dict(type='str'),
prefix_length=dict(choices=(56,), type='int'),
reverse_ptr=dict(type='str'),
))

View file

@ -30,6 +30,7 @@ version_added: '2.3'
author:
- Gaudenz Steinlin (@gaudenz)
- René Moser (@resmo)
- Denis Krienbühl (@href)
options:
state:
description:
@ -55,6 +56,11 @@ options:
description:
- Image used to create the server.
type: str
zone:
description:
- Zone in which the server resides (e.g. C(lgp1) or C(rma1)).
type: str
version_added: '2.10'
volume_size_gb:
description:
- Size of the root volume in GB.
@ -131,6 +137,7 @@ EXAMPLES = '''
flavor: flex-4
ssh_keys: ssh-rsa XXXXXXXXXX...XXXX ansible@cloudscale
server_groups: shiny-group
zone: lpg1
use_private_network: True
bulk_volume_size_gb: 100
api_token: xxxxxx
@ -143,6 +150,7 @@ EXAMPLES = '''
flavor: flex-8
ssh_keys: ssh-rsa XXXXXXXXXXX ansible@cloudscale
server_groups: shiny-group
zone: lpg1
api_token: xxxxxx
@ -218,6 +226,12 @@ image:
returned: success when not state == absent
type: dict
sample: { "default_username": "ubuntu", "name": "Ubuntu 18.04 LTS", "operating_system": "Ubuntu", "slug": "ubuntu-18.04" }
zone:
description: The zone used for booting this server
returned: success when not state == absent
type: dict
sample: { 'slug': 'lpg1' }
version_added: '2.10'
volumes:
description: List of volumes attached to the server
returned: success when not state == absent
@ -511,6 +525,7 @@ def main():
uuid=dict(),
flavor=dict(),
image=dict(),
zone=dict(),
volume_size_gb=dict(type='int', default=10),
bulk_volume_size_gb=dict(type='int'),
ssh_keys=dict(type='list'),

View file

@ -21,6 +21,7 @@ description:
- Create, update and remove server groups.
author:
- René Moser (@resmo)
- Denis Krienbühl (@href)
version_added: '2.8'
options:
name:
@ -38,6 +39,11 @@ options:
- Type of the server group.
default: anti-affinity
type: str
zone:
description:
- Zone slug of the server group (e.g. C(lgp1) or C(rma1)).
type: str
version_added: '2.10'
state:
description:
- State of the server group.
@ -60,6 +66,13 @@ EXAMPLES = '''
type: anti-affinity
api_token: xxxxxx
- name: Ensure server group in a specific zone
cloudscale_server_group:
name: my-rma-group
type: anti-affinity
zone: lpg1
api_token: xxxxxx
- name: Ensure a server group is absent
cloudscale_server_group:
name: my-name
@ -89,6 +102,12 @@ type:
returned: if available
type: str
sample: anti-affinity
zone:
description: The zone of the server group
returned: success
type: dict
sample: { 'slug': 'rma1' }
version_added: '2.10'
servers:
description: A list of servers that are part of the server group.
returned: if available
@ -130,6 +149,7 @@ class AnsibleCloudscaleServerGroup(AnsibleCloudscaleBase):
data = {
'name': self._module.params.get('name'),
'type': self._module.params.get('type'),
'zone': self._module.params.get('zone'),
'tags': self._module.params.get('tags'),
}
if not self._module.check_mode:
@ -193,6 +213,7 @@ def main():
name=dict(),
uuid=dict(),
type=dict(default='anti-affinity'),
zone=dict(),
tags=dict(type='dict'),
state=dict(default='present', choices=['absent', 'present']),
))

View file

@ -29,6 +29,7 @@ version_added: '2.8'
author:
- Gaudenz Steinlin (@gaudenz)
- René Moser (@resmo)
- Denis Krienbühl (@href)
options:
state:
description:
@ -56,6 +57,12 @@ options:
Defaults to C(ssd) on volume creation.
choices: [ ssd, bulk ]
type: str
zone:
description:
- Zone in which the volume resides (e.g. C(lgp1) or C(rma1)). Cannot be
changed after creating the volume. Defaults to the project default zone.
type: str
version_added: '2.10'
server_uuids:
description:
- UUIDs of the servers this volume is attached to. Set this to C([]) to
@ -76,6 +83,7 @@ EXAMPLES = '''
- name: Create an SSD volume
cloudscale_volume:
name: my_ssd_volume
zone: 'lpg1'
size_gb: 50
api_token: xxxxxx
register: my_ssd_volume
@ -92,6 +100,7 @@ EXAMPLES = '''
- name: Create and attach volume to server
cloudscale_volume:
name: my_ssd_volume
zone: 'lpg1'
size_gb: 50
server_uuids:
- ea3b39a3-77a8-4d0b-881d-0bb00a1e7f48
@ -138,6 +147,12 @@ type:
returned: state == present
type: str
sample: bulk
zone:
description: The zone of the volume.
returned: state == present
type: dict
sample: {'slug': 'lpg1'}
version_added: '2.10'
server_uuids:
description: The UUIDs of the servers this volume is attached to.
returned: state == present
@ -189,6 +204,7 @@ class AnsibleCloudscaleVolume(AnsibleCloudscaleBase):
data = {
'name': self._module.params.get('name'),
'type': self._module.params.get('type'),
'zone': self._module.params.get('zone'),
'size_gb': self._module.params.get('size_gb') or 'ssd',
'server_uuids': self._module.params.get('server_uuids') or [],
'tags': self._module.params.get('tags'),
@ -262,6 +278,7 @@ def main():
state=dict(default='present', choices=('present', 'absent')),
name=dict(),
uuid=dict(),
zone=dict(),
size_gb=dict(type='int'),
type=dict(choices=('ssd', 'bulk')),
server_uuids=dict(type='list', aliases=['server_uuid']),

View file

@ -11,3 +11,9 @@ cloudscale_test_flavor: 'flex-2'
# SSH key to use for test servers
cloudscale_test_ssh_key: |
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSPmiqkvDH1/+MDAVDZT8381aYqp73Odz8cnD5hegNhqtXajqtiH0umVg7HybX3wt1HjcrwKJovZURcIbbcDvzdH2bnYbF93T4OLXA0bIfuIp6M86x1iutFtXdpN3TTicINrmSXEE2Ydm51iMu77B08ZERjVaToya2F7vC+egfoPvibf7OLxE336a5tPCywavvNihQjL8sjgpDT5AAScjb3YqK/6VLeQ18Ggt8/ufINsYkb+9/Ji/3OcGFeflnDXq80vPUyF3u4iIylob6RSZenC38cXmQB05tRNxS1B6BXCjMRdy0v4pa7oKM2GA4ADKpNrr0RI9ed+peRFwmsclH test@ansible
# The zone to use to test servers
cloudscale_test_zone: 'lpg1'
# The region to use to request floating IPs
cloudscale_test_region: 'lpg'

View file

@ -1,29 +1,64 @@
- name: Request floating IP
- name: Request regional floating IP
cloudscale_floating_ip:
server: '{{ test01.uuid }}'
ip_version: '{{ item.ip_version }}'
reverse_ptr: '{{ item.reverse_ptr | default(omit) }}'
prefix_length: '{{ item.prefix_length | default(omit) }}'
region: '{{ cloudscale_test_region }}'
register: floating_ip
- name: Verify request floating IP
assert:
that:
- floating_ip is successful
- floating_ip is changed
- floating_ip.region.slug == '{{ cloudscale_test_region }}'
- (item.ip_version == 4 and floating_ip.ip | ipv4) or (item.ip_version == 6 and floating_ip.ip | ipv6)
- floating_ip.server == test01.uuid
- name: Check floating IP indempotence
- name: Check floating IP idempotence
cloudscale_floating_ip:
server: '{{ test01.uuid }}'
ip: '{{ floating_ip.ip }}'
register: floating_ip_indempotence
- name: Verify floating IP indempotence
region: '{{ cloudscale_test_region }}'
register: floating_ip_idempotence
- name: Verify floating IP idempotence
assert:
that:
- floating_ip_indempotence is successful
- floating_ip_indempotence is not changed
- floating_ip_indempotence.server == test01.uuid
- floating_ip_idempotence is successful
- floating_ip_idempotence is not changed
- floating_ip_idempotence.server == test01.uuid
- floating_ip.region.slug == '{{ cloudscale_test_region }}'
- name: Request global floating IP
cloudscale_floating_ip:
server: '{{ test01.uuid }}'
ip_version: '{{ item.ip_version }}'
reverse_ptr: '{{ item.reverse_ptr | default(omit) }}'
prefix_length: '{{ item.prefix_length | default(omit) }}'
type: 'global'
register: global_floating_ip
- name: Verify global floating IP
assert:
that:
- global_floating_ip is successful
- global_floating_ip is changed
- global_floating_ip.region == None
- global_floating_ip.type == 'global'
- (item.ip_version == 4 and global_floating_ip.ip | ipv4) or (item.ip_version == 6 and global_floating_ip.ip | ipv6)
- global_floating_ip.server == test01.uuid
- name: Release global floating IP
cloudscale_floating_ip:
ip: '{{ global_floating_ip.ip }}'
state: 'absent'
register: global_floating_ip
- name: Verify release of global floating IP
assert:
that:
- global_floating_ip is successful
- global_floating_ip is changed
- global_floating_ip.state == 'absent'
- name: Check network parameter alias
cloudscale_floating_ip:
@ -70,12 +105,12 @@
- release_ip is changed
- release_ip.state == 'absent'
- name: Release floating IP indempotence
- name: Release floating IP idempotence
cloudscale_floating_ip:
ip: '{{ floating_ip.ip }}'
state: 'absent'
register: release_ip
- name: Verify release floating IPs indempotence
- name: Verify release floating IPs idempotence
assert:
that:
- release_ip is successful

View file

@ -6,6 +6,7 @@
flavor: '{{ cloudscale_test_flavor }}'
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
zone: '{{ cloudscale_test_zone }}'
register: test01
- name: Create a second server
@ -14,6 +15,7 @@
flavor: '{{ cloudscale_test_flavor }}'
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
zone: '{{ cloudscale_test_zone }}'
register: test02
- include_tasks: floating_ip.yml

View file

@ -4,6 +4,7 @@
ip_version: 6
server: '{{ test01.uuid }}'
reverse_ptr: '{{ cloudscale_resource_prefix }}-unassigned.example.com'
region: '{{ cloudscale_test_region }}'
register: floating_ip
# The only way to have an unassigned floating IP is to delete the server

View file

@ -3,6 +3,7 @@
cloudscale_server_group:
name: '{{ cloudscale_resource_prefix }}-group-{{ item }}'
type: anti-affinity
zone: '{{ cloudscale_test_zone }}'
with_sequence: count=2
- name: Test create a running server in check mode
@ -12,6 +13,7 @@
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
server_groups: '{{ cloudscale_resource_prefix }}-group-1'
zone: '{{ cloudscale_test_zone }}'
tags:
project: ansible-test
stage: production
@ -31,6 +33,7 @@
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
server_groups: '{{ cloudscale_resource_prefix }}-group-1'
zone: '{{ cloudscale_test_zone }}'
tags:
project: ansible-test
stage: production
@ -42,6 +45,7 @@
- server is changed
- server.state == 'running'
- server.server_groups.0.name == '{{ cloudscale_resource_prefix }}-group-1'
- server.zone.slug == '{{ cloudscale_test_zone }}'
- server.tags.project == 'ansible-test'
- server.tags.stage == 'production'
- server.tags.sla == '24-7'
@ -53,6 +57,7 @@
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
server_groups: '{{ cloudscale_resource_prefix }}-group-1'
zone: '{{ cloudscale_test_zone }}'
tags:
project: ansible-test
stage: production
@ -64,6 +69,7 @@
- server is not changed
- server.state == 'running'
- server.server_groups.0.name == '{{ cloudscale_resource_prefix }}-group-1'
- server.zone.slug == '{{ cloudscale_test_zone }}'
- server.tags.project == 'ansible-test'
- server.tags.stage == 'production'
- server.tags.sla == '24-7'
@ -348,6 +354,7 @@
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
server_groups: '{{ cloudscale_resource_prefix }}-group-1'
zone: '{{ cloudscale_test_zone }}'
use_public_network: no
use_private_network: yes
state: stopped
@ -366,6 +373,7 @@
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
server_groups: '{{ cloudscale_resource_prefix }}-group-1'
zone: '{{ cloudscale_test_zone }}'
use_public_network: no
use_private_network: yes
state: stopped
@ -375,6 +383,7 @@
that:
- server_stopped is changed
- server_stopped.state == 'stopped'
- server_stopped.zone.slug == '{{ cloudscale_test_zone }}'
- server_stopped.anti_affinity_with.0.uuid == running_server_uuid
- server_stopped.interfaces.0.type == 'private'
- server_stopped.server_groups.0.name == '{{ cloudscale_resource_prefix }}-group-1'
@ -386,6 +395,7 @@
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
server_groups: '{{ cloudscale_resource_prefix }}-group-1'
zone: '{{ cloudscale_test_zone }}'
use_public_network: no
use_private_network: yes
state: stopped
@ -395,6 +405,7 @@
that:
- server_stopped is not changed
- server_stopped.state == 'stopped'
- server_stopped.zone.slug == '{{ cloudscale_test_zone }}'
- server_stopped.anti_affinity_with.0.uuid == running_server_uuid
- server_stopped.interfaces.0.type == 'private'
- server_stopped.server_groups.0.name == '{{ cloudscale_resource_prefix }}-group-1'
@ -415,6 +426,7 @@
that:
- server_stopped is not changed
- server_stopped.state == 'stopped'
- server_stopped.zone.slug == '{{ cloudscale_test_zone }}'
- server_stopped.anti_affinity_with.0.uuid == running_server_uuid
- server_stopped.interfaces.0.type == 'private'
- server_stopped.server_groups.0.name == '{{ cloudscale_resource_prefix }}-group-1'

View file

@ -18,6 +18,7 @@
- name: Create server group
cloudscale_server_group:
name: '{{ cloudscale_resource_prefix }}-grp'
zone: '{{ cloudscale_test_zone }}'
tags:
project: ansible-test
stage: production
@ -29,6 +30,7 @@
- grp is changed
- grp.type == 'anti-affinity'
- grp.name == '{{ cloudscale_resource_prefix }}-grp'
- grp.zone.slug == '{{ cloudscale_test_zone }}'
- grp.uuid
- grp.tags.project == 'ansible-test'
- grp.tags.stage == 'production'
@ -41,6 +43,7 @@
- name: Create server group idempotence
cloudscale_server_group:
name: '{{ cloudscale_resource_prefix }}-grp'
zone: '{{ cloudscale_test_zone }}'
tags:
project: ansible-test
stage: production
@ -51,6 +54,7 @@
that:
- grp is not changed
- grp.name == '{{ cloudscale_resource_prefix }}-grp'
- grp.zone.slug == '{{ cloudscale_test_zone }}'
- grp.uuid == server_group_uuid
- grp.tags.project == 'ansible-test'
- grp.tags.stage == 'production'
@ -72,6 +76,7 @@
- grp is changed
- grp.name == '{{ cloudscale_resource_prefix }}-grp'
- grp.uuid == server_group_uuid
- grp.zone.slug == '{{ cloudscale_test_zone }}'
- grp.tags.project == 'ansible-test'
- grp.tags.stage == 'production'
- grp.tags.sla == '24-7'
@ -91,6 +96,7 @@
- grp is changed
- grp.name == '{{ cloudscale_resource_prefix }}-grp2'
- grp.uuid == server_group_uuid
- grp.zone.slug == '{{ cloudscale_test_zone }}'
- grp.tags.project == 'ansible-test'
- grp.tags.stage == 'staging'
- grp.tags.sla == '8-5'
@ -110,6 +116,7 @@
- grp is not changed
- grp.name == '{{ cloudscale_resource_prefix }}-grp2'
- grp.uuid == server_group_uuid
- grp.zone.slug == '{{ cloudscale_test_zone }}'
- grp.tags.project == 'ansible-test'
- grp.tags.stage == 'staging'
- grp.tags.sla == '8-5'

View file

@ -3,6 +3,7 @@
cloudscale_server:
name: '{{ cloudscale_resource_prefix }}-server'
flavor: '{{ cloudscale_test_flavor }}'
zone: '{{ cloudscale_test_zone }}'
image: '{{ cloudscale_test_image }}'
ssh_keys: '{{ cloudscale_test_ssh_key }}'
register: server

View file

@ -2,6 +2,7 @@
- name: Create volume in check mode
cloudscale_volume:
name: '{{ cloudscale_resource_prefix }}-vol'
zone: '{{ cloudscale_test_zone }}'
size_gb: 50
tags:
project: ansible-test
@ -19,6 +20,7 @@
- name: Create volume
cloudscale_volume:
name: '{{ cloudscale_resource_prefix }}-vol'
zone: '{{ cloudscale_test_zone }}'
size_gb: 50
tags:
project: ansible-test
@ -32,26 +34,29 @@
- vol is changed
- vol.size_gb == 50
- vol.name == '{{ cloudscale_resource_prefix }}-vol'
- vol.zone.slug == '{{ cloudscale_test_zone }}'
- vol.tags.project == 'ansible-test'
- vol.tags.stage == 'production'
- vol.tags.sla == '24-7'
- name: Create volume indempotence
- name: Create volume idempotence
cloudscale_volume:
name: '{{ cloudscale_resource_prefix }}-vol'
zone: '{{ cloudscale_test_zone }}'
size_gb: 50
tags:
project: ansible-test
stage: production
sla: 24-7
register: vol
- name: 'VERIFY: Create volume indempotence'
- name: 'VERIFY: Create volume idempotence'
assert:
that:
- vol is successful
- vol is not changed
- vol.size_gb == 50
- vol.name == '{{ cloudscale_resource_prefix }}-vol'
- vol.zone.slug == '{{ cloudscale_test_zone }}'
- vol.tags.project == 'ansible-test'
- vol.tags.stage == 'production'
- vol.tags.sla == '24-7'
@ -83,13 +88,13 @@
- vol is changed
- server.uuid in vol.server_uuids
- name: Attach existing volume by name to server indempotence
- name: Attach existing volume by name to server idempotence
cloudscale_volume:
name: '{{ cloudscale_resource_prefix }}-vol'
server_uuids:
- '{{ server.uuid }}'
register: vol
- name: 'VERIFY: Attach existing volume by name to server indempotence'
- name: 'VERIFY: Attach existing volume by name to server idempotence'
assert:
that:
- vol is successful
@ -121,12 +126,12 @@
- vol is changed
- vol.size_gb == 100
- name: Resize attached volume by UUID indempotence
- name: Resize attached volume by UUID idempotence
cloudscale_volume:
uuid: '{{ vol.uuid }}'
size_gb: 100
register: vol
- name: 'VERIFY: Resize attached volume by UUID indempotence'
- name: 'VERIFY: Resize attached volume by UUID idempotence'
assert:
that:
- vol is successful
@ -162,12 +167,12 @@
- deleted.uuid == vol.uuid
- deleted.name == '{{ cloudscale_resource_prefix }}-vol'
- name: Delete attached volume by UUID indempotence
- name: Delete attached volume by UUID idempotence
cloudscale_volume:
uuid: '{{ vol.uuid }}'
state: 'absent'
register: deleted
- name: 'VERIFY: Delete attached volume by UUID indempotence'
- name: 'VERIFY: Delete attached volume by UUID idempotence'
assert:
that:
- deleted is successful
@ -180,6 +185,7 @@
cloudscale_volume:
name: '{{ cloudscale_resource_prefix }}-bulk'
type: bulk
zone: '{{ cloudscale_test_zone }}'
size_gb: 100
server_uuids:
- '{{ server.uuid }}'