mirror of https://github.com/ansible/ansible.git
Migrated to openvswitch.openvswitch
parent
b182f411ea
commit
512183d75b
@ -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