def _makeHTTPService(self): """Create the HTTP service.""" from provisioningserver.rackdservices.http import HTTPResource from twisted.application.internet import StreamServerEndpointService from twisted.internet.endpoints import AdoptedStreamServerEndpoint from provisioningserver.utils.twisted import SiteNoLog port = 5249 s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except socket_error as e: if e.errno != ENOPROTOOPT: raise e s.bind(('::', port)) # Use a backlog of 50, which seems to be fairly common. s.listen(50) # Adopt this socket into Twisted's reactor. site_endpoint = AdoptedStreamServerEndpoint(reactor, s.fileno(), s.family) site_endpoint.port = port # Make it easy to get the port number. site_endpoint.socket = s # Prevent garbage collection. http_service = StreamServerEndpointService(site_endpoint, SiteNoLog(HTTPResource())) http_service.setName("http_service") return http_service
def create_prometheus_exporter_service(reactor, port): """Return a service exposing prometheus metrics on the specified port.""" root = Resource() root.putChild(b"metrics", PrometheusMetricsResource(PROMETHEUS_METRICS)) site = Site(root, logFormatter=reducedWebLogFormatter) endpoint = TCP6ServerEndpoint(reactor, port) service = StreamServerEndpointService(endpoint, site) service.setName("prometheus-exporter") return service
def _build_api_service(self): """ Once called, the resource is initialized. Any calls to self._add_resource() should be done before calling this fn. :return: """ wsgi_app = self.anchore_service.get_api_application() wsgi_site = wsgi.WSGIResource(reactor, reactor.getThreadPool(), application=wsgi_app) self._add_resource(self.anchore_service.__service_api_version__.encode('utf-8'), wsgi_site) self.root_resource = web.resource.Resource() # Add nodes for name, resource in self.resource_nodes.items(): self.root_resource.putChild(name, resource) # this will rewrite any calls that do not have an explicit version to the base path before being processed by flask self._api_version_bytes = self.anchore_service.__service_api_version__.encode('utf-8') # This is optimization # Handle the auth vs non-auth child resources to not consume a path element root = rewrite.RewriterResource(self.root_resource, self._default_version_rewrite) # Build the main site server site = server.Site(root) listen = self.anchore_service.configuration['listen'] if str(self.anchore_service.configuration.get('ssl_enable', '')).lower() == 'true': try: ssl_data = { 'ssl_cert': _load_ssl_cert(self.anchore_service.configuration['ssl_cert']) if 'ssl_cert' in self.anchore_service.configuration else None, 'ssl_chain': _load_ssl_cert(self.anchore_service.configuration['ssl_chain']) if 'ssl_chain' in self.anchore_service.configuration else None, 'ssl_key': _load_ssl_key(self.anchore_service.configuration['ssl_key']) if 'ssl_key' in self.anchore_service.configuration else None } if ssl_data['ssl_chain']: sfact = ssl.CertificateOptions(privateKey=ssl_data['ssl_key'], certificate=ssl_data['ssl_cert'], extraCertChain=[ssl_data['ssl_chain']]) else: sfact = ssl.CertificateOptions(privateKey=ssl_data['ssl_key'], certificate=ssl_data['ssl_cert']) endpoint = SSL4ServerEndpoint(reactor=reactor, port=int(self.anchore_service.configuration['port']), sslContextFactory=sfact, interface=listen) except Exception as err: raise err else: endpoint = TCP4ServerEndpoint(reactor=reactor, port=int(self.anchore_service.configuration['port']), interface=listen) ret_svc = StreamServerEndpointService(endpoint=endpoint, factory=site) ret_svc.setName(self.anchore_service.name) return ret_svc
def _build_api_service(self): """ Once called, the resource is initialized. Any calls to self._add_resource() should be done before calling this fn. :return: """ thread_count = int( self.service_config.get('max_request_threads', localconfig.DEFAULT_SERVICE_THREAD_COUNT)) wsgi_app = self.anchore_service.get_api_application() wsgi_site = wsgi.WSGIResource(reactor, reactor.getThreadPool(), application=wsgi_app) reactor.getThreadPool().adjustPoolsize(maxthreads=thread_count) logger.debug('Thread pool size stats. Min={}, Max={}'.format( reactor.getThreadPool().min, reactor.getThreadPool().max)) self._add_resource( self.anchore_service.__service_api_version__.encode('utf-8'), wsgi_site) if enable_thread_dumper: logger.warn( "Adding thread dump route for debugging since debug flag is set. This is dangerous and should not be done in normal production" ) self._add_resource(b'threads', ThreadDumperResource()) self.root_resource = web.resource.Resource() # Add nodes for name, resource in self.resource_nodes.items(): self.root_resource.putChild(name, resource) # this will rewrite any calls that do not have an explicit version to the base path before being processed by flask self._api_version_bytes = self.anchore_service.__service_api_version__.encode( 'utf-8') # This is optimization # Handle the auth vs non-auth child resources to not consume a path element root = rewrite.RewriterResource(self.root_resource, self._default_version_rewrite) # Build the main site server site = server.Site(root) listen = self.anchore_service.configuration['listen'] # Disable the twisted access logging by overriding the log function as it uses a raw 'write' and cannot otherwise be disabled, iff enable_access_logging is set to False in either the service or global config try: eal = True if "enable_access_logging" in self.anchore_service.configuration: eal = self.anchore_service.configuration.get( "enable_access_logging", True) elif "enable_access_logging" in self.configuration: eal = self.configuration.get("enable_access_logging", True) if not eal: def _null_logger(request): pass site.log = _null_logger except: pass if str(self.anchore_service.configuration.get('ssl_enable', '')).lower() == 'true': try: ssl_data = { 'ssl_cert': _load_ssl_cert( self.anchore_service.configuration['ssl_cert']) if 'ssl_cert' in self.anchore_service.configuration else None, 'ssl_chain': _load_ssl_cert( self.anchore_service.configuration['ssl_chain']) if 'ssl_chain' in self.anchore_service.configuration else None, 'ssl_key': _load_ssl_key( self.anchore_service.configuration['ssl_key']) if 'ssl_key' in self.anchore_service.configuration else None } if ssl_data['ssl_chain']: sfact = ssl.CertificateOptions( privateKey=ssl_data['ssl_key'], certificate=ssl_data['ssl_cert'], extraCertChain=[ssl_data['ssl_chain']]) else: sfact = ssl.CertificateOptions( privateKey=ssl_data['ssl_key'], certificate=ssl_data['ssl_cert']) endpoint = SSL4ServerEndpoint( reactor=reactor, port=int(self.anchore_service.configuration['port']), sslContextFactory=sfact, interface=listen) except Exception as err: raise err else: endpoint = TCP4ServerEndpoint( reactor=reactor, port=int(self.anchore_service.configuration['port']), interface=listen) ret_svc = StreamServerEndpointService(endpoint=endpoint, factory=site) ret_svc.setName(self.anchore_service.name) return ret_svc