os_port allowed_address_pairs and extra_dhcp_opts list of dicts comparison fix (#56577)

* compare list of dicts

* update example for dhcp_server_opts to include ip_version which is automatically added by openstack

* add note about dhcp_server_opts

* add changelog fragment

* fix forgotten exception+pass

* no need to excplicitly check for None

* fix oops

* fix import error

* missed missing_required_lib

* changelog fragment formatting and grammar fixes

* update requirements in documentation and fix spelling
pull/49506/head
Andreas Calminder 5 years ago committed by Felix Fontein
parent b8650c0a50
commit cac93cbd1f

@ -0,0 +1,2 @@
bugfixes:
- "os_port - no longer triggers change when ``allowed_address_pairs`` items are in different order."

@ -22,6 +22,9 @@ version_added: "2.0"
description: description:
- Add, Update or Remove ports from an OpenStack cloud. A I(state) of - Add, Update or Remove ports from an OpenStack cloud. A I(state) of
'present' will ensure the port is created or updated if required. 'present' will ensure the port is created or updated if required.
requirements:
- "ordereddict unless python >= 2.7"
- "openstacksdk"
options: options:
network: network:
description: description:
@ -60,11 +63,13 @@ options:
- ip_address: ..." - ip_address: ..."
extra_dhcp_opts: extra_dhcp_opts:
description: description:
- "Extra dhcp options to be assigned to this port. Extra options are - "Extra dhcp options to be assigned to this port. Extra options are
supported with dictionary structure. supported with dictionary structure. Note that options cannot be removed
only updated.
e.g. extra_dhcp_opts: e.g. extra_dhcp_opts:
- opt_name: opt name1 - opt_name: opt name1
opt_value: value1 opt_value: value1
ip_version: 4
- opt_name: ..." - opt_name: ..."
device_owner: device_owner:
description: description:
@ -213,10 +218,21 @@ port_security_enabled:
type: bool type: bool
''' '''
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module
try:
from collections import OrderedDict
HAS_ORDEREDDICT = True
except ImportError:
try:
from ordereddict import OrderedDict
HAS_ORDEREDDICT = True
except ImportError:
HAS_ORDEREDDICT = False
def _needs_update(module, port, cloud): def _needs_update(module, port, cloud):
"""Check for differences in the updatable values. """Check for differences in the updatable values.
@ -228,21 +244,35 @@ def _needs_update(module, port, cloud):
'device_id', 'device_id',
'binding:vnic_type', 'binding:vnic_type',
'port_security_enabled'] 'port_security_enabled']
compare_dict = ['allowed_address_pairs', compare_list_dict = ['allowed_address_pairs',
'extra_dhcp_opts'] 'extra_dhcp_opts']
compare_list = ['security_groups'] compare_list = ['security_groups']
for key in compare_simple: for key in compare_simple:
if module.params[key] is not None and module.params[key] != port[key]: if module.params[key] is not None and module.params[key] != port[key]:
return True return True
for key in compare_dict:
if module.params[key] is not None and module.params[key] != port[key]:
return True
for key in compare_list: for key in compare_list:
if module.params[key] is not None and (set(module.params[key]) != if module.params[key] is not None and (set(module.params[key]) !=
set(port[key])): set(port[key])):
return True return True
for key in compare_list_dict:
if not module.params[key]:
if not port[key]:
return True
# sort dicts in list
port_ordered = [OrderedDict(sorted(d.items())) for d in port[key]]
param_ordered = [OrderedDict(sorted(d.items())) for d in module.params[key]]
for d in param_ordered:
if d not in port_ordered:
return True
for d in port_ordered:
if d not in param_ordered:
return True
# NOTE: if port was created or updated with 'no_security_groups=True', # NOTE: if port was created or updated with 'no_security_groups=True',
# subsequent updates without 'no_security_groups' flag or # subsequent updates without 'no_security_groups' flag or
# 'no_security_groups=False' and no specified 'security_groups', will not # 'no_security_groups=False' and no specified 'security_groups', will not
@ -343,6 +373,9 @@ def main():
supports_check_mode=True, supports_check_mode=True,
**module_kwargs) **module_kwargs)
if not HAS_ORDEREDDICT:
module.fail_json(msg=missing_required_lib('ordereddict'))
name = module.params['name'] name = module.params['name']
state = module.params['state'] state = module.params['state']

Loading…
Cancel
Save