salt/salt/modules/lvs.py
Chris Rebert d8c26763ae modules.lvs: use alias to avoid shadowing list built-in type
salt/modules/lvs.py:353: [W0622(redefined-builtin), list] Redefining built-in 'list'
2013-12-03 15:27:37 -08:00

472 lines
12 KiB
Python

# -*- coding: utf-8 -*-
'''
Support for LVS (Linux Virtual Server)
'''
# Import python libs
# Import salt libs
import salt.utils
import salt.utils.decorators as decorators
from salt.exceptions import SaltException
__func_alias__ = {
'list_': 'list'
}
# Cache the output of running which('ipvsadm')
@decorators.memoize
def __detect_os():
return salt.utils.which('ipvsadm')
def __virtual__():
'''
Only load if ipvsadm command exists on the system.
'''
if not __detect_os():
return False
return 'lvs'
def _build_cmd(**kwargs):
'''
Build a well-formatted ipvsadm command based on kwargs.
'''
cmd = ''
if 'service_address' in kwargs:
if kwargs['service_address']:
if 'protocol' in kwargs:
if kwargs['protocol'] == 'tcp':
cmd += ' -t {0}'.format(kwargs['service_address'])
elif kwargs['protocol'] == 'udp':
cmd += ' -u {0}'.format(kwargs['service_address'])
elif kwargs['protocol'] == 'fwmark':
cmd += ' -f {0}'.format(kwargs['service_address'])
else:
raise SaltException('Error: Only support tcp, udp and fwmark service protocol')
del kwargs['protocol']
else:
raise SaltException('Error: protocol should specified')
if 'scheduler' in kwargs:
if kwargs['scheduler']:
cmd += ' -s {0}'.format(kwargs['scheduler'])
del kwargs['scheduler']
else:
raise SaltException('Error: service_address should specified')
del kwargs['service_address']
if 'server_address' in kwargs:
if kwargs['server_address']:
cmd += ' -r {0}'.format(kwargs['server_address'])
if 'packet_forward_method' in kwargs and kwargs['packet_forward_method']:
if kwargs['packet_forward_method'] == 'dr':
cmd += ' -g'
elif kwargs['packet_forward_method'] == 'tunnel':
cmd += ' -i'
elif kwargs['packet_forward_method'] == 'nat':
cmd += ' -m'
else:
raise SaltException('Error: only support dr, tunnel and nat')
del kwargs['packet_forward_method']
if 'weight' in kwargs and kwargs['weight']:
cmd += ' -w {0}'.format(kwargs['weight'])
del kwargs['weight']
else:
raise SaltException('Error: server_address should specified')
del kwargs['server_address']
return cmd
def add_service(protocol=None, service_address=None, scheduler='wlc'):
'''
Add a virtual service.
protocol
The service protocol(only support tcp, udp and fwmark service).
service_address
The LVS service address.
scheduler
Algorithm for allocating TCP connections and UDP datagrams to real servers.
CLI Example:
.. code-block:: bash
salt '*' lvs.add_service tcp 1.1.1.1:80 rr
'''
cmd = '{0} -A {1}'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address,
scheduler=scheduler))
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def edit_service(protocol=None, service_address=None, scheduler=None):
'''
Edit the virtual service.
protocol
The service protocol(only support tcp, udp and fwmark service).
service_address
The LVS service address.
scheduler
Algorithm for allocating TCP connections and UDP datagrams to real servers.
CLI Example:
.. code-block:: bash
salt '*' lvs.edit_service tcp 1.1.1.1:80 rr
'''
cmd = '{0} -E {1}'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address,
scheduler=scheduler))
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def delete_service(protocol=None, service_address=None):
'''
Delete the virtual service.
protocol
The service protocol(only support tcp, udp and fwmark service).
service_address
The LVS service address.
CLI Example:
.. code-block:: bash
salt '*' lvs.delete_service tcp 1.1.1.1:80
'''
cmd = '{0} -D {1}'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address))
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def add_server(protocol=None, service_address=None, server_address=None, packet_forward_method='dr', weight=1, **kwargs):
'''
Add a real server to a virtual service.
protocol
The service protocol(only support ``tcp``, ``udp`` and ``fwmark`` service).
service_address
The LVS service address.
server_address
The real server address.
packet_forward_method
The LVS packet forwarding method(``dr`` for direct routing, ``tunnel`` for tunneling, ``nat`` for network access translation).
weight
The capacity of a server relative to the others in the pool.
CLI Example:
.. code-block:: bash
salt '*' lvs.add_server tcp 1.1.1.1:80 192.168.0.11:8080 nat 1
'''
cmd = '{0} -a {1}'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address,
server_address=server_address,
packet_forward_method=packet_forward_method,
weight=weight,
**kwargs))
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def edit_server(protocol=None, service_address=None, server_address=None, packet_forward_method=None, weight=None, **kwargs):
'''
Edit a real server to a virtual service.
protocol
The service protocol(only support ``tcp``, ``udp`` and ``fwmark`` service).
service_address
The LVS service address.
server_address
The real server address.
packet_forward_method
The LVS packet forwarding method(``dr`` for direct routing, ``tunnel`` for tunneling, ``nat`` for network access translation).
weight
The capacity of a server relative to the others in the pool.
CLI Example:
.. code-block:: bash
salt '*' lvs.edit_server tcp 1.1.1.1:80 192.168.0.11:8080 nat 1
'''
cmd = '{0} -e {1}'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address,
server_address=server_address,
packet_forward_method=packet_forward_method,
weight=weight,
**kwargs))
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def delete_server(protocol=None, service_address=None, server_address=None):
'''
Delete the realserver from the virtual service.
protocol
The service protocol(only support ``tcp``, ``udp`` and ``fwmark`` service).
service_address
The LVS service address.
server_address
The real server address.
CLI Example:
.. code-block:: bash
salt '*' lvs.delete_server tcp 1.1.1.1:80 192.168.0.11:8080
'''
cmd = '{0} -d {1}'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address,
server_address=server_address))
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def clear():
'''
Clear the virtual server table
CLI Example:
.. code-block:: bash
salt '*' lvs.clear
'''
cmd = '{0} -C'.format(__detect_os())
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def get_rules():
'''
Get the virtual server rules
CLI Example:
.. code-block:: bash
salt '*' lvs.get_rules
'''
cmd = '{0} -S -n'.format(__detect_os())
ret = __salt__['cmd.run'](cmd)
return ret
def list_(protocol=None, service_address=None):
'''
List the virtual server table if service_address is not specified. If a service_address is selected, list this service only.
CLI Example:
.. code-block:: bash
salt '*' lvs.list
'''
if service_address:
cmd = '{0} -L {1} -n'.format(__detect_os(),
_build_cmd(protocol=protocol,
service_address=service_address))
else:
cmd = '{0} -L -n'.format(__detect_os())
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = out['stdout'].strip()
return ret
def zero(protocol=None, service_address=None):
'''
Zero the packet, byte and rate counters in a service or all services.
CLI Example:
.. code-block:: bash
salt '*' lvs.zero
'''
if service_address:
cmd = '{0} -Z {1}'.format(__detect_os(),
_build_cmd(protocol=None,
service_address=None))
else:
cmd = '{0} -Z'.format(__detect_os())
out = __salt__['cmd.run_all'](cmd)
# A non-zero return code means fail
if out['retcode']:
ret = out['stderr'].strip()
else:
ret = True
return ret
def check_service(protocol=None, service_address=None, **kwargs):
'''
Check the virtual service exists.
CLI Example:
.. code-block:: bash
salt '*' lvs.check_service tcp 1.1.1.1:80
'''
cmd = '{0}'.format(_build_cmd(protocol=protocol,
service_address=service_address,
**kwargs))
# Exact match
if not kwargs:
cmd += ' '
all_rules = get_rules()
out = all_rules.find(cmd)
if out != -1:
ret = True
else:
ret = 'Error: service not exists'
return ret
def check_server(protocol=None, service_address=None, server_address=None, **kwargs):
'''
Check the real server exists in the specified service.
CLI Example:
.. code-block:: bash
salt '*' lvs.check_server tcp 1.1.1.1:80 192.168.0.11:8080
'''
cmd = '{0}'.format(_build_cmd(protocol=protocol,
service_address=service_address,
server_address=server_address,
**kwargs))
# Exact match
if not kwargs:
cmd += ' '
all_rules = get_rules()
out = all_rules.find(cmd)
if out != -1:
ret = True
else:
ret = 'Error: server not exists'
return ret