Refactor openvswitch_db module (#23288)

The openvswitch_db module uses the ovs-vsctl binary to
address changes.
On other network modules we follow the pattern of returning 'commands'
as part of the result, containing the commands run on the target device.
Follow that for code consistency and maintenance.
Also, adding state param, which allows to add/remove keys on columns.
pull/18758/head
Ricardo Carrillo Cruz 8 years ago committed by GitHub
parent e8538213fa
commit 2571d2f64b

@ -38,6 +38,16 @@ requirements: [ "ovs-vsctl >= 2.3.3" ]
description: description:
- Set column values in record in database table. - Set column values in record in database table.
options: options:
state:
required: false
description:
- Configures the state of the key. When set
to I(present), the I(key) and I(value) pair will be set
on the I(record) and when set to I(absent) the I(key)
will not be set.
default: present
choices: ['present', 'absent']
version_added: "2.4"
table: table:
required: true required: true
description: description:
@ -82,58 +92,114 @@ EXAMPLES = '''
col: other_config col: other_config
key: disable-in-band key: disable-in-band
value: true value: true
# Remove in band key
- openvswitch_db:
state: present
table: Bridge
record: br-int
col: other_config
key: disable-in-band
''' '''
def cmd_run(module, cmd, check_rc=True): def map_obj_to_command(want, have, module):
""" Log and run ovs-vsctl command. """ """ Define ovs-vsctl command to meet desired state """
return module.run_command(cmd.split(" "), check_rc=check_rc) command = None
if module.params['state'] == 'absent':
if 'key' in have.keys():
templatized_command = "%(ovs-vsctl)s -t %(timeout)s remove %(table)s %(record)s " \
"%(col)s %(key)s=%(value)s"
command = templatized_command % module.params
else:
if 'key' not in have.keys():
templatized_command = "%(ovs-vsctl)s -t %(timeout)s add %(table)s %(record)s " \
"%(col)s %(key)s=%(value)s"
command = templatized_command % module.params
elif want['value'] != have['value']:
templatized_command = "%(ovs-vsctl)s -t %(timeout)s set %(table)s %(record)s " \
"%(col)s:%(key)s=%(value)s"
command = templatized_command % module.params
return command
def params_set(module):
""" Implement the ovs-vsctl set commands. """
changed = False def map_config_to_obj(module):
templatized_command = "%(ovs-vsctl)s -t %(timeout)s list %(table)s %(record)s"
command = templatized_command % module.params
rc, out, err = module.run_command(command, check_rc=True)
## if rc != 0:
# Place in params dictionary in order to support the string format below. module.fail_json(msg=err)
module.params["ovs-vsctl"] = module.get_bin_path("ovs-vsctl", True)
fmt = "%(ovs-vsctl)s -t %(timeout)s get %(table)s %(record)s " \ match = re.search(r'^' + module.params['col'] + r'(\s+):(\s+)(.*)$', out, re.M)
"%(col)s:%(key)s"
cmd = fmt % module.params col_value = match.group(3)
col_value_to_dict = {}
if match.group(3):
for kv in col_value[1:-1].split(','):
k, v = kv.split('=')
col_value_to_dict[k.strip()] = v.strip()
(_, output, _) = cmd_run(module, cmd, False) obj = {
if module.params['value'] not in output: 'table': module.params['table'],
fmt = "%(ovs-vsctl)s -t %(timeout)s set %(table)s %(record)s " \ 'record': module.params['record'],
"%(col)s:%(key)s=%(value)s" 'col': module.params['col'],
cmd = fmt % module.params }
##
# Check if flow exists and is the same. if module.params['key'] in col_value_to_dict:
(rtc, _, err) = cmd_run(module, cmd) obj['key'] = module.params['key']
if rtc != 0: obj['value'] = col_value_to_dict[module.params['key']]
module.fail_json(msg=err)
changed = True return obj
module.exit_json(changed=changed)
def map_params_to_obj(module):
obj = {
'table': module.params['table'],
'record': module.params['record'],
'col': module.params['col'],
'key': module.params['key'],
'value': module.params['value']
}
return obj
# pylint: disable=E0602 # pylint: disable=E0602
def main(): def main():
""" Entry point for ansible module. """ """ Entry point for ansible module. """
module = AnsibleModule(
argument_spec = { argument_spec = {
'state': {'default': 'present', 'choices': ['present', 'absent']},
'table': {'required': True}, 'table': {'required': True},
'record': {'required': True}, 'record': {'required': True},
'col': {'required': True}, 'col': {'required': True},
'key': {'required': True}, 'key': {'required': True},
'value': {'required': True}, 'value': {'required': True},
'timeout': {'default': 5, 'type': 'int'}, 'timeout': {'default': 5, 'type': 'int'},
}, }
supports_check_mode=True,
) module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=True)
result = {'changed': False}
# We add ovs-vsctl to module_params to later build up templatized commands
module.params["ovs-vsctl"] = module.get_bin_path("ovs-vsctl", True)
want = map_params_to_obj(module)
have = map_config_to_obj(module)
command = map_obj_to_command(want, have, module)
result['command'] = command
if command:
if not module.check_mode:
module.run_command(command, check_rc=True)
result['changed'] = True
params_set(module) module.exit_json(**result)
# pylint: disable=W0614 # pylint: disable=W0614
@ -142,6 +208,7 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
import re
if __name__ == '__main__': if __name__ == '__main__':
main() main()

Loading…
Cancel
Save