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