%PDF- %PDF-
Direktori : /proc/self/root/proc/thread-self/root/lib/python2.7/site-packages/salt/runners/ |
Current File : //proc/self/root/proc/thread-self/root/lib/python2.7/site-packages/salt/runners/f5.py |
# -*- coding: utf-8 -*- ''' Runner to provide F5 Load Balancer functionality :depends: - pycontrol Python module :configuration: In order to connect to a F5 Load Balancer, you must specify in the Salt master configuration the currently available load balancers .. code-block:: yaml load_balancers: bigip1.example.com username: admin password: secret bigip2.example.com: username: admin password: secret ''' from __future__ import absolute_import, print_function, unicode_literals # Import salt libs from salt.exceptions import CommandExecutionError # Import third party libs try: import pycontrol.pycontrol as f5 HAS_PYCONTROL = True except ImportError: HAS_PYCONTROL = False def __virtual__(): if not HAS_PYCONTROL: return False return True class F5Mgmt(object): def __init__(self, lb, username, password): self.lb = lb self.username = username self.password = password self._connect() def _connect(self): ''' Connect to F5 ''' try: self.bigIP = f5.BIGIP(hostname=self.lb, username=self.username, password=self.password, fromurl=True, wsdls=['LocalLB.VirtualServer', 'LocalLB.Pool']) except Exception: raise Exception( 'Unable to connect to {0}'.format(self.lb) ) return True def create_vs(self, name, ip, port, protocol, profile, pool_name): ''' Create a virtual server ''' vs = self.bigIP.LocalLB.VirtualServer vs_def = vs.typefactory.create('Common.VirtualServerDefinition') vs_def.name = name vs_def.address = ip vs_def.port = port common_protocols = vs.typefactory.create('Common.ProtocolType') p = [i[0] for i in common_protocols if i[0].split('_')[1] == protocol.upper()] if p: vs_def.protocol = p else: raise CommandExecutionError('Unknown protocol') vs_def_seq = vs.typefactory.create('Common.VirtualServerSequence') vs_def_seq.item = [vs_def] vs_type = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerType' ) vs_resource = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerResource' ) vs_resource.type = vs_type.RESOURCE_TYPE_POOL vs_resource.default_pool_name = pool_name resource_seq = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerResourceSequence' ) resource_seq.item = [vs_resource] vs_context = vs.typefactory.create('LocalLB.ProfileContextType') vs_profile = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerProfile' ) vs_profile.profile_context = vs_context.PROFILE_CONTEXT_TYPE_ALL vs_profile.profile_name = protocol vs_profile_http = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerProfile' ) vs_profile_http.profile_name = profile vs_profile_conn = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerProfile' ) vs_profile_conn.profile_name = 'oneconnect' vs_profile_seq = vs.typefactory.create( 'LocalLB.VirtualServer.VirtualServerProfileSequence' ) vs_profile_seq.item = [vs_profile, vs_profile_http, vs_profile_conn] try: vs.create(definitions=vs_def_seq, wildmasks=['255.255.255.255'], resources=resource_seq, profiles=[vs_profile_seq]) except Exception as e: raise Exception( 'Unable to create `{0}` virtual server\n\n{1}'.format(name, e) ) return True def create_pool(self, name, method='ROUND_ROBIN'): ''' Create a pool on the F5 load balancer ''' lbmethods = self.bigIP.LocalLB.Pool.typefactory.create( 'LocalLB.LBMethod' ) supported_method = [i[0] for i in lbmethods if ( i[0].split('_', 2)[-1] == method.upper() )] if supported_method and not self.check_pool(name): try: self.bigIP.LocalLB.Pool.create(pool_names=[name], lb_methods=[supported_method], members=[[]]) except Exception as e: raise Exception( 'Unable to create `{0}` pool\n\n{1}'.format(name, e) ) else: raise Exception('Unsupported method') return True def add_pool_member(self, name, port, pool_name): ''' Add a node to a pool ''' if not self.check_pool(pool_name): raise CommandExecutionError( '{0} pool does not exists'.format(pool_name) ) members_seq = self.bigIP.LocalLB.Pool.typefactory.create( 'Common.IPPortDefinitionSequence' ) members_seq.items = [] member = self.bigIP.LocalLB.Pool.typefactory.create( 'Common.IPPortDefinition' ) member.address = name member.port = port members_seq.items.append(member) try: self.bigIP.LocalLB.Pool.add_member(pool_names=[pool_name], members=[members_seq]) except Exception as e: raise Exception( 'Unable to add `{0}` to `{1}`\n\n{2}'.format(name, pool_name, e) ) return True def check_pool(self, name): ''' Check to see if a pool exists ''' pools = self.bigIP.LocalLB.Pool for pool in pools.get_list(): if pool.split('/')[-1] == name: return True return False def check_virtualserver(self, name): ''' Check to see if a virtual server exists ''' vs = self.bigIP.LocalLB.VirtualServer for v in vs.get_list(): if v.split('/')[-1] == name: return True return False def check_member_pool(self, member, pool_name): ''' Check a pool member exists in a specific pool ''' members = self.bigIP.LocalLB.Pool.get_member(pool_names=[pool_name])[0] for mem in members: if member == mem.address: return True return False def lbmethods(self): ''' List all the load balancer methods ''' methods = self.bigIP.LocalLB.Pool.typefactory.create( 'LocalLB.LBMethod' ) return [method[0].split('_', 2)[-1] for method in methods] def create_vs(lb, name, ip, port, protocol, profile, pool_name): ''' Create a virtual server CLI Examples: .. code-block:: bash salt-run f5.create_vs lbalancer vs_name 10.0.0.1 80 tcp http poolname ''' if __opts__['load_balancers'].get(lb, None): (username, password) = list(__opts__['load_balancers'][lb].values()) else: raise Exception('Unable to find `{0}` load balancer'.format(lb)) F5 = F5Mgmt(lb, username, password) F5.create_vs(name, ip, port, protocol, profile, pool_name) return True def create_pool(lb, name, method='ROUND_ROBIN'): ''' Create a pool on the F5 load balancer CLI Examples: .. code-block:: bash salt-run f5.create_pool load_balancer pool_name loadbalance_method salt-run f5.create_pool load_balancer my_pool ROUND_ROBIN ''' if __opts__['load_balancers'].get(lb, None): (username, password) = list(__opts__['load_balancers'][lb].values()) else: raise Exception('Unable to find `{0}` load balancer'.format(lb)) F5 = F5Mgmt(lb, username, password) F5.create_pool(name, method) return True def add_pool_member(lb, name, port, pool_name): ''' Add a node to a pool CLI Examples: .. code-block:: bash salt-run f5.add_pool_member load_balancer 10.0.0.1 80 my_pool ''' if __opts__['load_balancers'].get(lb, None): (username, password) = list(__opts__['load_balancers'][lb].values()) else: raise Exception('Unable to find `{0}` load balancer'.format(lb)) F5 = F5Mgmt(lb, username, password) F5.add_pool_member(name, port, pool_name) return True def check_pool(lb, name): ''' Check to see if a pool exists CLI Examples: .. code-block:: bash salt-run f5.check_pool load_balancer pool_name ''' if __opts__['load_balancers'].get(lb, None): (username, password) = list(__opts__['load_balancers'][lb].values()) else: raise Exception('Unable to find `{0}` load balancer'.format(lb)) F5 = F5Mgmt(lb, username, password) return F5.check_pool(name) def check_virtualserver(lb, name): ''' Check to see if a virtual server exists CLI Examples: .. code-block:: bash salt-run f5.check_virtualserver load_balancer virtual_server ''' if __opts__['load_balancers'].get(lb, None): (username, password) = list(__opts__['load_balancers'][lb].values()) else: raise Exception('Unable to find `{0}` load balancer'.format(lb)) F5 = F5Mgmt(lb, username, password) return F5.check_virtualserver(name) def check_member_pool(lb, member, pool_name): ''' Check a pool member exists in a specific pool CLI Examples: .. code-block:: bash salt-run f5.check_member_pool load_balancer 10.0.0.1 my_pool ''' if __opts__['load_balancers'].get(lb, None): (username, password) = list(__opts__['load_balancers'][lb].values()) else: raise Exception('Unable to find `{0}` load balancer'.format(lb)) F5 = F5Mgmt(lb, username, password) return F5.check_member_pool(member, pool_name)