Пример #1
0
class NeighborsContainer(object):
    """This class manages the network neighbor information"""
    def __init__(self, logger):
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_NEIGHBORS)

        self.blinkyNeighbors = None

        self.isApplicationInitiatedDiscoveryWrapperCreated = False
        self.applicationInitiatedDiscovery = ApplicationInitiatedDiscoveryContainer(
            self._log)

    def notifyAttachToBlinky(self, blinkyNeighbors):
        # --- /tech/network/ipv6/neighbors/application-initiated-discovery
        blinkyNeighbors.setCreateApplicationInitiatedDiscoveryFunctor(
            self.createApplicationInitiatedDiscovery)
        blinkyNeighbors.setDeleteApplicationInitiatedDiscoveryFunctor(
            self.deleteApplicationInitiatedDiscovery)
        self.blinkyNeighbors = blinkyNeighbors

    def createApplicationInitiatedDiscovery(
            self, phase, blinkyApplicationInitiatedDiscovery):
        self._log("create-application-initiated-discovery").debug3(
            "%s: blinkyApplicationInitiatedDiscovery=%s", phase,
            blinkyApplicationInitiatedDiscovery)
        if (phase.isPreparePrivate()):
            self.applicationInitiatedDiscovery = SimpleContainerWrapper(
                self._log,
                self.applicationInitiatedDiscovery,
                setOperDataFunctor=True)
            self.isApplicationInitiatedDiscoveryWrapperCreated = True
            self.applicationInitiatedDiscovery.attachToBlinky(
                blinkyApplicationInitiatedDiscovery)
        elif (phase.isCommitPublic()):
            self.applicationInitiatedDiscovery.attachToBlinkyOper()
        elif (phase.isAbortPrivate()):
            if self.isApplicationInitiatedDiscoveryWrapperCreated is True:
                self.applicationInitiatedDiscovery = self.applicationInitiatedDiscovery.realObject
        return ReturnCodes.kOk

    def deleteApplicationInitiatedDiscovery(self, phase):
        self._log("delete-application-initiated-discovery").debug3(
            "phase=%s", phase)
        if (phase.isCommitPrivate()):
            if self.isApplicationInitiatedDiscoveryWrapperCreated is True:
                self.applicationInitiatedDiscovery = self.applicationInitiatedDiscovery.realObject
        return ReturnCodes.kOk
Пример #2
0
class StaticResolutionContainer(object):
    """This class manages the system static resolution information"""
    def __init__(self, logger):
        self._log = logger.createLoggerSameModule(
            G_NAME_GROUP_NET_NAME_RESOLUTION_STATIC)
        self.name = "network-name-resolution-static"
        self.hosts = None
        self.blinkyStaticResolution = None

    #-------------------------------------------------------------------------------------------------------------------
    def getHosts(self):
        hosts = []
        if self.hosts and self.hosts.ipv4List:
            candidates = self.hosts.ipv4List.candidateValues()
            for candidate in candidates:
                hosts.append(
                    (candidate.getAddress(), candidate.getHostNames()))
        return hosts

    #-------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyStaticResolution):
        # --- /tech/system/name-resolution/static/hosts
        blinkyStaticResolution.setCreateHostsFunctor(self.createHosts)
        blinkyStaticResolution.setDeleteHostsFunctor(self.deleteHosts)
        self.blinkyStaticResolution = blinkyStaticResolution

    #-------------------------------------------------------------------------------------------------------------------
    def createHosts(self, phase, blinkyHosts):
        self._log("create-hosts").debug2("%s: blinkyHosts=%s", phase,
                                         blinkyHosts)
        if (phase.isPreparePrivate()):
            hosts = HostsContainer(self._log)
            self.hosts = SimpleContainerWrapper(self._log, hosts)
            self.hosts.attachToBlinky(blinkyHosts)
        elif (phase.isAbortPrivate()):
            self.hosts = None
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def deleteHosts(self, phase):
        self._log("delete-hosts").debug2("phase=%s", phase)
        if (phase.isCommitPrivate()):
            self.hosts = None
        return ReturnCodes.kOk
Пример #3
0
class StaticResolutionContainer(object):
    """This class manages the system static resolution information"""

    def __init__ (self, logger):
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_NAME_RESOLUTION_STATIC)
        self.name = "network-name-resolution-static"
        self.hosts = None
        self.blinkyStaticResolution = None

    #-------------------------------------------------------------------------------------------------------------------
    def getHosts (self):
        hosts = []
        if self.hosts and self.hosts.ipv4List:
            candidates = self.hosts.ipv4List.candidateValues()
            for candidate in candidates:
                hosts.append((candidate.getAddress(), candidate.getHostNames()))
        return hosts

    #-------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyStaticResolution):
        # --- /tech/system/name-resolution/static/hosts
        blinkyStaticResolution.setCreateHostsFunctor(self.createHosts)
        blinkyStaticResolution.setDeleteHostsFunctor(self.deleteHosts)
        self.blinkyStaticResolution = blinkyStaticResolution

    #-------------------------------------------------------------------------------------------------------------------
    def createHosts(self, phase, blinkyHosts):
        self._log("create-hosts").debug2("%s: blinkyHosts=%s", phase, blinkyHosts)
        if (phase.isPreparePrivate()):
            hosts = HostsContainer(self._log)
            self.hosts = SimpleContainerWrapper(self._log, hosts)
            self.hosts.attachToBlinky(blinkyHosts)
        elif (phase.isAbortPrivate()):
            self.hosts = None
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def deleteHosts(self, phase):
        self._log("delete-hosts").debug2("phase=%s", phase)
        if (phase.isCommitPrivate()):
            self.hosts = None
        return ReturnCodes.kOk
Пример #4
0
class NetworkIpv6Container(object):
    def __init__ (self, logger):
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_NETWORK_IPV6)

        self.blinkyNetworkIpv6 = None

        self.isNeighborsWrapperCreated = False
        self.neighbors = NeighborsContainer(self._log)

        self._log("create-network-ipv6-container").debug3("create network ipv6 container called")


    def notifyAttachToBlinky(self, blinkyNetworkIpv6):
        # --- /tech/network/ipv6/neighbors
        blinkyNetworkIpv6.setCreateNeighborsFunctor(self.createNeighbors)
        blinkyNetworkIpv6.setDeleteNeighborsFunctor(self.deleteNeighbors)

        self.blinkyNetworkIpv6 = blinkyNetworkIpv6

    def createNeighbors (self, phase, blinkyNeighbors):
        self._log("create-neighbors").debug3("%s: blinkyNeighbors=%s", phase, blinkyNeighbors)
        if (phase.isPreparePrivate()):
    
            self.neighbors = SimpleContainerWrapper(self._log, self.neighbors)
            self.isNeighborsWrapperCreated = True
            self.neighbors.attachToBlinky(blinkyNeighbors)
    
        elif (phase.isAbortPrivate()):
            if self.isNeighborsWrapperCreated is True:
                self.neighbors = self.neighbors.realObject
    
        return ReturnCodes.kOk

    def deleteNeighbors (self, phase):
        self._log("delete-neighbors").debug3("phase=%s", phase)
    
        if (phase.isCommitPrivate()):
            if self.isNeighborsWrapperCreated is True:
                self.neighbors = self.neighbors.realObject
    
        return ReturnCodes.kOk
Пример #5
0
class NeighborsContainer(object):
    """This class manages the network neighbor information"""

    def __init__ (self, logger):
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_NEIGHBORS)

        self.blinkyNeighbors = None

        self.isApplicationInitiatedDiscoveryWrapperCreated = False
        self.applicationInitiatedDiscovery = ApplicationInitiatedDiscoveryContainer(self._log)

    def notifyAttachToBlinky(self, blinkyNeighbors):
        # --- /tech/network/ipv6/neighbors/application-initiated-discovery
        blinkyNeighbors.setCreateApplicationInitiatedDiscoveryFunctor(self.createApplicationInitiatedDiscovery)
        blinkyNeighbors.setDeleteApplicationInitiatedDiscoveryFunctor(self.deleteApplicationInitiatedDiscovery)
        self.blinkyNeighbors = blinkyNeighbors

    def createApplicationInitiatedDiscovery (self, phase, blinkyApplicationInitiatedDiscovery):
        self._log("create-application-initiated-discovery").debug3("%s: blinkyApplicationInitiatedDiscovery=%s", phase, blinkyApplicationInitiatedDiscovery)
        if (phase.isPreparePrivate()):
            self.applicationInitiatedDiscovery = SimpleContainerWrapper(self._log, self.applicationInitiatedDiscovery, 
                                                                        setOperDataFunctor=True)
            self.isApplicationInitiatedDiscoveryWrapperCreated = True
            self.applicationInitiatedDiscovery.attachToBlinky(blinkyApplicationInitiatedDiscovery)
        elif (phase.isCommitPublic()):
            self.applicationInitiatedDiscovery.attachToBlinkyOper()
        elif (phase.isAbortPrivate()):
            if self.isApplicationInitiatedDiscoveryWrapperCreated is True:
                self.applicationInitiatedDiscovery = self.applicationInitiatedDiscovery.realObject
        return ReturnCodes.kOk

    def deleteApplicationInitiatedDiscovery (self, phase):
        self._log("delete-application-initiated-discovery").debug3("phase=%s", phase)
        if (phase.isCommitPrivate()):
            if self.isApplicationInitiatedDiscoveryWrapperCreated is True:
                self.applicationInitiatedDiscovery = self.applicationInitiatedDiscovery.realObject
        return ReturnCodes.kOk
Пример #6
0
class _BaseIpConnectivity(object):
    """a generic base connectivity object.
    """
    def __init__(self, logger, interfaceName, version, ipMethodMap, counters):
        """
        Args:
            logger

        Raises:
            None
        """

        self.interfaceName = interfaceName
        self.version = version
        self.ipMethodMap = ipMethodMap  # maps blinky ip version method type specific enum to a generic
        self._log = logger.createLoggerSameModule(
            G_NAME_GROUP_NET_INTERFACES_CONNECTIVITY_IP % version)

        # data
        self.candidateMethod = MethodTypes.kMethodLink
        self.runningMethod = MethodTypes.kMethodLink
        self.ndisc = None
        self.ping = None
        self.muteReporting = False

        # dummy
        self.link = a.sys.net.interfaces.connectivity.ConnectivityTestContainer(
            self._log, "%s-link%s" % (self.interfaceName, self.version),
            MethodTypes.kMethodLink)
        self.countersOnClear = counters

        # status
        self.connectivityOperStatus = None
        self.operStatusReason = ConnectivityOperationalStatusReasonType.kInterfaceFunctionsDoesNotRequireConnectivityCheck
        self.actualMethod = None

        # counters
        self.numNdiscSuccessfulTests = 0
        self.numNdiscTimeouts = 0
        self.numNdiscErrors = 0
        self.numPingSuccessfulTests = 0
        self.numPingTimeouts = 0
        self.numPingErrors = 0

        # connectivity availability
        self.connectivityStatusMonitor = a.sys.net.interfaces.connectivity.ConnectivityStatusMonitor(
            self._log)

        self.blinkyIpConnectivity = None

#-----------------------------------------------------------------------------------------------------------------------

    def __str__(self):
        return "%s-ipv%s: ndisc=%s , ping=%s" % (
            self.interfaceName, self.version, self.ndisc, self.ping)

#-----------------------------------------------------------------------------------------------------------------------

    def notifyAttachToBlinky(self, blinkyIpConnectivity):
        self.blinkyIpConnectivity = blinkyIpConnectivity

        # clear-counters
        blinkyIpConnectivity.setDoActionFunctor(self.doActionClearCounters)

        self._registerOnAttachToBlinky(blinkyIpConnectivity)

#-----------------------------------------------------------------------------------------------------------------------

    def setConfigErrorStr(self, msg):
        if self.blinkyIpConnectivity:
            self.blinkyIpConnectivity.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------

    def setOperErrorStr(self, tctx, msg):
        if self.blinkyIpConnectivity is not None:
            self.blinkyIpConnectivity.setTransError(tctx, msg)

#-----------------------------------------------------------------------------------------------------------------------

    def doActionClearCounters(self, userInfo, actionPoint, actionName, params,
                              nParams):
        self._log("do-action-clear-counters").debug2(
            'called. userInfo=%s, actionPoint=%s, actionName=%s, params=%s, nParams=%s',
            userInfo, actionPoint, actionName, params, nParams)

        rc = self._doClearCounters()

        if rc != ReturnCodes.kOk:
            self.blinkyIpConnectivity.setActionError(
                userInfo, '%s: failed on ipv%s connectivity clear counters',
                self.interfaceName, self.version)

        return rc

#-----------------------------------------------------------------------------------------------------------------------

    def _doClearCounters(self):
        rc = self._getConnectivityCounters(None, self.countersOnClear, False)
        self._log("do-clear-counters").debug2(
            "%s: clear counters snapshot - %s", self.interfaceName,
            self.countersOnClear)

        return rc

