Esempio n. 1
0
    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}')
Esempio n. 2
0
    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}')
Esempio n. 3
0
    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}')
Esempio n. 4
0
    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}')
Esempio n. 5
0
    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
Esempio n. 6
0
    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 = ""