mirror of https://github.com/ansible/ansible.git
Migrated to openvswitch.openvswitch
parent
ab914b9ab6
commit
40714dfca9
@ -1,274 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# coding: utf-8 -*-
|
|
||||||
|
|
||||||
# (c) 2013, David Stygstra <david.stygstra@gmail.com>
|
|
||||||
# Portions copyright @ 2015 VMware, Inc.
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
||||||
'status': ['preview'],
|
|
||||||
'supported_by': 'network'}
|
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
|
||||||
---
|
|
||||||
module: openvswitch_bridge
|
|
||||||
version_added: 1.4
|
|
||||||
author: "David Stygstra (@stygstra)"
|
|
||||||
short_description: Manage Open vSwitch bridges
|
|
||||||
requirements: [ ovs-vsctl ]
|
|
||||||
description:
|
|
||||||
- Manage Open vSwitch bridges
|
|
||||||
options:
|
|
||||||
bridge:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Name of bridge or fake bridge to manage
|
|
||||||
parent:
|
|
||||||
version_added: "2.3"
|
|
||||||
description:
|
|
||||||
- Bridge parent of the fake bridge to manage
|
|
||||||
vlan:
|
|
||||||
version_added: "2.3"
|
|
||||||
description:
|
|
||||||
- The VLAN id of the fake bridge to manage (must be between 0 and
|
|
||||||
4095). This parameter is required if I(parent) parameter is set.
|
|
||||||
state:
|
|
||||||
default: "present"
|
|
||||||
choices: [ present, absent ]
|
|
||||||
description:
|
|
||||||
- Whether the bridge should exist
|
|
||||||
timeout:
|
|
||||||
default: 5
|
|
||||||
description:
|
|
||||||
- How long to wait for ovs-vswitchd to respond
|
|
||||||
external_ids:
|
|
||||||
version_added: 2.0
|
|
||||||
description:
|
|
||||||
- A dictionary of external-ids. Omitting this parameter is a No-op.
|
|
||||||
To clear all external-ids pass an empty value.
|
|
||||||
fail_mode:
|
|
||||||
version_added: 2.0
|
|
||||||
choices : [secure, standalone]
|
|
||||||
description:
|
|
||||||
- Set bridge fail-mode. The default value (None) is a No-op.
|
|
||||||
set:
|
|
||||||
version_added: 2.3
|
|
||||||
description:
|
|
||||||
- Run set command after bridge configuration. This parameter is
|
|
||||||
non-idempotent, play will always return I(changed) state if
|
|
||||||
present
|
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = '''
|
|
||||||
# Create a bridge named br-int
|
|
||||||
- openvswitch_bridge:
|
|
||||||
bridge: br-int
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Create a fake bridge named br-int within br-parent on the VLAN 405
|
|
||||||
- openvswitch_bridge:
|
|
||||||
bridge: br-int
|
|
||||||
parent: br-parent
|
|
||||||
vlan: 405
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Create an integration bridge
|
|
||||||
- openvswitch_bridge:
|
|
||||||
bridge: br-int
|
|
||||||
state: present
|
|
||||||
fail_mode: secure
|
|
||||||
args:
|
|
||||||
external_ids:
|
|
||||||
bridge-id: br-int
|
|
||||||
'''
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.six import iteritems
|
|
||||||
|
|
||||||
|
|
||||||
def _fail_mode_to_str(text):
|
|
||||||
if not text:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return text.strip()
|
|
||||||
|
|
||||||
|
|
||||||
def _external_ids_to_dict(text):
|
|
||||||
if not text:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
d = {}
|
|
||||||
|
|
||||||
for l in text.splitlines():
|
|
||||||
if l:
|
|
||||||
k, v = l.split('=')
|
|
||||||
d[k] = v
|
|
||||||
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
def map_obj_to_commands(want, have, module):
|
|
||||||
commands = list()
|
|
||||||
|
|
||||||
if module.params['state'] == 'absent':
|
|
||||||
if have:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s del-br"
|
|
||||||
" %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
else:
|
|
||||||
if have:
|
|
||||||
if want['fail_mode'] != have['fail_mode']:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" set-fail-mode %(bridge)s"
|
|
||||||
" %(fail_mode)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
if want['external_ids'] != have['external_ids']:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" br-set-external-id %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
if want['external_ids']:
|
|
||||||
for k, v in iteritems(want['external_ids']):
|
|
||||||
if (k not in have['external_ids']
|
|
||||||
or want['external_ids'][k] != have['external_ids'][k]):
|
|
||||||
command += " " + k + " " + v
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
if want['vlan'] and want['vlan'] != have['vlan']:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" set port %(bridge)s tag=%(vlan)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
else:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s add-br"
|
|
||||||
" %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
|
|
||||||
if want['parent']:
|
|
||||||
templatized_command = "%(parent)s %(vlan)s"
|
|
||||||
command += " " + templatized_command % module.params
|
|
||||||
|
|
||||||
if want['set']:
|
|
||||||
templatized_command = " -- set %(set)s"
|
|
||||||
command += templatized_command % module.params
|
|
||||||
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
if want['fail_mode']:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" set-fail-mode %(bridge)s"
|
|
||||||
" %(fail_mode)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
if want['external_ids']:
|
|
||||||
for k, v in iteritems(want['external_ids']):
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" br-set-external-id %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
command += " " + k + " " + v
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
return commands
|
|
||||||
|
|
||||||
|
|
||||||
def map_config_to_obj(module):
|
|
||||||
templatized_command = "%(ovs-vsctl)s -t %(timeout)s list-br"
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
if rc != 0:
|
|
||||||
module.fail_json(msg=err)
|
|
||||||
|
|
||||||
obj = {}
|
|
||||||
|
|
||||||
if module.params['bridge'] in out.splitlines():
|
|
||||||
obj['bridge'] = module.params['bridge']
|
|
||||||
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s br-to-parent"
|
|
||||||
" %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
obj['parent'] = out.strip()
|
|
||||||
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s br-to-vlan"
|
|
||||||
" %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
obj['vlan'] = out.strip()
|
|
||||||
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s get-fail-mode"
|
|
||||||
" %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
obj['fail_mode'] = _fail_mode_to_str(out)
|
|
||||||
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s br-get-external-id"
|
|
||||||
" %(bridge)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
obj['external_ids'] = _external_ids_to_dict(out)
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
def map_params_to_obj(module):
|
|
||||||
obj = {
|
|
||||||
'bridge': module.params['bridge'],
|
|
||||||
'parent': module.params['parent'],
|
|
||||||
'vlan': module.params['vlan'],
|
|
||||||
'fail_mode': module.params['fail_mode'],
|
|
||||||
'external_ids': module.params['external_ids'],
|
|
||||||
'set': module.params['set']
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
""" Entry point. """
|
|
||||||
argument_spec = {
|
|
||||||
'bridge': {'required': True},
|
|
||||||
'parent': {'default': None},
|
|
||||||
'vlan': {'default': None, 'type': 'int'},
|
|
||||||
'state': {'default': 'present', 'choices': ['present', 'absent']},
|
|
||||||
'timeout': {'default': 5, 'type': 'int'},
|
|
||||||
'external_ids': {'default': None, 'type': 'dict'},
|
|
||||||
'fail_mode': {'default': None},
|
|
||||||
'set': {'required': False, 'default': None}
|
|
||||||
}
|
|
||||||
|
|
||||||
required_if = [('parent', not None, ('vlan',))]
|
|
||||||
|
|
||||||
module = AnsibleModule(argument_spec=argument_spec,
|
|
||||||
required_if=required_if,
|
|
||||||
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)
|
|
||||||
|
|
||||||
commands = map_obj_to_commands(want, have, module)
|
|
||||||
result['commands'] = commands
|
|
||||||
|
|
||||||
if commands:
|
|
||||||
if not module.check_mode:
|
|
||||||
for c in commands:
|
|
||||||
module.run_command(c, check_rc=True)
|
|
||||||
result['changed'] = True
|
|
||||||
|
|
||||||
module.exit_json(**result)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,231 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# coding: utf-8 -*-
|
|
||||||
|
|
||||||
#
|
|
||||||
# (c) 2015, Mark Hamilton <mhamilton@vmware.com>
|
|
||||||
# Portions copyright @ 2015 VMware, Inc.
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
||||||
'status': ['preview'],
|
|
||||||
'supported_by': 'network'}
|
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = """
|
|
||||||
---
|
|
||||||
module: openvswitch_db
|
|
||||||
author: "Mark Hamilton (@markleehamilton) <mhamilton@vmware.com>"
|
|
||||||
version_added: 2.0
|
|
||||||
short_description: Configure open vswitch database.
|
|
||||||
requirements: [ "ovs-vsctl >= 2.3.3" ]
|
|
||||||
description:
|
|
||||||
- Set column values in record in database table.
|
|
||||||
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:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Identifies the table in the database.
|
|
||||||
record:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Identifies the record in the table.
|
|
||||||
col:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Identifies the column in the record.
|
|
||||||
key:
|
|
||||||
required: false
|
|
||||||
description:
|
|
||||||
- Identifies the key in the record column, when the column is a map
|
|
||||||
type.
|
|
||||||
value:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Expected value for the table, record, column and key.
|
|
||||||
timeout:
|
|
||||||
required: false
|
|
||||||
default: 5
|
|
||||||
description:
|
|
||||||
- How long to wait for ovs-vswitchd to respond
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = '''
|
|
||||||
# Increase the maximum idle time to 50 seconds before pruning unused kernel
|
|
||||||
# rules.
|
|
||||||
- openvswitch_db:
|
|
||||||
table: open_vswitch
|
|
||||||
record: .
|
|
||||||
col: other_config
|
|
||||||
key: max-idle
|
|
||||||
value: 50000
|
|
||||||
|
|
||||||
# Disable in band copy
|
|
||||||
- openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-int
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: true
|
|
||||||
|
|
||||||
# Remove in band key
|
|
||||||
- openvswitch_db:
|
|
||||||
state: present
|
|
||||||
table: Bridge
|
|
||||||
record: br-int
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
|
|
||||||
# Mark port with tag 10
|
|
||||||
- openvswitch_db:
|
|
||||||
table: Port
|
|
||||||
record: port0
|
|
||||||
col: tag
|
|
||||||
value: 10
|
|
||||||
'''
|
|
||||||
import re
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
|
|
||||||
# Regular expression for map type, must not be empty
|
|
||||||
NON_EMPTY_MAP_RE = re.compile(r'{.+}')
|
|
||||||
# Regular expression for a map column type
|
|
||||||
MAP_RE = re.compile(r'{.*}')
|
|
||||||
|
|
||||||
|
|
||||||
def map_obj_to_commands(want, have, module):
|
|
||||||
""" Define ovs-vsctl command to meet desired state """
|
|
||||||
commands = list()
|
|
||||||
|
|
||||||
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"
|
|
||||||
commands.append(templatized_command % module.params)
|
|
||||||
elif module.params['key'] is None:
|
|
||||||
templatized_command = "%(ovs-vsctl)s -t %(timeout)s remove %(table)s %(record)s " \
|
|
||||||
"%(col)s"
|
|
||||||
commands.append(templatized_command % module.params)
|
|
||||||
else:
|
|
||||||
if want == have:
|
|
||||||
# Nothing to commit
|
|
||||||
return commands
|
|
||||||
if module.params['key'] is None:
|
|
||||||
templatized_command = "%(ovs-vsctl)s -t %(timeout)s set %(table)s %(record)s " \
|
|
||||||
"%(col)s=%(value)s"
|
|
||||||
commands.append(templatized_command % module.params)
|
|
||||||
else:
|
|
||||||
templatized_command = "%(ovs-vsctl)s -t %(timeout)s set %(table)s %(record)s " \
|
|
||||||
"%(col)s:%(key)s=%(value)s"
|
|
||||||
commands.append(templatized_command % module.params)
|
|
||||||
|
|
||||||
return commands
|
|
||||||
|
|
||||||
|
|
||||||
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:
|
|
||||||
module.fail_json(msg=err)
|
|
||||||
|
|
||||||
match = re.search(r'^' + module.params['col'] + r'(\s+):(\s+)(.*)$', out, re.M)
|
|
||||||
|
|
||||||
col_value = match.group(3)
|
|
||||||
|
|
||||||
# Map types require key argument
|
|
||||||
has_key = module.params['key'] is not None
|
|
||||||
is_map = MAP_RE.match(col_value)
|
|
||||||
if is_map and not has_key:
|
|
||||||
module.fail_json(
|
|
||||||
msg="missing required arguments: key for map type of column")
|
|
||||||
|
|
||||||
col_value_to_dict = {}
|
|
||||||
if NON_EMPTY_MAP_RE.match(col_value):
|
|
||||||
for kv in col_value[1:-1].split(', '):
|
|
||||||
k, v = kv.split('=')
|
|
||||||
col_value_to_dict[k.strip()] = v.strip('\"')
|
|
||||||
|
|
||||||
obj = {
|
|
||||||
'table': module.params['table'],
|
|
||||||
'record': module.params['record'],
|
|
||||||
'col': module.params['col'],
|
|
||||||
}
|
|
||||||
|
|
||||||
if has_key and is_map:
|
|
||||||
if module.params['key'] in col_value_to_dict:
|
|
||||||
obj['key'] = module.params['key']
|
|
||||||
obj['value'] = col_value_to_dict[module.params['key']]
|
|
||||||
else:
|
|
||||||
obj['value'] = str(col_value.strip())
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
def map_params_to_obj(module):
|
|
||||||
if module.params['value'] in ['True', 'False']:
|
|
||||||
module.params['value'] = module.params['value'].lower()
|
|
||||||
obj = {
|
|
||||||
'table': module.params['table'],
|
|
||||||
'record': module.params['record'],
|
|
||||||
'col': module.params['col'],
|
|
||||||
'value': module.params['value']
|
|
||||||
}
|
|
||||||
|
|
||||||
key = module.params['key']
|
|
||||||
if key is not None:
|
|
||||||
obj['key'] = key
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
""" Entry point for ansible module. """
|
|
||||||
argument_spec = {
|
|
||||||
'state': {'default': 'present', 'choices': ['present', 'absent']},
|
|
||||||
'table': {'required': True},
|
|
||||||
'record': {'required': True},
|
|
||||||
'col': {'required': True},
|
|
||||||
'key': {'required': False},
|
|
||||||
'value': {'required': True, 'type': 'str'},
|
|
||||||
'timeout': {'default': 5, 'type': 'int'},
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
commands = map_obj_to_commands(want, have, module)
|
|
||||||
result['commands'] = commands
|
|
||||||
|
|
||||||
if commands:
|
|
||||||
if not module.check_mode:
|
|
||||||
for c in commands:
|
|
||||||
module.run_command(c, check_rc=True)
|
|
||||||
result['changed'] = True
|
|
||||||
|
|
||||||
module.exit_json(**result)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1,262 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# coding: utf-8 -*-
|
|
||||||
|
|
||||||
# (c) 2013, David Stygstra <david.stygstra@gmail.com>
|
|
||||||
# Portions copyright @ 2015 VMware, Inc.
|
|
||||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
||||||
'status': ['preview'],
|
|
||||||
'supported_by': 'network'}
|
|
||||||
|
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
|
||||||
---
|
|
||||||
module: openvswitch_port
|
|
||||||
version_added: 1.4
|
|
||||||
author: "David Stygstra (@stygstra)"
|
|
||||||
short_description: Manage Open vSwitch ports
|
|
||||||
requirements: [ ovs-vsctl ]
|
|
||||||
description:
|
|
||||||
- Manage Open vSwitch ports
|
|
||||||
options:
|
|
||||||
bridge:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Name of bridge to manage
|
|
||||||
port:
|
|
||||||
required: true
|
|
||||||
description:
|
|
||||||
- Name of port to manage on the bridge
|
|
||||||
tag:
|
|
||||||
version_added: 2.2
|
|
||||||
description:
|
|
||||||
- VLAN tag for this port. Must be a value between
|
|
||||||
0 and 4095.
|
|
||||||
state:
|
|
||||||
default: "present"
|
|
||||||
choices: [ present, absent ]
|
|
||||||
description:
|
|
||||||
- Whether the port should exist
|
|
||||||
timeout:
|
|
||||||
default: 5
|
|
||||||
description:
|
|
||||||
- How long to wait for ovs-vswitchd to respond
|
|
||||||
external_ids:
|
|
||||||
version_added: 2.0
|
|
||||||
default: {}
|
|
||||||
description:
|
|
||||||
- Dictionary of external_ids applied to a port.
|
|
||||||
set:
|
|
||||||
version_added: 2.0
|
|
||||||
description:
|
|
||||||
- Set a single property on a port.
|
|
||||||
'''
|
|
||||||
|
|
||||||
EXAMPLES = '''
|
|
||||||
# Creates port eth2 on bridge br-ex
|
|
||||||
- openvswitch_port:
|
|
||||||
bridge: br-ex
|
|
||||||
port: eth2
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# Creates port eth6
|
|
||||||
- openvswitch_port:
|
|
||||||
bridge: bridge-loop
|
|
||||||
port: eth6
|
|
||||||
state: present
|
|
||||||
set: Interface eth6
|
|
||||||
|
|
||||||
# Creates port vlan10 with tag 10 on bridge br-ex
|
|
||||||
- openvswitch_port:
|
|
||||||
bridge: br-ex
|
|
||||||
port: vlan10
|
|
||||||
tag: 10
|
|
||||||
state: present
|
|
||||||
set: Interface vlan10
|
|
||||||
|
|
||||||
# Assign interface id server1-vifeth6 and mac address 00:00:5E:00:53:23
|
|
||||||
# to port vifeth6 and setup port to be managed by a controller.
|
|
||||||
- openvswitch_port:
|
|
||||||
bridge: br-int
|
|
||||||
port: vifeth6
|
|
||||||
state: present
|
|
||||||
args:
|
|
||||||
external_ids:
|
|
||||||
iface-id: '{{ inventory_hostname }}-vifeth6'
|
|
||||||
attached-mac: '00:00:5E:00:53:23'
|
|
||||||
vm-id: '{{ inventory_hostname }}'
|
|
||||||
iface-status: active
|
|
||||||
'''
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.six import iteritems
|
|
||||||
|
|
||||||
|
|
||||||
def _external_ids_to_dict(text):
|
|
||||||
text = text.strip()
|
|
||||||
|
|
||||||
if text == '{}':
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
d = {}
|
|
||||||
|
|
||||||
for kv in text[1:-1].split(','):
|
|
||||||
kv = kv.strip()
|
|
||||||
k, v = kv.split('=')
|
|
||||||
d[k] = v
|
|
||||||
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
def _tag_to_str(text):
|
|
||||||
text = text.strip()
|
|
||||||
|
|
||||||
if text == '[]':
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return text
|
|
||||||
|
|
||||||
|
|
||||||
def map_obj_to_commands(want, have, module):
|
|
||||||
commands = list()
|
|
||||||
|
|
||||||
if module.params['state'] == 'absent':
|
|
||||||
if have:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s del-port"
|
|
||||||
" %(bridge)s %(port)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
else:
|
|
||||||
if have:
|
|
||||||
if want['tag'] != have['tag']:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" set port %(port)s tag=%(tag)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
if want['external_ids'] != have['external_ids']:
|
|
||||||
for k, v in iteritems(want['external_ids']):
|
|
||||||
if (not have['external_ids']
|
|
||||||
or k not in have['external_ids']
|
|
||||||
or want['external_ids'][k] != have['external_ids'][k]):
|
|
||||||
if v is None:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" remove port %(port)s"
|
|
||||||
" external_ids " + k)
|
|
||||||
command = templatized_command % module.params
|
|
||||||
commands.append(command)
|
|
||||||
else:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" set port %(port)s"
|
|
||||||
" external_ids:")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
command += k + "=" + v
|
|
||||||
commands.append(command)
|
|
||||||
else:
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s add-port"
|
|
||||||
" %(bridge)s %(port)s")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
|
|
||||||
if want['tag']:
|
|
||||||
templatized_command = " tag=%(tag)s"
|
|
||||||
command += templatized_command % module.params
|
|
||||||
|
|
||||||
if want['set']:
|
|
||||||
templatized_command = " -- set %(set)s"
|
|
||||||
command += templatized_command % module.params
|
|
||||||
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
if want['external_ids']:
|
|
||||||
for k, v in iteritems(want['external_ids']):
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s"
|
|
||||||
" set port %(port)s external_ids:")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
command += k + "=" + v
|
|
||||||
commands.append(command)
|
|
||||||
|
|
||||||
return commands
|
|
||||||
|
|
||||||
|
|
||||||
def map_config_to_obj(module):
|
|
||||||
templatized_command = "%(ovs-vsctl)s -t %(timeout)s list-ports %(bridge)s"
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
if rc != 0:
|
|
||||||
module.fail_json(msg=err)
|
|
||||||
|
|
||||||
obj = {}
|
|
||||||
|
|
||||||
if module.params['port'] in out.splitlines():
|
|
||||||
obj['bridge'] = module.params['bridge']
|
|
||||||
obj['port'] = module.params['port']
|
|
||||||
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s get"
|
|
||||||
" Port %(port)s tag")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
obj['tag'] = _tag_to_str(out)
|
|
||||||
|
|
||||||
templatized_command = ("%(ovs-vsctl)s -t %(timeout)s get"
|
|
||||||
" Port %(port)s external_ids")
|
|
||||||
command = templatized_command % module.params
|
|
||||||
rc, out, err = module.run_command(command, check_rc=True)
|
|
||||||
obj['external_ids'] = _external_ids_to_dict(out)
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
def map_params_to_obj(module):
|
|
||||||
obj = {
|
|
||||||
'bridge': module.params['bridge'],
|
|
||||||
'port': module.params['port'],
|
|
||||||
'tag': module.params['tag'],
|
|
||||||
'external_ids': module.params['external_ids'],
|
|
||||||
'set': module.params['set']
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
""" Entry point. """
|
|
||||||
argument_spec = {
|
|
||||||
'bridge': {'required': True},
|
|
||||||
'port': {'required': True},
|
|
||||||
'state': {'default': 'present', 'choices': ['present', 'absent']},
|
|
||||||
'timeout': {'default': 5, 'type': 'int'},
|
|
||||||
'external_ids': {'default': None, 'type': 'dict'},
|
|
||||||
'tag': {'default': None},
|
|
||||||
'set': {'required': False, 'default': None}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
commands = map_obj_to_commands(want, have, module)
|
|
||||||
result['commands'] = commands
|
|
||||||
|
|
||||||
if commands:
|
|
||||||
if not module.check_mode:
|
|
||||||
for c in commands:
|
|
||||||
module.run_command(c, check_rc=True)
|
|
||||||
result['changed'] = True
|
|
||||||
|
|
||||||
module.exit_json(**result)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
@ -1 +0,0 @@
|
|||||||
non_local
|
|
@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
testcase: "*"
|
|
||||||
test_items: []
|
|
@ -1,2 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- prepare_ovs_tests
|
|
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: collect all test cases
|
|
||||||
find:
|
|
||||||
paths: "{{ role_path }}/tests"
|
|
||||||
patterns: "{{ testcase }}.yaml"
|
|
||||||
delegate_to: localhost
|
|
||||||
register: test_cases
|
|
||||||
|
|
||||||
- name: set test_items
|
|
||||||
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
|
|
||||||
|
|
||||||
- name: run test case
|
|
||||||
include: "{{ test_case_to_run }}"
|
|
||||||
with_items: "{{ test_items }}"
|
|
||||||
loop_control:
|
|
||||||
loop_var: test_case_to_run
|
|
@ -1,48 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Make sure test bridge does not exist before tests
|
|
||||||
command: ovs-vsctl del-br br-test
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Create bridge
|
|
||||||
openvswitch_bridge:
|
|
||||||
bridge: br-test
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Create bridge again (idempotent)
|
|
||||||
openvswitch_bridge:
|
|
||||||
bridge: br-test
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is not changed
|
|
||||||
|
|
||||||
- name: Add fake bridge
|
|
||||||
openvswitch_bridge:
|
|
||||||
bridge: fake-br-test
|
|
||||||
parent: br-test
|
|
||||||
vlan: 100
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Change fake bridge vlan
|
|
||||||
openvswitch_bridge:
|
|
||||||
bridge: fake-br-test
|
|
||||||
parent: br-test
|
|
||||||
vlan: 300
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Tear down test bridges
|
|
||||||
command: ovs-vsctl del-br br-test
|
|
@ -1 +0,0 @@
|
|||||||
non_local
|
|
@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
testcase: "*"
|
|
||||||
test_items: []
|
|
@ -1,2 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- prepare_ovs_tests
|
|
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: collect all test cases
|
|
||||||
find:
|
|
||||||
paths: "{{ role_path }}/tests"
|
|
||||||
patterns: "{{ testcase }}.yaml"
|
|
||||||
delegate_to: localhost
|
|
||||||
register: test_cases
|
|
||||||
|
|
||||||
- name: set test_items
|
|
||||||
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
|
|
||||||
|
|
||||||
- name: run test case
|
|
||||||
include: "{{ test_case_to_run }}"
|
|
||||||
with_items: "{{ test_items }}"
|
|
||||||
loop_control:
|
|
||||||
loop_var: test_case_to_run
|
|
@ -1,183 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
- name: Make sure test bridge does not exist before tests
|
|
||||||
command: ovs-vsctl del-br br-test
|
|
||||||
become: yes
|
|
||||||
ignore_errors: yes
|
|
||||||
|
|
||||||
- name: Create test bridge
|
|
||||||
command: ovs-vsctl add-br br-test
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
- name: Create bridge
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: true
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Create bridge again (idempotent)
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: true
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is not changed
|
|
||||||
|
|
||||||
- name: Change key value with quotes
|
|
||||||
openvswitch_db:
|
|
||||||
table: open_vswitch
|
|
||||||
record: .
|
|
||||||
col: other_config
|
|
||||||
key: pmd-cpu-mask
|
|
||||||
value: "0xaaa00000000"
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Change keyvalue with quotes(idempotent)
|
|
||||||
openvswitch_db:
|
|
||||||
table: open_vswitch
|
|
||||||
record: .
|
|
||||||
col: other_config
|
|
||||||
key: pmd-cpu-mask
|
|
||||||
value: "0xaaa00000000"
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is not changed
|
|
||||||
|
|
||||||
- name: Remove key value with quotes
|
|
||||||
openvswitch_db:
|
|
||||||
table: open_vswitch
|
|
||||||
record: .
|
|
||||||
col: other_config
|
|
||||||
key: pmd-cpu-mask
|
|
||||||
value: "0xaaa00000000"
|
|
||||||
state: absent
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Change column value in a map
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: false
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Change column value in a map again (idempotent)
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: false
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is not changed
|
|
||||||
|
|
||||||
- name: Change column value
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: stp_enable
|
|
||||||
value: true
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Change column value again (idempotent)
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: stp_enable
|
|
||||||
value: true
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is not changed
|
|
||||||
|
|
||||||
- name: Try to set value on a map type without a key (negative)
|
|
||||||
ignore_errors: true
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
value: true
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is failed
|
|
||||||
|
|
||||||
- name: Remove bridge
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: false
|
|
||||||
state: absent
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is changed
|
|
||||||
|
|
||||||
- name: Remove bridge again (idempotent)
|
|
||||||
openvswitch_db:
|
|
||||||
table: Bridge
|
|
||||||
record: br-test
|
|
||||||
col: other_config
|
|
||||||
key: disable-in-band
|
|
||||||
value: false
|
|
||||||
state: absent
|
|
||||||
become: yes
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- result is not changed
|
|
||||||
|
|
||||||
- name: Tear down test bridge
|
|
||||||
command: ovs-vsctl del-br br-test
|
|
||||||
become: yes
|
|
@ -1 +0,0 @@
|
|||||||
foo=bar
|
|
@ -1 +0,0 @@
|
|||||||
test-br
|
|
@ -1 +0,0 @@
|
|||||||
0
|
|
@ -1 +0,0 @@
|
|||||||
secure
|
|
@ -1 +0,0 @@
|
|||||||
{foo=bar}
|
|
@ -1 +0,0 @@
|
|||||||
10
|
|
@ -1 +0,0 @@
|
|||||||
test-br
|
|
@ -1 +0,0 @@
|
|||||||
eth2
|
|
@ -1,23 +0,0 @@
|
|||||||
_uuid : 64f04422-d510-4258-9648-ee0a982f58c1
|
|
||||||
auto_attach : []
|
|
||||||
controller : []
|
|
||||||
datapath_id : "00002244f0645842"
|
|
||||||
datapath_type : ""
|
|
||||||
datapath_version : "<unknown>"
|
|
||||||
external_ids : {}
|
|
||||||
fail_mode : []
|
|
||||||
flood_vlans : []
|
|
||||||
flow_tables : {}
|
|
||||||
ipfix : []
|
|
||||||
mcast_snooping_enable: false
|
|
||||||
mirrors : []
|
|
||||||
name : test-br
|
|
||||||
netflow : []
|
|
||||||
other_config : {}
|
|
||||||
ports : [2c9c1b35-a304-4dee-bb7a-092d656543c7]
|
|
||||||
protocols : []
|
|
||||||
rstp_enable : false
|
|
||||||
rstp_status : {}
|
|
||||||
sflow : []
|
|
||||||
status : {}
|
|
||||||
stp_enable : false
|
|
@ -1,23 +0,0 @@
|
|||||||
_uuid : 64f04422-d510-4258-9648-ee0a982f58c1
|
|
||||||
auto_attach : []
|
|
||||||
controller : []
|
|
||||||
datapath_id : "00002244f0645842"
|
|
||||||
datapath_type : ""
|
|
||||||
datapath_version : "<unknown>"
|
|
||||||
external_ids : {}
|
|
||||||
fail_mode : []
|
|
||||||
flood_vlans : []
|
|
||||||
flow_tables : {}
|
|
||||||
ipfix : []
|
|
||||||
mcast_snooping_enable: false
|
|
||||||
mirrors : []
|
|
||||||
name : test-br
|
|
||||||
netflow : []
|
|
||||||
other_config : {disable-in-band=true}
|
|
||||||
ports : [2c9c1b35-a304-4dee-bb7a-092d656543c7]
|
|
||||||
protocols : []
|
|
||||||
rstp_enable : false
|
|
||||||
rstp_status : {}
|
|
||||||
sflow : []
|
|
||||||
status : {}
|
|
||||||
stp_enable : false
|
|
@ -1,86 +0,0 @@
|
|||||||
# (c) 2017 Red Hat Inc.
|
|
||||||
#
|
|
||||||
# This file is part of Ansible
|
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
|
|
||||||
from units.modules.utils import AnsibleExitJson, AnsibleFailJson, ModuleTestCase
|
|
||||||
|
|
||||||
|
|
||||||
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
|
|
||||||
fixture_data = {}
|
|
||||||
|
|
||||||
|
|
||||||
def load_fixture(name):
|
|
||||||
path = os.path.join(fixture_path, name)
|
|
||||||
|
|
||||||
if path in fixture_data:
|
|
||||||
return fixture_data[path]
|
|
||||||
|
|
||||||
with open(path) as f:
|
|
||||||
data = f.read()
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = json.loads(data)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
fixture_data[path] = data
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
class TestOpenVSwitchModule(ModuleTestCase):
|
|
||||||
|
|
||||||
def execute_module(self, failed=False, changed=False,
|
|
||||||
commands=None, test_name=None):
|
|
||||||
|
|
||||||
self.load_fixtures(test_name)
|
|
||||||
|
|
||||||
if failed:
|
|
||||||
result = self.failed()
|
|
||||||
self.assertTrue(result['failed'], result)
|
|
||||||
else:
|
|
||||||
result = self.changed(changed)
|
|
||||||
self.assertEqual(result['changed'], changed, result)
|
|
||||||
|
|
||||||
if commands is not None:
|
|
||||||
self.assertEqual(commands, result['commands'], result['commands'])
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def failed(self):
|
|
||||||
with self.assertRaises(AnsibleFailJson) as exc:
|
|
||||||
self.module.main()
|
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
|
||||||
self.assertTrue(result['failed'], result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def changed(self, changed=False):
|
|
||||||
with self.assertRaises(AnsibleExitJson) as exc:
|
|
||||||
self.module.main()
|
|
||||||
|
|
||||||
result = exc.exception.args[0]
|
|
||||||
self.assertEqual(result['changed'], changed, result)
|
|
||||||
return result
|
|
||||||
|
|
||||||
def load_fixtures(self, test_name):
|
|
||||||
pass
|
|
@ -1,232 +0,0 @@
|
|||||||
#
|
|
||||||
# (c) 2016 Red Hat Inc.
|
|
||||||
#
|
|
||||||
# This file is part of Ansible
|
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
from ansible.modules.network.ovs import openvswitch_bridge
|
|
||||||
from units.compat.mock import patch, MagicMock
|
|
||||||
from units.modules.utils import set_module_args
|
|
||||||
from .ovs_module import TestOpenVSwitchModule, load_fixture
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def patched_openvswitch_bridge(monkeypatch):
|
|
||||||
mocked_bridge = MagicMock()
|
|
||||||
mocked_bridge.return_value = {'bridge': 'test-br2', 'parent': 'test-br',
|
|
||||||
'vlan': 200, 'fail_mode': None,
|
|
||||||
'external_ids': None, 'set': None}
|
|
||||||
monkeypatch.setattr(openvswitch_bridge, 'map_config_to_obj', mocked_bridge)
|
|
||||||
return openvswitch_bridge
|
|
||||||
|
|
||||||
|
|
||||||
test_name_side_effect_matrix = {
|
|
||||||
'test_openvswitch_bridge_absent_idempotent': [
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_absent_removes_bridge': [
|
|
||||||
(0, 'list_br_test_br.cfg', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_present_idempotent': [
|
|
||||||
(0, 'list_br_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_parent_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_vlan_zero.cfg', ''),
|
|
||||||
(0, 'get_fail_mode_secure.cfg', ''),
|
|
||||||
(0, 'br_get_external_id_foo_bar.cfg', '')],
|
|
||||||
'test_openvswitch_bridge_present_creates_bridge': [
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_present_creates_fake_bridge': [
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_updates_vlan': [
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_present_adds_external_id': [
|
|
||||||
(0, 'list_br_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_parent_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_vlan_zero.cfg', ''),
|
|
||||||
(0, 'get_fail_mode_secure.cfg', ''),
|
|
||||||
(0, 'br_get_external_id_foo_bar.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_present_clears_external_id': [
|
|
||||||
(0, 'list_br_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_parent_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_vlan_zero.cfg', ''),
|
|
||||||
(0, 'get_fail_mode_secure.cfg', ''),
|
|
||||||
(0, 'br_get_external_id_foo_bar.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_present_changes_fail_mode': [
|
|
||||||
(0, 'list_br_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_parent_test_br.cfg', ''),
|
|
||||||
(0, 'br_to_vlan_zero.cfg', ''),
|
|
||||||
(0, 'get_fail_mode_secure.cfg', ''),
|
|
||||||
(0, 'br_get_external_id_foo_bar.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_bridge_present_runs_set_mode': [
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TestOpenVSwitchBridgeModule(TestOpenVSwitchModule):
|
|
||||||
|
|
||||||
module = openvswitch_bridge
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestOpenVSwitchBridgeModule, self).setUp()
|
|
||||||
|
|
||||||
self.mock_run_command = (
|
|
||||||
patch('ansible.module_utils.basic.AnsibleModule.run_command'))
|
|
||||||
self.run_command = self.mock_run_command.start()
|
|
||||||
self.mock_get_bin_path = (
|
|
||||||
patch('ansible.module_utils.basic.AnsibleModule.get_bin_path'))
|
|
||||||
self.get_bin_path = self.mock_get_bin_path.start()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(TestOpenVSwitchBridgeModule, self).tearDown()
|
|
||||||
|
|
||||||
self.mock_run_command.stop()
|
|
||||||
self.mock_get_bin_path.stop()
|
|
||||||
|
|
||||||
def load_fixtures(self, test_name):
|
|
||||||
test_side_effects = []
|
|
||||||
for s in test_name_side_effect_matrix[test_name]:
|
|
||||||
rc = s[0]
|
|
||||||
out = s[1] if s[1] == '' else str(load_fixture(s[1]))
|
|
||||||
err = s[2]
|
|
||||||
side_effect_with_fixture_loaded = (rc, out, err)
|
|
||||||
test_side_effects.append(side_effect_with_fixture_loaded)
|
|
||||||
self.run_command.side_effect = test_side_effects
|
|
||||||
|
|
||||||
self.get_bin_path.return_value = '/usr/bin/ovs-vsctl'
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_absent_idempotent(self):
|
|
||||||
set_module_args(dict(state='absent',
|
|
||||||
bridge='test-br'))
|
|
||||||
self.execute_module(test_name='test_openvswitch_bridge_absent_idempotent')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_absent_removes_bridge(self):
|
|
||||||
set_module_args(dict(state='absent',
|
|
||||||
bridge='test-br'))
|
|
||||||
commands = ['/usr/bin/ovs-vsctl -t 5 del-br test-br']
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_absent_removes_bridge')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_idempotent(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
fail_mode='secure',
|
|
||||||
external_ids={'foo': 'bar'}))
|
|
||||||
self.execute_module(test_name='test_openvswitch_bridge_present_idempotent')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_creates_bridge(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
fail_mode='secure',
|
|
||||||
external_ids={'foo': 'bar'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 add-br test-br',
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set-fail-mode test-br secure',
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 br-set-external-id test-br foo bar'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_present_creates_bridge')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_creates_fake_bridge(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br2',
|
|
||||||
parent='test-br',
|
|
||||||
vlan=10))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 add-br test-br2 test-br 10',
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_present_creates_fake_bridge')
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('patched_openvswitch_bridge')
|
|
||||||
def test_openvswitch_bridge_updates_vlan(self):
|
|
||||||
set_module_args({'state': 'present', 'bridge': 'test-br2', 'parent':
|
|
||||||
'test-br', 'vlan': 300})
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set port test-br2 tag=300'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_updates_vlan')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_adds_external_id(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
fail_mode='secure',
|
|
||||||
external_ids={'bip': 'bop'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 br-set-external-id test-br bip bop'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_present_adds_external_id')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_clears_external_id(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
fail_mode='secure',
|
|
||||||
external_ids={'foo': ''}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 br-set-external-id test-br foo '
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_present_clears_external_id')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_changes_fail_mode(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
fail_mode='standalone',
|
|
||||||
external_ids={'foo': 'bar'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set-fail-mode test-br standalone'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_present_changes_fail_mode')
|
|
||||||
|
|
||||||
def test_openvswitch_bridge_present_runs_set_mode(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
fail_mode='secure',
|
|
||||||
external_ids={'foo': 'bar'},
|
|
||||||
set="bridge test-br datapath_type=netdev"))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 add-br test-br -- set bridge test-br'
|
|
||||||
' datapath_type=netdev',
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set-fail-mode test-br secure',
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 br-set-external-id test-br foo bar'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_bridge_present_runs_set_mode')
|
|
@ -1,173 +0,0 @@
|
|||||||
#
|
|
||||||
# (c) 2016 Red Hat Inc.
|
|
||||||
#
|
|
||||||
# This file is part of Ansible
|
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
from ansible.modules.network.ovs import openvswitch_db
|
|
||||||
from units.compat.mock import patch, MagicMock
|
|
||||||
from units.modules.utils import set_module_args
|
|
||||||
from .ovs_module import TestOpenVSwitchModule, load_fixture
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def patched_openvswitch_db(monkeypatch):
|
|
||||||
mocked_ovs_db = MagicMock()
|
|
||||||
mocked_ovs_db.return_value = {'table': 'open_vswitch',
|
|
||||||
'record': '.',
|
|
||||||
'col': 'other_config',
|
|
||||||
'key': 'pmd-cpu-mask',
|
|
||||||
'value': '0xaaa00000000'}
|
|
||||||
monkeypatch.setattr(openvswitch_db, 'map_config_to_obj', mocked_ovs_db)
|
|
||||||
return openvswitch_db
|
|
||||||
|
|
||||||
|
|
||||||
test_name_side_effect_matrix = {
|
|
||||||
'test_openvswitch_db_absent_idempotent': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_missing.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_absent_removes_key': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_true.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_present_idempotent': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_true.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_present_idempotent_value': [
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_present_adds_key': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_missing.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_present_updates_key': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_true.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_present_missing_key_on_map': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_true.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
'test_openvswitch_db_present_stp_enable': [
|
|
||||||
(0, 'openvswitch_db_disable_in_band_true.cfg', None),
|
|
||||||
(0, None, None)],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TestOpenVSwitchDBModule(TestOpenVSwitchModule):
|
|
||||||
|
|
||||||
module = openvswitch_db
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestOpenVSwitchDBModule, self).setUp()
|
|
||||||
|
|
||||||
self.mock_run_command = (
|
|
||||||
patch('ansible.module_utils.basic.AnsibleModule.run_command'))
|
|
||||||
self.run_command = self.mock_run_command.start()
|
|
||||||
self.mock_get_bin_path = (
|
|
||||||
patch('ansible.module_utils.basic.AnsibleModule.get_bin_path'))
|
|
||||||
self.get_bin_path = self.mock_get_bin_path.start()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(TestOpenVSwitchDBModule, self).tearDown()
|
|
||||||
|
|
||||||
self.mock_run_command.stop()
|
|
||||||
self.mock_get_bin_path.stop()
|
|
||||||
|
|
||||||
def load_fixtures(self, test_name):
|
|
||||||
test_side_effects = []
|
|
||||||
for s in test_name_side_effect_matrix[test_name]:
|
|
||||||
rc = s[0]
|
|
||||||
out = load_fixture(s[1]) if s[1] else None
|
|
||||||
err = s[2]
|
|
||||||
side_effect_with_fixture_loaded = (rc, out, err)
|
|
||||||
test_side_effects.append(side_effect_with_fixture_loaded)
|
|
||||||
self.run_command.side_effect = test_side_effects
|
|
||||||
|
|
||||||
self.get_bin_path.return_value = '/usr/bin/ovs-vsctl'
|
|
||||||
|
|
||||||
def test_openvswitch_db_absent_idempotent(self):
|
|
||||||
set_module_args(dict(state='absent',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='other_config', key='disable-in-band',
|
|
||||||
value='true'))
|
|
||||||
self.execute_module(test_name='test_openvswitch_db_absent_idempotent')
|
|
||||||
|
|
||||||
def test_openvswitch_db_absent_removes_key(self):
|
|
||||||
set_module_args(dict(state='absent',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='other_config', key='disable-in-band',
|
|
||||||
value='true'))
|
|
||||||
self.execute_module(
|
|
||||||
changed=True,
|
|
||||||
commands=['/usr/bin/ovs-vsctl -t 5 remove Bridge test-br other_config'
|
|
||||||
' disable-in-band=true'],
|
|
||||||
test_name='test_openvswitch_db_absent_removes_key')
|
|
||||||
|
|
||||||
def test_openvswitch_db_present_idempotent(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='other_config', key='disable-in-band',
|
|
||||||
value='true'))
|
|
||||||
self.execute_module(test_name='test_openvswitch_db_present_idempotent')
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures('patched_openvswitch_db')
|
|
||||||
def test_openvswitch_db_present_idempotent_value(self):
|
|
||||||
set_module_args({"col": "other_config",
|
|
||||||
"key": "pmd-cpu-mask",
|
|
||||||
"record": ".",
|
|
||||||
"table": "open_vswitch",
|
|
||||||
"value": "0xaaa00000000"})
|
|
||||||
self.execute_module(test_name='test_openvswitch_db_present_idempotent_value')
|
|
||||||
|
|
||||||
def test_openvswitch_db_present_adds_key(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='other_config', key='disable-in-band',
|
|
||||||
value='true'))
|
|
||||||
self.execute_module(
|
|
||||||
changed=True,
|
|
||||||
commands=['/usr/bin/ovs-vsctl -t 5 set Bridge test-br other_config'
|
|
||||||
':disable-in-band=true'],
|
|
||||||
test_name='test_openvswitch_db_present_adds_key')
|
|
||||||
|
|
||||||
def test_openvswitch_db_present_updates_key(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='other_config', key='disable-in-band',
|
|
||||||
value='false'))
|
|
||||||
self.execute_module(
|
|
||||||
changed=True,
|
|
||||||
commands=['/usr/bin/ovs-vsctl -t 5 set Bridge test-br other_config'
|
|
||||||
':disable-in-band=false'],
|
|
||||||
test_name='test_openvswitch_db_present_updates_key')
|
|
||||||
|
|
||||||
def test_openvswitch_db_present_missing_key_on_map(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='other_config',
|
|
||||||
value='false'))
|
|
||||||
self.execute_module(
|
|
||||||
failed=True,
|
|
||||||
test_name='test_openvswitch_db_present_missing_key_on_map')
|
|
||||||
|
|
||||||
def test_openvswitch_db_present_stp_enable(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
table='Bridge', record='test-br',
|
|
||||||
col='stp_enable',
|
|
||||||
value='true'))
|
|
||||||
self.execute_module(changed=True,
|
|
||||||
test_name='test_openvswitch_db_present_stp_enable')
|
|
@ -1,207 +0,0 @@
|
|||||||
#
|
|
||||||
# (c) 2016 Red Hat Inc.
|
|
||||||
#
|
|
||||||
# This file is part of Ansible
|
|
||||||
#
|
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# Ansible is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import (absolute_import, division, print_function)
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
from units.compat.mock import patch
|
|
||||||
from ansible.modules.network.ovs import openvswitch_port
|
|
||||||
from units.modules.utils import set_module_args
|
|
||||||
from .ovs_module import TestOpenVSwitchModule, load_fixture
|
|
||||||
|
|
||||||
test_name_side_effect_matrix = {
|
|
||||||
'test_openvswitch_port_absent_idempotent': [
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_absent_removes_port': [
|
|
||||||
(0, 'list_ports_test_br.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_tag.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_external_ids.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_idempotent': [
|
|
||||||
(0, 'list_ports_test_br.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_tag.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_external_ids.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_creates_port': [
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_changes_tag': [
|
|
||||||
(0, 'list_ports_test_br.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_tag.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_external_ids.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_changes_external_id': [
|
|
||||||
(0, 'list_ports_test_br.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_tag.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_external_ids.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_adds_external_id': [
|
|
||||||
(0, 'list_ports_test_br.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_tag.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_external_ids.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_clears_external_id': [
|
|
||||||
(0, 'list_ports_test_br.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_tag.cfg', ''),
|
|
||||||
(0, 'get_port_eth2_external_ids.cfg', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
'test_openvswitch_port_present_runs_set_mode': [
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', ''),
|
|
||||||
(0, '', '')],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class TestOpenVSwitchPortModule(TestOpenVSwitchModule):
|
|
||||||
|
|
||||||
module = openvswitch_port
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(TestOpenVSwitchPortModule, self).setUp()
|
|
||||||
|
|
||||||
self.mock_run_command = (
|
|
||||||
patch('ansible.module_utils.basic.AnsibleModule.run_command'))
|
|
||||||
self.run_command = self.mock_run_command.start()
|
|
||||||
self.mock_get_bin_path = (
|
|
||||||
patch('ansible.module_utils.basic.AnsibleModule.get_bin_path'))
|
|
||||||
self.get_bin_path = self.mock_get_bin_path.start()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
super(TestOpenVSwitchPortModule, self).tearDown()
|
|
||||||
|
|
||||||
self.mock_run_command.stop()
|
|
||||||
self.mock_get_bin_path.stop()
|
|
||||||
|
|
||||||
def load_fixtures(self, test_name):
|
|
||||||
test_side_effects = []
|
|
||||||
for s in test_name_side_effect_matrix[test_name]:
|
|
||||||
rc = s[0]
|
|
||||||
out = s[1] if s[1] == '' else str(load_fixture(s[1]))
|
|
||||||
err = s[2]
|
|
||||||
side_effect_with_fixture_loaded = (rc, out, err)
|
|
||||||
test_side_effects.append(side_effect_with_fixture_loaded)
|
|
||||||
self.run_command.side_effect = test_side_effects
|
|
||||||
|
|
||||||
self.get_bin_path.return_value = '/usr/bin/ovs-vsctl'
|
|
||||||
|
|
||||||
def test_openvswitch_port_absent_idempotent(self):
|
|
||||||
set_module_args(dict(state='absent',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2'))
|
|
||||||
self.execute_module(test_name='test_openvswitch_port_absent_idempotent')
|
|
||||||
|
|
||||||
def test_openvswitch_port_absent_removes_port(self):
|
|
||||||
set_module_args(dict(state='absent',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2'))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 del-port test-br eth2',
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_port_absent_removes_port')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_idempotent(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=10,
|
|
||||||
external_ids={'foo': 'bar'}))
|
|
||||||
self.execute_module(test_name='test_openvswitch_port_present_idempotent')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_creates_port(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=10,
|
|
||||||
external_ids={'foo': 'bar'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 add-port test-br eth2 tag=10',
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set port eth2 external_ids:foo=bar'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True,
|
|
||||||
commands=commands,
|
|
||||||
test_name='test_openvswitch_port_present_creates_port')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_changes_tag(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=20,
|
|
||||||
external_ids={'foo': 'bar'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set port eth2 tag=20'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True,
|
|
||||||
commands=commands,
|
|
||||||
test_name='test_openvswitch_port_present_changes_tag')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_changes_external_id(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=10,
|
|
||||||
external_ids={'foo': 'baz'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set port eth2 external_ids:foo=baz'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True,
|
|
||||||
commands=commands,
|
|
||||||
test_name='test_openvswitch_port_present_changes_external_id')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_adds_external_id(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=10,
|
|
||||||
external_ids={'foo2': 'bar2'}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set port eth2 external_ids:foo2=bar2'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True,
|
|
||||||
commands=commands,
|
|
||||||
test_name='test_openvswitch_port_present_adds_external_id')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_clears_external_id(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=10,
|
|
||||||
external_ids={'foo': None}))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 remove port eth2 external_ids foo'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True,
|
|
||||||
commands=commands,
|
|
||||||
test_name='test_openvswitch_port_present_clears_external_id')
|
|
||||||
|
|
||||||
def test_openvswitch_port_present_runs_set_mode(self):
|
|
||||||
set_module_args(dict(state='present',
|
|
||||||
bridge='test-br',
|
|
||||||
port='eth2',
|
|
||||||
tag=10,
|
|
||||||
external_ids={'foo': 'bar'},
|
|
||||||
set="port eth2 other_config:stp-path-cost=10"))
|
|
||||||
commands = [
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 add-port test-br eth2 tag=10 -- set'
|
|
||||||
' port eth2 other_config:stp-path-cost=10',
|
|
||||||
'/usr/bin/ovs-vsctl -t 5 set port eth2 external_ids:foo=bar'
|
|
||||||
]
|
|
||||||
self.execute_module(changed=True, commands=commands,
|
|
||||||
test_name='test_openvswitch_port_present_runs_set_mode')
|
|
Loading…
Reference in New Issue