#-----------------------------------------------------------------------------------------------------------------------

    def preparePrivateValueSet(self, data):
        self._log("prepare-private-value-set").debug2(
            "%s: ipv%s prepare data - %s", self.interfaceName, self.version,
            data)

        method = self.ipMethodMap.get(data.method, None)

        if method is None:
            self._log("candidate-method-invalid").error(
                "Candidate IPv%s method type '%s' is invalid. see valid options: %s ",
                self.version, data.method, self.ipMethodMap)
            self.setConfigErrorStr("ipv%s method type '%s' is invalid" %
                                   (self.version, data.method))
            return ReturnCodes.kGeneralError

        # we are successfull
        self.candidateMethod = method
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def commitPrivateValueSet(self, data):
        __pychecker__ = "no-argsused"  # data not used
        self._log("commit-private-value-set").debug2(
            "%s: ipv%s commit data - %s", self.interfaceName, self.version,
            data)

        self.runningMethod = self.candidateMethod

        # update connectivity monitor
        currentConnectivity = self.link

        # arp/ndisc6
        if self.runningMethod == MethodTypes.kMethodNeighDisc:
            currentConnectivity = self.ndisc
        # ping/ping6
        elif self.runningMethod == MethodTypes.kMethodPing:
            currentConnectivity = self.ping

        self.connectivityStatusMonitor.setCurrentConnectivityTest(
            currentConnectivity)
        self._log("ip-connectivity-check-change").info(
            "ipv%s connectivity check is going to be %s", self.version,
            self.runningMethod)

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def abortPrivateValueSet(self, data):
        __pychecker__ = "no-argsused"  # data not used

        self.candidateMethod = self.runningMethod
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def getStatus(self, tctx, operData):

        self._log("ip-connectivity-availability-status").debug3(
            "ipv%s connectivity availability: get status was called. tctx=%s",
            self.version, tctx)

        operStatusMap = {
            True: ConnectivityOperationalStatusType.kUp,
            False: ConnectivityOperationalStatusType.kDown,
            None: ConnectivityOperationalStatusType.kNotApplicable
        }
        # set data
        operData.setOperationalStatus(
            operStatusMap.get(self.connectivityOperStatus,
                              ConnectivityOperationalStatusType.kUnknown))
        operData.setOperationalStatusReason(self.operStatusReason)

        if self.actualMethod is not None:
            for method in self.ipMethodMap:
                if self.ipMethodMap[method] == self.actualMethod:
                    operData.setActualMethod(method)
                    break

        self._log("ip-connectivity-status-results").debug3(
            "ipv%s connectivity availability: status results=%s", self.version,
            operData)
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def getCounters(self, tctx, operData):

        rc = self._getConnectivityCounters(tctx, operData, True)
        return rc

#-----------------------------------------------------------------------------------------------------------------------

    def _getConnectivityCounters(self, tctx, operData, shouldUseClear):
        self._log("ip-connectivity-availability-counters").debug3(
            "ipv%s connectivity availability: get counters was called. tctx=%s",
            self.version, tctx)

        # set counters
        operData.setPingRequestsSent(self.numPingSuccessfulTests +
                                     self.numPingTimeouts + self.numPingErrors)
        operData.setPingSuccesses(self.numPingSuccessfulTests)
        operData.setPingTimeouts(self.numPingTimeouts)
        operData.setPingFailures(self.numPingErrors)

        self._setNdiscCounters(operData)

        # substract counters on clear
        if shouldUseClear is True:
            self._log("connectivity-counters-original-data").debug4(
                "%s: get original counters oper data=%s", self.interfaceName,
                operData)

            for key, value in self.countersOnClear.__dict__.iteritems():
                if type(value) is int:
                    operData.__dict__[key] -= value

        self._log("ip-connectivity-counters-results").debug3(
            "ipv%s connectivity availability: counters results=%s",
            self.version, operData)

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def createNeighDisc(self, phase, blinkyNdisc):
        self._log("create-neigh-disc").debug2("phase=%s, ipv%s blinkyNdisc=%s",
                                              phase, self.version, blinkyNdisc)

        if (phase.isPreparePrivate()):

            if self.version == 4:
                testName = "arp"
            else:
                testName = "ndisc6"

            ndisc = a.sys.net.interfaces.connectivity.ConnectivityTestContainer(
                self._log, "%s-%s" % (self.interfaceName, testName),
                MethodTypes.kMethodNeighDisc)
            self.ndisc = SimpleContainerWrapper(self._log, ndisc)
            self.ndisc.attachToBlinky(blinkyNdisc)

        elif (phase.isAbortPrivate()):
            self.ndisc = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteNeighDisc(self, phase):
        self._log("delete-neigh-disc").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ndisc = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def createPing(self, phase, blinkyPing):
        self._log("create-ping").debug2("phase=%s, ipv%s blinkyPing=%s", phase,
                                        self.version, blinkyPing)

        if (phase.isPreparePrivate()):

            ping = a.sys.net.interfaces.connectivity.ConnectivityTestContainer(
                self._log, "%s-ping%s" % (self.interfaceName, self.version),
                MethodTypes.kMethodPing)
            self.ping = SimpleContainerWrapper(self._log, ping)
            self.ping.attachToBlinky(blinkyPing)

        elif (phase.isAbortPrivate()):
            self.ping = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deletePing(self, phase):
        self._log("delete-ping").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ping = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def testConnectivityDone(self, connectivityOperStatus, operStatusReason,
                             actualMethod):

        currentConnectivityOperStatus = self.connectivityOperStatus

        # set data
        self.connectivityOperStatus = connectivityOperStatus
        self.operStatusReason = operStatusReason
        self.actualMethod = actualMethod

        # ConnectivityTestChange @ user-log
        if self.connectivityOperStatus != currentConnectivityOperStatus:
            self._logUserConnectivityTestChangeMessage()

        # we are done
        self.connectivityStatusMonitor.clear()

#-----------------------------------------------------------------------------------------------------------------------

    def testConnectivityCheck(self, osDevice, linkOperStatus, linkAdminStatus,
                              defaultGateway, ipAddress):

        self._log("ip-connectivity-test").debug3(
            "%s: testConnectivityCheck() ipv%s was called - device=%s, oper-status=%s",
            self.interfaceName, self.version, osDevice, linkOperStatus)

        if not osDevice:
            a.infra.process.processFatal(
                "%s: connectivity test ipv%s has no os device associated",
                self.interfaceName, self.version)

        self._log("ip-connectivity-data").debug4(
            "%s: testConnectivityCheck() ipv%s was called with configuration- admin-status=%s, default-gateway=%s, ip-address=%s",
            self.interfaceName, self.version, linkAdminStatus, defaultGateway,
            ipAddress)

        # -----------------------------------------
        # phase 1: prepare for connectivity check
        # -----------------------------------------

        # admin-down -->
        #  - oper-status:   n/a
        #  - actual-method: disabled
        if linkAdminStatus is False:
            self._log("connectivity-admin-down").debug3(
                "%s: connectivity test ipv%s admin is down",
                self.interfaceName, self.version)
            self.testConnectivityDone(
                None, ConnectivityOperationalStatusReasonType.
                kInterfaceAdministrativelyDown, None)
            return

        # no ip address -->
        #  - oper-status:   n/a
        #  - actual-method: disabled
        if not ipAddress:
            self._log("connectivity-no-ip").debug3(
                "%s: connectivity test ipv%s has no ip", self.interfaceName,
                self.version)
            self.testConnectivityDone(
                None, ConnectivityOperationalStatusReasonType.
                kInterfaceHasNoIpAddress, None)
            return

        # -----------------------------------------
        # phase 2: choose actual connectivity check
        # -----------------------------------------

        self.connectivityStatusMonitor.oneTick()
        method = self.connectivityStatusMonitor.getTestMethod(
            default=MethodTypes.kMethodLink)
        self._log("connectivity-method-test-config").debug3(
            "%s: configured connectivity test ipv%s - method=%s",
            self.interfaceName, self.version, method)

        # no default gateway (no ping/arp/ndisc)
        if not defaultGateway:
            self._log("connectivity-no-default-gateway").debug3(
                "%s: connectivity test ipv%s has no defaultGateway",
                self.interfaceName, self.version)
            method = MethodTypes.kMethodLink

        # link is down (no ping/arp/ndisc)
        operStateStr = a.sys.net.lnx.device.DeviceUtils.getOperState(
            osDevice, self._log, osDevice)
        linkCurrentStatus = (operStateStr == "up")
        if linkCurrentStatus is False and linkOperStatus is False:
            self._log("connectivity-oper-down").debug3(
                "%s: connectivity test ipv%s link oper is down",
                self.interfaceName, self.version)
            method = MethodTypes.kMethodLink

        # -----------------------------------------
        # phase 3: link check
        # -----------------------------------------

        isConnectivityAvailable = False
        downOperStatusReason = ConnectivityOperationalStatusReasonType.kUnknown
        self._log("connectivity-method-test-running").debug3(
            "%s: running connectivity test ipv%s - method=%s",
            self.interfaceName, self.version, method)

        # link
        if method == MethodTypes.kMethodLink:

            operStatusReason = ConnectivityOperationalStatusReasonType.kSuccess
            if linkOperStatus is False:
                operStatusReason = ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown

            self.testConnectivityDone(linkOperStatus, operStatusReason,
                                      MethodTypes.kMethodLink)
            return

        # -----------------------------------------
        # phase 4: execute connectivity check
        # -----------------------------------------
        if self.connectivityStatusMonitor.shouldTest() is False:
            return

        self._log("connectivity-test-run").debug3(
            "%s: going to run connectivity test ipv%s - method=%s",
            self.interfaceName, self.version, method)

        # arp/ndisc (link is up by now)
        if method == MethodTypes.kMethodNeighDisc:

            if self.ndisc.testIntervalSec == 0:
                # assumes arp/ndisc was successful
                isConnectivityAvailable = True
            elif linkCurrentStatus is False:
                # assumes arp/ndisc was failure
                isConnectivityAvailable = False
                rc = (1, )
            else:
                rc = self._sendNeighDiscRequest(osDevice, defaultGateway)
                isConnectivityAvailable = a.sys.net.lnx.common.Command.isReturnOk(
                    rc)
                self._log("connectivity-ndisc-test").debug2(
                    "%s: test arp/ndisc ipv%s rc=%s", self.interfaceName,
                    self.version, rc)

            # arping return code:
            # 0 - Sent 2 probes (1 broadcast(s)) Received 2 response(s)
            # 1 - Sent 2 probes (1 broadcast(s)) Received 0 response(s)
            # 2 - unknown host / unknown iface / etc.
            if isConnectivityAvailable is True:
                self.numNdiscSuccessfulTests += 1
            else:
                if rc[0] != 1:
                    self.numNdiscErrors += 1
                    self._log("connectivity-ndisc-error").debug1(
                        "%s: test arp/ndisc ipv%s error=%s",
                        self.interfaceName, self.version, rc[2])
                else:
                    self.numNdiscTimeouts += 1

            # set arp/ndisc down reason
            # note: even if arp/ndsic was successfull for a single test, we might still be in the up-period

            if linkOperStatus is False:
                downOperStatusReason = ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown
            else:
                if self.version == 4:
                    downOperStatusReason = ConnectivityOperationalStatusReasonType.kArpTestFailure
                else:
                    downOperStatusReason = ConnectivityOperationalStatusReasonType.kNeighborDiscoveryTestFailure

        # ping/ping6 (link is up by now)
        elif method == MethodTypes.kMethodPing:

            if self.ping.testIntervalSec == 0:
                # assumes ping/ping6 was successful
                isConnectivityAvailable = True
            elif linkCurrentStatus is False:
                # assumes ping/ping6 was failure
                isConnectivityAvailable = False
                rc = (1, )
            else:
                rc = self._sendPing(osDevice, defaultGateway)
                isConnectivityAvailable = a.sys.net.lnx.common.Command.isReturnOk(
                    rc)
                self._log("connectivity-ping-test").debug4(
                    "%s: test ping ipv%s rc=%s", self.interfaceName,
                    self.version, rc)

            # ping return code:
            # 0 - 1 packets transmitted, 1 received, 0% packet loss
            # 1 - 1 packets transmitted, 0 received, 100% packet loss
            # 2 - unknown host / bad number of packets to transmit / etc.
            if isConnectivityAvailable is True:
                self.numPingSuccessfulTests += 1
            else:
                if rc[0] != 1:
                    self.numPingErrors += 1
                    self._log("connectivity-ping-error").debug1(
                        "%s: test ping ipv%s error=%s", self.interfaceName,
                        self.version, rc[2])
                else:
                    self.numPingTimeouts += 1

            # set ping down reason
            # note: even if ping was successfull for a single test, we might still be in the up-period
            if linkOperStatus is False:
                downOperStatusReason = ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown
            else:
                downOperStatusReason = ConnectivityOperationalStatusReasonType.kPingTestFailure

        else:

            isConnectivityAvailable = False
            downOperStatusReason = ConnectivityOperationalStatusReasonType.kUnknown
            self._log("connectivity-unknown-test").error(
                "%s: unknown ipv%s test method type - %s", self.interfaceName,
                self.version, method)

        # update connectivity monitor (ran one of the tests ping/arp/ndisc by now)
        self.connectivityStatusMonitor.addTestResult(isConnectivityAvailable)
        currentConnectivityOperStatus = linkOperStatus and self.connectivityStatusMonitor.isConnectivityAvailable(
        )

        self._log("connectivity-test-results").debug3(
            "%s: ipv%s connectivity availability results is '%s' (method=%s)",
            self.interfaceName, self.version, currentConnectivityOperStatus,
            self.actualMethod)

        if currentConnectivityOperStatus is True:
            currentOperStatusReason = ConnectivityOperationalStatusReasonType.kSuccess
        else:
            currentOperStatusReason = downOperStatusReason

        shouldUserLog = False

        # update oper status reason
        if self.operStatusReason != currentOperStatusReason:
            self._log("connectivity-reason-change").notice(
                "%s: ipv%s connectivity reason changed to %s",
                self.interfaceName, self.version, currentOperStatusReason)
            self.operStatusReason = currentOperStatusReason
            shouldUserLog = True

        # update oper status (if needed)
        if self.connectivityOperStatus != currentConnectivityOperStatus:
            self._log("connectivity-stats-change").notice(
                "%s: ipv%s connectivity status changed to %s",
                self.interfaceName, self.version,
                currentConnectivityOperStatus)
            self.connectivityOperStatus = currentConnectivityOperStatus
            shouldUserLog = True

        # update actual method
        self.actualMethod = method

        if shouldUserLog is True:
            # ConnectivityTestChange @ user-log
            self._logUserConnectivityTestChangeMessage()

