def execute(self, action, actionargs=None, vs=None, rs=None): """ Execute an action. """ if action not in [ "enable", "disable", "operenable", "operdisable", "enableall", "disableall" ]: yield None return v, httpclass, rip, port = self.parse(vs, rs) if rip is None: yield {} return orip = ip2oid(rip) if action == "enableall" or action == "disableall": d = defer.waitForDeferred( self.proxy.set( (self.oids['ltmNodeAddrNewSessionEnable'], orip), (action == "enableall") and 2 or 1)) yield d d.getResult() yield True return # Get pool ov = str2oid(v) if httpclass is None: p = defer.waitForDeferred( self.cache_or_get(('ltmVirtualServDefaultPool', ov))) else: oc = str2oid(httpclass) p = defer.waitForDeferred( self.cache_or_get(('ltmHttpClassPoolName', oc))) yield p p = p.getResult() op = str2oid(p) d = defer.waitForDeferred( self.proxy.set( (self.oids['ltmPoolMemberNewSessionEnable'], op, orip, port), action.endswith("enable") and 2 or 1)) yield d d.getResult() yield True return
def execute(self, action, actionargs=None, vs=None, rs=None): """ Execute an action. """ if action not in ["enable", "disable", "operenable", "operdisable", "enableall", "disableall"]: yield None return v, httpclass, rip, port = self.parse(vs, rs) if rip is None: yield {} return orip = ip2oid(rip) if action == "enableall" or action == "disableall": d = defer.waitForDeferred( self.proxy.set((self.oids['ltmNodeAddrNewSessionEnable'], orip), (action == "enableall") and 2 or 1)) yield d d.getResult() yield True return # Get pool ov = str2oid(v) if httpclass is None: p = defer.waitForDeferred(self.cache_or_get(('ltmVirtualServDefaultPool', ov))) else: oc = str2oid(httpclass) p = defer.waitForDeferred(self.cache_or_get(('ltmHttpClassPoolName', oc))) yield p p = p.getResult() op = str2oid(p) d = defer.waitForDeferred( self.proxy.set((self.oids['ltmPoolMemberNewSessionEnable'], op, orip, port), action.endswith("enable") and 2 or 1)) yield d d.getResult() yield True return
def process_rs(self, owner, content, service, backup=False): """ Process data for a given virtual server and real server. @param service: service name @param backup: C{False} or a string representing backup position C{None} is we don't know if it is a backup or not @return: a deferred C{IRealServer} or None """ oservice = str2oid(service) # Retrieve some data if needed: oids = [] for o in self.oids: if o.startswith("apSvc"): oids.append((o, oservice)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # Is it a backup? if backup is None: oowner = str2oid(owner) ocontent = str2oid(content) for b in ["primary", "second"]: s = defer.waitForDeferred( self.cache_or_get(('apCnt%sSorryServer' % b.capitalize(), oowner, ocontent))) yield s s = s.getResult() if s and s == service: backup = b break if backup is None: backup = False # Build the real server rip = self.cache(('apSvcIPAddress', oservice)) rport = self.cache(('apSvcPort', oservice)) protocol = self.protocols[ self.cache(('apSvcIPProtocol', oservice))] state = self.states[ self.cache(('apSvcState', oservice))] if not backup: weight = self.cache(('apSvcWeight', oservice)) rs = RealServer(service, rip, rport, protocol, weight, state) else: rs = SorryServer(service, rip, rport, protocol, state) rs.extra["backup type"] = backup rs.extra["KAL type"] = self.kals[ self.cache(('apSvcKALType', oservice))] for key, oid in [ ('KAL frequency', 'apSvcKALFrequency'), ('KAL max failure', 'apSvcKALMaxFailure'), ('KAL retry period', 'apSvcKALRetryPeriod'), ('KAL URI', 'apSvcKALUri'), ('KAL port', 'apSvcKALPort') ]: try: rs.extra[key] = self.cache((oid, oservice)) except KeyError: pass yield rs return
def process_vs(self, owner, content): """ Process data for a given virtual server when no real server is provided @param owner: owner of the content @param content: content name @return: a deferred C{IVirtualServer} or None """ oowner = str2oid(owner) ocontent = str2oid(content) # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("apCnt") and not o.startswith("apCntsvc"): oids.append((o, oowner, ocontent)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # Let's build our virtual server vip = "%s:%d" % tuple(self.cache(('apCntIPAddress', oowner, ocontent), ('apCntPort', oowner, ocontent))) protocol = self.protocols[self.cache(('apCntIPProtocol', oowner, ocontent))] mode = self.modes[self.cache(('apCntBalance', oowner, ocontent))] vs = VirtualServer(content, vip, protocol, mode) # Add some extra information vs.extra["URL"] = self.cache(('apCntUrl', oowner, ocontent)) vs.extra["sticky"] = self.sticky[ self.cache(('apCntSticky', oowner, ocontent))] vs.extra["virtual server status"] = self.status[ self.cache(('apCntEnable', oowner, ocontent))] and "up" or "down" vs.extra["persistence"] = self.status[ self.cache(('apCntPersistence', oowner, ocontent))] and "enabled" or "disabled" vs.extra["content type"] = self.contents[ self.cache(('apCntContentType', oowner, ocontent))] # Find and attach real servers if not self.is_cached(('apCntsvcSvcName', oowner, ocontent)): services = defer.waitForDeferred( self.proxy.walk("%s.%s.%s" % (self.oids['apCntsvcSvcName'], oowner, ocontent))) yield services services.getResult() for r in self.cache(('apCntsvcSvcName', oowner, ocontent)): service = oid2str(r) rs = defer.waitForDeferred(self.process_rs(owner, content, service)) yield rs rs = rs.getResult() if rs is not None: vs.realservers[service] = rs # Add backups for backup in ["primary", "second"]: service = self.cache(('apCnt%sSorryServer' % backup.capitalize(), oowner, ocontent)) if not service: continue rs = defer.waitForDeferred(self.process_rs(owner, content, service, backup)) yield rs rs = rs.getResult() if rs is not None: vs.realservers[service] = rs yield vs return
def process_rs(self, v, httpclass, rip, port): """ Process data for a given virtual server and real server. @param v: virtual server @param httpclass: HTTP class (or C{None} for default pool) @param rip: real IP @param port: port """ # Retrieve some data if needed: ov = str2oid(v) orip = ip2oid(rip) if httpclass is None: p = defer.waitForDeferred(self.cache_or_get(('ltmVirtualServDefaultPool', ov))) else: oc = str2oid(httpclass) p = defer.waitForDeferred(self.cache_or_get(('ltmHttpClassPoolName', oc))) yield p p = p.getResult() op = str2oid(p) oids = [] for o in self.oids: if o.startswith("ltmPoolMbr") or o.startswith("ltmPoolMember"): oids.append((o, op, orip, port)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() oids = [] for o in self.oids: if o.startswith("ltmNodeAddr"): oids.append((o, orip)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() name = self.cache(('ltmNodeAddrScreenName', orip)) protocol = defer.waitForDeferred(self.get_protocol(ov)) yield protocol protocol = protocol.getResult() weight = self.cache(('ltmPoolMemberWeight', op, orip, port)) avail, enabled, session = self.cache( ('ltmPoolMbrStatusAvailState', op, orip, port), ('ltmPoolMbrStatusEnabledState', op, orip, port), ('ltmPoolMemberSessionStatus', op, orip, port)) if session != 1 or self.enabledstates[enabled] != "enabled": state = "disabled" else: state = self.availstates[avail] rs = RealServer(name, rip, port, protocol, weight, state) rs.extra["detailed reason"] = self.cache(('ltmPoolMbrStatusDetailReason', op, orip, port)) rs.extra["monitor rule"] = self.cache(('ltmPoolMemberMonitorRule', op, orip, port)) # Actions if self.proxy.writable: # ltmPoolMemberNewSessionEnable == 1 means user disabled if self.cache(('ltmPoolMemberNewSessionEnable', op, orip, port)) != 1: rs.actions['disable'] = 'Disable (permanent)' else: rs.actions['enable'] = 'Enable (permanent)' if self.cache(('ltmNodeAddrNewSessionEnable', orip)) != 1: rs.actions['disableall'] = 'Disable globally (permanent)' else: rs.actions['enableall'] = 'Enable globally (permanent)' yield rs return
def process_vs(self, v, httpclass): """ Process data for a given virtual server when no real server is provided @param v: virtual server @param httpclass: HTTP class to use (or C{None} for default pool) to select pool @return: a maybe deferred C{IVirtualServer} """ ov = str2oid(v) # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("ltmVirtualServ") or o.startswith("ltmVs"): if not o.startswith("ltmVirtualServProfile"): oids.append((o, ov)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # IPv6 or IPv4 virtual server if self.cache(('ltmVirtualServAddrType', ov)) not in [1, 2]: log.msg("In %r, unknown address type for virtual server %s, skip it" % (self.lb.name, v)) yield None return # Get pool if httpclass is None: p = self.cache(('ltmVirtualServDefaultPool', ov)) if not p: log.msg("In %r, no pool for %s, skip it" % (self.lb.name, v)) yield None return else: oc = str2oid(httpclass) p = defer.waitForDeferred(self.cache_or_get(('ltmHttpClassPoolName', oc))) yield p p = p.getResult() if not p: log.msg("In %r, no pool for %s (class %s), skip it" % (self.lb.name, v, httpclass)) yield None return op = str2oid(p) oids = [] for o in self.oids: if o.startswith("ltmPool") and not o.startswith("ltmPoolMbr") and \ not o.startswith("ltmPoolMember"): oids.append((o, op)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() if self.cache(('ltmVirtualServAddrType', ov)) == 1: vip = "%s:%d" % (socket.inet_ntop(socket.AF_INET, self.cache(('ltmVirtualServAddr', ov))), self.cache(('ltmVirtualServPort', ov))) else: vip = "[%s]:%d" % (socket.inet_ntop(socket.AF_INET6, self.cache(('ltmVirtualServAddr', ov))), self.cache(('ltmVirtualServPort', ov))) protocol = defer.waitForDeferred(self.get_protocol(ov)) yield protocol protocol = protocol.getResult() mode = self.modes[self.cache(('ltmPoolLbMode', op))] vs = VirtualServer(httpclass is None and v or ("%s;%s" % (v, httpclass)), vip, protocol, mode) if httpclass: vs.extra["http class"] = httpclass vs.extra["vs availability state"] = \ self.availstates[self.cache(('ltmVsStatusAvailState', ov))] vs.extra["vs enabled state"] = \ self.enabledstates[self.cache(('ltmVsStatusEnabledState', ov))] vs.extra["virtual server detailed reason"] = \ self.cache(('ltmVsStatusDetailReason', ov)) vs.extra["address translation"] = \ self.cache(('ltmVirtualServTranslateAddr', ov)) == 1 and "enabled" or "disabled" vs.extra["pool name"] = p vs.extra["pool availability state"] = \ self.availstates[self.cache(('ltmPoolStatusAvailState', op))] vs.extra["pool enabled state"] = \ self.enabledstates[self.cache(('ltmPoolStatusEnabledState', op))] vs.extra["pool detailed reason"] = \ self.cache(('ltmPoolStatusDetailReason', op)) # Find and attach real servers if not self.is_cached(('ltmPoolMbrStatusAvailState', op)): for o in self.oids: if o.startswith('ltmPoolMbr') or o.startswith('ltmPoolMember'): # F5 is buggy here, we need to walk all pool members # pm = defer.waitForDeferred( # self.proxy.walk("%s.%s" % (self.oids[o], op))) pm = defer.waitForDeferred( self.proxy.walk(self.oids[o])) yield pm pm.getResult() if not self.is_cached(('ltmPoolMbrStatusAvailState', op)): print "pool %s is empty..." % p yield None return for r in self.cache(('ltmPoolMbrStatusAvailState', op)): rip = socket.inet_ntop(r[0] == 1 and socket.AF_INET or socket.AF_INET6, struct.pack("B"*r[1], *r[-(r[1]+1):-1])) port = r[-1] rs = defer.waitForDeferred(self.process_rs(v, httpclass, rip, port)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["%s,%d" % (rip, port)] = rs yield vs return
def process_rs(self, owner, content, service, backup=False): """ Process data for a given virtual server and real server. @param service: service name @param backup: C{False} or a string representing backup position C{None} is we don't know if it is a backup or not @return: a deferred C{IRealServer} or None """ oservice = str2oid(service) # Retrieve some data if needed: oids = [] for o in self.oids: if o.startswith("apSvc"): oids.append((o, oservice)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # Is it a backup? if backup is None: oowner = str2oid(owner) ocontent = str2oid(content) for b in ["primary", "second"]: s = defer.waitForDeferred( self.cache_or_get(('apCnt%sSorryServer' % b.capitalize(), oowner, ocontent))) yield s s = s.getResult() if s and s == service: backup = b break if backup is None: backup = False # Build the real server rip = self.cache(('apSvcIPAddress', oservice)) rport = self.cache(('apSvcPort', oservice)) protocol = self.protocols[self.cache(('apSvcIPProtocol', oservice))] state = self.states[self.cache(('apSvcState', oservice))] if not backup: weight = self.cache(('apSvcWeight', oservice)) rs = RealServer(service, rip, rport, protocol, weight, state) else: rs = SorryServer(service, rip, rport, protocol, state) rs.extra["backup type"] = backup rs.extra["KAL type"] = self.kals[self.cache( ('apSvcKALType', oservice))] for key, oid in [('KAL frequency', 'apSvcKALFrequency'), ('KAL max failure', 'apSvcKALMaxFailure'), ('KAL retry period', 'apSvcKALRetryPeriod'), ('KAL URI', 'apSvcKALUri'), ('KAL port', 'apSvcKALPort')]: try: rs.extra[key] = self.cache((oid, oservice)) except KeyError: pass yield rs return
def process_vs(self, owner, content): """ Process data for a given virtual server when no real server is provided @param owner: owner of the content @param content: content name @return: a deferred C{IVirtualServer} or None """ oowner = str2oid(owner) ocontent = str2oid(content) # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("apCnt") and not o.startswith("apCntsvc"): oids.append((o, oowner, ocontent)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # Let's build our virtual server vip = "%s:%d" % tuple( self.cache(('apCntIPAddress', oowner, ocontent), ('apCntPort', oowner, ocontent))) protocol = self.protocols[self.cache( ('apCntIPProtocol', oowner, ocontent))] mode = self.modes[self.cache(('apCntBalance', oowner, ocontent))] vs = VirtualServer(content, vip, protocol, mode) # Add some extra information vs.extra["URL"] = self.cache(('apCntUrl', oowner, ocontent)) vs.extra["sticky"] = self.sticky[self.cache( ('apCntSticky', oowner, ocontent))] vs.extra["virtual server status"] = self.status[self.cache( ('apCntEnable', oowner, ocontent))] and "up" or "down" vs.extra["persistence"] = self.status[self.cache( ('apCntPersistence', oowner, ocontent))] and "enabled" or "disabled" vs.extra["content type"] = self.contents[self.cache( ('apCntContentType', oowner, ocontent))] # Find and attach real servers if not self.is_cached(('apCntsvcSvcName', oowner, ocontent)): services = defer.waitForDeferred( self.proxy.walk( "%s.%s.%s" % (self.oids['apCntsvcSvcName'], oowner, ocontent))) yield services services.getResult() for r in self.cache(('apCntsvcSvcName', oowner, ocontent)): service = oid2str(r) rs = defer.waitForDeferred(self.process_rs(owner, content, service)) yield rs rs = rs.getResult() if rs is not None: vs.realservers[service] = rs # Add backups for backup in ["primary", "second"]: service = self.cache( ('apCnt%sSorryServer' % backup.capitalize(), oowner, ocontent)) if not service: continue rs = defer.waitForDeferred( self.process_rs(owner, content, service, backup)) yield rs rs = rs.getResult() if rs is not None: vs.realservers[service] = rs yield vs return
def process_rs(self, v, httpclass, rip, port): """ Process data for a given virtual server and real server. @param v: virtual server @param httpclass: HTTP class (or C{None} for default pool) @param rip: real IP @param port: port """ # Retrieve some data if needed: ov = str2oid(v) orip = ip2oid(rip) if httpclass is None: p = defer.waitForDeferred( self.cache_or_get(('ltmVirtualServDefaultPool', ov))) else: oc = str2oid(httpclass) p = defer.waitForDeferred( self.cache_or_get(('ltmHttpClassPoolName', oc))) yield p p = p.getResult() op = str2oid(p) oids = [] for o in self.oids: if o.startswith("ltmPoolMbr") or o.startswith("ltmPoolMember"): oids.append((o, op, orip, port)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() oids = [] for o in self.oids: if o.startswith("ltmNodeAddr"): oids.append((o, orip)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() name = self.cache(('ltmNodeAddrScreenName', orip)) protocol = defer.waitForDeferred(self.get_protocol(ov)) yield protocol protocol = protocol.getResult() weight = self.cache(('ltmPoolMemberWeight', op, orip, port)) avail, enabled, session = self.cache( ('ltmPoolMbrStatusAvailState', op, orip, port), ('ltmPoolMbrStatusEnabledState', op, orip, port), ('ltmPoolMemberSessionStatus', op, orip, port)) if session != 1 or self.enabledstates[enabled] != "enabled": state = "disabled" else: state = self.availstates[avail] rs = RealServer(name, rip, port, protocol, weight, state) rs.extra["detailed reason"] = self.cache( ('ltmPoolMbrStatusDetailReason', op, orip, port)) rs.extra["monitor rule"] = self.cache( ('ltmPoolMemberMonitorRule', op, orip, port)) # Actions if self.proxy.writable: # ltmPoolMemberNewSessionEnable == 1 means user disabled if self.cache( ('ltmPoolMemberNewSessionEnable', op, orip, port)) != 1: rs.actions['disable'] = 'Disable (permanent)' else: rs.actions['enable'] = 'Enable (permanent)' if self.cache(('ltmNodeAddrNewSessionEnable', orip)) != 1: rs.actions['disableall'] = 'Disable globally (permanent)' else: rs.actions['enableall'] = 'Enable globally (permanent)' yield rs return
def process_vs(self, v, httpclass): """ Process data for a given virtual server when no real server is provided @param v: virtual server @param httpclass: HTTP class to use (or C{None} for default pool) to select pool @return: a maybe deferred C{IVirtualServer} """ ov = str2oid(v) # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("ltmVirtualServ") or o.startswith("ltmVs"): if not o.startswith("ltmVirtualServProfile"): oids.append((o, ov)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # IPv6 or IPv4 virtual server if self.cache(('ltmVirtualServAddrType', ov)) not in [1, 2]: log.msg( "In %r, unknown address type for virtual server %s, skip it" % (self.lb.name, v)) yield None return # Get pool if httpclass is None: p = self.cache(('ltmVirtualServDefaultPool', ov)) if not p: log.msg("In %r, no pool for %s, skip it" % (self.lb.name, v)) yield None return else: oc = str2oid(httpclass) p = defer.waitForDeferred( self.cache_or_get(('ltmHttpClassPoolName', oc))) yield p p = p.getResult() if not p: log.msg("In %r, no pool for %s (class %s), skip it" % (self.lb.name, v, httpclass)) yield None return op = str2oid(p) oids = [] for o in self.oids: if o.startswith("ltmPool") and not o.startswith("ltmPoolMbr") and \ not o.startswith("ltmPoolMember"): oids.append((o, op)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() if self.cache(('ltmVirtualServAddrType', ov)) == 1: vip = "%s:%d" % (socket.inet_ntop( socket.AF_INET, self.cache(('ltmVirtualServAddr', ov))), self.cache(('ltmVirtualServPort', ov))) else: vip = "[%s]:%d" % (socket.inet_ntop( socket.AF_INET6, self.cache(('ltmVirtualServAddr', ov))), self.cache(('ltmVirtualServPort', ov))) protocol = defer.waitForDeferred(self.get_protocol(ov)) yield protocol protocol = protocol.getResult() mode = self.modes[self.cache(('ltmPoolLbMode', op))] vs = VirtualServer( httpclass is None and v or ("%s;%s" % (v, httpclass)), vip, protocol, mode) if httpclass: vs.extra["http class"] = httpclass vs.extra["vs availability state"] = \ self.availstates[self.cache(('ltmVsStatusAvailState', ov))] vs.extra["vs enabled state"] = \ self.enabledstates[self.cache(('ltmVsStatusEnabledState', ov))] vs.extra["virtual server detailed reason"] = \ self.cache(('ltmVsStatusDetailReason', ov)) vs.extra["address translation"] = \ self.cache(('ltmVirtualServTranslateAddr', ov)) == 1 and "enabled" or "disabled" vs.extra["pool name"] = p vs.extra["pool availability state"] = \ self.availstates[self.cache(('ltmPoolStatusAvailState', op))] vs.extra["pool enabled state"] = \ self.enabledstates[self.cache(('ltmPoolStatusEnabledState', op))] vs.extra["pool detailed reason"] = \ self.cache(('ltmPoolStatusDetailReason', op)) # Find and attach real servers if not self.is_cached(('ltmPoolMbrStatusAvailState', op)): for o in self.oids: if o.startswith('ltmPoolMbr') or o.startswith('ltmPoolMember'): # F5 is buggy here, we need to walk all pool members # pm = defer.waitForDeferred( # self.proxy.walk("%s.%s" % (self.oids[o], op))) pm = defer.waitForDeferred(self.proxy.walk(self.oids[o])) yield pm pm.getResult() if not self.is_cached(('ltmPoolMbrStatusAvailState', op)): print "pool %s is empty..." % p yield None return for r in self.cache(('ltmPoolMbrStatusAvailState', op)): rip = socket.inet_ntop( r[0] == 1 and socket.AF_INET or socket.AF_INET6, struct.pack("B" * r[1], *r[-(r[1] + 1):-1])) port = r[-1] rs = defer.waitForDeferred(self.process_rs(v, httpclass, rip, port)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["%s,%d" % (rip, port)] = rs yield vs return