Change network modules to work with new SDK

Change-Id: I7625d696f6462a7a955008a5c7276f1548acbc2e
This commit is contained in:
Sagi Shnaidman 2022-01-19 12:24:08 +02:00 committed by Jakob Meng
parent a9fa496ebe
commit 9272146cf7
6 changed files with 275 additions and 136 deletions

View File

@ -86,6 +86,7 @@
keystone_idp keystone_idp
keystone_mapping keystone_mapping
loadbalancer loadbalancer
network
nova_flavor nova_flavor
nova_services nova_services
object object
@ -102,7 +103,6 @@
# failing tags # failing tags
# floating_ip # floating_ip
# orchestrate # orchestrate
# network
# neutron_rbac # neutron_rbac
# router # router
# server # server

View File

@ -8,7 +8,7 @@
- name: Assert that public network exists - name: Assert that public network exists
assert: assert:
that: public_network.openstack_networks|length == 1 that: public_network.networks|length == 1
- name: Create external network - name: Create external network
openstack.cloud.network: openstack.cloud.network:
@ -120,7 +120,7 @@
- name: Check if public network has any floating ips - name: Check if public network has any floating ips
set_fact: set_fact:
public_network_had_fips: "{{ fips.floating_ips| public_network_had_fips: "{{ fips.floating_ips|
selectattr('floating_network_id', '==', public_network.openstack_networks.0.id)| selectattr('floating_network_id', '==', public_network.networks.0.id)|
list|length > 0 }}" list|length > 0 }}"
# TODO: Replace with appropriate Ansible module once available # TODO: Replace with appropriate Ansible module once available
@ -371,7 +371,7 @@
when: not public_network_had_fips when: not public_network_had_fips
command: > command: >
openstack --os-cloud={{ cloud }} floating ip delete openstack --os-cloud={{ cloud }} floating ip delete
{{ fips.floating_ips|selectattr('floating_network_id', '==', public_network.openstack_networks.0.id)| {{ fips.floating_ips|selectattr('floating_network_id', '==', public_network.networks.0.id)|
map(attribute="floating_ip_address")|list|join(' ') }} map(attribute="floating_ip_address")|list|join(' ') }}
# TODO: Replace with appropriate Ansible module once available # TODO: Replace with appropriate Ansible module once available

View File

@ -1,7 +1,35 @@
expected_fields:
- availability_zone_hints
- availability_zones
- created_at
- description
- dns_domain
- id
- ipv4_address_scope_id
- ipv6_address_scope_id
- is_admin_state_up
- is_default
- is_port_security_enabled
- is_router_external
- is_shared
- is_vlan_transparent
- mtu
- name
- project_id
- provider_network_type
- provider_physical_network
- provider_segmentation_id
- qos_policy_id
- revision_number
- segments
- status
- subnet_ids
- tags
- updated_at
dns_domain: example.opendev.org
mtu: 1250
network_external: false
network_name: shade_network network_name: shade_network
network_name_newparams: newparams_network network_name_newparams: newparams_network
network_shared: false network_shared: false
network_external: false
dns_domain: example.opendev.org
mtu: 1250
port_security_enabled: false port_security_enabled: false

View File