#-----------------------------------------------------------------------------------------------------------------------

    def _logUserConnectivityTestChangeMessage(self):
        # mute user-log
        if self.muteReporting is True:
            return

        operStatusMap = {True: "up", False: "down", None: "not applicable"}

        operReasonMap = {
            ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown:
            "link operational status down",
            ConnectivityOperationalStatusReasonType.kInterfaceFunctionsDoesNotRequireConnectivityCheck:
            "interface functions does not require connectivity check",
            ConnectivityOperationalStatusReasonType.kInterfaceHasNoIpAddress:
            "interface has no ip address",
            ConnectivityOperationalStatusReasonType.kArpTestFailure:
            "arp test failure",
            ConnectivityOperationalStatusReasonType.kPingTestFailure:
            "ping test failure",
            ConnectivityOperationalStatusReasonType.kNeighborDiscoveryTestFailure:
            "neighbor discovery test failure",
            ConnectivityOperationalStatusReasonType.kInterfaceAdministrativelyDown:
            "interface administratively down",
            ConnectivityOperationalStatusReasonType.kSuccess:
            "success"
        }

        state = operStatusMap.get(self.connectivityOperStatus, "unknown")
        reason = operReasonMap.get(self.operStatusReason, "unknown")

        # ConnectivityTestChange @ user-log
        a.infra.process.logUserMessage(
            a.api.user_log.msg.net.ConnectivityTestChange(
                self.interfaceName, "IPv%s" % self.version, state, reason))

#-----------------------------------------------------------------------------------------------------------------------

    def isConnectivityAvailable(self):
        if self.connectivityOperStatus is True:
            return True

        return False

#-----------------------------------------------------------------------------------------------------------------------

    def getConnectivityReason(self):
        return self.operStatusReason

#-----------------------------------------------------------------------------------------------------------------------

    def setMuteReporting(self, muteReporting):
        self._log("connectivity-mute-reporting").info(
            "%s: ipv%s connectivity mute reporting was changed to %s",
            self.interfaceName, self.version, muteReporting)
        self.muteReporting = muteReporting

#-----------------------------------------------------------------------------------------------------------------------

    def _sendNeighDiscRequest(self, device, destination):
        raise NotImplementedError

#-----------------------------------------------------------------------------------------------------------------------

    def _sendPing(self, device, destination):
        return a.sys.net.lnx.route.Ping.ping(
            self._log,
            destination,
            source=device,
            version=self.version,
            count=1,
            timeout=self.ping.testTimeoutSec,
            blocking=(self.ping.testTimeoutSec > 0))

#-----------------------------------------------------------------------------------------------------------------------

    def _registerOnAttachToBlinky(self, blinkyIpConnectivity):
        raise NotImplementedError

#-----------------------------------------------------------------------------------------------------------------------

    def _setNdiscCounters(self, operData):
        raise NotImplementedError
Пример #7
0
class NetManager(_NetBase):
    """This class manages the network configuration"""

    # consts use for the specific params dictionary 
    SPECIFIC_PARAM_KEY_ALLOW_DYNAMIC_CONFIG    = "allow-dynamic-config" # allow only on std/vm
    SPECIFIC_PARAM_KEY_SSHD_PORT        = "sshd-port"
    SPECIFIC_PARAM_KEY_UPDATE_OSCAR_CMD   = "update-osc-cmd"
    SPECIFIC_PARAM_KEY_EARLY_CFG_FILE   = "early-cfg"
    SPECIFIC_PARAM_KEY_LINE_CFG_FILE    = "line-cfg"
    SPECIFIC_PARAM_KEY_LINE_STATE_FILE  = "line-state"
    SPECIFIC_PARAM_KEY_MNG_CFG_FILE     = "mng-cfg"
    SPECIFIC_PARAM_KEY_NET_STATE_FILE   = "net-sig"
    SPECIFIC_PARAM_KEY_LINE_NICS_FILE   = "line-nics"
    SPECIFIC_PARAM_KEY_DELIVERY_STATUS_FILE = "delivery-status"
    SPECIFIC_PARAM_KEY_IPV6_NEIGHBOR_TABLE_FILE = "ipv6-neighbor-table"
    SPECIFIC_PARAM_KEY_NDISC6_REQUESTS_DIRECTORY = "ndisc6-requests-directory"

    #consts for sections/fields names in sys-param
    CONFIG_SECTION_NET_MANAGER = "net-manager"
    CONFIG_VAR_NET_MANAGER_SSH_PORT= "ssh-port"

    #default values for data in sys-param
    DEFAULT_SSH_PORT = 2022

    DELIVERY_INTERFACES_STATE_INTERVAL_RATE_SEC = 3     # 3 seconds
    DELIVERY_INTERFACES_IPV6_NEIGHBOR_TABLE_INTERVAL_RATE_SEC = 10  #10 seconds
    DELIVERY_INTERFACES_IPV6_NDISC6_REQUESTS_INTERVAL_RATE_SEC = 10  #10 seconds



    def __init__ (self, name):
        _NetBase.__init__(self, name, DomainPriority.kSystemIP_NetworkMain)
        self.systemContainer = None
        self.contentInterfaceList = None
        self.contentDeliveryContainer = None

        self.networkIpv6Container = None
        self.applicationInitiatedDiscoveryContainer = None

        self.allowDynamicConfig = False
        self.lineNicsFile = ""
        self.startTrx = False
        self.sshPort = -1
        self.signalFile = None

        # network configuration files
        self.hostsFile = None
        self.resolvConfFile = None
        self.earlyCfgFile = None
        self.lineCfgFile = None  
        self.lineStateFile = None  
        self.mngCfgFile = None
        self.deliveryStatusFileName = None

        self.localIpv6AddressResolver = None
        self.processLineNdisc6RequestTask = None
        self.updateDeliveryIpv6NeighborTableTask = None

        # thread in charge of periodic tasks
        self.thread = None

        # cached interfaces - use to cache running interfaces for repeated periodic tasks
        self.cachedInterfaces = []

        # snmp traps manager
        self.snmpTrapsManager = SnmpTrapsManager()

#-----------------------------------------------------------------------------------------------------------------------
    def initExternalData(self, sysParamsCfg, specificParams):
        #__pychecker__="no-argsused"  # sysParamsCfg not used

        self.sshPort = sysParamsCfg.getInt(self.CONFIG_SECTION_NET_MANAGER, 
                                           self.CONFIG_VAR_NET_MANAGER_SSH_PORT, 
                                           self.DEFAULT_SSH_PORT)

        self.allowDynamicConfig = specificParams[self.SPECIFIC_PARAM_KEY_ALLOW_DYNAMIC_CONFIG]
        self.lineNicsFile = specificParams[self.SPECIFIC_PARAM_KEY_LINE_NICS_FILE]
        self.signalFile = specificParams[self.SPECIFIC_PARAM_KEY_NET_STATE_FILE]

        # set static update command
        config_file.SysWebConfigFile.setUpdateCommand(specificParams[self.SPECIFIC_PARAM_KEY_UPDATE_OSCAR_CMD])

        self.mngCfgFile = config_file.SysWebConfigFile(specificParams[self.SPECIFIC_PARAM_KEY_MNG_CFG_FILE])
        self.earlyCfgFile = config_file.EarlyConfigFile(specificParams[self.SPECIFIC_PARAM_KEY_EARLY_CFG_FILE])
        self.lineCfgFile = config_file.LineConfigFile(specificParams[self.SPECIFIC_PARAM_KEY_LINE_CFG_FILE])
        self.lineStateFile = config_file.LineStateFile(specificParams[self.SPECIFIC_PARAM_KEY_LINE_STATE_FILE])
        self.deliveryStatusFileName = specificParams.get(self.SPECIFIC_PARAM_KEY_DELIVERY_STATUS_FILE,None)

        lineIpv6NeighborTableFile = specificParams.get(self.SPECIFIC_PARAM_KEY_IPV6_NEIGHBOR_TABLE_FILE,None)
        lineNdisc6RequestsDirectory = specificParams.get(self.SPECIFIC_PARAM_KEY_NDISC6_REQUESTS_DIRECTORY,None)
        self.localIpv6AddressResolver = LocalIpv6AddressResolver(lineNdisc6RequestsDirectory, lineIpv6NeighborTableFile)

        # dump configuration
        #---------------------------------------------------------------------------
        logLines = []        
        for k,v  in specificParams.iteritems():
            logLines.append("%-*s : %s" % (25,k,v))
        logLines.sort()
        print "\n".join(logLines)   
         
#-----------------------------------------------------------------------------------------------------------------------
    def domainTrxProgress(self, progress):

        self._log("domain-trx-progress").debug2("Net manager progress=%s", progress)

        rc = ReturnCodes.kOk

        if progress.isPreparePrivateAfter():
            rc = self.preparePrivateAfter()
            if rc == ReturnCodes.kOk:
                self.startTrx = True
        elif progress.isCommitPrivateAfter():
            rc = self.commitPrivateAfter()
        elif progress.isAbortPrivateAfter():
            rc = self.abortPrivateAfter()

        return rc

#-----------------------------------------------------------------------------------------------------------------------
    def commitPrivateAfter(self):

        if self.startTrx is True:
            self._log("net-manager-commit-private-after").debug3("Net manager commitPrivateAfter was called")

            # commit
            self.lineCfgFile.commit()
            self.mngCfgFile.commit()
            self.earlyCfgFile.commit()

            if self.allowDynamicConfig: 
                self.hostsFile.commit()
                self.resolvConfFile.commit()

            self.startTrx = False

        # update interfaces cache
        # note: holds a copy of the interfaces list
        if self.interfaceContainer.interfaceList:
            self._log("cache-interfaces-update").debug3("Net manager updates cache interfaces")
            self.cachedInterfaces = self.interfaceContainer.interfaceList.runningValues()

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def abortPrivateAfter(self):

        if self.startTrx is True:
            self._log("net-manager-abort-private-after").debug3("Net manager abortPrivateAfter was called")

            self.mngCfgFile.abort()
            self.earlyCfgFile.abort()

            if self.allowDynamicConfig: 
                self.hostsFile.abort()
                self.resolvConfFile.abort()

            self.startTrx = False

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def preparePrivateAfter(self):

        self._log("net-manager-prepare-private-after").debug3("Net manager preparePrivateAfter was called")

        mngIf = None
        techIf = None
        deliveryIfList = []
        lineIfList = []

        if self.interfaceContainer.interfaceList:
            interfaces = self.interfaceContainer.interfaceList.candidateValues()

            for currentI in interfaces:

                if currentI.isDeliveryEnabled() is True:
                    deliveryIfList.append(currentI)

                elif currentI.isLineEnabled() is True:
                    lineIfList.append(currentI)

                elif currentI.isManagementEnabled() is True:

                    if currentI.candidateTechMode:
                        techIf = currentI
                    else:
                        mngIf = currentI
        
        rc = self.__validateContentInterfaces(deliveryIfList, lineIfList)
        if rc != ReturnCodes.kOk:
            return ReturnCodes.kGeneralError

        # prepare configuration files
        rc = self.prepareConfigFiles(deliveryIfList, lineIfList, mngIf, techIf)
        if rc != ReturnCodes.kOk:
            return ReturnCodes.kGeneralError

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def prepareConfigFiles(self, deliveryIfList, lineIfList, mngIf, techIf):

        # clear data
        self.lineCfgFile.clear()
        self.mngCfgFile.clear()
        self.earlyCfgFile.clear()

        pairList = []
        hostname = self.systemContainer.getHostname(False)

        i=0
        # add delivery interfaces
        for deliveryIf in deliveryIfList:

            ipv4 = deliveryIf.getIpNetwork(IpVersion.kIPv4)
            ipv6 = deliveryIf.getIpNetwork(IpVersion.kIPv6)
            ipv4Gateway = deliveryIf.getDefaultGateway(IpVersion.kIPv4)
            ipv6Gateway = deliveryIf.getDefaultGateway(IpVersion.kIPv6)
            device = deliveryIf.deviceName(False)

            interface = self.lineCfgFile.deliveryInterfaces[i]
            i += 1

            interface.interfaceName = deliveryIf.name

            if ipv4: 
                interface.deliveryIPv4.deliveryIP = str(ipv4.ip)
                interface.deliveryIPv4.deliveryPrefixLen = int(ipv4.prefixlen)

            if ipv6: 
                interface.deliveryIPv6.deliveryIP = str(ipv6.ip)
                interface.deliveryIPv6.deliveryPrefixLen = int(ipv6.prefixlen)

            if ipv4Gateway: interface.deliveryIPv4.deliveryGateway = str(ipv4Gateway)
            if ipv6Gateway: interface.deliveryIPv6.deliveryGateway = str(ipv6Gateway)
            if device: interface.osDevice = device

            interface.adminEnable = deliveryIf.isUp(False)


        # set delivery-interface-failover
        self.lineCfgFile.deliveryInterfaceFailover = self.contentDeliveryContainer.candidateDeliveryInterfaceFailover

        # set lan IPv6 redirects configuration
        if self.applicationInitiatedDiscoveryContainer != None:
            self.lineCfgFile.lanIpv6Redirects.enabled = self.applicationInitiatedDiscoveryContainer.enabledCandidate
            self.lineCfgFile.lanIpv6Redirects.maxRequestsPerSec = self.applicationInitiatedDiscoveryContainer.maxRequestRateCandidate
            self.lineCfgFile.lanIpv6Redirects.requestsQueueSize = self.applicationInitiatedDiscoveryContainer.maxPendingRequestsCandidate

        # add line interfaces
        lineToDeliveryMap = self.__getLineToDeliveryMap()
        for lineIf in lineIfList:
            adminEnable = lineIf.isUp(False)
            self.lineCfgFile.addLineInterface(lineIf.name, 
                                              lineIf.device.candidatePciIndex,
                                              lineToDeliveryMap.get(lineIf.name,""),
                                              adminEnable)

        # add management interface
        if not mngIf is None:
            ipv4 = mngIf.getIpNetwork(IpVersion.kIPv4)
            gateway = mngIf.getDefaultGateway(IpVersion.kIPv4)
            
            if ipv4: 
                self.mngCfgFile.mngIp = str(ipv4.ip)
                self.earlyCfgFile.ip[mngIf.name] = str(ipv4)

            if hostname:
                self.earlyCfgFile.host = hostname

            if ipv4 and hostname:
                pair = (str(ipv4.ip), hostname)
                pairList.append(pair) 

            if gateway: self.earlyCfgFile.gw = str(gateway) 
            if hostname: 
                for interface in self.lineCfgFile.deliveryInterfaces:
                    interface.hostname = hostname 
                
        # add tech interface
        if not techIf is None: 
            ipv4 = techIf.getIpNetwork(IpVersion.kIPv4)

            if ipv4: self.earlyCfgFile.ip[techIf.name] = str(ipv4)

            if ipv4 and hostname:
                pair = (str(ipv4.ip), hostname+"-tech")
                pairList.append(pair) 

        # dump data
        self.mngCfgFile.dumpData()
        self.earlyCfgFile.dumpData()
        self.lineCfgFile.dumpData()

        if self.allowDynamicConfig: 
            # Set name-resolving information in resolv.conf
            nameResolution = self.systemContainer.getNameResolution()
            nameServers = []
            if nameResolution.getDnsEnabled():
                nameServers = nameResolution.getDnsNameServers()
            searchDomains = nameResolution.getDnsSearchDomains()
            self.resolvConfFile.dumpData(nameServers = nameServers, searchDomains = searchDomains)
    
            # Add static name-resolving information to /etc/hosts
            staticHosts = nameResolution.getStaticHosts() 
            for (addr, hosts) in staticHosts:
                if len(hosts) == 0:
                    self._log("empty-hosts-list").notice("No host names for ip %s" % addr)
                    self.setConfigErrorStr("No host names for ip %s" % addr)
                    return ReturnCodes.kGeneralError

            pairList.extend(nameResolution.getStaticHosts())
    
            self.hostsFile.dumpData(pairList)

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
### temp until 2.7.0 (1/11/2012)###
    def __validateContentInterfaces(self, deliveryIfList, lineIfList):

        deliveryNames = []
        for  deliveryIf in deliveryIfList:
            deliveryNames.append(deliveryIf.name)

        lineNames = []
        for  lineIf in lineIfList:
            lineNames.append(lineIf.name)

        if self.contentInterfaceList:
            contentInterfaces = self.contentInterfaceList.candidateValues()

            for currentI in contentInterfaces:
                if currentI.delivery is not None:
                    preferredDeliveryInterface = currentI.delivery.candidatePreferredDeliveryInterface

                    # line interface must be mapped to delivery interface
                    if (currentI.name in lineNames) and (not preferredDeliveryInterface in deliveryNames):
   
                        self._log("invalid-preferred-delivery-interface").notice("%s: preferredDeliveryInterface '%s' is not a valid delivery interface", 
                                                                                currentI.name, preferredDeliveryInterface)
                        self.setConfigErrorStr("%s: preferred-delivery-interface '%s' is not a valid delivery interface" % 
                                               (currentI.name, preferredDeliveryInterface))

                        return ReturnCodes.kGeneralError

        return ReturnCodes.kOk 

