示例#1
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],
                               vc[config.DATABASE_HOST],
                               vc[config.SERVICE_ID_START])

        service_endpoints = []

        # base names
        base_name = vc[config.NETWORK_NAME]
        network_name = base_name + ':topology'  # because we say so
        nsa_name = base_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')

        # topology
        nrm_map = open(vc[config.NRM_MAP_FILE]) if vc[
            config.NRM_MAP_FILE] is not None else None
        nrm_ports, nml_network, link_vector = setupTopology(
            nrm_map, network_name, base_name)

        # 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})
        aggr = aggregator.Aggregator(network_name, ns_agent, nml_network,
                                     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) == 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)
        elif len(backend_configs) > 1:
            raise config.ConfigurationError(
                'Only one backend supported for now. Multiple will probably come later.'
            )
        else:  # 1 backend
            if not nrm_ports:
                raise config.ConfigurationError(
                    'No NRM Map file specified. Cannot configure a backend without port spec.'
                )

            backend_cfg = backend_configs.values()[0]

            backend_service = setupBackend(backend_cfg, network_name,
                                           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_name])

        # 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)
        else:
            log.msg(
                'No peers configured, will not be able to do outbound requests.'
            )

        # 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] if nml_network is not None else []
        interfaces = [(cnt.CS2_PROVIDER, provider_endpoint, None),
                      (cnt.CS2_SERVICE_TYPE, provider_endpoint, None)]
        features = []
        if nrm_ports:
            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'].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))

        # nml topology
        if nml_network is not None:
            nml_resource_name = base_name + '.nml.xml'
            nml_url = '%s/NSI/%s' % (base_url, nml_resource_name)

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

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

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

        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()))

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

        # print 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

        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')
示例#2
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
示例#3
0
文件: setup.py 项目: b0urn3/opennsa
    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')