@ -6,6 +6,28 @@
state: present state: present
shared: "{{ network_shared }}" shared: "{{ network_shared }}"
external: "{{ network_external }}" external: "{{ network_external }}"
register: infonet
- name: Check output of creating network
assert:
that:
- infonet.network
- item in infonet.network
loop: "{{ expected_fields }}"
- name: Gather networks info
openstack.cloud.networks_info:
cloud: "{{ cloud }}"
name: "{{ infonet.network.id }}"
register: result
- name: Check output of network info
# TODO: Remove ignore_errors once SDK's search_networks() (re)implemented searching by id
ignore_errors: yes
assert:
that:
- result.networks|length == 1
- infonet.network.id == result.networks[0].id
- name: Gather networks info - generic - name: Gather networks info - generic
openstack.cloud.networks_info: openstack.cloud.networks_info:
@ -15,12 +37,28 @@
shared: "{{ network_shared|string|capitalize }}" shared: "{{ network_shared|string|capitalize }}"
register: result register: result
- name: Check output of network info
assert:
that:
- item in result.networks[0]
loop: "{{ expected_fields }}"
- name: Gather networks info
openstack.cloud.networks_info:
cloud: "{{ cloud }}"
name: "{{ network_name }}"
filters:
shared: "False"
register: result
- name: Verify networks info - generic - name: Verify networks info - generic
assert: assert:
that: that:
- result.openstack_networks.0.name == network_name - result.networks.0.name == network_name
- (result.openstack_networks.0.shared|lower) == (network_shared|lower) - "'is_shared' in result.networks.0"
- result.openstack_networks[0]['router:external'] == {{ network_external }} - result.networks.0['is_shared']|lower == network_shared|lower
- "'is_router_external' in result.networks.0"
- result.networks[0]['is_router_external'] == {{ network_external }}
- name: Create network - with new SDK params - name: Create network - with new SDK params
openstack.cloud.network: openstack.cloud.network:
@ -32,29 +70,21 @@
mtu: "{{ mtu }}" mtu: "{{ mtu }}"
port_security_enabled: "{{ port_security_enabled }}" port_security_enabled: "{{ port_security_enabled }}"
register: result_create_nw_with_new_params register: result_create_nw_with_new_params
ignore_errors: yes ignore_errors: true
- name: Check errors below min sdk version - with new SDK params
assert:
that:
- result_create_nw_with_new_params.failed
- '"the installed version of the openstacksdk library MUST be >=0.18.0." in result_create_nw_with_new_params.msg'
when: sdk_version is version('0.18', '<')
- name: Gather networks info - with new SDK params - name: Gather networks info - with new SDK params
openstack.cloud.networks_info: openstack.cloud.networks_info:
cloud: "{{ cloud }}" cloud: "{{ cloud }}"
name: "{{ network_name_newparams }}" name: "{{ network_name_newparams }}"
register: result_newparams register: result_newparams
when: sdk_version is version('0.18', '>=')
- name: Verify networks info - with new SDK params - name: Verify networks info - with new SDK params
assert: assert:
that: that:
- result_newparams.openstack_networks.0.name == network_name_newparams - result_newparams.networks.0.name == network_name_newparams
- result_newparams.openstack_networks.0.mtu == mtu - result_newparams.networks.0.mtu == mtu
- result_newparams.openstack_networks.0.port_security_enabled == port_security_enabled - "'is_port_security_enabled' in result_newparams.networks.0"
when: sdk_version is version('0.18', '>=') - result_newparams.networks.0['is_port_security_enabled'] == port_security_enabled
- name: Delete network - generic and with new SDK params - name: Delete network - generic and with new SDK params
openstack.cloud.network: openstack.cloud.network:
@ -74,4 +104,4 @@
- name: Verify networks info - deleted - name: Verify networks info - deleted
assert: assert:
that: that:
- result_nonet.openstack_networks == [] - result_nonet.networks == []

View File