#-----------------------------------------------------------------------------------------------------------------------
### temp until 2.7.0 (1/11/2012)###
    def __getLineToDeliveryMap(self):

        lineToDeliveryMap = {}

        if self.contentInterfaceList:
            contentInterfaces = self.contentInterfaceList.candidateValues()

            for currentI in contentInterfaces:
                if currentI.delivery is not None:
                    preferredDeliveryInterface = currentI.delivery.candidatePreferredDeliveryInterface
                    lineToDeliveryMap[currentI.name] = preferredDeliveryInterface

        return lineToDeliveryMap 

#-----------------------------------------------------------------------------------------------------------------------
    def getStatsCounters(self):

        self._log("net-manager-get-stats-counters").debug3("Net manager getStatsCounters was called")

        interfacesCountersMap = {}
        iCountersData = CountersOperData() 

        for currentI in self.cachedInterfaces:

            iCountersData.__init__() # clear
            rc = currentI.getIfCounters(None, iCountersData, isRateCounters=True, shouldSetExtCounters=True)

            if rc == ReturnCodes.kOk:
                for key, value in iCountersData.__dict__.iteritems():
                    if type(value) is int:
                        # '/' char is considred a path notation in stats
                        # so TenGigE0/0 will be modified to TenGigE0-0
                        iName = currentI.name.replace("/","-",1)
                        iKey = "%s-%s" % (iName,key) 

                        interfacesCountersMap[iKey] = value

        self._log("net-manager-stats-counters-results").debug4("Net manager stats counters= %s" % interfacesCountersMap)

        return interfacesCountersMap

#-----------------------------------------------------------------------------------------------------------------------
    def __registerBlinkySystem(self, domain):

        blinkySystem = BlinkySystem.s_create(self._log, domain)

        systemContainer = SystemContainer(self._log)
        if self.allowDynamicConfig:
            systemContainer.setAllowDynamicConfig()

        self.systemContainer = SimpleContainerWrapper(self._log, systemContainer)
        self.hostsFile = a.sys.net.lnx.name.HostsFile(self._log)
        self.resolvConfFile = a.sys.net.lnx.name.ResolvConfFile(self._log)

        # attach
        rc = self.systemContainer.attachToBlinky(blinkySystem)
        if rc != ReturnCodes.kOk:
            self._log("attach-sys-blinky-failed").error("net manager has failed attaching to system blinky")
            return ReturnCodes.kGeneralError
      
        # register
        domain.registerNode(blinkySystem)

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def __registerBlinkyNetworkIpv6(self, domain):

        blinkyNetworkIpv6Neighbors = BlinkyNetworkIpv6Neighbors.s_create(self._log, domain)

        networkIpv6Container = NetworkIpv6Container(self._log)

        ### get applicationInitiatedDiscovery class ###
        self.applicationInitiatedDiscoveryContainer = networkIpv6Container.neighbors.applicationInitiatedDiscovery

        # configurable periodic tasks
        self.processLineNdisc6RequestTask = a.sys.net.interfaces.interface.Task(self._processLineNdisc6Requests, self.DELIVERY_INTERFACES_IPV6_NDISC6_REQUESTS_INTERVAL_RATE_SEC)
        self.updateDeliveryIpv6NeighborTableTask = a.sys.net.interfaces.interface.Task(self._updateDeliveryIpv6NeighborTable,self.DELIVERY_INTERFACES_IPV6_NEIGHBOR_TABLE_INTERVAL_RATE_SEC)

        ### attach localAddressResolver and ndisc6 file read/write tasks to applicationInitiatedDiscovery ###
        self.applicationInitiatedDiscoveryContainer.setLocalAddressResolver(self.localIpv6AddressResolver)
        self.applicationInitiatedDiscoveryContainer.setRequestReadPeriodicTask(self.processLineNdisc6RequestTask)
        self.applicationInitiatedDiscoveryContainer.setTableReadPeriodicTask(self.updateDeliveryIpv6NeighborTableTask)

        self.networkIpv6Container = SimpleContainerWrapper(self._log, networkIpv6Container)

        # attach
        rc = self.networkIpv6Container.attachToBlinky(blinkyNetworkIpv6Neighbors)
        if rc != ReturnCodes.kOk:
            self._log("attach-network-ipv6-blinky-failed").error("net manager has failed attaching to network ipv6 blinky")
            return ReturnCodes.kGeneralError
      
        # register
        domain.registerNode(blinkyNetworkIpv6Neighbors)

        return ReturnCodes.kOk 

#-----------------------------------------------------------------------------------------------------------------------
    def __registerBlinkyContentInterfaces(self, domain):

        blinkyContentInterfaceList = BlinkyContentInterfaceList.s_create(self._log, domain)
        self.contentInterfaceList = ContentIfTable(self._log)
        self.contentInterfaceList.setStatusFile(self.deliveryStatusFileName)

        # attach
        rc = self.contentInterfaceList.attachToBlinky(blinkyContentInterfaceList)
        if rc != ReturnCodes.kOk:
            self._log("attach-content-interfaces-blinky-failed").error("net manager has failed attaching to content interface list blinky")
            return ReturnCodes.kGeneralError
      
        # register 
        domain.registerNode(blinkyContentInterfaceList)

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def __registerBlinkyDelivery(self, domain):

        blinkyDelivery = BlinkyDelivery.s_create(self._log, domain)
        contentDeliveryContainer = ContentDeliveryContainer(self._log, self)
        self.contentDeliveryContainer = SimpleContainerWrapper(self._log, contentDeliveryContainer)
        
        # attach
        rc = self.contentDeliveryContainer.attachToBlinky(blinkyDelivery)
        if rc != ReturnCodes.kOk:
            self._log("attach-content-delivery-blinky-failed").error("net manager has failed attaching to content delivery blinky")
            return ReturnCodes.kGeneralError
      
        # register 
        domain.registerNode(blinkyDelivery)

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def _registerToDomain(self, domain):

        # register trx progress functor
        domain.registerNotifyTrxProgressFunctor(self.domainTrxProgress)

        # register BlinkySystem
        rc = self.__registerBlinkySystem(domain)
        if rc != ReturnCodes.kOk:
            return ReturnCodes.kGeneralError

        # register BlinkyContentInterfaceList
        rc = self.__registerBlinkyContentInterfaces(domain)
        if rc != ReturnCodes.kOk:
            return ReturnCodes.kGeneralError

        # register BlinkyDelivery
        rc = self.__registerBlinkyDelivery(domain)
        if rc != ReturnCodes.kOk:
            return ReturnCodes.kGeneralError

        # register BlinkyNetworkIpv6
        rc = self.__registerBlinkyNetworkIpv6(domain)
        if rc != ReturnCodes.kOk:
            return ReturnCodes.kGeneralError

        # init snmp
        self.snmpTrapsManager.init(domain)
        
        return ReturnCodes.kOk 

#-----------------------------------------------------------------------------------------------------------------------
    def _preActivation(self):

        # check for IPv6 support in the current running kernel
        if os.path.exists("/proc/net/if_inet6") is True:
            self._log("kernel-ipv6-ready").notice("running kernel is ipv6 ready")
        else:
            self._log("kernel-ipv6-not-ready").error("running kernel is NOT ipv6 ready")
            raise RuntimeError("Running kernel is NOT IPv6 ready")

        if self.allowDynamicConfig:  
            # start ip table service
            self.__startIpTable()
             
            # activate Loopback
            self.__activateLoopback()
    
            # deactivate all eth devices and set a temporary name
            self.__renameAndDownEths()

            # dumps all the rules
            self.__clearRoutingPolicy()

#-----------------------------------------------------------------------------------------------------------------------
    def _postActivation(self):

        # cold start notification
        self.snmpTrapsManager.snmpInterfaceConfigured()

        # launch interface periodic tasks thread
        for currentI in self.cachedInterfaces:
            currentI.launchTasksThread()

        # create and start thread
        self.thread = a.sys.net.interfaces.interface.TasksThread(self._log, self.CONFIG_SECTION_NET_MANAGER)
        self.thread.addTask(self._updateInterfacesPeriodicCounters, Interface.PERIODIC_COUNTERS_INTERVAL_RATE_SEC)
        self.thread.addTask(self._updateDevicesChange, Interface.DEVICE_EVENTS_INTERVAL_RATE_SEC)
        self.thread.addTask(self._updateDeliveryInterfacesState, self.DELIVERY_INTERFACES_STATE_INTERVAL_RATE_SEC)

        # add configurable tasks
        self.thread.addTaskObject(self.processLineNdisc6RequestTask)
        self.thread.addTaskObject(self.updateDeliveryIpv6NeighborTableTask) #not on mini?

        self.thread.start()

        # signal activation done
        if os.path.exists(self.signalFile):
            a.infra.process.processFatal("signal file was already exists - %s", self.signalFile)

        fd = open(self.signalFile, 'w')
        fd.close()

        self._log("signal-file").debug3("net manager has signaled activation by creating %s" % self.signalFile)

#-----------------------------------------------------------------------------------------------------------------------
    def _preShutdown(self):
        if self.thread is not None:
            # stop and wait until the thread terminates
            self.thread.stop()
            self.thread.join(0.1)
    
            if self.thread.isAlive():
                self._log("net-manager-thread-alive").notice("net manager thread after shutdown is still alive")

        self.thread=None

        self.localIpv6AddressResolver.shutDown()

#-----------------------------------------------------------------------------------------------------------------------
    def _updateInterfacesPeriodicCounters(self):

        for currentI in self.cachedInterfaces:
            currentI.periodicCounters.tick()

#-----------------------------------------------------------------------------------------------------------------------
    def _updateDevicesChange(self):

        for currentI in self.cachedInterfaces:
            currentI.actionOnDeviceChange()

#-----------------------------------------------------------------------------------------------------------------------
    def _updateDeliveryInterfacesState(self):

        if len(self.cachedInterfaces) > 0:

            i=0
            for currentI in self.cachedInterfaces:
    
                if currentI.isDeliveryEnabled() is True:
                    
                    deliveryIf = self.lineStateFile.deliveryInterfaces[i]
                    i += 1
    
                    # 1 - set interface name
                    deliveryIf.interfaceName = currentI.name
    
                    # 2 - connectivity check
                    if currentI.connectivityCheck:
                        deliveryIf.deliveryIPv4State.serviceStatus = currentI.connectivityCheck.isConnectivityAvailable(IpVersion.kIPv4)
                        deliveryIf.deliveryIPv6State.serviceStatus = currentI.connectivityCheck.isConnectivityAvailable(IpVersion.kIPv6)

                    # 3 - resolve default gateway MAC address
                    osDevice = currentI.deviceName(True)
                    if osDevice:
                        
                        # ipv4
                        ipv4Gateway = currentI.getDefaultGateway(IpVersion.kIPv4)
                        if ipv4Gateway:
                            
                            macV4 = a.sys.net.lnx.neighbour.NeighbourUtils.getNeighbourMacAddress(self._log, osDevice, 
                                                                                                  str(ipv4Gateway),
                                                                                                  IpVersion.kIPv4)
                            if macV4: 
                                deliveryIf.deliveryIPv4State.deliveryGatewayMac = macV4
                            else:
                                a.sys.net.lnx.neighbour.Arping.sendArpRequest(self._log, osDevice, str(ipv4Gateway),
                                                                              count=3,timeout=1,blocking=False)
                        else:
                            deliveryIf.deliveryIPv4State.deliveryGatewayMac = ""


                        # ipv6
                        ipv6Gateway = currentI.getDefaultGateway(IpVersion.kIPv6)
                        if ipv6Gateway:
        
                            macV6 = a.sys.net.lnx.neighbour.NeighbourUtils.getNeighbourMacAddress(self._log, osDevice,
                                                                                                  str(ipv6Gateway),
                                                                                                  IpVersion.kIPv6)
                            if macV6: 
                                deliveryIf.deliveryIPv6State.deliveryGatewayMac = macV6
                            else:
                                a.sys.net.lnx.neighbour.Ndisc.sendNdiscRequest(self._log, osDevice, str(ipv6Gateway),
                                                                               count=3,timeout=1,blocking=False)
                        else:
                            deliveryIf.deliveryIPv6State.deliveryGatewayMac = ""

    
            # dump and commit
            self.lineStateFile.dumpData()
            self.lineStateFile.commit()

