# -*- coding: utf-8 -*- | |||||
''' | |||||
Support for Open vSwitch database configuration. | |||||
''' | |||||
from __future__ import absolute_import | |||||
import logging | |||||
import salt.utils | |||||
log = logging.getLogger(__name__) | |||||
def __virtual__(): | |||||
''' | |||||
Only load the module if Open vSwitch is installed | |||||
''' | |||||
if salt.utils.which('ovs-vsctl'): | |||||
return 'ovs_config' | |||||
return False | |||||
def _retcode_to_bool(retcode): | |||||
''' | |||||
Evaulates ovs-vsctl command`s retcode value. | |||||
Args: | |||||
retcode: Value of retcode field from response. | |||||
''' | |||||
return True if retcode == 0 else False | |||||
def set(cfg, value, wait=True): | |||||
''' | |||||
Updates a specified configuration entry. | |||||
Args: | |||||
cfg/value: a config entry to update | |||||
wait: wait or not for ovs-vswitchd to reconfigure itself before it exits. | |||||
CLI Example: | |||||
.. code-block:: bash | |||||
salt '*' ovs_config.set other_config:dpdk-init true | |||||
''' | |||||
wait = '' if wait else '--no-wait ' | |||||
cmd = 'ovs-vsctl {0}set Open_vSwitch . {1}="{2}"'.format(wait, cfg, str(value).lower()) | |||||
result = __salt__['cmd.run_all'](cmd) | |||||
return _retcode_to_bool(result['retcode']) | |||||
def remove(cfg): | |||||
''' | |||||
Removes a specified configuration entry. | |||||
Args: | |||||
cfg: a config entry to remove | |||||
CLI Example: | |||||
.. code-block:: bash | |||||
salt '*' ovs_config.remove other_config | |||||
''' | |||||
if ':' in cfg: | |||||
section, key = cfg.split(':') | |||||
cmd = 'ovs-vsctl remove Open_vSwitch . {} {}'.format(section, key) | |||||
else: | |||||
cmd = 'ovs-vsctl clear Open_vSwitch . ' + cfg | |||||
result = __salt__['cmd.run_all'](cmd) | |||||
return _retcode_to_bool(result['retcode']) | |||||
def list(): | |||||
''' | |||||
Return a current config of Open vSwitch | |||||
CLI Example: | |||||
.. code-block:: bash | |||||
salt '*' ovs_config.list | |||||
''' | |||||
cmd = 'ovs-vsctl list Open_vSwitch .' | |||||
result = __salt__['cmd.run_all'](cmd) | |||||
if result['retcode'] == 0: | |||||
config = {} | |||||
for l in result['stdout'].splitlines(): | |||||
cfg, value = map((lambda x: x.strip()), l.split(' : ')) | |||||
if value.startswith('{') and len(value) > 2: | |||||
for i in value[1:-1].replace('"', '').split(', '): | |||||
_k, _v = i.split('=') | |||||
config['{}:{}'.format(cfg,_k)] = _v | |||||
else: | |||||
config[cfg] = value | |||||
return config | |||||
else: | |||||
return False |
# -*- coding: utf-8 -*- | |||||
''' | |||||
Management of Open vSwitch configuration | |||||
======================================== | |||||
The OVS config can be managed with the ovs_config state module: | |||||
.. code-block:: yaml | |||||
other_config:dpdk-init: | |||||
ovs_config.present: | |||||
- value: True | |||||
other_config:dpdk-extra: | |||||
ovs_config.present: | |||||
- value: -n 12 --vhost-owner libvirt-qemu:kvm --vhost-perm 0664 | |||||
external_ids: | |||||
ovs_config.absent | |||||
''' | |||||
def __virtual__(): | |||||
''' | |||||
Only make these states available if Open vSwitch is installed. | |||||
''' | |||||
return 'ovs_config.list' in __salt__ | |||||
def present(name, value, wait=True): | |||||
''' | |||||
Ensures that the named config exists, eventually creates it. | |||||
Args: | |||||
name/value: The name/value of the config entry. | |||||
wait: Whether wait for ovs-vswitchd to reconfigure itself according to the modified database. | |||||
''' | |||||
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''} | |||||
ovs_config = __salt__['ovs_config.list']() | |||||
if name in ovs_config and ovs_config[name] == str(value).lower(): | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} is already set to {1}.'.format(name, value) | |||||
else: | |||||
config_updated = __salt__['ovs_config.set'](name, value, wait) | |||||
if config_updated: | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} is updated.'.format(name) | |||||
ret['changes'] = { name: 'Updated to {0}'.format(value) } | |||||
else: | |||||
ret['result'] = False | |||||
ret['comment'] = 'Unable to update config of {0}.'.format(name) | |||||
return ret | |||||
def absent(name): | |||||
''' | |||||
Ensures that the named config does not exist, eventually deletes it. | |||||
Args: | |||||
name: The name of the config entry. | |||||
''' | |||||
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''} | |||||
ovs_config = __salt__['ovs_config.list']() | |||||
if ':' in name and name not in ovs_config: | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} does not exist.'.format(name) | |||||
else: | |||||
config_removed = __salt__['ovs_config.remove'](name) | |||||
if config_removed: | |||||
ret['result'] = True | |||||
ret['comment'] = '{0} is removed.'.format(name) | |||||
ret['changes'] = { name: '{0} removed'.format(name) } | |||||
else: | |||||
ret['result'] = False | |||||
ret['comment'] = 'Unable to delete config of {0}.'.format(name) | |||||
return ret |