@ -10,7 +10,7 @@ module: network
short_description: Creates/removes networks from OpenStack short_description: Creates/removes networks from OpenStack
author: OpenStack Ansible SIG author: OpenStack Ansible SIG
description: description:
- Add or remove network from OpenStack. - Add or remove network from OpenStack (doesn't update network properties).
options: options:
name: name:
description: description:
@ -61,18 +61,18 @@ options:
description: description:
- Whether port security is enabled on the network or not. - Whether port security is enabled on the network or not.
Network will use OpenStack defaults if this option is Network will use OpenStack defaults if this option is
not utilised. Requires openstacksdk>=0.18. not utilised.
type: bool type: bool
mtu_size: mtu:
description: description:
- The maximum transmission unit (MTU) value to address fragmentation. - The maximum transmission unit (MTU) value to address fragmentation.
Network will use OpenStack defaults if this option is Network will use OpenStack defaults if this option is
not provided. Requires openstacksdk>=0.18. not provided.
type: int type: int
aliases: ['mtu'] aliases: ['mtu_size']
dns_domain: dns_domain:
description: description:
- The DNS domain value to set. Requires openstacksdk>=0.29. - The DNS domain value to set.
Network will use Openstack defaults if this option is Network will use Openstack defaults if this option is
not provided. not provided.
type: str type: str
@ -94,67 +94,96 @@ EXAMPLES = '''
''' '''
RETURN = ''' RETURN = '''
id:
description: Id of network
returned: On success when network exists.
type: str
network: network:
description: Dictionary describing the network. description: Dictionary describing the network.
returned: On success when I(state) is 'present'. returned: On success when network exists.
type: complex type: dict
contains: contains:
id: availability_zone_hints:
description: Network ID. description: Availability zone hints
type: str type: str
sample: "4bb4f9a5-3bd2-4562-bf6a-d17a6341bb56" availability_zones:
name: description: Availability zones
description: Network name.
type: str type: str
sample: "ext_network" created_at:
shared: description: Created at timestamp
description: Indicates whether this network is shared across all tenants. type: str
type: bool description:
sample: false description: Description
status:
description: Network status.
type: str type: str
sample: "ACTIVE"
mtu:
description: The MTU of a network resource.
type: int
sample: 0
dns_domain: dns_domain:
description: The DNS domain of a network resource. description: Dns domain
type: str type: str
sample: "sample.openstack.org." id:
admin_state_up: description: Id
description: The administrative state of the network.
type: bool
sample: true
port_security_enabled:
description: The port security status
type: bool
sample: true
router:external:
description: Indicates whether this network is externally accessible.
type: bool
sample: true
tenant_id:
description: The tenant ID.
type: str type: str
sample: "06820f94b9f54b119636be2728d216fc" ipv4_address_scope_id:
subnets: description: Ipv4 address scope id
description: The associated subnets.
type: list
sample: []
"provider:physical_network":
description: The physical network where this network object is implemented.
type: str type: str
sample: my_vlan_net ipv6_address_scope_id:
"provider:network_type": description: Ipv6 address scope id
description: The type of physical network that maps to this network resource.
type: str type: str
sample: vlan is_admin_state_up:
"provider:segmentation_id": description: Is admin state up
description: An isolated segment on the physical network. type: str
is_default:
description: Is default
type: str
is_port_security_enabled:
description: Is port security enabled
type: str
is_router_external:
description: Is router external
type: str
is_shared:
description: Is shared
type: str
is_vlan_transparent:
description: Is vlan transparent
type: str
mtu:
description: Mtu
type: str
name:
description: Name
type: str
project_id:
description: Project id
type: str
provider_network_type:
description: Provider network type
type: str
provider_physical_network:
description: Provider physical network
type: str
provider_segmentation_id:
description: Provider segmentation id
type: str
qos_policy_id:
description: Qos policy id
type: str
revision_number:
description: Revision number
type: str
segments:
description: Segments
type: str
status:
description: Status
type: str
subnet_ids:
description: Subnet ids
type: str
tags:
description: Tags
type: str
updated_at:
description: Updated at timestamp
type: str type: str
sample: 101
''' '''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
@ -172,9 +201,9 @@ class NetworkModule(OpenStackModule):
provider_segmentation_id=dict(required=False, type='int'), provider_segmentation_id=dict(required=False, type='int'),
state=dict(default='present', choices=['absent', 'present']), state=dict(default='present', choices=['absent', 'present']),
project=dict(default=None), project=dict(default=None),
port_security_enabled=dict(type='bool', min_ver='0.18.0'), port_security_enabled=dict(type='bool'),
mtu_size=dict(required=False, type='int', min_ver='0.18.0', aliases=['mtu']), mtu=dict(required=False, type='int', aliases=['mtu_size']),
dns_domain=dict(required=False, min_ver='0.29.0') dns_domain=dict(required=False)
) )
def run(self): def run(self):
@ -189,41 +218,38 @@ class NetworkModule(OpenStackModule):
provider_segmentation_id = self.params['provider_segmentation_id'] provider_segmentation_id = self.params['provider_segmentation_id']
project = self.params['project'] project = self.params['project']
kwargs = self.check_versioned( kwargs = {}
mtu_size=self.params['mtu_size'], port_security_enabled=self.params['port_security_enabled'], for arg in ('port_security_enabled', 'mtu', 'dns_domain'):
dns_domain=self.params['dns_domain'] if self.params[arg] is not None:
) kwargs[arg] = self.params[arg]
if project is not None: if project is not None:
proj = self.conn.get_project(project) proj = self.conn.identity.find_project(project, ignore_missing=False)
if proj is None:
self.fail_json(msg='Project %s could not be found' % project)
project_id = proj['id'] project_id = proj['id']
filters = {'tenant_id': project_id} net_kwargs = {'project_id': project_id}
else: else:
project_id = None project_id = None
filters = None net_kwargs = {}
net = self.conn.get_network(name, filters=filters) net = self.conn.network.find_network(name, **net_kwargs)
if state == 'present': if state == 'present':
if not net: if not net:
provider = {}
if provider_physical_network: if provider_physical_network:
provider['physical_network'] = provider_physical_network kwargs['provider_physical_network'] = provider_physical_network
if provider_network_type: if provider_network_type:
provider['network_type'] = provider_network_type kwargs['provider_network_type'] = provider_network_type
if provider_segmentation_id: if provider_segmentation_id:
provider['segmentation_id'] = provider_segmentation_id kwargs['provider_segmentation_id'] = provider_segmentation_id
if project_id is not None: if project_id is not None:
net = self.conn.create_network(name, shared, admin_state_up, kwargs['project_id'] = project_id
external, provider, project_id, net = self.conn.network.create_network(name=name,
**kwargs) shared=shared,
else: admin_state_up=admin_state_up,
net = self.conn.create_network(name, shared, admin_state_up, is_router_external=external,
external, provider, **kwargs)
**kwargs)
changed = True changed = True
net = net.to_dict(computed=False)
else: else:
changed = False changed = False
self.exit(changed=changed, network=net, id=net['id']) self.exit(changed=changed, network=net, id=net['id'])
@ -232,7 +258,7 @@ class NetworkModule(OpenStackModule):
if not net: if not net:
self.exit(changed=False) self.exit(changed=False)
else: else:
self.conn.delete_network(name) self.conn.network.delete_network(net['id'])
self.exit(changed=True) self.exit(changed=True)

View File

@ -44,7 +44,7 @@ EXAMPLES = '''
- name: Show openstack networks - name: Show openstack networks
debug: debug:
msg: "{{ result.openstack_networks }}" msg: "{{ result.networks }}"
- name: Gather information about a previously created network by name - name: Gather information about a previously created network by name
openstack.cloud.networks_info: openstack.cloud.networks_info:
@ -58,7 +58,7 @@ EXAMPLES = '''
- name: Show openstack networks - name: Show openstack networks
debug: debug:
msg: "{{ result.openstack_networks }}" msg: "{{ result.networks }}"
- name: Gather information about a previously created network with filter - name: Gather information about a previously created network with filter
# Note: name and filters parameters are Not mutually exclusive # Note: name and filters parameters are Not mutually exclusive
@ -77,40 +77,97 @@ EXAMPLES = '''
- name: Show openstack networks - name: Show openstack networks
debug: debug:
msg: "{{ result.openstack_networks }}" msg: "{{ result.networks }}"
''' '''
RETURN = ''' RETURN = '''
openstack_networks: networks:
description: has all the openstack information about the networks description: has all the openstack information about the networks
returned: always, but can be null returned: always, but can be empty list
type: complex type: list
elements: dict
contains: contains:
availability_zone_hints:
description: Availability zone hints
type: str
availability_zones:
description: Availability zones
type: str
created_at:
description: Created at timestamp
type: str
description:
description: Description
type: str
dns_domain:
description: Dns domain
type: str
id: id:
description: Unique UUID. description: Id
returned: success type: str
ipv4_address_scope_id:
description: Ipv4 address scope id
type: str
ipv6_address_scope_id:
description: Ipv6 address scope id
type: str
is_admin_state_up:
description: Is admin state up
type: str
is_default:
description: Is default
type: str
is_port_security_enabled:
description: Is port security enabled
type: str
is_router_external:
description: Is router external
type: str
is_shared:
description: Is shared
type: str
is_vlan_transparent:
description: Is vlan transparent
type: str
mtu:
description: Mtu
type: str type: str
name: name:
description: Name given to the network. description: Name
returned: success type: str
project_id:
description: Project id
type: str
provider_network_type:
description: Provider network type
type: str
provider_physical_network:
description: Provider physical network
type: str
provider_segmentation_id:
description: Provider segmentation id
type: str
qos_policy_id:
description: Qos policy id
type: str
revision_number:
description: Revision number
type: str
segments:
description: Segments
type: str type: str
status: status:
description: Network status. description: Status
returned: success
type: str type: str
subnets: subnet_ids:
description: Subnet(s) included in this network. description: Subnet ids
returned: success type: str
type: list tags:
elements: str description: Tags
tenant_id: type: str
description: Tenant id associated with this network. updated_at:
returned: success description: Updated at timestamp
type: str type: str
shared:
description: Network shared flag.
returned: success
type: bool
''' '''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
@ -129,15 +186,13 @@ class NetworkInfoModule(OpenStackModule):
) )
def run(self): def run(self):
kwargs = {
kwargs = self.check_versioned( 'filters': self.params['filters'],
filters=self.params['filters'] 'name_or_id': self.params['name']
) }
if self.params['name']:
kwargs['name_or_id'] = self.params['name']
networks = self.conn.search_networks(**kwargs) networks = self.conn.search_networks(**kwargs)
networks = [i.to_dict(computed=False) for i in networks]
self.exit(changed=False, openstack_networks=networks) self.exit(changed=False, networks=networks)
def main(): def main():