#-----------------------------------------------------------------------------------------------------------------------
    def _updateDeliveryIpv6NeighborTable(self):
        if len(self.cachedInterfaces) > 0:
            cachedDeliveryInterfaces = []
            for currentI in self.cachedInterfaces:
    
                if currentI.isDeliveryEnabled() is True:
                    cachedDeliveryInterfaces.append(currentI.deviceName(True))

            self.localIpv6AddressResolver.updateDeliveryIpv6NeighborTable(cachedDeliveryInterfaces)


#-----------------------------------------------------------------------------------------------------------------------
    def _processLineNdisc6Requests(self):
        if len(self.cachedInterfaces) > 0:
            cachedDeliveryInterfaces = []
            for currentI in self.cachedInterfaces:
                
                if currentI.isDeliveryEnabled() is True:
                    if currentI.deviceName(True):
                        cachedDeliveryInterfaces.append(currentI.deviceName(True))

            self.localIpv6AddressResolver.processNdisc6Requests(cachedDeliveryInterfaces)
            

#-----------------------------------------------------------------------------------------------------------------------
    def _createInterfaceContainer(self):
        ifManager = IfManager(self._log, self.name, self.allowDynamicConfig, self.lineNicsFile, self.snmpTrapsManager)
        ifManager.initData(self.sshPort)

        return ifManager

#-----------------------------------------------------------------------------------------------------------------------
    def _postInitLogger(self):

        # init logger
        self.mngCfgFile.initLogger(self._log)
        self.earlyCfgFile.initLogger(self._log)
        self.lineCfgFile.initLogger(self._log)
        self.lineStateFile.initLogger(self._log)
        self.localIpv6AddressResolver.initLogger(self._log)
        self.snmpTrapsManager.initLogger(self._log)
                 
        # dump first config files
        self.__dumpData(self.earlyCfgFile)
        self.__dumpData(self.lineCfgFile)
        self.__dumpData(self.mngCfgFile)

#-----------------------------------------------------------------------------------------------------------------------
    def __startIpTable(self):

        timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

        self.__createIpTablesFileIfNeeded(IpTablesConfigFile.IPV4_TABLE_CONFIG_FILE, IpTablesConfigFile.IPV4TABLES_CONFIG_TEMPLATE, timestamp)
        self.__createIpTablesFileIfNeeded(IpTablesConfigFile.IPV6_TABLE_CONFIG_FILE, IpTablesConfigFile.IPV6TABLES_CONFIG_TEMPLATE, timestamp)
        
        # restarting the iptables service flushes exisitng firewall rules 
        # and reloads new rules from the iptables config file
        self.__restartServiceOrCrash(IpTablesService.IPV4_TABLE_COMMAND_NAME)
        self.__restartServiceOrCrash(IpTablesService.IPV6_TABLE_COMMAND_NAME)

        self._log("iptables-config-file").notice("iptables config files: ipv4 = '%s' , ipv6 = '%s'", 
                                                 IpTablesConfigFile.IPV4_TABLE_CONFIG_FILE, 
                                                 IpTablesConfigFile.IPV6_TABLE_CONFIG_FILE)

#-----------------------------------------------------------------------------------------------------------------------
    def __restartServiceOrCrash(self, serviceName):
        (rc, stdOut, stdErr) = a.sys.net.lnx.common.Command.execute(self._log, self.CONFIG_SECTION_NET_MANAGER, 
                                                                    ("service %s restart" % serviceName), blocking=True)

        if rc != 0:
            self._log("restart-service-failed").error("failed to restart service %s (rc=%s) - %s", serviceName,  rc, stdErr)
            a.infra.process.processFatal("service %s failed loading", serviceName)

#-----------------------------------------------------------------------------------------------------------------------
    def __createIpTablesFileIfNeeded(self, filename, template, timestamp):
        if not os.path.exists(filename):

            data = {'timestamp' : timestamp}
            self._log("create-iptables-config-file").notice("creates iptables config file '%s' - template: %s", 
                                                            filename, template)
    
            fd =  open(filename, 'w')
            fd.write(template % data)
            fd.close()          

#-----------------------------------------------------------------------------------------------------------------------
    def __activateLoopback(self):
        rc = a.sys.net.lnx.device.IpLink.activateDevice(self._log, "lo")
        self._log("loopback-activate").debug2("Activating Loopback device.")

        if not a.sys.net.lnx.common.Command.isReturnOk(rc):
            a.infra.process.processFatal("%s: Failed at activate Loopback device", self.name)

#-----------------------------------------------------------------------------------------------------------------------
    def __clearRoutingPolicy(self):
        routeTables = [100,101, # qb100-6a2 and qvm-30
                       108,109] # qb100-6b2

        for table in routeTables:
            a.sys.net.lnx.route.IpRule.flushRules(self._log, str(table), version=4)
            a.sys.net.lnx.route.IpRule.flushRules(self._log, str(table), version=6)
            self._log("flush-rules").debug2("Flushing all ip rules of table %s.", table)

#-----------------------------------------------------------------------------------------------------------------------
    def __renameAndDownEths(self):

        ethList = a.sys.net.lnx.device.DeviceUtils.getEthDevices()
        self._log("eth-list").debug2("eth List: ", ethList)

        for eth in ethList:

            # device is down
            rc = a.sys.net.lnx.device.IpLink.deactivateDevice(self._log, eth)
            self._log("eth-deactivate").debug2("Deactivating %s device", eth)

            if a.sys.net.lnx.common.Command.isReturnOk(rc):
                # removing all IPs from a device
                rc = a.sys.net.lnx.device.IpAddress.flushAddresses(self._log, eth, scope="global")
                self._log("flush-addr").debug2("Flush all IP addresses of %s device", eth)
    
                if not a.sys.net.lnx.common.Command.isReturnOk(rc):
                    a.infra.process.processFatal("%s: Failed flushing all IPs of %s device", self.name, eth)
    
                # eth device name length is limited
                if len(eth) < 10:
                    # set temp name to device
                    tempEth = "%s-tmp" % eth
                    rc = a.sys.net.lnx.device.IpLink.renameDevice(self._log, eth, tempEth)
                    self._log("eth-tmp-rename").debug2("Renaming %s device to %s", eth, tempEth)
        
                    if not a.sys.net.lnx.common.Command.isReturnOk(rc):
                        a.infra.process.processFatal("%s: Failed renaming %s device", self.name, eth)
            else:
                # Note: DPDK interfaces are handled in user space 
                # and are not visible to the Linux kernel
                self._log("eth-deactivate-failed").debug2("Failed at deactivate %s device", eth)

#-----------------------------------------------------------------------------------------------------------------------
    def __dumpData(self, fileObject):
        fileObject.dumpData()
        fileObject.commit()
Пример #8
0
class Content(object):
    """This class represents a content service object"""

    def __init__ (self, logger):
        """Instantiate a new content service object.

        Args:
            logger

        Raises:
            None
        """

        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_INTERFACES_CONTENT)

        self.analytics = None
        self.acquisition = None
        self.delivery = None

        self.blinkyContent = None

#-----------------------------------------------------------------------------------------------------------------------  
    def __str__(self):
        strList = []
        strList.append("analytics: %s" % self.analytics)
        strList.append("acquisition: %s" % self.acquisition)
        strList.append("delivery: %s" % self.delivery)

        return '\t'.join(strList) 


#-----------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyContent):

        self._log("notify-attach-blinky").debug2("attach by blinky content")

        # analytics
        blinkyContent.setCreateAnalyticsFunctor(self.createAnalytics)
        blinkyContent.setDeleteAnalyticsFunctor(self.deleteAnalytics)

        # acquisition
        blinkyContent.setCreateAcquisitionFunctor(self.createAcquistion)
        blinkyContent.setDeleteAcquisitionFunctor(self.deleteAcquistion)

        # delivery
        blinkyContent.setCreateDeliveryFunctor(self.createDelivery)
        blinkyContent.setDeleteDeliveryFunctor(self.deleteDelivery)

        self.blinkyContent = blinkyContent

#-----------------------------------------------------------------------------------------------------------------------
    def setConfigErrorStr(self, msg):
        if self.blinkyContent:
            self.blinkyContent.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------
    def createAnalytics(self, phase, blinkyAnalytics):
        self._log("create-analytics").debug2("phase=%s, blinkyAnalytics=%s", phase, blinkyAnalytics)

        if (phase.isPreparePrivate()):

            analytics = service.AnalyticsService(self._log)
            self.analytics = SimpleContainerWrapper(self._log, analytics)
            self.analytics.attachToBlinky(blinkyAnalytics)

        elif (phase.isAbortPrivate()):
            self.analytics = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deleteAnalytics(self, phase):
        self._log("delete-analytics").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.analytics = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def createAcquistion(self, phase, blinkyAcquistion):
        self._log("create-acquisition").debug2("phase=%s, blinkyAcquistion=%s", phase, blinkyAcquistion)

        if (phase.isPreparePrivate()):

            acquisition = service.AcquistionService(self._log)
            self.acquisition = SimpleContainerWrapper(self._log, acquisition)
            self.acquisition.attachToBlinky(blinkyAcquistion)

        elif (phase.isAbortPrivate()):
            self.acquisition = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deleteAcquistion(self, phase):
        self._log("delete-acquisition").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.acquisition = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def createDelivery(self, phase, blinkyDelivery):
        self._log("create-delivery").debug2("phase=%s, blinkyDelivery=%s", phase, blinkyDelivery)

        if (phase.isPreparePrivate()):

            delivery = service.DeliveryService(self._log)
            self.delivery = SimpleContainerWrapper(self._log, delivery)
            self.delivery.attachToBlinky(blinkyDelivery)

        elif (phase.isAbortPrivate()):
            self.delivery = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deleteDelivery(self, phase):
        self._log("delete-delivery").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.delivery = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def isLineEnabled(self):
        if ((not self.analytics is None) and (self.analytics.isServiceEnabled() is True)):
            return True

        if ((not self.acquisition is None) and (self.acquisition.isServiceEnabled() is True)):
            return True

        return False

#-----------------------------------------------------------------------------------------------------------------------
    def isDeliveryEnabled(self):
        if self.delivery is None:
            return False

        return self.delivery.isServiceEnabled()

#-----------------------------------------------------------------------------------------------------------------------
    def preparePrivateAfter(self):
        """all content services are being evaluated and verified for correctness system-wise"""

        self._log("content-prepare-private-after").debug3("Content: preparePrivateAfter was called")

        # delivey and line cannot coexist
        if self.isDeliveryEnabled() is True:
  
            if self.isLineEnabled() is True:
                self._log("delivery-and-line").error("Delivey and Line cannot coexist")
                self.setConfigErrorStr("Delivey and Analytics/Acquisition is not supported")
                return ReturnCodes.kGeneralError

        elif self.isLineEnabled() is True:

            # cannot acquire without analytics
            if not ((self.analytics.isServiceEnabled() is True) and (self.acquisition.isServiceEnabled() is True)):
                self._log("acquire-without-analytics").error("Cannot acquire without analytics")
                self.setConfigErrorStr("Acquisition without Analytics is not supported")
                return ReturnCodes.kGeneralError
            
        return ReturnCodes.kOk 
Пример #9
0
class _BaseIpConnectivity(object):
    """a generic base connectivity object.
    """

    def __init__(self, logger, interfaceName, version, ipMethodMap, counters):
        """
        Args:
            logger

        Raises:
            None
        """

        self.interfaceName = interfaceName
        self.version = version
        self.ipMethodMap = ipMethodMap # maps blinky ip version method type specific enum to a generic
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_INTERFACES_CONNECTIVITY_IP % version)

        # data
        self.candidateMethod = MethodTypes.kMethodLink
        self.runningMethod   = MethodTypes.kMethodLink
        self.ndisc = None
        self.ping = None
        self.muteReporting = False

        # dummy
        self.link = a.sys.net.interfaces.connectivity.ConnectivityTestContainer(self._log, 
                                                                               "%s-link%s" % (self.interfaceName, self.version),
                                                                                MethodTypes.kMethodLink) 
        self.countersOnClear = counters

        # status
        self.connectivityOperStatus = None
        self.operStatusReason = ConnectivityOperationalStatusReasonType.kInterfaceFunctionsDoesNotRequireConnectivityCheck
        self.actualMethod   = None

        # counters
        self.numNdiscSuccessfulTests= 0
        self.numNdiscTimeouts       = 0
        self.numNdiscErrors         = 0
        self.numPingSuccessfulTests = 0
        self.numPingTimeouts        = 0
        self.numPingErrors          = 0
        
        # connectivity availability
        self.connectivityStatusMonitor = a.sys.net.interfaces.connectivity.ConnectivityStatusMonitor(self._log)
        
        self.blinkyIpConnectivity = None

