Bump openstacksdk to >1
This patch also vendors the openstack.cloud.subnet
module due to a problem with `disable_gateway_ip`
not being set for newly created subnets[1].
[1]: https://review.opendev.org/c/openstack/ansible-collections-openstack/+/940927
Change-Id: Ia021a1d7b82823c2e7498fdd66da3e2d5c6a8a79
(cherry picked from commit 8ccabb61cb8aa6a86c653cc47e43a648e8e07268)
diff --git a/.ansible-lint b/.ansible-lint
index 2776884..d6ddfd2 100644
--- a/.ansible-lint
+++ b/.ansible-lint
@@ -7,6 +7,7 @@
- molecule
- playbooks
- plugins/filter
+ - plugins/modules/subnet.py
- roles/defaults/vars/main.yml
- roles/kube_prometheus_stack/files/jsonnet
- roles/storpool_csi/files
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 2c0ca4e..0fe99aa 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,4 +1,4 @@
-exclude: "^(roles/kube_prometheus_stack/files/jsonnet|charts)"
+exclude: "^(roles/kube_prometheus_stack/files/jsonnet|charts|plugins/modules/subnet.py)"
repos:
- repo: local
diff --git a/galaxy.yml b/galaxy.yml
index ccbcf02..ab7e9b0 100644
--- a/galaxy.yml
+++ b/galaxy.yml
@@ -15,7 +15,7 @@
community.general: 7.3.0
community.mysql: 3.6.0
kubernetes.core: 2.4.0
- openstack.cloud: 1.7.0
+ openstack.cloud: ">=2.0.0"
vexxhost.ceph: 3.0.1
vexxhost.kubernetes: ">=2.0.1"
tags:
diff --git a/molecule/default/requirements.txt b/molecule/default/requirements.txt
index 862d238..4544af7 100644
--- a/molecule/default/requirements.txt
+++ b/molecule/default/requirements.txt
@@ -1,3 +1,3 @@
molecule==3.5.2 # https://github.com/ansible-community/molecule/issues/3435
-openstacksdk==0.61.0
+openstacksdk
netaddr
diff --git a/molecule/keycloak/verify.yml b/molecule/keycloak/verify.yml
index e481319..7a4a179 100644
--- a/molecule/keycloak/verify.yml
+++ b/molecule/keycloak/verify.yml
@@ -48,15 +48,15 @@
# we try a few more times.
retries: 30
delay: 1
- until: identity_user_info_result.openstack_users | length > 0
+ until: identity_user_info_result.users | length > 0
- name: Assert that the user exists
run_once: true
ansible.builtin.assert:
that:
- - identity_user_info_result.openstack_users | length > 0
- - identity_user_info_result.openstack_users[0].id == keycloak_user_info.id | regex_replace('-', '')
- - identity_user_info_result.openstack_users[0].name == keycloak_user_info.username
+ - identity_user_info_result.users | length > 0
+ - identity_user_info_result.users[0].id == keycloak_user_info.id | regex_replace('-', '')
+ - identity_user_info_result.users[0].name == keycloak_user_info.username
# TODO: Simulate Keystone authentication
# TODO: Simulate Horizon login
diff --git a/plugins/modules/subnet.py b/plugins/modules/subnet.py
new file mode 100644
index 0000000..7c50aee
--- /dev/null
+++ b/plugins/modules/subnet.py
@@ -0,0 +1,486 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# (c) 2013, Benno Joy <benno@ansible.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+DOCUMENTATION = '''
+---
+module: subnet
+short_description: Add/Remove subnet to an OpenStack network
+author: OpenStack Ansible SIG
+description:
+ - Add or Remove a subnet to an OpenStack network
+options:
+ state:
+ description:
+ - Indicate desired state of the resource
+ choices: ['present', 'absent']
+ default: present
+ type: str
+ allocation_pool_start:
+ description:
+ - From the subnet pool the starting address from which the IP
+ should be allocated.
+ type: str
+ allocation_pool_end:
+ description:
+ - From the subnet pool the last IP that should be assigned to the
+ virtual machines.
+ type: str
+ allocation_pools:
+ description:
+ - List of allocation pools to assign to the subnet. Each element
+ consists of a 'start' and 'end' value.
+ type: list
+ elements: dict
+ cidr:
+ description:
+ - The CIDR representation of the subnet that should be assigned to
+ the subnet. Required when I(state) is 'present' and a subnetpool
+ is not specified.
+ type: str
+ description:
+ description:
+ - Description of the subnet
+ type: str
+ disable_gateway_ip:
+ description:
+ - The gateway IP would not be assigned for this subnet
+ type: bool
+ aliases: ['no_gateway_ip']
+ default: 'false'
+ dns_nameservers:
+ description:
+ - List of DNS nameservers for this subnet.
+ type: list
+ elements: str
+ extra_attrs:
+ description:
+ - Dictionary with extra key/value pairs passed to the API
+ required: false
+ aliases: ['extra_specs']
+ default: {}
+ type: dict
+ host_routes:
+ description:
+ - A list of host route dictionaries for the subnet.
+ type: list
+ elements: dict
+ suboptions:
+ destination:
+ description: The destination network (CIDR).
+ type: str
+ required: true
+ nexthop:
+ description: The next hop (aka gateway) for the I(destination).
+ type: str
+ required: true
+ gateway_ip:
+ description:
+ - The ip that would be assigned to the gateway for this subnet
+ type: str
+ ip_version:
+ description:
+ - The IP version of the subnet 4 or 6
+ default: 4
+ type: int
+ choices: [4, 6]
+ is_dhcp_enabled:
+ description:
+ - Whether DHCP should be enabled for this subnet.
+ type: bool
+ aliases: ['enable_dhcp']
+ default: 'true'
+ ipv6_ra_mode:
+ description:
+ - IPv6 router advertisement mode
+ choices: ['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac']
+ type: str
+ ipv6_address_mode:
+ description:
+ - IPv6 address mode
+ choices: ['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac']
+ type: str
+ name:
+ description:
+ - The name of the subnet that should be created. Although Neutron
+ allows for non-unique subnet names, this module enforces subnet
+ name uniqueness.
+ required: true
+ type: str
+ network:
+ description:
+ - Name or id of the network to which the subnet should be attached
+ - Required when I(state) is 'present'
+ aliases: ['network_name']
+ type: str
+ project:
+ description:
+ - Project name or ID containing the subnet (name admin-only)
+ type: str
+ prefix_length:
+ description:
+ - The prefix length to use for subnet allocation from a subnet pool
+ type: str
+ use_default_subnet_pool:
+ description:
+ - Use the default subnetpool for I(ip_version) to obtain a CIDR.
+ type: bool
+ aliases: ['use_default_subnetpool']
+ subnet_pool:
+ description:
+ - The subnet pool name or ID from which to obtain a CIDR
+ type: str
+ required: false
+extends_documentation_fragment:
+- openstack.cloud.openstack
+'''
+
+EXAMPLES = '''
+# Create a new (or update an existing) subnet on the specified network
+- openstack.cloud.subnet:
+ state: present
+ network_name: network1
+ name: net1subnet
+ cidr: 192.168.0.0/24
+ dns_nameservers:
+ - 8.8.8.7
+ - 8.8.8.8
+ host_routes:
+ - destination: 0.0.0.0/0
+ nexthop: 12.34.56.78
+ - destination: 192.168.0.0/24
+ nexthop: 192.168.0.1
+
+# Delete a subnet
+- openstack.cloud.subnet:
+ state: absent
+ name: net1subnet
+
+# Create an ipv6 stateless subnet
+- openstack.cloud.subnet:
+ state: present
+ name: intv6
+ network_name: internal
+ ip_version: 6
+ cidr: 2db8:1::/64
+ dns_nameservers:
+ - 2001:4860:4860::8888
+ - 2001:4860:4860::8844
+ ipv6_ra_mode: dhcpv6-stateless
+ ipv6_address_mode: dhcpv6-stateless
+'''
+
+RETURN = '''
+id:
+ description: Id of subnet
+ returned: On success when subnet exists.
+ type: str
+subnet:
+ description: Dictionary describing the subnet.
+ returned: On success when subnet exists.
+ type: dict
+ contains:
+ allocation_pools:
+ description: Allocation pools associated with this subnet.
+ returned: success
+ type: list
+ elements: dict
+ cidr:
+ description: Subnet's CIDR.
+ returned: success
+ type: str
+ created_at:
+ description: Created at timestamp
+ type: str
+ description:
+ description: Description
+ type: str
+ dns_nameservers:
+ description: DNS name servers for this subnet.
+ returned: success
+ type: list
+ elements: str
+ dns_publish_fixed_ip:
+ description: Whether to publish DNS records for fixed IPs.
+ returned: success
+ type: bool
+ gateway_ip:
+ description: Subnet's gateway ip.
+ returned: success
+ type: str
+ host_routes:
+ description: A list of host routes.
+ returned: success
+ type: str
+ id:
+ description: Unique UUID.
+ returned: success
+ type: str
+ ip_version:
+ description: IP version for this subnet.
+ returned: success
+ type: int
+ ipv6_address_mode:
+ description: |
+ The IPv6 address modes which are 'dhcpv6-stateful',
+ 'dhcpv6-stateless' or 'slaac'.
+ returned: success
+ type: str
+ ipv6_ra_mode:
+ description: |
+ The IPv6 router advertisements modes which can be 'slaac',
+ 'dhcpv6-stateful', 'dhcpv6-stateless'.
+ returned: success
+ type: str
+ is_dhcp_enabled:
+ description: DHCP enable flag for this subnet.
+ returned: success
+ type: bool
+ name:
+ description: Name given to the subnet.
+ returned: success
+ type: str
+ network_id:
+ description: Network ID this subnet belongs in.
+ returned: success
+ type: str
+ prefix_length:
+ description: |
+ The prefix length to use for subnet allocation from a subnet
+ pool.
+ returned: success
+ type: str
+ project_id:
+ description: Project id associated with this subnet.
+ returned: success
+ type: str
+ revision_number:
+ description: Revision number of the resource
+ returned: success
+ type: int
+ segment_id:
+ description: The ID of the segment this subnet is associated with.
+ returned: success
+ type: str
+ service_types:
+ description: Service types for this subnet
+ returned: success
+ type: list
+ subnet_pool_id:
+ description: The subnet pool ID from which to obtain a CIDR.
+ returned: success
+ type: str
+ tags:
+ description: Tags
+ type: str
+ updated_at:
+ description: Timestamp when the subnet was last updated.
+ returned: success
+ type: str
+ use_default_subnet_pool:
+ description: |
+ Whether to use the default subnet pool to obtain a CIDR.
+ returned: success
+ type: bool
+'''
+
+from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
+
+
+class SubnetModule(OpenStackModule):
+ ipv6_mode_choices = ['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac']
+ argument_spec = dict(
+ name=dict(required=True),
+ network=dict(aliases=['network_name']),
+ cidr=dict(),
+ description=dict(),
+ ip_version=dict(type='int', default=4, choices=[4, 6]),
+ is_dhcp_enabled=dict(type='bool', default=True,
+ aliases=['enable_dhcp']),
+ gateway_ip=dict(),
+ disable_gateway_ip=dict(
+ type='bool', default=False, aliases=['no_gateway_ip']),
+ dns_nameservers=dict(type='list', elements='str'),
+ allocation_pool_start=dict(),
+ allocation_pool_end=dict(),
+ allocation_pools=dict(type='list', elements='dict'),
+ host_routes=dict(type='list', elements='dict'),
+ ipv6_ra_mode=dict(choices=ipv6_mode_choices),
+ ipv6_address_mode=dict(choices=ipv6_mode_choices),
+ subnet_pool=dict(),
+ prefix_length=dict(),
+ use_default_subnet_pool=dict(
+ type='bool', aliases=['use_default_subnetpool']),
+ extra_attrs=dict(type='dict', default=dict(), aliases=['extra_specs']),
+ state=dict(default='present',
+ choices=['absent', 'present']),
+ project=dict(),
+ )
+
+ module_kwargs = dict(
+ supports_check_mode=True,
+ required_together=[['allocation_pool_end', 'allocation_pool_start']],
+ required_if=[
+ ('state', 'present', ('network',)),
+ ('state', 'present',
+ ('cidr', 'use_default_subnet_pool', 'subnet_pool'), True),
+ ],
+ mutually_exclusive=[
+ ('use_default_subnet_pool', 'subnet_pool'),
+ ('allocation_pool_start', 'allocation_pools'),
+ ('allocation_pool_end', 'allocation_pools')
+ ]
+ )
+
+ # resource attributes obtainable directly from params
+ attr_params = ('cidr', 'description',
+ 'dns_nameservers', 'gateway_ip', 'host_routes',
+ 'ip_version', 'ipv6_address_mode', 'ipv6_ra_mode',
+ 'is_dhcp_enabled', 'name', 'prefix_length',
+ 'use_default_subnet_pool',)
+
+ def _validate_update(self, subnet, update):
+ """ Check for differences in non-updatable values """
+ # Ref.: https://docs.openstack.org/api-ref/network/v2/index.html#update-subnet
+ for attr in ('cidr', 'ip_version', 'ipv6_ra_mode', 'ipv6_address_mode',
+ 'prefix_length', 'use_default_subnet_pool'):
+ if attr in update and update[attr] != subnet[attr]:
+ self.fail_json(
+ msg='Cannot update {0} in existing subnet'.format(attr))
+
+ def _system_state_change(self, subnet, network, project, subnet_pool):
+ state = self.params['state']
+ if state == 'absent':
+ return subnet is not None
+ # else state is present
+ if not subnet:
+ return True
+ params = self._build_params(network, project, subnet_pool)
+ updates = self._build_updates(subnet, params)
+ self._validate_update(subnet, updates)
+ return bool(updates)
+
+ def _build_pool(self):
+ pool_start = self.params['allocation_pool_start']
+ pool_end = self.params['allocation_pool_end']
+ if pool_start:
+ return [dict(start=pool_start, end=pool_end)]
+ return None
+
+ def _build_params(self, network, project, subnet_pool):
+ params = {attr: self.params[attr] for attr in self.attr_params}
+ params['network_id'] = network.id
+ if project:
+ params['project_id'] = project.id
+ if subnet_pool:
+ params['subnet_pool_id'] = subnet_pool.id
+ if self.params['allocation_pool_start']:
+ params['allocation_pools'] = self._build_pool()
+ else:
+ params['allocation_pools'] = self.params['allocation_pools']
+ params = self._add_extra_attrs(params)
+ params = {k: v for k, v in params.items() if v is not None}
+ if self.params['disable_gateway_ip']:
+ params['gateway_ip'] = None
+ return params
+
+ def _build_updates(self, subnet, params):
+ # Sort lists before doing comparisons comparisons
+ if 'dns_nameservers' in params:
+ params['dns_nameservers'].sort()
+ subnet['dns_nameservers'].sort()
+
+ if 'host_routes' in params:
+ params['host_routes'].sort(key=lambda r: sorted(r.items()))
+ subnet['host_routes'].sort(key=lambda r: sorted(r.items()))
+
+ if 'allocation_pools' in params:
+ params['allocation_pools'].sort(key=lambda r: sorted(r.items()))
+ subnet['allocation_pools'].sort(key=lambda r: sorted(r.items()))
+
+ updates = {k: params[k] for k in params if params[k] != subnet[k]}
+ if self.params['disable_gateway_ip'] and subnet.gateway_ip:
+ updates['gateway_ip'] = None
+ return updates
+
+ def _add_extra_attrs(self, params):
+ duplicates = set(self.params['extra_attrs']) & set(params)
+ if duplicates:
+ self.fail_json(msg='Duplicate key(s) {0} in extra_specs'
+ .format(list(duplicates)))
+ params.update(self.params['extra_attrs'])
+ return params
+
+ def run(self):
+ state = self.params['state']
+ network_name_or_id = self.params['network']
+ project_name_or_id = self.params['project']
+ subnet_pool_name_or_id = self.params['subnet_pool']
+ subnet_name = self.params['name']
+ gateway_ip = self.params['gateway_ip']
+ disable_gateway_ip = self.params['disable_gateway_ip']
+
+ # fail early if incompatible options have been specified
+ if disable_gateway_ip and gateway_ip:
+ self.fail_json(msg='no_gateway_ip is not allowed with gateway_ip')
+
+ subnet_pool_filters = {}
+ filters = {}
+
+ project = None
+ if project_name_or_id:
+ project = self.conn.identity.find_project(project_name_or_id,
+ ignore_missing=False)
+ subnet_pool_filters['project_id'] = project.id
+ filters['project_id'] = project.id
+
+ network = None
+ if network_name_or_id:
+ # At this point filters can only contain project_id
+ network = self.conn.network.find_network(network_name_or_id,
+ ignore_missing=False,
+ **filters)
+ filters['network_id'] = network.id
+
+ subnet_pool = None
+ if subnet_pool_name_or_id:
+ subnet_pool = self.conn.network.find_subnet_pool(
+ subnet_pool_name_or_id,
+ ignore_missing=False,
+ **subnet_pool_filters)
+ filters['subnet_pool_id'] = subnet_pool.id
+
+ subnet = self.conn.network.find_subnet(subnet_name, **filters)
+
+ if self.ansible.check_mode:
+ self.exit_json(changed=self._system_state_change(
+ subnet, network, project, subnet_pool))
+
+ changed = False
+ if state == 'present':
+ params = self._build_params(network, project, subnet_pool)
+ if subnet is None:
+ subnet = self.conn.network.create_subnet(**params)
+ changed = True
+ else:
+ updates = self._build_updates(subnet, params)
+ if updates:
+ self._validate_update(subnet, updates)
+ subnet = self.conn.network.update_subnet(subnet, **updates)
+ changed = True
+ self.exit_json(changed=changed, subnet=subnet, id=subnet.id)
+ elif state == 'absent' and subnet is not None:
+ self.conn.network.delete_subnet(subnet)
+ changed = True
+ self.exit_json(changed=changed)
+
+
+def main():
+ module = SubnetModule()
+ module()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/releasenotes/notes/bump-openstack-collection-382923f617548b01.yaml b/releasenotes/notes/bump-openstack-collection-382923f617548b01.yaml
new file mode 100644
index 0000000..60eb020
--- /dev/null
+++ b/releasenotes/notes/bump-openstack-collection-382923f617548b01.yaml
@@ -0,0 +1,4 @@
+---
+other:
+ - The Atmosphere collection now uses the new major version of the OpenStack
+ collection as a dependency.
diff --git a/requirements.txt b/requirements.txt
index 9157d5b..038719c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,6 @@
ansible-core>=2.15.9
jmespath>=1.0.1
-openstacksdk<0.99.0
+openstacksdk>1
docker-image-py>=0.1.12
rjsonnet>=0.5.2
netaddr>=0.8.0
diff --git a/roles/designate/vars/main.yml b/roles/designate/vars/main.yml
index e6bfe9b..1bf3970 100644
--- a/roles/designate/vars/main.yml
+++ b/roles/designate/vars/main.yml
@@ -26,7 +26,7 @@
max_pool_size: 5
pool_timeout: 30
service:central:
- managed_resource_tenant_id: "{{ _designate_project_info.openstack_projects[0].id }}"
+ managed_resource_tenant_id: "{{ _designate_project_info.projects[0].id }}"
pools: "{{ designate_pools | to_yaml }}"
pod:
replicas:
diff --git a/roles/glance_image/tasks/main.yml b/roles/glance_image/tasks/main.yml
index 5f56e55..5823680 100644
--- a/roles/glance_image/tasks/main.yml
+++ b/roles/glance_image/tasks/main.yml
@@ -26,7 +26,7 @@
- name: Download image and upload into Glance
run_once: true
- when: _image_info.openstack_image == None
+ when: _image_info.images | length == 0
block:
- name: Generate temporary work directory
ansible.builtin.tempfile:
diff --git a/roles/ironic/tasks/network/create.yml b/roles/ironic/tasks/network/create.yml
index 8032983..a459b74 100644
--- a/roles/ironic/tasks/network/create.yml
+++ b/roles/ironic/tasks/network/create.yml
@@ -25,7 +25,7 @@
- name: Create bare metal network subnet
run_once: true
- openstack.cloud.subnet:
+ vexxhost.atmosphere.subnet:
cloud: atmosphere
# Subnet settings
network_name: "{{ ironic_bare_metal_subnet_name }}"
diff --git a/roles/ironic/tasks/network/lookup.yml b/roles/ironic/tasks/network/lookup.yml
index 8838ac9..95a8f71 100644
--- a/roles/ironic/tasks/network/lookup.yml
+++ b/roles/ironic/tasks/network/lookup.yml
@@ -23,11 +23,11 @@
- name: Assert that we match a single network only
ansible.builtin.assert:
that:
- - ironic_bare_metal_networks_info.openstack_networks | length == 1
- fail_msg: "Expected exactly one network, but found {{ ironic_bare_metal_networks_info.openstack_networks | length }}"
+ - ironic_bare_metal_networks_info.networks | length == 1
+ fail_msg: "Expected exactly one network, but found {{ ironic_bare_metal_networks_info.networks | length }}"
success_msg: "Successfully matched a single network"
run_once: true
- name: Set fact with bare metal network information
ansible.builtin.set_fact:
- ironic_bare_metal_network: "{{ ironic_bare_metal_networks_info.openstack_networks[0] }}"
+ ironic_bare_metal_network: "{{ ironic_bare_metal_networks_info.networks[0] }}"
diff --git a/roles/ironic/vars/main.yml b/roles/ironic/vars/main.yml
index 51d32b4..e863699 100644
--- a/roles/ironic/vars/main.yml
+++ b/roles/ironic/vars/main.yml
@@ -50,8 +50,8 @@
rbac_service_role_elevated_access: true
conductor:
clean_step_priority_override: deploy.erase_devices_express:5
- deploy_kernel: "{{ ironic_python_agent_deploy_kernel.openstack_image.id }}"
- deploy_ramdisk: "{{ ironic_python_agent_deploy_ramdisk.openstack_image.id }}"
+ deploy_kernel: "{{ ironic_python_agent_deploy_kernel.images.0.id }}"
+ deploy_ramdisk: "{{ ironic_python_agent_deploy_ramdisk.images.0.id }}"
deploy:
erase_devices_priority: 0
erase_devices_metadata_priority: 0
diff --git a/roles/keystone/tasks/main.yml b/roles/keystone/tasks/main.yml
index a35a9ce..3aa013c 100644
--- a/roles/keystone/tasks/main.yml
+++ b/roles/keystone/tasks/main.yml
@@ -119,6 +119,7 @@
vexxhost.atmosphere.federation_idp:
name: "{{ item.domain.name }}"
domain_id: "{{ item.domain.id }}"
+ is_enabled: true
remote_ids:
- "{{ item.item | vexxhost.atmosphere.issuer_from_domain }}"
loop: "{{ keystone_domains_result.results }}"
diff --git a/roles/manila/tasks/generate_resources.yml b/roles/manila/tasks/generate_resources.yml
index 9bfa6c8..08c5278 100644
--- a/roles/manila/tasks/generate_resources.yml
+++ b/roles/manila/tasks/generate_resources.yml
@@ -43,7 +43,7 @@
- name: Create generic share driver security group tcp rules
openstack.cloud.security_group_rule:
cloud: atmosphere
- security_group: "{{ _manila_service_security_group.id }}"
+ security_group: "{{ _manila_service_security_group.security_group.id }}"
direction: ingress
ethertype: IPv4
protocol: tcp
@@ -58,7 +58,7 @@
- name: Create generic share driver security group icmp rules
openstack.cloud.security_group_rule:
cloud: atmosphere
- security_group: "{{ _manila_service_security_group.id }}"
+ security_group: "{{ _manila_service_security_group.security_group.id }}"
direction: ingress
ethertype: IPv4
protocol: icmp
diff --git a/roles/manila/vars/main.yml b/roles/manila/vars/main.yml
index ce2175d..3c86604 100644
--- a/roles/manila/vars/main.yml
+++ b/roles/manila/vars/main.yml
@@ -58,7 +58,7 @@
path_to_private_key: /etc/manila/ssh-keys/id_rsa
path_to_public_key: /etc/manila/ssh-keys/id_rsa.pub
service_image_name: "{{ manila_image_name }}"
- service_instance_flavor_id: "{{ _manila_flavor.id }}"
+ service_instance_flavor_id: "{{ _manila_flavor.flavor.id }}"
service_instance_security_group: manila-service-security-group
oslo_messaging_notifications:
driver: noop
diff --git a/roles/neutron/tasks/main.yml b/roles/neutron/tasks/main.yml
index 874ed3c..2331880 100644
--- a/roles/neutron/tasks/main.yml
+++ b/roles/neutron/tasks/main.yml
@@ -87,7 +87,7 @@
until: _result is not failed
- name: Create subnets
- openstack.cloud.subnet:
+ vexxhost.atmosphere.subnet:
cloud: atmosphere
# Subnet settings
network_name: "{{ item.0.name }}"
diff --git a/roles/octavia/tasks/generate_resources.yml b/roles/octavia/tasks/generate_resources.yml
index 5960aa1..e582be4 100644
--- a/roles/octavia/tasks/generate_resources.yml
+++ b/roles/octavia/tasks/generate_resources.yml
@@ -20,13 +20,13 @@
register: _octavia_management_network
- name: Create management subnet
- openstack.cloud.subnet:
+ vexxhost.atmosphere.subnet:
cloud: atmosphere
# Subnet settings
network_name: "{{ octavia_management_network_name }}"
name: "{{ octavia_management_subnet_name }}"
cidr: "{{ octavia_management_subnet_cidr }}"
- no_gateway_ip: true
+ disable_gateway_ip: true
- name: Create health manager security group
openstack.cloud.security_group:
@@ -37,7 +37,7 @@
- name: Create health manager security group rules
openstack.cloud.security_group_rule:
cloud: atmosphere
- security_group: "{{ _octavia_health_manager_sg.id }}"
+ security_group: "{{ _octavia_health_manager_sg.security_group.id }}"
direction: ingress
ethertype: IPv4
protocol: "{{ item.protocol }}"
@@ -67,7 +67,7 @@
if hostvars[item]['octavia_health_manager_ip'] is defined else omit
}}
security_groups:
- - "{{ _octavia_health_manager_sg.id }}"
+ - "{{ _octavia_health_manager_sg.security_group.id }}"
loop: "{{ groups['controllers'] }}"
loop_control:
index_var: _octavia_health_manager_port_index
@@ -110,10 +110,10 @@
- name: Set controller_ip_port_list
ansible.builtin.set_fact:
- _octavia_controller_ip_port_list: "{{ (_octavia_controller_ip_port_list | d([]) + [item.openstack_ports[0].fixed_ips[0].ip_address + ':5555']) | unique }}"
+ _octavia_controller_ip_port_list: "{{ (_octavia_controller_ip_port_list | d([]) + [item.ports[0].fixed_ips[0].ip_address + ':5555']) | unique }}"
loop: "{{ _octavia_health_manager_ports.results }}"
loop_control:
- label: "{{ item.openstack_ports[0].name }}"
+ label: "{{ item.ports[0].name }}"
- name: Create amphora security group
openstack.cloud.security_group:
@@ -124,13 +124,13 @@
- name: Create amphora security group rules
openstack.cloud.security_group_rule:
cloud: atmosphere
- security_group: "{{ _octavia_amphora_sg.id }}"
+ security_group: "{{ _octavia_amphora_sg.security_group.id }}"
direction: ingress
ethertype: IPv4
protocol: tcp
port_range_min: "{{ item.0 }}"
port_range_max: "{{ item.0 }}"
- remote_ip_prefix: "{{ item.1.openstack_ports[0].fixed_ips[0].ip_address }}/32"
+ remote_ip_prefix: "{{ item.1.ports[0].fixed_ips[0].ip_address }}/32"
with_nested:
- [22, 9443]
- "{{ _octavia_health_manager_ports.results }}"
diff --git a/roles/octavia/vars/main.yml b/roles/octavia/vars/main.yml
index 8423aba..1f78f70 100644
--- a/roles/octavia/vars/main.yml
+++ b/roles/octavia/vars/main.yml
@@ -98,10 +98,10 @@
endpoint_type: internalURL
controller_worker:
amp_boot_network_list: "{{ _octavia_management_network.id }}"
- amp_flavor_id: "{{ _octavia_amphora_flavor.id }}"
- amp_image_owner_id: "{{ _octavia_amphora_image.openstack_image.owner }}"
- amp_secgroup_list: "{{ _octavia_amphora_sg.id }}"
- amp_ssh_key_name: "{{ octavia_amphora_ssh_keypair.key.name }}"
+ amp_flavor_id: "{{ _octavia_amphora_flavor.flavor.id }}"
+ amp_image_owner_id: "{{ _octavia_amphora_image.images.0.owner }}"
+ amp_secgroup_list: "{{ _octavia_amphora_sg.security_group.id }}"
+ amp_ssh_key_name: "{{ octavia_amphora_ssh_keypair.keypair.name }}"
client_ca: /etc/octavia/certs/client/ca.crt
volume_driver: volume_cinder_driver
workers: 4
diff --git a/roles/openstacksdk/defaults/main.yml b/roles/openstacksdk/defaults/main.yml
index 27dc31a..96db768 100644
--- a/roles/openstacksdk/defaults/main.yml
+++ b/roles/openstacksdk/defaults/main.yml
@@ -12,4 +12,4 @@
# License for the specific language governing permissions and limitations
# under the License.
-openstacksdk_version: "0.61.0"
+# openstacksdk_version:
diff --git a/roles/openstacksdk/tasks/main.yml b/roles/openstacksdk/tasks/main.yml
index 1a4c3b4..5f082a1 100644
--- a/roles/openstacksdk/tasks/main.yml
+++ b/roles/openstacksdk/tasks/main.yml
@@ -15,7 +15,7 @@
- name: Install openstacksdk
ansible.builtin.pip:
name: openstacksdk
- version: "{{ openstacksdk_version }}"
+ version: "{{ openstacksdk_version | default(omit) }}"
- name: Create openstack config directory
become: true
diff --git a/roles/rook_ceph_cluster/tasks/main.yml b/roles/rook_ceph_cluster/tasks/main.yml
index 92f3842..9fa1f8d 100644
--- a/roles/rook_ceph_cluster/tasks/main.yml
+++ b/roles/rook_ceph_cluster/tasks/main.yml
@@ -96,13 +96,21 @@
password: "{{ openstack_helm_endpoints.identity.auth.rgw.password }}"
domain: service
+# NOTE(mnaser): https://storyboard.openstack.org/#!/story/2010579
- name: Grant access to "service" project
- openstack.cloud.role_assignment:
- cloud: atmosphere
- domain: service
- user: "{{ openstack_helm_endpoints.identity.auth.rgw.username }}"
- project: service
- role: admin
+ changed_when: false
+ ansible.builtin.shell: |
+ set -o posix
+ source /etc/profile.d/atmosphere.sh
+ openstack role add \
+ --user-domain service \
+ --project service \
+ --user {{ openstack_helm_endpoints.identity.auth.rgw.username }} \
+ admin
+ args:
+ executable: /bin/bash
+ environment:
+ OS_CLOUD: atmosphere
- name: Create OpenStack service
openstack.cloud.catalog_service:
diff --git a/roles/tempest/tasks/main.yml b/roles/tempest/tasks/main.yml
index 8ea8e8f..3440b2d 100644
--- a/roles/tempest/tasks/main.yml
+++ b/roles/tempest/tasks/main.yml
@@ -34,10 +34,10 @@
conf:
tempest:
compute:
- image_ref: "{{ _tempest_test_image.openstack_image.id }}"
+ image_ref: "{{ _tempest_test_image.images.0.id }}"
when:
- tempest_helm_values.conf.tempest.compute.image_ref is not defined
- - _tempest_test_image.openstack_image.id is defined
+ - _tempest_test_image.images | length > 0
- name: Get test flavor object
openstack.cloud.compute_flavor_info:
@@ -53,10 +53,10 @@
conf:
tempest:
compute:
- flavor_ref: "{{ _tempest_test_flavor.openstack_flavors[0].id }}"
+ flavor_ref: "{{ _tempest_test_flavor.flavors[0].id }}"
when:
- tempest_helm_values.conf.tempest.compute.flavor_ref is not defined
- - _tempest_test_flavor.openstack_flavors[0].id is defined
+ - _tempest_test_flavor.flavors[0].id is defined
- name: Get test network object
openstack.cloud.networks_info:
@@ -72,10 +72,10 @@
conf:
tempest:
network:
- public_network_id: "{{ _tempest_test_network.openstack_networks[0].id }}"
+ public_network_id: "{{ _tempest_test_network.networks[0].id }}"
when:
- tempest_helm_values.conf.tempest.network.public_network_id is not defined
- - _tempest_test_network.openstack_networks[0].id is defined
+ - _tempest_test_network.networks[0].id is defined
- name: Deploy Helm chart
failed_when: false