def testLocalThenRemoteVector(self):

        ARUBA_OJS_NET = 'aruba:ojs'
        ARUBA_SAN_NET = 'aruba:san'

        self.rv = linkvector.LinkVector([ARUBA_OJS_NET, ARUBA_SAN_NET])

        self.failUnlessEqual(
            self.rv.vector(ARUBA_OJS_NET, source=ARUBA_SAN_NET), (None, None))
        self.failUnlessEqual(
            self.rv.vector(ARUBA_SAN_NET, source=ARUBA_OJS_NET), (None, None))

        self.rv.updateVector(ARUBA_OJS_NET, 'san', {ARUBA_SAN_NET: 1})
        self.rv.updateVector(ARUBA_SAN_NET, 'ojs', {ARUBA_OJS_NET: 1})
        self.rv.updateVector(ARUBA_SAN_NET, 'bon', {BONAIRE_TOPO: 1})

        self.failUnlessEqual(
            self.rv.vector(ARUBA_OJS_NET, source=ARUBA_SAN_NET),
            (ARUBA_SAN_NET, 'ojs'))
        self.failUnlessEqual(
            self.rv.vector(ARUBA_SAN_NET, source=ARUBA_OJS_NET),
            (ARUBA_OJS_NET, 'san'))

        self.failUnlessEqual(
            self.rv.vector(BONAIRE_TOPO, source=ARUBA_OJS_NET),
            (ARUBA_OJS_NET, 'san'))
        self.failUnlessEqual(
            self.rv.vector(BONAIRE_TOPO, source=ARUBA_SAN_NET),
            (ARUBA_SAN_NET, 'bon'))
Exemple #2
0
    def testMaxCost(self):

        self.rv = linkvector.LinkVector([BONAIRE_TOPO], max_cost=3)

        self.rv.updateVector(ARUBA_PORT, {
            ARUBA_TOPO: 1,
            BONAIRE_TOPO: 1,
            CURACAO_TOPO: 4
        })

        self.failUnlessEqual(self.rv.vector(ARUBA_TOPO), ARUBA_PORT)
        self.failUnlessEqual(self.rv.vector(BONAIRE_TOPO), None)
        self.failUnlessEqual(self.rv.vector(CURACAO_TOPO), None)
Exemple #3
0
    def testLocalNetworkExclusion(self):

        self.rv = linkvector.LinkVector([BONAIRE_TOPO])

        self.rv.updateVector(ARUBA_PORT, {
            ARUBA_TOPO: 1,
            BONAIRE_TOPO: 1,
            CURACAO_TOPO: 2
        })

        self.failUnlessEqual(self.rv.vector(ARUBA_TOPO), ARUBA_PORT)
        self.failUnlessEqual(self.rv.vector(BONAIRE_TOPO), None)
        self.failUnlessEqual(self.rv.vector(CURACAO_TOPO), ARUBA_PORT)
Exemple #4
0
    def testBlackList(self):

        self.rv = linkvector.LinkVector([BONAIRE_TOPO],
                                        blacklist_networks=[CURACAO_TOPO])

        self.rv.updateVector(ARUBA_PORT, {
            ARUBA_TOPO: 1,
            BONAIRE_TOPO: 1,
            CURACAO_TOPO: 2
        })

        self.failUnlessEqual(self.rv.vector(ARUBA_TOPO), ARUBA_PORT)
        self.failUnlessEqual(self.rv.vector(BONAIRE_TOPO), None)
        self.failUnlessEqual(self.rv.vector(CURACAO_TOPO), None)
    def testMaxCost(self):

        self.rv = linkvector.LinkVector([LOCAL_TOPO], max_cost=3)

        self.rv.updateVector(LOCAL_TOPO, ARUBA_PORT, {
            ARUBA_TOPO: 1,
            BONAIRE_TOPO: 2,
            CURACAO_TOPO: 4
        })

        self.failUnlessEqual(self.rv.vector(ARUBA_TOPO, source=LOCAL_TOPO),
                             (LOCAL_TOPO, ARUBA_PORT))
        self.failUnlessEqual(self.rv.vector(BONAIRE_TOPO, source=LOCAL_TOPO),
                             (LOCAL_TOPO, ARUBA_PORT))
        self.failUnlessEqual(self.rv.vector(CURACAO_TOPO, source=LOCAL_TOPO),
                             (None, None))