#-----------------------------------------------------------------------------------------------------------------------  
    def __str__(self):
        return "%s-ipv%s: ndisc=%s , ping=%s" % (self.interfaceName, self.version, self.ndisc, self.ping)

#-----------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyIpConnectivity):
        self.blinkyIpConnectivity = blinkyIpConnectivity

        # clear-counters
        blinkyIpConnectivity.setDoActionFunctor(self.doActionClearCounters)

        self._registerOnAttachToBlinky(blinkyIpConnectivity)

#-----------------------------------------------------------------------------------------------------------------------
    def setConfigErrorStr(self, msg):
        if self.blinkyIpConnectivity:
            self.blinkyIpConnectivity.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------
    def setOperErrorStr(self, tctx, msg):
        if self.blinkyIpConnectivity is not None:
            self.blinkyIpConnectivity.setTransError(tctx, msg)

#-----------------------------------------------------------------------------------------------------------------------
    def doActionClearCounters(self, userInfo, actionPoint, actionName, params, nParams):
        self._log("do-action-clear-counters").debug2('called. userInfo=%s, actionPoint=%s, actionName=%s, params=%s, nParams=%s', 
                                                     userInfo, actionPoint, actionName, params, nParams)

        rc = self._doClearCounters()
        
        if rc != ReturnCodes.kOk:
            self.blinkyIpConnectivity.setActionError(userInfo, '%s: failed on ipv%s connectivity clear counters', self.interfaceName, self.version)

        return rc

#-----------------------------------------------------------------------------------------------------------------------
    def _doClearCounters(self):
        rc = self._getConnectivityCounters(None, self.countersOnClear, False)
        self._log("do-clear-counters").debug2("%s: clear counters snapshot - %s", self.interfaceName, self.countersOnClear)

        return rc

#-----------------------------------------------------------------------------------------------------------------------
    def preparePrivateValueSet(self, data):
        self._log("prepare-private-value-set").debug2("%s: ipv%s prepare data - %s", self.interfaceName, self.version, data)

        method = self.ipMethodMap.get(data.method, None)

        if method is None:
            self._log("candidate-method-invalid").error("Candidate IPv%s method type '%s' is invalid. see valid options: %s ", 
                                                        self.version, data.method, self.ipMethodMap)
            self.setConfigErrorStr("ipv%s method type '%s' is invalid" % (self.version, data.method))
            return ReturnCodes.kGeneralError

        # we are successfull 
        self.candidateMethod = method
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def commitPrivateValueSet(self, data):
        __pychecker__="no-argsused"  # data not used
        self._log("commit-private-value-set").debug2("%s: ipv%s commit data - %s", self.interfaceName, self.version, data)

        self.runningMethod = self.candidateMethod

        # update connectivity monitor
        currentConnectivity = self.link

        # arp/ndisc6
        if self.runningMethod == MethodTypes.kMethodNeighDisc:
            currentConnectivity = self.ndisc
        # ping/ping6
        elif self.runningMethod == MethodTypes.kMethodPing:
            currentConnectivity = self.ping

        self.connectivityStatusMonitor.setCurrentConnectivityTest(currentConnectivity) 
        self._log("ip-connectivity-check-change").info("ipv%s connectivity check is going to be %s", self.version, self.runningMethod)      
        
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def abortPrivateValueSet(self, data):
        __pychecker__="no-argsused"  # data not used

        self.candidateMethod = self.runningMethod
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def getStatus(self, tctx, operData):

        self._log("ip-connectivity-availability-status").debug3("ipv%s connectivity availability: get status was called. tctx=%s", self.version, tctx)

        operStatusMap = {True  : ConnectivityOperationalStatusType.kUp,
                         False : ConnectivityOperationalStatusType.kDown,
                         None  : ConnectivityOperationalStatusType.kNotApplicable}
        # set data
        operData.setOperationalStatus(operStatusMap.get(self.connectivityOperStatus,ConnectivityOperationalStatusType.kUnknown))
        operData.setOperationalStatusReason(self.operStatusReason)

        if self.actualMethod is not None:
            for method in self.ipMethodMap:
                if self.ipMethodMap[method] == self.actualMethod:
                    operData.setActualMethod(method)
                    break


        self._log("ip-connectivity-status-results").debug3("ipv%s connectivity availability: status results=%s", self.version, operData)
        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def getCounters(self, tctx, operData):

        rc = self._getConnectivityCounters(tctx, operData, True)
        return rc

#-----------------------------------------------------------------------------------------------------------------------
    def _getConnectivityCounters(self, tctx, operData, shouldUseClear):
        self._log("ip-connectivity-availability-counters").debug3("ipv%s connectivity availability: get counters was called. tctx=%s", self.version, tctx)

        # set counters
        operData.setPingRequestsSent(self.numPingSuccessfulTests + self.numPingTimeouts + self.numPingErrors)
        operData.setPingSuccesses(self.numPingSuccessfulTests)
        operData.setPingTimeouts(self.numPingTimeouts)
        operData.setPingFailures(self.numPingErrors)

        self._setNdiscCounters(operData)

        # substract counters on clear
        if shouldUseClear is True :
            self._log("connectivity-counters-original-data").debug4("%s: get original counters oper data=%s", self.interfaceName, operData)

            for key, value in self.countersOnClear.__dict__.iteritems():
                if type(value) is int:
                    operData.__dict__[key]  -= value

        self._log("ip-connectivity-counters-results").debug3("ipv%s connectivity availability: counters results=%s", self.version, operData)

        return ReturnCodes.kOk


#-----------------------------------------------------------------------------------------------------------------------
    def createNeighDisc(self, phase, blinkyNdisc):
        self._log("create-neigh-disc").debug2("phase=%s, ipv%s blinkyNdisc=%s", phase, self.version, blinkyNdisc)

        if (phase.isPreparePrivate()):

            if self.version == 4:
                testName = "arp"
            else:
                testName = "ndisc6"

            ndisc = a.sys.net.interfaces.connectivity.ConnectivityTestContainer(self._log, 
                                                                                "%s-%s" % (self.interfaceName, testName),
                                                                                MethodTypes.kMethodNeighDisc)
            self.ndisc = SimpleContainerWrapper(self._log, ndisc)
            self.ndisc.attachToBlinky(blinkyNdisc)

        elif (phase.isAbortPrivate()):
            self.ndisc = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deleteNeighDisc(self, phase):
        self._log("delete-neigh-disc").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ndisc = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def createPing(self, phase, blinkyPing):
        self._log("create-ping").debug2("phase=%s, ipv%s blinkyPing=%s", phase, self.version, blinkyPing)

        if (phase.isPreparePrivate()):

            ping = a.sys.net.interfaces.connectivity.ConnectivityTestContainer(self._log, 
                                                                               "%s-ping%s" % (self.interfaceName, self.version),
                                                                               MethodTypes.kMethodPing)
            self.ping = SimpleContainerWrapper(self._log, ping)
            self.ping.attachToBlinky(blinkyPing)

        elif (phase.isAbortPrivate()):
            self.ping = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deletePing(self, phase):
        self._log("delete-ping").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ping = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def testConnectivityDone(self, connectivityOperStatus, operStatusReason, actualMethod):

        currentConnectivityOperStatus = self.connectivityOperStatus

        # set data
        self.connectivityOperStatus = connectivityOperStatus
        self.operStatusReason       = operStatusReason
        self.actualMethod           = actualMethod
        
        # ConnectivityTestChange @ user-log
        if self.connectivityOperStatus != currentConnectivityOperStatus:
            self._logUserConnectivityTestChangeMessage()
        
        # we are done
        self.connectivityStatusMonitor.clear()

#-----------------------------------------------------------------------------------------------------------------------
    def testConnectivityCheck(self, osDevice, linkOperStatus, linkAdminStatus, defaultGateway, ipAddress):

        self._log("ip-connectivity-test").debug3("%s: testConnectivityCheck() ipv%s was called - device=%s, oper-status=%s",
                                                         self.interfaceName, self.version, osDevice, linkOperStatus)

        if not osDevice:
            a.infra.process.processFatal("%s: connectivity test ipv%s has no os device associated", self.interfaceName, self.version)


        self._log("ip-connectivity-data").debug4("%s: testConnectivityCheck() ipv%s was called with configuration- admin-status=%s, default-gateway=%s, ip-address=%s",
                                                 self.interfaceName, self.version, linkAdminStatus, defaultGateway, ipAddress)

        # -----------------------------------------
        # phase 1: prepare for connectivity check
        # -----------------------------------------

        # admin-down --> 
        #  - oper-status:   n/a
        #  - actual-method: disabled
        if linkAdminStatus is False:
            self._log("connectivity-admin-down").debug3("%s: connectivity test ipv%s admin is down", self.interfaceName, self.version)
            self.testConnectivityDone(None, ConnectivityOperationalStatusReasonType.kInterfaceAdministrativelyDown, None)
            return

        # no ip address --> 
        #  - oper-status:   n/a
        #  - actual-method: disabled
        if not ipAddress:
            self._log("connectivity-no-ip").debug3("%s: connectivity test ipv%s has no ip", self.interfaceName, self.version)
            self.testConnectivityDone(None, ConnectivityOperationalStatusReasonType.kInterfaceHasNoIpAddress, None)
            return 


        # -----------------------------------------
        # phase 2: choose actual connectivity check
        # -----------------------------------------

        self.connectivityStatusMonitor.oneTick()
        method = self.connectivityStatusMonitor.getTestMethod(default=MethodTypes.kMethodLink)
        self._log("connectivity-method-test-config").debug3("%s: configured connectivity test ipv%s - method=%s", self.interfaceName, self.version, method)

        # no default gateway (no ping/arp/ndisc)
        if not defaultGateway:
            self._log("connectivity-no-default-gateway").debug3("%s: connectivity test ipv%s has no defaultGateway", self.interfaceName, self.version)
            method = MethodTypes.kMethodLink

        # link is down (no ping/arp/ndisc)
        operStateStr = a.sys.net.lnx.device.DeviceUtils.getOperState(osDevice, self._log, osDevice)
        linkCurrentStatus = (operStateStr == "up")
        if linkCurrentStatus is False and linkOperStatus is False:
            self._log("connectivity-oper-down").debug3("%s: connectivity test ipv%s link oper is down", self.interfaceName, self.version)
            method = MethodTypes.kMethodLink

        # -----------------------------------------
        # phase 3: link check
        # -----------------------------------------
        
        isConnectivityAvailable = False
        downOperStatusReason = ConnectivityOperationalStatusReasonType.kUnknown
        self._log("connectivity-method-test-running").debug3("%s: running connectivity test ipv%s - method=%s", self.interfaceName, self.version, method)

        # link 
        if method == MethodTypes.kMethodLink:
           
            operStatusReason = ConnectivityOperationalStatusReasonType.kSuccess
            if linkOperStatus is False:
                operStatusReason = ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown               

            self.testConnectivityDone(linkOperStatus, operStatusReason, MethodTypes.kMethodLink)
            return

        # -----------------------------------------
        # phase 4: execute connectivity check
        # -----------------------------------------
        if self.connectivityStatusMonitor.shouldTest() is False:
            return

        self._log("connectivity-test-run").debug3("%s: going to run connectivity test ipv%s - method=%s", self.interfaceName, self.version, method)

        # arp/ndisc (link is up by now)
        if method == MethodTypes.kMethodNeighDisc:

            if self.ndisc.testIntervalSec == 0:
                # assumes arp/ndisc was successful
                isConnectivityAvailable = True
            elif linkCurrentStatus is False:
                # assumes arp/ndisc was failure
                isConnectivityAvailable = False
                rc = (1,)
            else:
                rc = self._sendNeighDiscRequest(osDevice, defaultGateway)
                isConnectivityAvailable = a.sys.net.lnx.common.Command.isReturnOk(rc)
                self._log("connectivity-ndisc-test").debug2("%s: test arp/ndisc ipv%s rc=%s", self.interfaceName, self.version, rc)

            # arping return code: 
            # 0 - Sent 2 probes (1 broadcast(s)) Received 2 response(s)
            # 1 - Sent 2 probes (1 broadcast(s)) Received 0 response(s)
            # 2 - unknown host / unknown iface / etc.
            if isConnectivityAvailable is True:
                self.numNdiscSuccessfulTests += 1
            else:
                if rc[0] != 1:
                    self.numNdiscErrors += 1
                    self._log("connectivity-ndisc-error").debug1("%s: test arp/ndisc ipv%s error=%s", self.interfaceName, self.version, rc[2])
                else:
                    self.numNdiscTimeouts += 1

            # set arp/ndisc down reason
            # note: even if arp/ndsic was successfull for a single test, we might still be in the up-period

            if linkOperStatus is False:
                downOperStatusReason = ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown
            else:
                if self.version == 4:
                    downOperStatusReason = ConnectivityOperationalStatusReasonType.kArpTestFailure
                else:
                    downOperStatusReason = ConnectivityOperationalStatusReasonType.kNeighborDiscoveryTestFailure

        # ping/ping6 (link is up by now)
        elif method == MethodTypes.kMethodPing:

            if self.ping.testIntervalSec == 0:
                # assumes ping/ping6 was successful
                isConnectivityAvailable = True
            elif linkCurrentStatus is False:
                # assumes ping/ping6 was failure
                isConnectivityAvailable = False
                rc = (1,)
            else:
                rc = self._sendPing(osDevice, defaultGateway)
                isConnectivityAvailable = a.sys.net.lnx.common.Command.isReturnOk(rc)
                self._log("connectivity-ping-test").debug4("%s: test ping ipv%s rc=%s", self.interfaceName, self.version, rc)

            # ping return code: 
            # 0 - 1 packets transmitted, 1 received, 0% packet loss
            # 1 - 1 packets transmitted, 0 received, 100% packet loss
            # 2 - unknown host / bad number of packets to transmit / etc.
            if isConnectivityAvailable is True:
                self.numPingSuccessfulTests += 1
            else:
                if rc[0] != 1:
                    self.numPingErrors += 1
                    self._log("connectivity-ping-error").debug1("%s: test ping ipv%s error=%s", self.interfaceName, self.version, rc[2])
                else:
                    self.numPingTimeouts += 1

            # set ping down reason
            # note: even if ping was successfull for a single test, we might still be in the up-period
            if linkOperStatus is False:
                downOperStatusReason = ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown
            else:
                downOperStatusReason = ConnectivityOperationalStatusReasonType.kPingTestFailure

        else:

            isConnectivityAvailable = False
            downOperStatusReason = ConnectivityOperationalStatusReasonType.kUnknown
            self._log("connectivity-unknown-test").error("%s: unknown ipv%s test method type - %s" , self.interfaceName, self.version, method)


        # update connectivity monitor (ran one of the tests ping/arp/ndisc by now)
        self.connectivityStatusMonitor.addTestResult(isConnectivityAvailable)
        currentConnectivityOperStatus = linkOperStatus and self.connectivityStatusMonitor.isConnectivityAvailable()

        self._log("connectivity-test-results").debug3("%s: ipv%s connectivity availability results is '%s' (method=%s)",
                                                 self.interfaceName, self.version, currentConnectivityOperStatus, self.actualMethod)

        if currentConnectivityOperStatus is True:
            currentOperStatusReason = ConnectivityOperationalStatusReasonType.kSuccess
        else:
            currentOperStatusReason = downOperStatusReason

        shouldUserLog = False

        # update oper status reason
        if self.operStatusReason != currentOperStatusReason:
            self._log("connectivity-reason-change").notice("%s: ipv%s connectivity reason changed to %s",
                                                           self.interfaceName, self.version, currentOperStatusReason)
            self.operStatusReason = currentOperStatusReason
            shouldUserLog = True

        # update oper status (if needed)
        if self.connectivityOperStatus != currentConnectivityOperStatus:
            self._log("connectivity-stats-change").notice("%s: ipv%s connectivity status changed to %s",
                                                          self.interfaceName, self.version, currentConnectivityOperStatus)
            self.connectivityOperStatus = currentConnectivityOperStatus 
            shouldUserLog = True

        # update actual method
        self.actualMethod = method

        if shouldUserLog is True:
            # ConnectivityTestChange @ user-log
            self._logUserConnectivityTestChangeMessage()

