Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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