Exemple #6
0
    def setUp(self):

        db.setupDatabase()

        self.requester = common.DUDRequester()

        self.clock = task.Clock()

        nrm_ports = nrm.parsePortSpec(StringIO(topology.ARUBA_TOPOLOGY))
        network_topology = nml.createNMLNetwork(nrm_ports, self.network,
                                                self.network)

        self.backend = dud.DUDNSIBackend(self.network, nrm_ports, None,
                                         {})  # we set the parent later
        self.backend.scheduler.clock = self.clock

        link_vector = linkvector.LinkVector([self.network])

        pl = plugin.BasePlugin()
        pl.init({config.NETWORK_NAME: self.network}, None)

        pr = provreg.ProviderRegistry(
            {self.provider_agent.urn(): self.backend}, {})
        self.aggregator = aggregator.Aggregator(self.network,
                                                self.provider_agent,
                                                network_topology, link_vector,
                                                None, pr, [],
                                                pl)  # we set the parent later

        self.backend.parent_requester = self.aggregator

        # provider protocol
        http_top_resource = resource.Resource()

        rest.setupService(self.aggregator, http_top_resource)

        # we need this for the aggregator not to blow up
        cs2_prov = nsi2.setupProvider(self.aggregator, http_top_resource)
        self.aggregator.parent_requester = cs2_prov

        provider_factory = server.Site(http_top_resource)
        self.provider_service = internet.TCPServer(self.PORT, provider_factory)

        # start engines!
        self.backend.startService()
        self.provider_service.startService()
    def testMultiNetworkReachability(self):

        self.rv = linkvector.LinkVector([LOCAL_TOPO])

        self.rv.updateVector(LOCAL_TOPO, ARUBA_PORT, {ARUBA_TOPO: 1})
        self.rv.updateVector(ARUBA_TOPO, BONAIRE_PORT, {BONAIRE_TOPO: 1})

        self.failUnlessEqual(self.rv.vector(ARUBA_TOPO, source=LOCAL_TOPO),
                             (LOCAL_TOPO, ARUBA_PORT))
        self.failUnlessEqual(self.rv.vector(BONAIRE_TOPO, source=LOCAL_TOPO),
                             (LOCAL_TOPO, ARUBA_PORT))
        self.failUnlessEqual(self.rv.vector(CURACAO_TOPO, source=LOCAL_TOPO),
                             (None, None))

        self.rv.updateVector(BONAIRE_TOPO, CURACAO_PORT, {CURACAO_TOPO: 1})

        self.failUnlessEqual(self.rv.vector(CURACAO_TOPO, source=LOCAL_TOPO),
                             (LOCAL_TOPO, ARUBA_PORT))
Exemple #8
0
def setupTopology(nrm_map, network_name, base_name):

    link_vector = linkvector.LinkVector([network_name])

    if nrm_map is not None:
        nrm_ports = nrm.parsePortSpec(nrm_map)
        nml_network = nml.createNMLNetwork(nrm_ports, network_name, base_name)

        # route vectors
        # hack in link vectors manually, since we don't have a mechanism for updating them automatically
        for np in nrm_ports:
            if np.remote_network is not None:
                link_vector.updateVector(np.name,
                                         {np.remote_network: 1})  # hack
                for network, cost in np.vectors.items():
                    link_vector.updateVector(np.name, {network: cost})
    else:
        nrm_ports = []
        nml_network = None

    return nrm_ports, nml_network, link_vector