#-----------------------------------------------------------------------------------------------------------------------
    def _logUserConnectivityTestChangeMessage(self):
        # mute user-log
        if self.muteReporting is True:
            return

        operStatusMap = {True  : "up", 
                         False : "down",
                         None  : "not applicable"}

        operReasonMap = {ConnectivityOperationalStatusReasonType.kLinkOperationalStatusDown         : "link operational status down",
                         ConnectivityOperationalStatusReasonType.kInterfaceFunctionsDoesNotRequireConnectivityCheck : "interface functions does not require connectivity check",
                         ConnectivityOperationalStatusReasonType.kInterfaceHasNoIpAddress           : "interface has no ip address",
                         ConnectivityOperationalStatusReasonType.kArpTestFailure                    : "arp test failure",
                         ConnectivityOperationalStatusReasonType.kPingTestFailure                   : "ping test failure",
                         ConnectivityOperationalStatusReasonType.kNeighborDiscoveryTestFailure      : "neighbor discovery test failure",
                         ConnectivityOperationalStatusReasonType.kInterfaceAdministrativelyDown     : "interface administratively down",
                         ConnectivityOperationalStatusReasonType.kSuccess                           : "success"}

        state = operStatusMap.get(self.connectivityOperStatus,"unknown")
        reason = operReasonMap.get(self.operStatusReason,"unknown")


        # ConnectivityTestChange @ user-log
        a.infra.process.logUserMessage(a.api.user_log.msg.net.ConnectivityTestChange(self.interfaceName, 
                                                                                     "IPv%s" % self.version,
                                                                                     state, 
                                                                                     reason)) 

#-----------------------------------------------------------------------------------------------------------------------
    def isConnectivityAvailable(self):
        if self.connectivityOperStatus is True:
            return True

        return False

#-----------------------------------------------------------------------------------------------------------------------
    def getConnectivityReason(self):
        return self.operStatusReason

#-----------------------------------------------------------------------------------------------------------------------
    def setMuteReporting(self, muteReporting):
        self._log("connectivity-mute-reporting").info("%s: ipv%s connectivity mute reporting was changed to %s",
                                                      self.interfaceName, self.version, muteReporting)
        self.muteReporting = muteReporting

#-----------------------------------------------------------------------------------------------------------------------
    def _sendNeighDiscRequest(self, device, destination):
        raise NotImplementedError

#-----------------------------------------------------------------------------------------------------------------------
    def _sendPing(self, device, destination):
        return a.sys.net.lnx.route.Ping.ping(self._log, 
                                             destination,
                                             source=device,
                                             version=self.version,
                                             count=1,
                                             timeout=self.ping.testTimeoutSec,
                                             blocking=(self.ping.testTimeoutSec>0))

#-----------------------------------------------------------------------------------------------------------------------
    def _registerOnAttachToBlinky(self, blinkyIpConnectivity):
        raise NotImplementedError

#-----------------------------------------------------------------------------------------------------------------------
    def _setNdiscCounters(self, operData):
        raise NotImplementedError
Пример #10
0
class ConnectivityCheck(object):
    """This class represents a connectivity check object"""

    def __init__ (self, logger, interfaceName):
        """Instantiate a new content connectivity check object.

        Args:
            logger

        Raises:
            None
        """

        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_INTERFACES_CONNECTIVITY)

        self.interfaceName = interfaceName
        self.ipv4 = None
        self.ipv6 = None

        self.blinkyConnectivityCheck = None

#-----------------------------------------------------------------------------------------------------------------------  
    def __str__(self):
        strList = []
        strList.append("ipv4 connectivity: %s" % self.ipv4)
        strList.append("ipv6 connectivity: %s" % self.ipv6)

        return '\t'.join(strList) 

#-----------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyConnectivityCheck):

        self._log("notify-attach-blinky").debug2("attach by blinky connectivity check")

        # ipv4
        blinkyConnectivityCheck.setCreateIpv4Functor(self.createIpv4)
        blinkyConnectivityCheck.setDeleteIpv4Functor(self.deleteIpv4)

        # ipv6
        blinkyConnectivityCheck.setCreateIpv6Functor(self.createIpv6)
        blinkyConnectivityCheck.setDeleteIpv6Functor(self.deleteIpv6)

        self.blinkyConnectivityCheck = blinkyConnectivityCheck

#-----------------------------------------------------------------------------------------------------------------------
    def setConfigErrorStr(self, msg):
        if self.blinkyConnectivityCheck:
            self.blinkyConnectivityCheck.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------
    def createIpv4(self, phase, blinkyIpv4):
        self._log("create-service-ipv4").debug2("phase=%s, blinkyIpv4=%s", phase, blinkyIpv4)

        if (phase.isPreparePrivate()):

            ipv4 = ip_service.Ipv4Connectivity(self._log, self.interfaceName)
            self.ipv4 = SimpleContainerWrapper(self._log, ipv4,
                                               setOperDataFunctor=True)
            self.ipv4.attachToBlinky(blinkyIpv4)

        elif (phase.isCommitPublic()):
            self.ipv4.attachToBlinkyOper()
        elif (phase.isAbortPrivate()):
            self.ipv4 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deleteIpv4(self, phase):
        self._log("delete-service-ipv4").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ipv4 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def createIpv6(self, phase, blinkyIpv6):
        self._log("create-service-ipv6").debug2("phase=%s, blinkyIpv6=%s", phase, blinkyIpv6)

        if (phase.isPreparePrivate()):

            ipv6 = ip_service.Ipv6Connectivity(self._log, self.interfaceName)
            self.ipv6 = SimpleContainerWrapper(self._log, ipv6,
                                               setOperDataFunctor=True)
            self.ipv6.attachToBlinky(blinkyIpv6)

        elif (phase.isCommitPublic()):
            self.ipv6.attachToBlinkyOper()
        elif (phase.isAbortPrivate()):
            self.ipv6 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def deleteIpv6(self, phase):
        self._log("delete-service-ipv6").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ipv6 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------
    def actionOnConnectivityCheck(self, osDevice, linkOperStatus, linkAdminStatus, defaultGateway, ipAddress, version=4):
        self._log("action-connectivity-check").debug4("%s: actionOnConnectivityCheck() was called ", self.interfaceName)

        if version == 4 and self.ipv4:
            self.ipv4.testConnectivityCheck(osDevice, linkOperStatus, linkAdminStatus, defaultGateway, ipAddress)
            
        if version == 6 and self.ipv6:
            self.ipv6.testConnectivityCheck(osDevice, linkOperStatus, linkAdminStatus, defaultGateway, ipAddress)  
            
#-----------------------------------------------------------------------------------------------------------------------
    def isConnectivityAvailable(self, version=4):

        isConnectivityAvailable = False

        if version == 4 and self.ipv4:
            isConnectivityAvailable = self.ipv4.isConnectivityAvailable()

        elif version == 6 and self.ipv6:
            isConnectivityAvailable = self.ipv6.isConnectivityAvailable()   

        return isConnectivityAvailable

#-----------------------------------------------------------------------------------------------------------------------
    def getConnectivityReason(self, version=4):

        connectivityReason = None

        if version == 4 and self.ipv4:
            connectivityReason = self.ipv4.getConnectivityReason()

        elif version == 6 and self.ipv6:
            connectivityReason = self.ipv6.getConnectivityReason()   

        return connectivityReason

#-----------------------------------------------------------------------------------------------------------------------
    def setMuteReporting(self, muteReporting):

        if self.ipv4:
            self.ipv4.setMuteReporting(muteReporting)

        if self.ipv6:
            self.ipv6.setMuteReporting(muteReporting)
Пример #11
0
class NameResolutionContainer(object):
    """This class manages the system name resolution information"""

    def __init__ (self, logger):
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_NAME_RESOLUTION)
        self.name = "network-name-resolution"
        self.blinkyNameResolution = None
        self.dns = None
        self.static = None

    #-----------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyNameResolution):
        # --- /tech/system/name-resolution/dns
        blinkyNameResolution.setCreateDnsFunctor(self.createDns)
        blinkyNameResolution.setDeleteDnsFunctor(self.deleteDns)
        # --- /tech/system/name-resolution/static
        blinkyNameResolution.setCreateStaticResolutionFunctor(self.createStaticResolution)
        blinkyNameResolution.setDeleteStaticResolutionFunctor(self.deleteStaticResolution)
        self.blinkyNameResolution = blinkyNameResolution

    #-----------------------------------------------------------------------------------------------------------------------
    def createDns(self, phase, blinkyDns):
        self._log("create-dns").debug2("%s: blinkyDns=%s", phase, blinkyDns)
        if (phase.isPreparePrivate()):
            dns = DnsContainer(self._log)
            self.dns = SimpleContainerWrapper(self._log, dns, 
                                              notifyTrxProgressFunctor = True,
                                              notifyDescendantsModifications = True)
            self.dns.attachToBlinky(blinkyDns)
        elif (phase.isAbortPrivate()):
            self.dns = None
        return ReturnCodes.kOk

    #-----------------------------------------------------------------------------------------------------------------------
    def deleteDns(self, phase):
        self._log("delete-dns").debug2("phase=%s", phase)
        if (phase.isCommitPrivate()):
            self.dns = None
        return ReturnCodes.kOk

    #-----------------------------------------------------------------------------------------------------------------------
    def createStaticResolution(self, phase, blinkyStaticResolution):
        self._log("create-static-resolution").debug2("%s: blinkyStaticResolution=%s", phase, blinkyStaticResolution)
        if (phase.isPreparePrivate()):
            staticResolution = StaticResolutionContainer(self._log)
            self.static = SimpleContainerWrapper(self._log, staticResolution)
            self.static.attachToBlinky(blinkyStaticResolution)
        elif (phase.isAbortPrivate()):
            self.static = None
        return ReturnCodes.kOk

    #-----------------------------------------------------------------------------------------------------------------------
    def deleteStaticResolution(self, phase):
        self._log("delete-static-resolution").debug2("phase=%s", phase)
        if (phase.isCommitPrivate()):
            self.static = None
        return ReturnCodes.kOk

    #-----------------------------------------------------------------------------------------------------------------------
    def getDnsNameServers(self):
        return self.dns.getNameServers()

    #-----------------------------------------------------------------------------------------------------------------------
    def getDnsSearchDomains(self):
        return self.dns.getSearchDomains()

    #-----------------------------------------------------------------------------------------------------------------------
    def getDnsEnabled(self):
        return self.dns.getEnabled()

    #-----------------------------------------------------------------------------------------------------------------------
    def getStaticHosts(self):
        hosts = []
        if self.static:
            hosts = self.static.getHosts()
        return hosts
Пример #12
0
class Content(object):
    """This class represents a content service object"""
    def __init__(self, logger):
        """Instantiate a new content service object.

        Args:
            logger

        Raises:
            None
        """

        self._log = logger.createLoggerSameModule(
            G_NAME_GROUP_NET_INTERFACES_CONTENT)

        self.analytics = None
        self.acquisition = None
        self.delivery = None

        self.blinkyContent = None

#-----------------------------------------------------------------------------------------------------------------------

    def __str__(self):
        strList = []
        strList.append("analytics: %s" % self.analytics)
        strList.append("acquisition: %s" % self.acquisition)
        strList.append("delivery: %s" % self.delivery)

        return '\t'.join(strList)

#-----------------------------------------------------------------------------------------------------------------------

    def notifyAttachToBlinky(self, blinkyContent):

        self._log("notify-attach-blinky").debug2("attach by blinky content")

        # analytics
        blinkyContent.setCreateAnalyticsFunctor(self.createAnalytics)
        blinkyContent.setDeleteAnalyticsFunctor(self.deleteAnalytics)

        # acquisition
        blinkyContent.setCreateAcquisitionFunctor(self.createAcquistion)
        blinkyContent.setDeleteAcquisitionFunctor(self.deleteAcquistion)

        # delivery
        blinkyContent.setCreateDeliveryFunctor(self.createDelivery)
        blinkyContent.setDeleteDeliveryFunctor(self.deleteDelivery)

        self.blinkyContent = blinkyContent

