mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #29185 from jirikotlin/develop
Support of tunnels in openvswitch modules.
This commit is contained in:
commit
ccf46a44bb
@ -215,7 +215,7 @@ def port_remove(br, port, if_exists=True):
|
||||
|
||||
Args:
|
||||
br: A string - bridge name (If bridge is None, port is removed from whatever bridge contains it)
|
||||
port: A string - port name (Required argument)
|
||||
port: A string - port name.
|
||||
if_exists: Bool, if False - attempting to delete a por that does not exist returns False. (Default True)
|
||||
|
||||
Returns:
|
||||
@ -243,6 +243,9 @@ def port_list(br):
|
||||
'''
|
||||
Lists all of the ports within bridge.
|
||||
|
||||
Args:
|
||||
br: A string - bridge name.
|
||||
|
||||
Returns:
|
||||
List of bridges (or empty list), False on failure.
|
||||
|
||||
@ -258,3 +261,188 @@ def port_list(br):
|
||||
retcode = result['retcode']
|
||||
stdout = result['stdout']
|
||||
return _stdout_list_split(retcode, stdout)
|
||||
|
||||
|
||||
def port_get_tag(port):
|
||||
'''
|
||||
Lists tags of the port.
|
||||
|
||||
Args:
|
||||
port: A string - port name.
|
||||
|
||||
Returns:
|
||||
List of tags (or empty list), False on failure.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' openvswitch.port_get_tag tap0
|
||||
'''
|
||||
cmd = 'ovs-vsctl get port {0} tag'.format(port)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
retcode = result['retcode']
|
||||
stdout = result['stdout']
|
||||
return _stdout_list_split(retcode, stdout)
|
||||
|
||||
|
||||
def interface_get_options(port):
|
||||
'''
|
||||
Port's interface's optional parameters.
|
||||
|
||||
Args:
|
||||
port: A string - port name.
|
||||
|
||||
Returns:
|
||||
String containing optional parameters of port's interface, False on failure.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' openvswitch.interface_get_options tap0
|
||||
'''
|
||||
cmd = 'ovs-vsctl get interface {0} options'.format(port)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
retcode = result['retcode']
|
||||
stdout = result['stdout']
|
||||
return _stdout_list_split(retcode, stdout)
|
||||
|
||||
|
||||
def interface_get_type(port):
|
||||
'''
|
||||
Type of port's interface.
|
||||
|
||||
Args:
|
||||
port: A string - port name.
|
||||
|
||||
Returns:
|
||||
String - type of interface or empty string, False on failure.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' openvswitch.interface_get_type tap0
|
||||
'''
|
||||
cmd = 'ovs-vsctl get interface {0} type'.format(port)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
retcode = result['retcode']
|
||||
stdout = result['stdout']
|
||||
return _stdout_list_split(retcode, stdout)
|
||||
|
||||
|
||||
def port_create_vlan(br, port, id):
|
||||
'''
|
||||
Isolate VM traffic using VLANs.
|
||||
|
||||
Args:
|
||||
br: A string - bridge name.
|
||||
port: A string - port name.
|
||||
id: An integer in the valid range 0 to 4095 (inclusive), name of VLAN.
|
||||
|
||||
Returns:
|
||||
True on success, else False.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' openvswitch.port_create_vlan br0 tap0 100
|
||||
'''
|
||||
interfaces = __salt__['network.interfaces']()
|
||||
if not 0 <= id <= 4095:
|
||||
return False
|
||||
elif not bridge_exists(br):
|
||||
return False
|
||||
elif port not in interfaces:
|
||||
return False
|
||||
elif port in port_list(br):
|
||||
cmd = 'ovs-vsctl set port {0} tag={1}'.format(port, id)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
return _retcode_to_bool(result['retcode'])
|
||||
else:
|
||||
cmd = 'ovs-vsctl add-port {0} {1} tag={2}'.format(br, port, id)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
return _retcode_to_bool(result['retcode'])
|
||||
|
||||
|
||||
def port_create_gre(br, port, id, remote):
|
||||
'''
|
||||
Generic Routing Encapsulation - creates GRE tunnel between endpoints.
|
||||
|
||||
Args:
|
||||
br: A string - bridge name.
|
||||
port: A string - port name.
|
||||
id: An integer - unsigned 32-bit number, tunnel's key.
|
||||
remote: A string - remote endpoint's IP address.
|
||||
|
||||
Returns:
|
||||
True on success, else False.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' openvswitch.port_create_gre br0 gre1 5001 192.168.1.10
|
||||
'''
|
||||
if not 0 <= id < 2**32:
|
||||
return False
|
||||
elif not __salt__['dig.check_ip'](remote):
|
||||
return False
|
||||
elif not bridge_exists(br):
|
||||
return False
|
||||
elif port in port_list(br):
|
||||
cmd = 'ovs-vsctl set interface {0} type=gre options:remote_ip={1} options:key={2}'.format(port, remote, id)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
return _retcode_to_bool(result['retcode'])
|
||||
else:
|
||||
cmd = 'ovs-vsctl add-port {0} {1} -- set interface {1} type=gre options:remote_ip={2} ' \
|
||||
'options:key={3}'.format(br, port, remote, id)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
return _retcode_to_bool(result['retcode'])
|
||||
|
||||
|
||||
def port_create_vxlan(br, port, id, remote, dst_port=None):
|
||||
'''
|
||||
Virtual eXtensible Local Area Network - creates VXLAN tunnel between endpoints.
|
||||
|
||||
Args:
|
||||
br: A string - bridge name.
|
||||
port: A string - port name.
|
||||
id: An integer - unsigned 64-bit number, tunnel's key.
|
||||
remote: A string - remote endpoint's IP address.
|
||||
dst_port: An integer - port to use when creating tunnelport in the switch.
|
||||
|
||||
Returns:
|
||||
True on success, else False.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
CLI Example:
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' openvswitch.port_create_vxlan br0 vx1 5001 192.168.1.10 8472
|
||||
'''
|
||||
dst_port = ' options:dst_port=' + str(dst_port) if 0 < dst_port <= 65535 else ''
|
||||
if not 0 <= id < 2**64:
|
||||
return False
|
||||
elif not __salt__['dig.check_ip'](remote):
|
||||
return False
|
||||
elif not bridge_exists(br):
|
||||
return False
|
||||
elif port in port_list(br):
|
||||
cmd = 'ovs-vsctl set interface {0} type=vxlan options:remote_ip={1} ' \
|
||||
'options:key={2}{3}'.format(port, remote, id, dst_port)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
return _retcode_to_bool(result['retcode'])
|
||||
else:
|
||||
cmd = 'ovs-vsctl add-port {0} {1} -- set interface {1} type=vxlan options:remote_ip={2} ' \
|
||||
'options:key={3}{4}'.format(br, port, remote, id, dst_port)
|
||||
result = __salt__['cmd.run_all'](cmd)
|
||||
return _retcode_to_bool(result['retcode'])
|
||||
|
@ -40,7 +40,6 @@ def present(name):
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_bridge_created
|
||||
ret['changes'] = changes_bridge_created
|
||||
|
||||
return ret
|
||||
|
||||
@ -90,7 +89,6 @@ def absent(name):
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_bridge_deleted
|
||||
ret['changes'] = changes_bridge_deleted
|
||||
|
||||
return ret
|
||||
|
||||
|
@ -11,16 +11,24 @@ def __virtual__():
|
||||
return 'openvswitch.port_add' in __salt__
|
||||
|
||||
|
||||
def present(name, bridge):
|
||||
def present(name, bridge, type=None, id=None, remote=None, dst_port=None):
|
||||
'''
|
||||
Ensures that the named port exists on bridge, eventually creates it.
|
||||
|
||||
Args:
|
||||
name: The name of the port.
|
||||
bridge: The name of the bridge.
|
||||
type: Optional type of interface to create, currently supports: vlan, vxlan and gre.
|
||||
id: Optional tunnel's key.
|
||||
remote: Remote endpoint's IP address.
|
||||
dst_port: Port to use when creating tunnelport in the switch.
|
||||
|
||||
'''
|
||||
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''}
|
||||
types = ('vlan', 'vxlan', 'gre')
|
||||
|
||||
if type and type not in types:
|
||||
raise TypeError('The optional type argument must be one of these values: {0}.'.format(str(types)))
|
||||
|
||||
bridge_exists = __salt__['openvswitch.bridge_exists'](bridge)
|
||||
|
||||
@ -37,17 +45,131 @@ def present(name, bridge):
|
||||
}
|
||||
}
|
||||
|
||||
comment_vlan_invalid_id = 'VLANs id must be between 0 and 4095.'
|
||||
comment_vlan_invalid_name = 'Could not find network interface {0}.'.format(name)
|
||||
comment_vlan_port_exists = 'Port {0} with access to VLAN {1} already exists on bridge {2}.'.format(name, id, bridge)
|
||||
comment_vlan_created = 'Created port {0} with access to VLAN {1} on bridge {2}.'.format(name, id, bridge)
|
||||
comment_vlan_notcreated = 'Unable to create port {0} with access to VLAN {1} on ' \
|
||||
'bridge {2}.'.format(name, id, bridge)
|
||||
changes_vlan_created = {name: {'old': 'No port named {0} with access to VLAN {1} present on '
|
||||
'bridge {2} present.'.format(name, id, bridge),
|
||||
'new': 'Created port {1} with access to VLAN {2} on '
|
||||
'bridge {0}.'.format(bridge, name, id),
|
||||
}
|
||||
}
|
||||
|
||||
comment_gre_invalid_id = 'Id of GRE tunnel must be an unsigned 32-bit integer.'
|
||||
comment_gre_interface_exists = 'GRE tunnel interface {0} with rempte ip {1} and key {2} ' \
|
||||
'already exists on bridge {3}.'.format(name, remote, id, bridge)
|
||||
comment_gre_created = 'Created GRE tunnel interface {0} with remote ip {1} and key {2} ' \
|
||||
'on bridge {3}.'.format(name, remote, id, bridge)
|
||||
comment_gre_notcreated = 'Unable to create GRE tunnel interface {0} with remote ip {1} and key {2} ' \
|
||||
'on bridge {3}.'.format(name, remote, id, bridge)
|
||||
changes_gre_created = {name: {'old': 'No GRE tunnel interface {0} with remote ip {1} and key {2} '
|
||||
'on bridge {3} present.'.format(name, remote, id, bridge),
|
||||
'new': 'Created GRE tunnel interface {0} with remote ip {1} and key {2} '
|
||||
'on bridge {3}.'.format(name, remote, id, bridge),
|
||||
}
|
||||
}
|
||||
|
||||
comment_dstport = ' (dst_port' + str(dst_port) + ')' if 0 < dst_port <= 65535 else ''
|
||||
comment_vxlan_invalid_id = 'Id of VXLAN tunnel must be an unsigned 64-bit integer.'
|
||||
comment_vxlan_interface_exists = 'VXLAN tunnel interface {0} with rempte ip {1} and key {2} ' \
|
||||
'already exists on bridge {3}{4}.'.format(name, remote, id, bridge, comment_dstport)
|
||||
comment_vxlan_created = 'Created VXLAN tunnel interface {0} with remote ip {1} and key {2} ' \
|
||||
'on bridge {3}{4}.'.format(name, remote, id, bridge, comment_dstport)
|
||||
comment_vxlan_notcreated = 'Unable to create VXLAN tunnel interface {0} with remote ip {1} and key {2} ' \
|
||||
'on bridge {3}{4}.'.format(name, remote, id, bridge, comment_dstport)
|
||||
changes_vxlan_created = {name: {'old': 'No VXLAN tunnel interface {0} with remote ip {1} and key {2} '
|
||||
'on bridge {3}{4} present.'.format(name, remote, id, bridge, comment_dstport),
|
||||
'new': 'Created VXLAN tunnel interface {0} with remote ip {1} and key {2} '
|
||||
'on bridge {3}{4}.'.format(name, remote, id, bridge, comment_dstport),
|
||||
}
|
||||
}
|
||||
comment_invalid_ip = 'Remote is not valid ip address.'
|
||||
|
||||
# Check VLANs attributes
|
||||
def _check_vlan():
|
||||
tag = __salt__['openvswitch.port_get_tag'](name)
|
||||
interfaces = __salt__['network.interfaces']()
|
||||
if not 0 <= id <= 4095:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_vlan_invalid_id
|
||||
elif name not in interfaces:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_vlan_invalid_name
|
||||
elif tag and name in port_list:
|
||||
try:
|
||||
if int(tag[0]) == id:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_vlan_port_exists
|
||||
except (ValueError, KeyError):
|
||||
pass
|
||||
|
||||
# Check GRE tunnels attributes
|
||||
def _check_gre():
|
||||
interface_options = __salt__['openvswitch.interface_get_options'](name)
|
||||
interface_type = __salt__['openvswitch.interface_get_type'](name)
|
||||
if not 0 <= id <= 2**32:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_gre_invalid_id
|
||||
elif not __salt__['dig.check_ip'](remote):
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_invalid_ip
|
||||
elif interface_options and interface_type and name in port_list:
|
||||
interface_attroptions = '{key=\"' + str(id) + '\", remote_ip=\"' + str(remote) + '\"}'
|
||||
try:
|
||||
if interface_type[0] == 'gre' and interface_options[0] == interface_attroptions:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_gre_interface_exists
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Check VXLAN tunnels attributes
|
||||
def _check_vxlan():
|
||||
interface_options = __salt__['openvswitch.interface_get_options'](name)
|
||||
interface_type = __salt__['openvswitch.interface_get_type'](name)
|
||||
if not 0 <= id <= 2**64:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_vxlan_invalid_id
|
||||
elif not __salt__['dig.check_ip'](remote):
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_invalid_ip
|
||||
elif interface_options and interface_type and name in port_list:
|
||||
opt_port = 'dst_port=\"' + str(dst_port) + '\", ' if 0 < dst_port <= 65535 else ''
|
||||
interface_attroptions = '{{{0}key=\"'.format(opt_port) + str(id) + '\", remote_ip=\"' + str(remote) + '\"}'
|
||||
try:
|
||||
if interface_type[0] == 'vxlan' and interface_options[0] == interface_attroptions:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_vxlan_interface_exists
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Dry run, test=true mode
|
||||
if __opts__['test']:
|
||||
if bridge_exists:
|
||||
if name in port_list:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_port_exists
|
||||
if type == 'vlan':
|
||||
_check_vlan()
|
||||
if not ret['comment']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_vlan_created
|
||||
elif type == 'vxlan':
|
||||
_check_vxlan()
|
||||
if not ret['comment']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_vxlan_created
|
||||
elif type == 'gre':
|
||||
_check_gre()
|
||||
if not ret['comment']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_gre_created
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_port_created
|
||||
ret['changes'] = changes_port_created
|
||||
|
||||
if name in port_list:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_port_exists
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_port_created
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_bridge_notexists
|
||||
@ -55,18 +177,52 @@ def present(name, bridge):
|
||||
return ret
|
||||
|
||||
if bridge_exists:
|
||||
if name in port_list:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_port_exists
|
||||
if type == 'vlan':
|
||||
_check_vlan()
|
||||
if not ret['comment']:
|
||||
port_create_vlan = __salt__['openvswitch.port_create_vlan'](bridge, name, id)
|
||||
if port_create_vlan:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_vlan_created
|
||||
ret['changes'] = changes_vlan_created
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_vlan_notcreated
|
||||
elif type == 'vxlan':
|
||||
_check_vxlan()
|
||||
if not ret['comment']:
|
||||
port_create_vxlan = __salt__['openvswitch.port_create_vxlan'](bridge, name, id, remote, dst_port)
|
||||
if port_create_vxlan:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_vxlan_created
|
||||
ret['changes'] = changes_vxlan_created
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_vxlan_notcreated
|
||||
elif type == 'gre':
|
||||
_check_gre()
|
||||
if not ret['comment']:
|
||||
port_create_gre = __salt__['openvswitch.port_create_gre'](bridge, name, id, remote)
|
||||
if port_create_gre:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_gre_created
|
||||
ret['changes'] = changes_gre_created
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_gre_notcreated
|
||||
else:
|
||||
port_add = __salt__['openvswitch.port_add'](bridge, name)
|
||||
if port_add:
|
||||
if name in port_list:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_port_created
|
||||
ret['changes'] = changes_port_created
|
||||
ret['comment'] = comment_port_exists
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_port_notcreated
|
||||
port_add = __salt__['openvswitch.port_add'](bridge, name)
|
||||
if port_add:
|
||||
ret['result'] = True
|
||||
ret['comment'] = comment_port_created
|
||||
ret['changes'] = changes_port_created
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_port_notcreated
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = comment_bridge_notexists
|
||||
@ -116,7 +272,6 @@ def absent(name, bridge=None):
|
||||
else:
|
||||
ret['result'] = None
|
||||
ret['comment'] = comment_port_deleted
|
||||
ret['changes'] = changes_port_deleted
|
||||
return ret
|
||||
|
||||
if bridge and not bridge_exists:
|
||||
|
Loading…
Reference in New Issue
Block a user