Exemple #9
0
    def setupServiceFactory(self):
        """
        This sets up the OpenNSA service and ties together everything in the initialization.
        There are a lot of things going on, but none of it it particular deep.
        """
        log.msg('OpenNSA service initializing')

        vc = self.vc

        now = datetime.datetime.utcnow().replace(microsecond=0)

        if vc[config.HOST] is None:
            # guess name if not configured
            import socket
            vc[config.HOST] = socket.getfqdn()

        # database
        database.setupDatabase(vc[config.DATABASE], vc[config.DATABASE_USER],
                               vc[config.DATABASE_PASSWORD],
                               vc[config.DATABASE_HOST],
                               vc[config.SERVICE_ID_START])

        service_endpoints = []

        # base names
        domain_name = vc[config.DOMAIN]  # FIXME rename variable to domain
        nsa_name = domain_name + ':nsa'

        # base url
        base_protocol = 'https://' if vc[config.TLS] else 'http://'
        base_url = base_protocol + vc[config.HOST] + ':' + str(vc[config.PORT])

        # nsi endpoint and agent
        provider_endpoint = base_url + '/NSI/services/CS2'  # hardcode for now
        service_endpoints.append(('Provider', provider_endpoint))

        ns_agent = nsa.NetworkServiceAgent(nsa_name, provider_endpoint,
                                           'local')

        # ssl/tls context
        ctx_factory = setupTLSContext(vc)  # May be None

        # plugin
        if vc[config.PLUGIN]:
            from twisted.python import reflect
            plugin = reflect.namedAny('opennsa.plugins.%s.plugin' %
                                      vc[config.PLUGIN])
        else:
            from opennsa.plugin import BasePlugin
            plugin = BasePlugin()

        plugin.init(vc, ctx_factory)

        # the dance to setup dynamic providers right
        top_resource = resource.Resource()
        requester_creator = CS2RequesterCreator(
            top_resource, None, vc[config.HOST], vc[config.PORT],
            vc[config.TLS], ctx_factory)  # set aggregator later

        provider_registry = provreg.ProviderRegistry(
            {cnt.CS2_SERVICE_TYPE: requester_creator.create})

        link_vector = linkvector.LinkVector()

        networks = {}
        ports = {}  # { network : { port : nrmport } }

        parent_requester = None  # parent requester is set later
        aggr = aggregator.Aggregator(ns_agent, ports, link_vector,
                                     parent_requester, provider_registry,
                                     vc[config.POLICY], plugin)

        requester_creator.aggregator = aggr

        pc = nsi2.setupProvider(aggr,
                                top_resource,
                                ctx_factory=ctx_factory,
                                allowed_hosts=vc.get(config.ALLOWED_HOSTS))
        aggr.parent_requester = pc

        # setup backend(s) - for now we only support one
        backend_configs = vc['backend']
        if len(backend_configs) == 0:
            log.msg('No backend specified. Running in aggregator-only mode')
            if not cnt.AGGREGATOR in vc[config.POLICY]:
                vc[config.POLICY].append(cnt.AGGREGATOR)

        else:  # at least one backend

            # This is all temporary right now... clean up later

            for backend_name, b_cfg in backend_configs.items():

                if backend_name is None or backend_name == '':
                    raise config.ConfigurationError(
                        'You need to specify backend name, use [backend:name]')

                backend_network_name = '{}:{}'.format(domain_name,
                                                      backend_name)

                if not config.NRM_MAP_FILE in b_cfg:  # move to verify config
                    raise config.ConfigurationError(
                        'No nrm map specified for backend')

                backend_nrm_map_file = b_cfg[config.NRM_MAP_FILE]
                if not os.path.exists(
                        backend_nrm_map_file):  # move to verify config
                    raise config.ConfigError(
                        'nrm map file {} for backend {} does not exists'.
                        format(backend_nrm_map_file, backend_name))

                nrm_map = open(backend_nrm_map_file)
                backend_nrm_ports = nrm.parsePortSpec(nrm_map)

                link_vector.addLocalNetwork(backend_network_name)
                for np in backend_nrm_ports:
                    if np.remote_network is not None:
                        link_vector.updateVector(
                            backend_network_name, np.name,
                            {np.remote_network: 1})  # hack
                        for network, cost in np.vectors.items():
                            link_vector.updateVector(np.name, {network: cost})
                    # build port map for aggreator to lookup
                    ports.setdefault(backend_network_name, {})[np.name] = np

                backend_service = setupBackend(b_cfg, backend_network_name,
                                               backend_nrm_ports, aggr)

                networks[backend_network_name] = {
                    'backend': backend_service,
                    'nrm_ports': backend_nrm_ports
                }

                provider_registry.addProvider(ns_agent.urn(),
                                              backend_network_name,
                                              backend_service)

        # fetcher
        if vc[config.PEERS]:
            fetcher_service = fetcher.FetcherService(link_vector,
                                                     networks,
                                                     vc[config.PEERS],
                                                     provider_registry,
                                                     ctx_factory=ctx_factory)
            fetcher_service.setServiceParent(self)
        else:
            log.msg(
                'No peers configured, will not be able to do outbound requests (UPA mode)'
            )

        # discovery service
        opennsa_version = 'OpenNSA-' + version
        network_urns = [
            '{}{}'.format(cnt.URN_OGF_PREFIX, network_name)
            for network_name in networks
        ]
        interfaces = [(cnt.CS2_PROVIDER, provider_endpoint, None),
                      (cnt.CS2_SERVICE_TYPE, provider_endpoint, None)]
        features = []
        if networks:
            features.append((cnt.FEATURE_UPA, None))
        if vc[config.PEERS]:
            features.append((cnt.FEATURE_AGGREGATOR, None))

        # view resource
        vr = viewresource.ConnectionListResource()
        top_resource.children[NSI_RESOURCE].putChild('connections', vr)

        # rest service
        if vc[config.REST]:
            rest_url = base_url + '/connections'

            rest.setupService(aggr, top_resource, vc.get(config.ALLOWED_HOSTS))

            service_endpoints.append(('REST', rest_url))
            interfaces.append((cnt.OPENNSA_REST, rest_url, None))

        for backend_network_name, no in networks.items():

            nml_resource_name = '{}.nml.xml'.format(backend_network_name)
            nml_url = '%s/NSI/%s' % (base_url, nml_resource_name)

            nml_network = nml.createNMLNetwork(no['nrm_ports'],
                                               backend_network_name,
                                               backend_network_name)
            can_swap_label = no['backend'].connection_manager.canSwapLabel(
                cnt.ETHERNET_VLAN)

            nml_service = nmlservice.NMLService(nml_network, can_swap_label)

            top_resource.children[NSI_RESOURCE].putChild(
                nml_resource_name.encode(), nml_service.resource())

            service_endpoints.append(('NML Topology', nml_url))
            interfaces.append((cnt.NML_SERVICE_TYPE, nml_url, None))

        # discovery service
        discovery_resource_name = b'discovery.xml'
        discovery_url = '%s/NSI/%s' % (base_url,
                                       discovery_resource_name.decode())

        ds = discoveryservice.DiscoveryService(ns_agent.urn(), now,
                                               domain_name, opennsa_version,
                                               now, network_urns, interfaces,
                                               features, provider_registry,
                                               link_vector)

        discovery_resource = ds.resource()
        top_resource.children[NSI_RESOURCE].putChild(discovery_resource_name,
                                                     discovery_resource)
        link_vector.callOnUpdate(
            lambda: discovery_resource.updateResource(ds.xml()))

        service_endpoints.append(('Discovery', discovery_url))

        # log service urls
        for service_name, url in service_endpoints:
            log.msg('{:<12} URL: {}'.format(service_name, url))

        factory = server.Site(top_resource)
        factory.log = httplog.logRequest  # default logging is weird, so we do our own

        return factory, ctx_factory