#-----------------------------------------------------------------------------------------------------------------------

    def setConfigErrorStr(self, msg):
        if self.blinkyContent:
            self.blinkyContent.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------

    def createAnalytics(self, phase, blinkyAnalytics):
        self._log("create-analytics").debug2("phase=%s, blinkyAnalytics=%s",
                                             phase, blinkyAnalytics)

        if (phase.isPreparePrivate()):

            analytics = service.AnalyticsService(self._log)
            self.analytics = SimpleContainerWrapper(self._log, analytics)
            self.analytics.attachToBlinky(blinkyAnalytics)

        elif (phase.isAbortPrivate()):
            self.analytics = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteAnalytics(self, phase):
        self._log("delete-analytics").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.analytics = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def createAcquistion(self, phase, blinkyAcquistion):
        self._log("create-acquisition").debug2("phase=%s, blinkyAcquistion=%s",
                                               phase, blinkyAcquistion)

        if (phase.isPreparePrivate()):

            acquisition = service.AcquistionService(self._log)
            self.acquisition = SimpleContainerWrapper(self._log, acquisition)
            self.acquisition.attachToBlinky(blinkyAcquistion)

        elif (phase.isAbortPrivate()):
            self.acquisition = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteAcquistion(self, phase):
        self._log("delete-acquisition").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.acquisition = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def createDelivery(self, phase, blinkyDelivery):
        self._log("create-delivery").debug2("phase=%s, blinkyDelivery=%s",
                                            phase, blinkyDelivery)

        if (phase.isPreparePrivate()):

            delivery = service.DeliveryService(self._log)
            self.delivery = SimpleContainerWrapper(self._log, delivery)
            self.delivery.attachToBlinky(blinkyDelivery)

        elif (phase.isAbortPrivate()):
            self.delivery = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteDelivery(self, phase):
        self._log("delete-delivery").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.delivery = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def isLineEnabled(self):
        if ((not self.analytics is None)
                and (self.analytics.isServiceEnabled() is True)):
            return True

        if ((not self.acquisition is None)
                and (self.acquisition.isServiceEnabled() is True)):
            return True

        return False

#-----------------------------------------------------------------------------------------------------------------------

    def isDeliveryEnabled(self):
        if self.delivery is None:
            return False

        return self.delivery.isServiceEnabled()

#-----------------------------------------------------------------------------------------------------------------------

    def preparePrivateAfter(self):
        """all content services are being evaluated and verified for correctness system-wise"""

        self._log("content-prepare-private-after").debug3(
            "Content: preparePrivateAfter was called")

        # delivey and line cannot coexist
        if self.isDeliveryEnabled() is True:

            if self.isLineEnabled() is True:
                self._log("delivery-and-line").error(
                    "Delivey and Line cannot coexist")
                self.setConfigErrorStr(
                    "Delivey and Analytics/Acquisition is not supported")
                return ReturnCodes.kGeneralError

        elif self.isLineEnabled() is True:

            # cannot acquire without analytics
            if not ((self.analytics.isServiceEnabled() is True) and
                    (self.acquisition.isServiceEnabled() is True)):
                self._log("acquire-without-analytics").error(
                    "Cannot acquire without analytics")
                self.setConfigErrorStr(
                    "Acquisition without Analytics is not supported")
                return ReturnCodes.kGeneralError

        return ReturnCodes.kOk
Пример #13
0
class DnsContainer(object):
    """This class manages the system dns client information"""
    def __init__ (self, logger):
        self._log = logger.createLoggerSameModule(G_NAME_GROUP_NET_NAME_RESOLUTION_DNS)
        self.name = "network-name-resolution-dns"
        self.blinkyDns = None
        self.nameServers = None
        self.searchList = None
        self.enabled = None
        self.candidateEnabled = None

    #-------------------------------------------------------------------------------------------------------------------
    def getEnabled(self):
        return self.candidateEnabled

    #-------------------------------------------------------------------------------------------------------------------
    def getNameServers(self):
        nameServers = []
        if self.nameServers and self.nameServers.ipv4:
            nameServers = self.nameServers.ipv4.getServers()                
        return nameServers

    #-------------------------------------------------------------------------------------------------------------------
    def getSearchDomains(self):
        searchDomains = []
        if self.searchList:
            candidates = self.searchList.candidateValues()
            for candidate in candidates:
                searchDomains.append(candidate.getName())
        return searchDomains

    #-------------------------------------------------------------------------------------------------------------------
    def notifyAttachToBlinky(self, blinkyDns):
        # --- /tech/system/name-resolution/dns/name-servers
        blinkyDns.setCreateNameServersFunctor(self.createNameServers)
        blinkyDns.setDeleteNameServersFunctor(self.deleteNameServers)
        # --- /tech/system/name-resolution/dns/search
        blinkyDns.setCreateSearchListFunctor(self.createSearchList)
        blinkyDns.setDeleteSearchListFunctor(self.deleteSearchList)
        self.blinkyDns = blinkyDns

    #-------------------------------------------------------------------------------------------------------------------
    def preparePrivateValueSet(self, data):
        """the dns client is being evaluated and verified for correctness"""
        self._log("dns-prepare-private-value-set").debug4("%s: prepare data - %s", self.name, data)
        self.candidateEnabled = data.enabled
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def abortPrivateValueSet(self, data):
        """the dns client changes are being aborted

            Raises:
                FATAL if fails
        """
        self._log("dns-abort-private-value-set").debug4("%s: abort data - %s", self.name, data)
        self.candidateEnabled = self.enabled
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def commitPrivateValueSet(self, data):
        """the dns client changes are being commited

            Raises:
                FATAL if fails
        """
        self._log("dns-commit-private-value-set").debug4("%s: commit data - %s", self.name, data)
        self.enabled = self.candidateEnabled
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def createNameServers(self, phase, blinkyNameServers):
        self._log("create-nameservers").debug2("%s: blinkyNameServers=%s", phase, blinkyNameServers)
        if (phase.isPreparePrivate()):
            nameServers = NameServersContainer(self._log)
            self.nameServers = SimpleContainerWrapper(self._log, nameServers)
            self.nameServers.attachToBlinky(blinkyNameServers)
        elif (phase.isAbortPrivate()):
            self.nameServers = None
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def deleteNameServers(self, phase):
        self._log("delete-nameservers").debug2("phase=%s", phase)
        if (phase.isCommitPrivate()):
            self.nameServers = None
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def createSearchList(self, phase, blinkySearchList):
        self._log("create-search").debug2("%s: blinkySearchList=%s", phase, blinkySearchList)
        if (phase.isPreparePrivate()):
            createSearchFunctor = self.CreateSearchFunctor()
            self.searchList = SimpleStringList(self._log, createSearchFunctor)
            self.searchList.attachToBlinky(blinkySearchList)
        elif (phase.isAbortPrivate()):
            self.searchList = None
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    def deleteSearchList(self, phase):
        self._log("delete-search").debug2("phase=%s", phase)
        if (phase.isCommitPrivate()):
            self.searchList = None
        return ReturnCodes.kOk

    #-------------------------------------------------------------------------------------------------------------------
    class CreateSearchFunctor(object):
        def __call__(self, logger, name):
            search = SearchContainer(logger, name)
            searchWrapper = SimpleContainerWrapper(logger, search)
            return searchWrapper

    #-------------------------------------------------------------------------------------------------------------------
    def preparePrivateAfter(self):

        # The below limitations are taken from the resolv.conf man page.
        # "The search list is currently limited to six domains with a total of 256 characters."

        searchDomains = self.getSearchDomains()

        if len(searchDomains) > 6:
            self.blinkyDns.setConfigErrorStr("The search list is limited to 6 domains")
            return ReturnCodes.kGeneralError

        searchDomainsLen = 0
        for searchDomain in searchDomains:
            searchDomainsLen += len(searchDomain)

        if searchDomainsLen > 256:
            self.blinkyDns.setConfigErrorStr("The search list is limited to 256 characters")
            return ReturnCodes.kGeneralError

        return ReturnCodes.kOk
Пример #14
0
class ContentInterface(object):
    """This class represents a content interface"""
    def __init__(self, logger, name, setStatusFunc):
        """Instantiate a new content interface object.

        Args:
            name: the interface name

        Raises:
            None
        """

        self._log = logger.createLoggerSameModule(
            G_NAME_GROUP_NET_CONTENT_INTERFACE)
        self.name = name
        self.setStatusFunc = setStatusFunc

        # data
        self.delivery = None

        self.blinkyInterface = None

#-----------------------------------------------------------------------------------------------------------------------

    def __str__(self):
        return "%s: delivery=%s" % (self.name, self.delivery)

#-----------------------------------------------------------------------------------------------------------------------

    def notifyAttachToBlinky(self, blinkyInterface):
        self.blinkyInterface = blinkyInterface

        self._log("notify-attach-blinky").debug2(
            "%s: attach by blinky interface", self.name)

        # Delivery
        blinkyInterface.setCreateDeliveryFunctor(self.createDelivery)
        blinkyInterface.setDeleteDeliveryFunctor(self.deleteDelivery)

#-----------------------------------------------------------------------------------------------------------------------

    def setConfigErrorStr(self, msg):
        if self.blinkyInterface:
            self.blinkyInterface.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------

    def createDelivery(self, phase, blinkyDelivery):
        self._log("create-delivery").debug2("%s: blinkyDelivery=%s", phase,
                                            blinkyDelivery)

        if (phase.isPreparePrivate()):

            delivery = DeliveryContainer(self._log, self)
            self.delivery = SimpleContainerWrapper(self._log, delivery)
            self.delivery.attachToBlinky(blinkyDelivery)

        elif (phase.isAbortPrivate()):
            self.delivery = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteDelivery(self, phase):
        self._log("delete-delivery").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.delivery = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def preparePrivateDestroySelf(self):
        self._log("content-interface-destroy-self").debug2(
            "%s: destroy interface", self.name)
        self.setConfigErrorStr("content interface '%s' cannot be deleted" %
                               self.name)

        return ReturnCodes.kGeneralError
Пример #15
0
class DeliveryContainer(object):
    """This class represents a delivery container"""
    def __init__(self, logger, parent):
        """Instantiate a new content interface object.
        """

        self._log = logger
        self.parent = parent

        # data
        self.candidatePreferredDeliveryInterface = ""
        self.runningData = DeliveryData()

        self.ipv4 = None
        self.ipv6 = None

        self.blinkyDelivery = None

#-----------------------------------------------------------------------------------------------------------------------

    def __str__(self):
        return str(self.runningData)

#-----------------------------------------------------------------------------------------------------------------------

    def notifyAttachToBlinky(self, blinkyDelivery):
        self.blinkyDelivery = blinkyDelivery

        # ipv4
        blinkyDelivery.setCreateIpv4Functor(self.createIpv4)
        blinkyDelivery.setDeleteIpv4Functor(self.deleteIpv4)

        # ipv6
        blinkyDelivery.setCreateIpv6Functor(self.createIpv6)
        blinkyDelivery.setDeleteIpv6Functor(self.deleteIpv6)

        self._log("notify-attach-blinky").debug2(
            "%s: attach by blinky delivery", self.parent.name)

#-----------------------------------------------------------------------------------------------------------------------

    def setConfigErrorStr(self, msg):
        if self.blinkyDelivery:
            self.blinkyDelivery.setConfigErrorStr(msg)

#-----------------------------------------------------------------------------------------------------------------------

    def createIpv4(self, phase, blinkyIpv4):
        self._log("create-ipv4").debug2("%s: blinkyIpv4=%s", phase, blinkyIpv4)

        if (phase.isPreparePrivate()):

            ipv4 = DeliveryIpv4Status(self._log, self.parent)
            self.ipv4 = SimpleContainerWrapper(self._log,
                                               ipv4,
                                               setOperDataFunctor=True)
            self.ipv4.attachToBlinky(blinkyIpv4)

        elif (phase.isCommitPublic()):
            self.ipv4.attachToBlinkyOper()
        elif (phase.isAbortPrivate()):
            self.ipv4 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteIpv4(self, phase):
        self._log("delete-ipv4").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ipv4 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def createIpv6(self, phase, blinkyIpv6):
        self._log("create-ipv6").debug2("%s: blinkyIpv6=%s", phase, blinkyIpv6)

        if (phase.isPreparePrivate()):

            ipv6 = DeliveryIpv6Status(self._log, self.parent)
            self.ipv6 = SimpleContainerWrapper(self._log,
                                               ipv6,
                                               setOperDataFunctor=True)
            self.ipv6.attachToBlinky(blinkyIpv6)

        elif (phase.isCommitPublic()):
            self.ipv6.attachToBlinkyOper()
        elif (phase.isAbortPrivate()):
            self.ipv6 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def deleteIpv6(self, phase):
        self._log("delete-ipv6").debug2("phase=%s", phase)

        if (phase.isCommitPrivate()):
            self.ipv6 = None

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def preparePrivateValueSet(self, data):
        self._log(
            "content-interface-delivery-prepare-private-value-set").debug4(
                "%s: prepare data - %s", self.parent.name, data)

        self.candidatePreferredDeliveryInterface = data.preferredDeliveryInterface

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def abortPrivateValueSet(self, data):
        self._log("content-interface-delivery-abort-private-value-set").debug4(
            "%s: abort data - %s", self.parent.name, data)

        self.candidatePreferredDeliveryInterface = self.runningData.preferredDeliveryInterface

        return ReturnCodes.kOk

#-----------------------------------------------------------------------------------------------------------------------

    def commitPrivateValueSet(self, data):
        self._log(
            "content-interface-delivery-commit-private-value-set").debug4(
                "%s: commit data - %s", self.parent.name, data)

        # copy data
        self.runningData.copyFrom(data)

        return ReturnCodes.kOk