def process_vs(self, v, s, g): """ Process data for a given virtual server when no real server is provided @param v: virtual server @param s: service @param g: group @return: a maybe deferred C{IVirtualServer} or C{None} """ # Retrieve some data if needed c = defer.waitForDeferred( self.cache_or_get( ('slbCurCfgVirtServerVname', v), ('slbCurCfgVirtServiceHname', v, s), ('slbCurCfgGroupName', g), ('slbCurCfgVirtServerIpAddress', v), ('slbCurCfgVirtServiceVirtPort', v, s), ('slbCurCfgVirtServiceUDPBalance', v, s), ('slbCurCfgVirtServiceRealPort', v, s), ('slbCurCfgVirtServiceUDPBalance', v, s), ('slbCurCfgVirtServicePBind', v, s), ('slbCurCfgGroupMetric', g), ('slbCurCfgVirtServerState', v), ('slbCurCfgGroupHealthCheckLayer', g), ('slbCurCfgGroupHealthUrl', g), ('slbCurCfgGroupBackupServer', g), ('slbCurCfgGroupBackupGroup', g), ('slbCurCfgGroupRealServers', g))) yield c c.getResult() # (v,s,g) is our tuple for a virtual server, let's build it index = "v%ds%dg%d" % (v, s, g) if not self.is_cached(('slbCurCfgGroupName', g)): log.msg("In %r, %s is in an inexistant group" % (self.lb.name, index)) yield None return name = " ~ ".join([ x for x in self.cache(('slbCurCfgVirtServerVname', v), ('slbCurCfgVirtServiceHname', v, s), ('slbCurCfgGroupName', g)) if x ]) if not name: name = index vip = "%s:%d" % tuple( self.cache(('slbCurCfgVirtServerIpAddress', v), ('slbCurCfgVirtServiceVirtPort', v, s))) protocol = "TCP" if self.cache(('slbCurCfgVirtServiceUDPBalance', v, s)) != 3: protocol = "UDP" mode = self.modes[self.cache(('slbCurCfgGroupMetric', g))] vs = VirtualServer(name, vip, protocol, mode) vs.extra["virtual server status"] = \ self.states[self.cache(('slbCurCfgVirtServerState', v))] vs.extra["healthcheck"] = self.healthchecks.get( self.cache(('slbCurCfgGroupHealthCheckLayer', g)), "unknown") vs.extra["url"] = self.cache(('slbCurCfgGroupHealthUrl', g)) if not vs.extra["url"]: del vs.extra["url"] vs.extra["pbind"] = self.pbind.get( self.cache(('slbCurCfgVirtServicePBind', v, s)), "unknown") # Find and attach real servers reals = self.cache(('slbCurCfgGroupRealServers', g)) for r in self.bitmap(reals): rs = defer.waitForDeferred(self.process_rs(v, s, g, r)) yield rs rs = rs.getResult() if rs is None: # This real does not exist continue vs.realservers["r%d" % r] = rs # Maybe a backup server? backup = defer.waitForDeferred( self.cache_or_get(('slbCurCfgRealServerBackUp', r))) yield backup backup = backup.getResult() if backup: rs = defer.waitForDeferred( self.process_rs(v, s, g, backup, True)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d" % backup] = rs # Attach backup servers backup = self.cache(('slbCurCfgGroupBackupServer', g)) if backup: rs = defer.waitForDeferred(self.process_rs(v, s, g, backup, True)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d" % backup] = rs backup = self.cache(('slbCurCfgGroupBackupGroup', g)) if backup: # We need to retrieve corresponding real servers. try: gr = defer.waitForDeferred( self.cache_or_get(('slbCurCfgGroupRealServers', backup))) yield gr gr.getResult() except: log.msg("In %r, %s has an inexistant backup group %d" % (self.lb.name, index, backup)) yield vs return for r in self.bitmap( self.cache(('slbCurCfgGroupRealServers', backup))): rs = defer.waitForDeferred(self.process_rs(v, s, g, r, True)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d" % r] = rs yield vs 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_vs(self, v): """ Process data for a given virtual server when no real server is provided @param v: virtual server @return: a deferred C{IVirtualServer} or None """ # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("virtualServer") and not o.startswith("virtualServerGroup"): oids.append((o, v)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # Let's build our virtual server, the name and the VIP depends on the type virttype = self.virttypes[self.cache(('virtualServerType', v))] if virttype == "fwmark": # We have a firewall mark. name = "fwmark %d" % self.cache(('virtualServerFwMark', v)) vip = "mark%d:0" % self.cache(('virtualServerFwMark', v)) elif virttype == "ip": # We have an IP address. ip = socket.inet_ntop(self.cache(('virtualServerAddrType', v)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache(('virtualServerAddress', v))) name = "IP %s" % ip if ":" in ip: ip = "[%s]" % ip vip = "%s:%d" % (ip, self.cache(('virtualServerPort', v))) elif virttype == "group": # Name is the name of the group name = self.cache(('virtualServerNameOfGroup', v)) # We need to search for the group name in all groups if not self.is_cached(('virtualServerGroupName', 1)): groups = defer.waitForDeferred(self.proxy.walk( self.oids['virtualServerGroupName'])) yield groups groups.getResult() names = [] for g in self.cache('virtualServerGroupName'): if self.cache(('virtualServerGroupName', g)) == name: # We found our group! Let's retrieve some information on it if not self.is_cached(('virtualServerGroupMemberType', g)): for o in self.oids: if o.startswith('virtualServerGroupMember'): groups = defer.waitForDeferred(self.proxy.walk( "%s.%s" % (self.oids[o], g))) yield groups groups.getResult() # The name will depend on group types for m in self.cache(('virtualServerGroupMemberType', g)): grouptype = self.grouptypes[ self.cache(('virtualServerGroupMemberType', g, m))] if grouptype == "ip": ip = socket.inet_ntop( self.cache(('virtualServerGroupMemberAddrType', g, m)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache(('virtualServerGroupMemberAddress', g, m))) if ":" in ip: ip = "[%s]" % ip names.append("%s:%d" % (ip, self.cache(('virtualServerGroupMemberPort', g, m)))) elif grouptype == "range": ip1 = socket.inet_ntop( self.cache(('virtualServerGroupMemberAddrType', g, m)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache(('virtualServerGroupMemberAddr1', g, m))) ip2 = socket.inet_ntop( self.cache(('virtualServerGroupMemberAddrType', g, m)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache(('virtualServerGroupMemberAddr2', g, m))) if ":" in ip1: names.append("[%s-%s]:%d" % (ip1, ip2, self.cache(('virtualServerGroupMemberPort', g, m)))) else: names.append("%s-%s:%d" % (ip1, ip2, self.cache(('virtualServerGroupMemberPort', g, m)))) elif grouptype == "fwmark": names.append("mark%d:0" % self.cache(( 'virtualServerGroupMemberFwMark', g, m))) else: # Unknown type, continue continue break # We need to build the VIP from names if not names: log.msg( "In %r, unable to build a VIP for virtual server group %s, skip it" % ( self.lb.name, name)) yield None return vip = " + ".join(names) else: # Unknown type, don't return a load balancer log.msg("In %r, unknown type for virtual server %d (%d), skip it" % (self.lb.name, v, virttype)) yield None return protocol = self.protocols[self.cache(('virtualServerProtocol', v))] mode = self.modes[self.cache(('virtualServerLoadBalancingAlgo', v))] vs = VirtualServer(name, vip, protocol, mode) # Add some extra information vs.extra["packet-forwarding method"] = self.methods[ self.cache(('virtualServerLoadBalancingKind', v))] vs.extra["virtual server status"] = self.status[ self.cache(('virtualServerStatus', v))] and "up" or "down" for key, oid in [ ('virtual host', 'virtualServerVirtualHost'), ('persist timeout', 'virtualServerPersistTimeout'), ('persist granularity', 'virtualServerPersistGranularity'), ('check delay', 'virtualServerDelayLoop'), ('quorum', 'virtualServerQuorum'), ('quorum up command', 'virtualServerQuorumUp'), ('quorum down command', 'virtualServerQuorumDown'), ('quorum hysterisis', 'virtualServerHysteresis') ]: try: vs.extra[key] = self.cache((oid, v)) except KeyError: pass vs.extra["persistence"] = \ self.status[self.cache(('virtualServerPersist', v))] and "enabled" or \ "disabled" vs.extra["quorum status"] = \ self.status[self.cache(('virtualServerQuorumStatus', v))] and "met" or \ "lost" vs.extra["real servers"] = "%d up / %d total" % tuple(self.cache( ('virtualServerRealServersUp', v), ('virtualServerRealServersTotal', v))) # Find and attach real servers if not self.is_cached(('realServerType', v, 1)): reals = defer.waitForDeferred( self.proxy.walk("%s.%d" % (self.oids['realServerType'], v))) yield reals reals.getResult() for r in self.cache(('realServerType', v)): rs = defer.waitForDeferred(self.process_rs(v, r)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["r%d" % r] = rs yield vs return
def process_vs(self, v): """ Process data for a given virtual server when no real server is provided @param v: virtual server @return: a deferred C{IVirtualServer} or None """ # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("virtualServer" ) and not o.startswith("virtualServerGroup"): oids.append((o, v)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() # Let's build our virtual server, the name and the VIP depends on the type virttype = self.virttypes[self.cache(('virtualServerType', v))] if virttype == "fwmark": # We have a firewall mark. name = "fwmark %d" % self.cache(('virtualServerFwMark', v)) vip = "mark%d:0" % self.cache(('virtualServerFwMark', v)) elif virttype == "ip": # We have an IP address. ip = socket.inet_ntop( self.cache( ('virtualServerAddrType', v)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache(('virtualServerAddress', v))) name = "IP %s" % ip if ":" in ip: ip = "[%s]" % ip vip = "%s:%d" % (ip, self.cache(('virtualServerPort', v))) elif virttype == "group": # Name is the name of the group name = self.cache(('virtualServerNameOfGroup', v)) # We need to search for the group name in all groups if not self.is_cached(('virtualServerGroupName', 1)): groups = defer.waitForDeferred( self.proxy.walk(self.oids['virtualServerGroupName'])) yield groups groups.getResult() names = [] for g in self.cache('virtualServerGroupName'): if self.cache(('virtualServerGroupName', g)) == name: # We found our group! Let's retrieve some information on it if not self.is_cached(('virtualServerGroupMemberType', g)): for o in self.oids: if o.startswith('virtualServerGroupMember'): groups = defer.waitForDeferred( self.proxy.walk("%s.%s" % (self.oids[o], g))) yield groups groups.getResult() # The name will depend on group types for m in self.cache(('virtualServerGroupMemberType', g)): grouptype = self.grouptypes[self.cache( ('virtualServerGroupMemberType', g, m))] if grouptype == "ip": ip = socket.inet_ntop( self.cache( ('virtualServerGroupMemberAddrType', g, m)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache( ('virtualServerGroupMemberAddress', g, m))) if ":" in ip: ip = "[%s]" % ip names.append( "%s:%d" % (ip, self.cache( ('virtualServerGroupMemberPort', g, m)))) elif grouptype == "range": ip1 = socket.inet_ntop( self.cache( ('virtualServerGroupMemberAddrType', g, m)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache( ('virtualServerGroupMemberAddr1', g, m))) ip2 = socket.inet_ntop( self.cache( ('virtualServerGroupMemberAddrType', g, m)) == 1 and socket.AF_INET or socket.AF_INET6, self.cache( ('virtualServerGroupMemberAddr2', g, m))) if ":" in ip1: names.append( "[%s-%s]:%d" % (ip1, ip2, self.cache( ('virtualServerGroupMemberPort', g, m)))) else: names.append( "%s-%s:%d" % (ip1, ip2, self.cache( ('virtualServerGroupMemberPort', g, m)))) elif grouptype == "fwmark": names.append("mark%d:0" % self.cache( ('virtualServerGroupMemberFwMark', g, m))) else: # Unknown type, continue continue break # We need to build the VIP from names if not names: log.msg( "In %r, unable to build a VIP for virtual server group %s, skip it" % (self.lb.name, name)) yield None return vip = " + ".join(names) else: # Unknown type, don't return a load balancer log.msg("In %r, unknown type for virtual server %d (%d), skip it" % (self.lb.name, v, virttype)) yield None return protocol = self.protocols[self.cache(('virtualServerProtocol', v))] mode = self.modes[self.cache(('virtualServerLoadBalancingAlgo', v))] vs = VirtualServer(name, vip, protocol, mode) # Add some extra information vs.extra["packet-forwarding method"] = self.methods[self.cache( ('virtualServerLoadBalancingKind', v))] vs.extra["virtual server status"] = self.status[self.cache( ('virtualServerStatus', v))] and "up" or "down" for key, oid in [('virtual host', 'virtualServerVirtualHost'), ('persist timeout', 'virtualServerPersistTimeout'), ('persist granularity', 'virtualServerPersistGranularity'), ('check delay', 'virtualServerDelayLoop'), ('quorum', 'virtualServerQuorum'), ('quorum up command', 'virtualServerQuorumUp'), ('quorum down command', 'virtualServerQuorumDown'), ('quorum hysterisis', 'virtualServerHysteresis')]: try: vs.extra[key] = self.cache((oid, v)) except KeyError: pass vs.extra["persistence"] = \ self.status[self.cache(('virtualServerPersist', v))] and "enabled" or \ "disabled" vs.extra["quorum status"] = \ self.status[self.cache(('virtualServerQuorumStatus', v))] and "met" or \ "lost" vs.extra["real servers"] = "%d up / %d total" % tuple( self.cache(('virtualServerRealServersUp', v), ('virtualServerRealServersTotal', v))) # Find and attach real servers if not self.is_cached(('realServerType', v, 1)): reals = defer.waitForDeferred( self.proxy.walk("%s.%d" % (self.oids['realServerType'], v))) yield reals reals.getResult() for r in self.cache(('realServerType', v)): rs = defer.waitForDeferred(self.process_rs(v, r)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["r%d" % r] = rs yield vs 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_vs(self, pid, front): """ Process data for a given virtual server when no real server is provided @param pid: process ID handling the virtual server @param front: frontend ID handling the virtual server @return: a deferred C{IVirtualServer} or None """ # Retrieve some data if needed oids = [] for o in self.oids: if o.startswith("alFrontend"): oids.append((o, pid, front)) oids = tuple(oids) c = defer.waitForDeferred(self.cache_or_get(*oids)) yield c c.getResult() fname = self.cache(('alFrontendName', pid, front)) sfname = fname if "--" in fname: vip, sfname = fname.split("--", 1) else: vip = "unknown" vs = VirtualServer(sfname, vip, "unknown", "unknown") # Add some extra information vs.extra["status"] = self.cache(('alFrontendStatus', pid, front)) # Find and attach real servers if not self.is_cached(('alBackendName', pid, 1)): backends = defer.waitForDeferred( self.proxy.walk("%s.%d" % (self.oids['alBackendName'], pid))) yield backends backends.getResult() for bid, bname in self.cache(('alBackendName', pid)).items(): if bname == fname or \ bname.startswith("%s--" % fname) or \ bname.startswith("%s--" % sfname): # This backend matches. We need to fetch associated servers if not self.is_cached(('alServerName', pid, bid, 1)): servers = defer.waitForDeferred( self.proxy.walk("%s.%d.%d" % (self.oids['alServerName'], pid, bid))) yield servers servers.getResult() try: servers = self.cache(('alServerName', pid, bid)) except KeyError: servers = None if not servers: log.msg("In %r, for backend %s, no servers, skip it" % (self.lb.name, bname)) yield None return for rid in servers: # Fetch information for each real server rs = defer.waitForDeferred(self.process_rs(pid, bid, rid)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d,s%d" % (bid, rid)] = rs yield vs 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_vs(self, v, s, g): """ Process data for a given virtual server when no real server is provided @param v: virtual server @param s: service @param g: group @return: a maybe deferred C{IVirtualServer} or C{None} """ # Retrieve some data if needed c = defer.waitForDeferred(self.cache_or_get( ('slbCurCfgVirtServerVname', v), ('slbCurCfgVirtServiceHname', v, s), ('slbCurCfgGroupName', g), ('slbCurCfgVirtServerIpAddress', v), ('slbCurCfgVirtServiceVirtPort', v, s), ('slbCurCfgVirtServiceUDPBalance', v, s), ('slbCurCfgVirtServiceRealPort', v, s), ('slbCurCfgVirtServiceUDPBalance', v, s), ('slbCurCfgVirtServicePBind', v, s), ('slbCurCfgGroupMetric', g), ('slbCurCfgVirtServerState', v), ('slbCurCfgGroupHealthCheckLayer', g), ('slbCurCfgGroupHealthUrl', g), ('slbCurCfgGroupBackupServer', g), ('slbCurCfgGroupBackupGroup', g), ('slbCurCfgGroupRealServers', g))) yield c c.getResult() # (v,s,g) is our tuple for a virtual server, let's build it index = "v%ds%dg%d" % (v, s, g) if not self.is_cached(('slbCurCfgGroupName', g)): log.msg("In %r, %s is in an inexistant group" % (self.lb.name, index)) yield None return name = " ~ ".join([x for x in self.cache( ('slbCurCfgVirtServerVname', v), ('slbCurCfgVirtServiceHname', v, s), ('slbCurCfgGroupName', g)) if x]) if not name: name = index vip = "%s:%d" % tuple(self.cache(('slbCurCfgVirtServerIpAddress', v), ('slbCurCfgVirtServiceVirtPort', v, s))) protocol = "TCP" if self.cache(('slbCurCfgVirtServiceUDPBalance', v, s)) != 3: protocol = "UDP" mode = self.modes[self.cache(('slbCurCfgGroupMetric', g))] vs = VirtualServer(name, vip, protocol, mode) vs.extra["virtual server status"] = \ self.states[self.cache(('slbCurCfgVirtServerState', v))] vs.extra["healthcheck"] = self.healthchecks.get( self.cache(('slbCurCfgGroupHealthCheckLayer', g)), "unknown") vs.extra["url"] = self.cache(('slbCurCfgGroupHealthUrl', g)) if not vs.extra["url"]: del vs.extra["url"] vs.extra["pbind"] = self.pbind.get( self.cache(('slbCurCfgVirtServicePBind', v, s)), "unknown") # Find and attach real servers reals = self.cache(('slbCurCfgGroupRealServers', g)) for r in self.bitmap(reals): rs = defer.waitForDeferred(self.process_rs(v, s, g, r)) yield rs rs = rs.getResult() if rs is None: # This real does not exist continue vs.realservers["r%d" % r] = rs # Maybe a backup server? backup = defer.waitForDeferred(self.cache_or_get(('slbCurCfgRealServerBackUp', r))) yield backup backup = backup.getResult() if backup: rs = defer.waitForDeferred(self.process_rs(v, s, g, backup, True)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d" % backup] = rs # Attach backup servers backup = self.cache(('slbCurCfgGroupBackupServer', g)) if backup: rs = defer.waitForDeferred(self.process_rs(v, s, g, backup, True)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d" % backup] = rs backup = self.cache(('slbCurCfgGroupBackupGroup', g)) if backup: # We need to retrieve corresponding real servers. try: gr = defer.waitForDeferred( self.cache_or_get(('slbCurCfgGroupRealServers', backup))) yield gr gr.getResult() except: log.msg("In %r, %s has an inexistant backup group %d" % (self.lb.name, index, backup)) yield vs return for r in self.bitmap(self.cache(('slbCurCfgGroupRealServers', backup))): rs = defer.waitForDeferred(self.process_rs(v, s, g, r, True)) yield rs rs = rs.getResult() if rs is not None: vs.realservers["b%d" % r] = rs yield vs 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