From 413a9d0c62b3dbadf890dff0d74521ee3391d88a Mon Sep 17 00:00:00 2001 From: Lars Kellogg-Stedman Date: Wed, 14 Oct 2015 16:27:04 -0400 Subject: [PATCH] fix handling of nics argument The existing code was receiving a list of strings and erroneously assuming it was being given a list of dictionaries, leading it to fail with: AttributeError: 'str' object has no attribute 'get' This commit corrects the list handling code to check the type of each item and handle it appropriately. Also, based on bcoca's comment in #2253, thie code removes the special case for a string-only argument. By transforming string arguments into dicts and then handling them like any other dict argument, this also permits arguments of the form: nics: net-name=mynet Or: nics: port-name=mynet Previous versions of this code only supported `net-id` and `port-id` in string specifications. --- .../modules/cloud/openstack/os_server.py | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/lib/ansible/modules/cloud/openstack/os_server.py b/lib/ansible/modules/cloud/openstack/os_server.py index d5afdab94d3..573f56ecea2 100644 --- a/lib/ansible/modules/cloud/openstack/os_server.py +++ b/lib/ansible/modules/cloud/openstack/os_server.py @@ -86,8 +86,8 @@ options: - A list of networks to which the instance's interface should be attached. Networks may be referenced by net-id/net-name/port-id or port-name. - - 'Also this accepts a string containing a list of net-id/port-id. - Eg: nics: "net-id=uuid-1,net-id=uuid-2"' + - 'Also this accepts a string containing a list of (net/port)-(id/name) + Eg: nics: "net-id=uuid-1,port-name=myport"' required: false default: None auto_ip: @@ -288,35 +288,37 @@ def _exit_hostvars(module, cloud, server, changed=True): changed=changed, server=server, id=server.id, openstack=hostvars) +def _parse_nics(nics): + for net in nics: + if type(net) == str: + for nic in net.split(','): + yield dict((nic.split('='),)) + else: + yield net + def _network_args(module, cloud): args = [] nics = module.params['nics'] - if type(nics) == str : - for kv_str in nics.split(","): - nic = {} - k, v = kv_str.split("=") - nic[k] = v - args.append(nic) - else: - for net in module.params['nics']: - if net.get('net-id'): - args.append(net) - elif net.get('net-name'): - by_name = cloud.get_network(net['net-name']) - if not by_name: - module.fail_json( - msg='Could not find network by net-name: %s' % - net['net-name']) - args.append({'net-id': by_name['id']}) - elif net.get('port-id'): - args.append(net) - elif net.get('port-name'): - by_name = cloud.get_port(net['port-name']) - if not by_name: - module.fail_json( - msg='Could not find port by port-name: %s' % - net['port-name']) - args.append({'port-id': by_name['id']}) + + for net in _parse_nics(nics): + if net.get('net-id'): + args.append(net) + elif net.get('net-name'): + by_name = cloud.get_network(net['net-name']) + if not by_name: + module.fail_json( + msg='Could not find network by net-name: %s' % + net['net-name']) + args.append({'net-id': by_name['id']}) + elif net.get('port-id'): + args.append(net) + elif net.get('port-name'): + by_name = cloud.get_port(net['port-name']) + if not by_name: + module.fail_json( + msg='Could not find port by port-name: %s' % + net['port-name']) + args.append({'port-id': by_name['id']}) return args