def run(self) -> None: try: try: old_creds = self.mgr.get_store('cephadm_endpoint_credentials') if not old_creds: raise OrchestratorError('No old credentials for cephadm endpoint found') old_creds_dict = json.loads(old_creds) old_key = old_creds_dict['key'] old_cert = old_creds_dict['cert'] self.ssl_certs.load_root_credentials(old_cert, old_key) except (OrchestratorError, json.decoder.JSONDecodeError, KeyError, ValueError): self.ssl_certs.generate_root_cert() cert, key = self.ssl_certs.generate_cert() self.key_tmp = tempfile.NamedTemporaryFile() self.key_tmp.write(key.encode('utf-8')) self.key_tmp.flush() # pkey_tmp must not be gc'ed key_fname = self.key_tmp.name self.cert_tmp = tempfile.NamedTemporaryFile() self.cert_tmp.write(cert.encode('utf-8')) self.cert_tmp.flush() # cert_tmp must not be gc'ed cert_fname = self.cert_tmp.name verify_tls_files(cert_fname, key_fname) cherrypy.config.update({ 'server.socket_host': self.server_addr, 'server.socket_port': self.server_port, 'engine.autoreload.on': False, 'server.ssl_module': 'builtin', 'server.ssl_certificate': cert_fname, 'server.ssl_private_key': key_fname, }) root_conf = {'/': {'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'tools.response_headers.on': True}} cherrypy.tree.mount(Root(self.mgr), '/', root_conf) self.mgr.log.debug('Starting cherrypy engine...') self.start_engine() self.mgr.log.debug('Cherrypy engine started.') cephadm_endpoint_creds = { 'cert': self.ssl_certs.get_root_cert(), 'key': self.ssl_certs.get_root_key() } self.mgr.set_store('cephadm_endpoint_credentials', json.dumps(cephadm_endpoint_creds)) self.mgr._kick_serve_loop() # wait for the shutdown event self.cherrypy_shutdown_event.wait() self.cherrypy_shutdown_event.clear() cherrypy.engine.stop() self.mgr.log.debug('Cherrypy engine stopped.') except Exception as e: self.mgr.log.error(f'Failed to run cephadm cherrypy endpoint: {e}')
def run(self) -> None: try: server_addr = self.mgr.get_mgr_ip() server_port = self.mgr.endpoint_port self.ssl_certs.generate_root_cert() cert, key = self.ssl_certs.generate_cert() self.key_tmp = tempfile.NamedTemporaryFile() self.key_tmp.write(key.encode('utf-8')) self.key_tmp.flush() # pkey_tmp must not be gc'ed key_fname = self.key_tmp.name self.cert_tmp = tempfile.NamedTemporaryFile() self.cert_tmp.write(cert.encode('utf-8')) self.cert_tmp.flush() # cert_tmp must not be gc'ed cert_fname = self.cert_tmp.name verify_tls_files(cert_fname, key_fname) self.mgr.set_uri('https://{0}:{1}/'.format(server_addr, server_port)) cherrypy.config.update({ 'server.socket_host': server_addr, 'server.socket_port': server_port, 'engine.autoreload.on': False, 'server.ssl_module': 'builtin', 'server.ssl_certificate': cert_fname, 'server.ssl_private_key': key_fname, }) root_conf = { '/': { 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'tools.response_headers.on': True } } cherrypy.tree.mount(Root(self.mgr), '/', root_conf) self.mgr.log.info('Starting cherrypy engine...') cherrypy.engine.start() self.mgr.log.info('Cherrypy engine started.') agents_down = [] for h in self.mgr.cache.get_hosts(): if self.mgr.agent_helpers._check_agent(h): agents_down.append(h) self.mgr.agent_helpers._update_agent_down_healthcheck(agents_down) # wait for the shutdown event self.cherrypy_shutdown_event.wait() self.cherrypy_shutdown_event.clear() cherrypy.engine.stop() self.mgr.log.info('Cherrypy engine stopped.') except Exception as e: self.mgr.log.error(f'Failed to run cephadm cherrypy endpoint: {e}')
def run(self) -> None: try: try: old_creds = self.mgr.get_store('cephadm_endpoint_credentials') if not old_creds: raise OrchestratorError('No old credentials for cephadm endpoint found') old_creds_dict = json.loads(old_creds) old_key = old_creds_dict['key'] old_cert = old_creds_dict['cert'] self.ssl_certs.load_root_credentials(old_cert, old_key) except (OrchestratorError, json.decoder.JSONDecodeError, KeyError, ValueError): self.ssl_certs.generate_root_cert() cert, key = self.ssl_certs.generate_cert() self.key_tmp = tempfile.NamedTemporaryFile() self.key_tmp.write(key.encode('utf-8')) self.key_tmp.flush() # pkey_tmp must not be gc'ed key_fname = self.key_tmp.name self.cert_tmp = tempfile.NamedTemporaryFile() self.cert_tmp.write(cert.encode('utf-8')) self.cert_tmp.flush() # cert_tmp must not be gc'ed cert_fname = self.cert_tmp.name verify_tls_files(cert_fname, key_fname) self.configure_cherrypy() self.mgr.log.debug('Starting cherrypy engine...') self.start_engine() self.mgr.log.debug('Cherrypy engine started.') cephadm_endpoint_creds = { 'cert': self.ssl_certs.get_root_cert(), 'key': self.ssl_certs.get_root_key() } self.mgr.set_store('cephadm_endpoint_credentials', json.dumps(cephadm_endpoint_creds)) self.mgr._kick_serve_loop() # wait for the shutdown event self.cherrypy_shutdown_event.wait() self.cherrypy_shutdown_event.clear() cherrypy.engine.stop() self.mgr.log.debug('Cherrypy engine stopped.') except Exception as e: self.mgr.log.error(f'Failed to run cephadm cherrypy endpoint: {e}')
def run(self) -> None: try: self.ssl_certs.generate_root_cert() cert, key = self.ssl_certs.generate_cert() self.key_tmp = tempfile.NamedTemporaryFile() self.key_tmp.write(key.encode('utf-8')) self.key_tmp.flush() # pkey_tmp must not be gc'ed key_fname = self.key_tmp.name self.cert_tmp = tempfile.NamedTemporaryFile() self.cert_tmp.write(cert.encode('utf-8')) self.cert_tmp.flush() # cert_tmp must not be gc'ed cert_fname = self.cert_tmp.name verify_tls_files(cert_fname, key_fname) cherrypy.config.update({ 'server.socket_host': self.server_addr, 'server.socket_port': self.server_port, 'engine.autoreload.on': False, 'server.ssl_module': 'builtin', 'server.ssl_certificate': cert_fname, 'server.ssl_private_key': key_fname, }) root_conf = { '/': { 'request.dispatch': cherrypy.dispatch.MethodDispatcher(), 'tools.response_headers.on': True } } cherrypy.tree.mount(Root(self.mgr), '/', root_conf) self.mgr.log.debug('Starting cherrypy engine...') self.start_engine() self.mgr.log.debug('Cherrypy engine started.') # wait for the shutdown event self.cherrypy_shutdown_event.wait() self.cherrypy_shutdown_event.clear() cherrypy.engine.stop() self.mgr.log.debug('Cherrypy engine stopped.') except Exception as e: self.mgr.log.error(f'Failed to run cephadm cherrypy endpoint: {e}')
def _configure(self): """ Configure CherryPy and initialize self.url_prefix :returns our URI """ server_addr = self.get_localized_module_option( # type: ignore 'server_addr', get_default_addr()) ssl = self.get_localized_module_option('ssl', True) # type: ignore if not ssl: server_port = self.get_localized_module_option( 'server_port', 8080) # type: ignore else: server_port = self.get_localized_module_option( 'ssl_server_port', 8443) # type: ignore if server_addr is None: raise ServerConfigException( 'no server_addr configured; ' 'try "ceph config set mgr mgr/{}/{}/server_addr <ip>"'.format( self.module_name, self.get_mgr_id())) # type: ignore self.log.info( 'server: ssl=%s host=%s port=%d', 'yes' if ssl else 'no', # type: ignore server_addr, server_port) # Initialize custom handlers. cherrypy.tools.authenticate = AuthManagerTool() cherrypy.tools.plugin_hooks_filter_request = cherrypy.Tool( 'before_handler', lambda: PLUGIN_MANAGER.hook.filter_request_before_handler( request=cherrypy.request), priority=1) cherrypy.tools.request_logging = RequestLoggingTool() cherrypy.tools.dashboard_exception_handler = HandlerWrapperTool( dashboard_exception_handler, priority=31) cherrypy.log.access_log.propagate = False cherrypy.log.error_log.propagate = False # Apply the 'global' CherryPy configuration. config = { 'engine.autoreload.on': False, 'server.socket_host': server_addr, 'server.socket_port': int(server_port), 'error_page.default': json_error_page, 'tools.request_logging.on': True, 'tools.gzip.on': True, 'tools.gzip.mime_types': [ # text/html and text/plain are the default types to compress 'text/html', 'text/plain', # We also want JSON and JavaScript to be compressed 'application/json', 'application/javascript', ], 'tools.json_in.on': True, 'tools.json_in.force': False, 'tools.plugin_hooks_filter_request.on': True, } if ssl: # SSL initialization cert = self.get_store("crt") # type: ignore if cert is not None: self.cert_tmp = tempfile.NamedTemporaryFile() self.cert_tmp.write(cert.encode('utf-8')) self.cert_tmp.flush() # cert_tmp must not be gc'ed cert_fname = self.cert_tmp.name else: cert_fname = self.get_localized_module_option( 'crt_file') # type: ignore pkey = self.get_store("key") # type: ignore if pkey is not None: self.pkey_tmp = tempfile.NamedTemporaryFile() self.pkey_tmp.write(pkey.encode('utf-8')) self.pkey_tmp.flush() # pkey_tmp must not be gc'ed pkey_fname = self.pkey_tmp.name else: pkey_fname = self.get_localized_module_option( 'key_file') # type: ignore verify_tls_files(cert_fname, pkey_fname) config['server.ssl_module'] = 'builtin' config['server.ssl_certificate'] = cert_fname config['server.ssl_private_key'] = pkey_fname self.update_cherrypy_config(config) self._url_prefix = prepare_url_prefix( self.get_module_option( # type: ignore 'url_prefix', default='')) uri = "{0}://{1}:{2}{3}/".format( 'https' if ssl else 'http', socket.getfqdn() if server_addr in ['::', '0.0.0.0'] else server_addr, server_port, self.url_prefix) return uri
def verify_config(self): """Verify mandatory settings for the module and provide help to configure properly the orchestrator """ # Retrieve TLS content to use and check them # First try to get certiticate and key content for this manager instance # ex: mgr/ansible/mgr0/[crt/key] self.log.info("Tying to use configured specific certificate and key" "files for this server") the_crt = self.get_store("{}/{}".format(self.get_mgr_id(), "crt")) the_key = self.get_store("{}/{}".format(self.get_mgr_id(), "key")) if the_crt is None or the_key is None: # If not possible... try to get generic certificates and key content # ex: mgr/ansible/[crt/key] self.log.warning("Specific tls files for this manager not " "configured, trying to use generic files") the_crt = self.get_store("crt") the_key = self.get_store("key") if the_crt is None or the_key is None: self.status_message = "No client certificate configured. Please "\ "set Ansible Runner Service client "\ "certificate and key:\n"\ "ceph ansible set-ssl-certificate-"\ "{key,certificate} -i <file>" self.log.error(self.status_message) return # generate certificate temp files self.client_cert_fname = generate_temp_file("crt", the_crt) self.client_key_fname = generate_temp_file("key", the_key) try: verify_tls_files(self.client_cert_fname, self.client_key_fname) except ServerConfigException as e: self.status_message = str(e) if self.status_message: self.log.error(self.status_message) return # Check module options if not self.get_module_option("server_location", ""): self.status_message = "No Ansible Runner Service base URL "\ "<server_name>:<port>."\ "Try 'ceph config set mgr mgr/{0}/server_location "\ "<server name/ip>:<port>'".format(self.module_name) self.log.error(self.status_message) return if self.get_module_option("verify_server", True): self.status_message = "TLS server identity verification is enabled"\ " by default.Use 'ceph config set mgr mgr/{0}/verify_server False'"\ "to disable it.Use 'ceph config set mgr mgr/{0}/ca_bundle <path>'"\ "to point an alternative CA bundle path used for TLS server "\ "verification".format(self.module_name) self.log.error(self.status_message) return # Everything ok self.status_message = ""