Exemple #10
0
    def setUp(self):

        self.rv = linkvector.LinkVector([LOCAL_TOPO])
Exemple #11
0
    def startService(self):
        """
        This sets up the OpenNSA service and ties together everything in the initialization.
        There are a lot of things going on, but none of it it particular deep.
        """
        log.msg('OpenNSA service initializing')

        vc = self.vc

        now = datetime.datetime.utcnow().replace(microsecond=0)

        if vc[config.HOST] is None:
            # guess name if not configured
            import socket
            vc[config.HOST] = socket.getfqdn()

        # database
        database.setupDatabase(vc[config.DATABASE], vc[config.DATABASE_USER], vc[config.DATABASE_PASSWORD])

        # base names
        base_name = vc[config.NETWORK_NAME]
        network_name = base_name + ':topology' # because we say so
        nsa_name  = base_name + ':nsa'

        # url stuffs
        base_protocol = 'https://' if vc[config.TLS] else 'http://'
        base_url = base_protocol + vc[config.HOST] + ':' + str(vc[config.PORT])

        # nsi agent
        provider_endpoint = base_url + '/NSI/services/CS2' # hardcode for now
        ns_agent = nsa.NetworkServiceAgent(nsa_name, provider_endpoint, 'local')

        # topology
        nrm_ports = nrm.parsePortSpec( open( vc[config.NRM_MAP_FILE] ) )
        network_topology = nml.createNMLNetwork(nrm_ports, network_name, base_name)

        # route vectors
        link_vector = linkvector.LinkVector( [ network_name ] )
        # hack in link vectors manually, since we don't have a mechanism for updating them automatically
        for np in nrm_ports:
            if np.remote_network is not None:
                link_vector.updateVector(np.name, { np.remote_network : 1 } ) # hack
                for network, cost in np.vectors.items():
                    link_vector.updateVector(np.name, { network : cost })

        # ssl/tls contxt
        if vc[config.TLS]:
            from opennsa import ctxfactory
            ctx_factory = ctxfactory.ContextFactory(vc[config.KEY], vc[config.CERTIFICATE], vc[config.CERTIFICATE_DIR], vc[config.VERIFY_CERT])
        elif os.path.isdir(vc[config.CERTIFICATE_DIR]):
            # we can at least create a context
            from opennsa import ctxfactory
            ctx_factory = ctxfactory.RequestContextFactory(vc[config.CERTIFICATE_DIR], vc[config.VERIFY_CERT])
        else:
            ctx_factory = None

        # plugin
        if vc[config.PLUGIN]:
            from twisted.python import reflect
            plugin = reflect.namedAny('opennsa.plugins.%s.plugin' % vc[config.PLUGIN])
        else:
            from opennsa.plugin import BasePlugin
            plugin = BasePlugin()
        plugin.init(vc, ctx_factory)

        # the dance to setup dynamic providers right
        top_resource = resource.Resource()
        requester_creator = CS2RequesterCreator(top_resource, None, vc[config.HOST], vc[config.PORT], vc[config.TLS], ctx_factory) # set aggregator later

        provider_registry = provreg.ProviderRegistry({}, { cnt.CS2_SERVICE_TYPE : requester_creator.create } )
        aggr = aggregator.Aggregator(network_topology.id_, ns_agent, network_topology, link_vector, None, provider_registry, vc[config.POLICY], plugin ) # set parent requester later

        requester_creator.aggregator = aggr

        pc = nsi2.setupProvider(aggr, top_resource, ctx_factory=ctx_factory, allowed_hosts=vc.get(config.ALLOWED_HOSTS))
        aggr.parent_requester = pc

        # setup backend(s) - for now we only support one

        backend_configs = vc['backend']
        if len(backend_configs) > 1:
            raise config.ConfigurationError('Only one backend supported for now. Multiple will probably come later.')

        backend_cfg = backend_configs.values()[0]

        backend_service = setupBackend(backend_cfg, network_topology.id_, nrm_ports, aggr)
        backend_service.setServiceParent(self)
        can_swap_label = backend_service.connection_manager.canSwapLabel(cnt.ETHERNET_VLAN)

        provider_registry.addProvider(ns_agent.urn(), backend_service, [ network_topology.id_ ] )

        # fetcher
        if vc[config.PEERS]:
            fetcher_service = fetcher.FetcherService(link_vector, nrm_ports, vc[config.PEERS], provider_registry, ctx_factory=ctx_factory)
            fetcher_service.setServiceParent(self)

        # wire up the http stuff

        discovery_resource_name = 'discovery.xml'
        nml_resource_name       = base_name + '.nml.xml'
        nml_resource_url        = '%s/NSI/%s' % (base_url, nml_resource_name)

        # discovery service
        name = base_name.split(':')[0] if ':' in base_name else base_name
        opennsa_version = 'OpenNSA-' + version
        networks    = [ cnt.URN_OGF_PREFIX + network_name ]
        interfaces  = [ ( cnt.CS2_PROVIDER, provider_endpoint, None), ( cnt.CS2_SERVICE_TYPE, provider_endpoint, None), (cnt.NML_SERVICE_TYPE, nml_resource_url, None) ]
        features    = [ (cnt.FEATURE_AGGREGATOR, None), (cnt.FEATURE_UPA, None) ]
        ds = discoveryservice.DiscoveryService(ns_agent.urn(), now, name, opennsa_version, now, networks, interfaces, features, provider_registry, link_vector)

        discovery_resource = ds.resource()
        top_resource.children['NSI'].putChild(discovery_resource_name, discovery_resource)
        link_vector.callOnUpdate( lambda : discovery_resource.updateResource ( ds.xml() ))

        # view resource
        vr = viewresource.ConnectionListResource(aggr)
        top_resource.children['NSI'].putChild('connections', vr)

        # topology
        nml_service = nmlservice.NMLService(network_topology, can_swap_label)
        top_resource.children['NSI'].putChild(nml_resource_name, nml_service.resource() )

        log.msg('Provider  URL: %s' % provider_endpoint )
        log.msg('Discovery URL: %s/NSI/%s' % (base_url, discovery_resource_name) )
        log.msg('Topology  URL: %s' % (nml_resource_url) )

        factory = server.Site(top_resource)
        factory.log = httplog.logRequest # default logging is weird, so we do our own

        if vc[config.TLS]:
            internet.SSLServer(vc[config.PORT], factory, ctx_factory).setServiceParent(self)
        else:
            internet.TCPServer(vc[config.PORT], factory).setServiceParent(self)

        # do not start sub-services until we have started this one
        twistedservice.MultiService.startService(self)

        log.msg('OpenNSA service started')