def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type deps = [] # type: List[str] prom_services = [] # type: List[str] for dd in self.mgr.cache.get_daemons_by_service('prometheus'): assert dd.hostname is not None addr = dd.ip if dd.ip else self._inventory_get_fqdn(dd.hostname) port = dd.ports[0] if dd.ports else 9095 prom_services.append(build_url(scheme='http', host=addr, port=port)) deps.append(dd.name()) daemons = self.mgr.cache.get_daemons_by_service('mgr') loki_host = '' assert daemons is not None if daemons != []: assert daemons[0].hostname is not None addr = daemons[0].ip if daemons[0].ip else self._inventory_get_fqdn(daemons[0].hostname) loki_host = build_url(scheme='http', host=addr, port=3100) grafana_data_sources = self.mgr.template.render( 'services/grafana/ceph-dashboard.yml.j2', {'hosts': prom_services, 'loki_host': loki_host}) cert = self.mgr.get_store('grafana_crt') pkey = self.mgr.get_store('grafana_key') if cert and pkey: try: verify_tls(cert, pkey) except ServerConfigException as e: logger.warning('Provided grafana TLS certificates invalid: %s', str(e)) cert, pkey = None, None if not (cert and pkey): cert, pkey = create_self_signed_cert('Ceph', 'cephadm') self.mgr.set_store('grafana_crt', cert) self.mgr.set_store('grafana_key', pkey) if 'dashboard' in self.mgr.get('mgr_map')['modules']: self.mgr.check_mon_command({ 'prefix': 'dashboard set-grafana-api-ssl-verify', 'value': 'false', }) spec: GrafanaSpec = cast( GrafanaSpec, self.mgr.spec_store.active_specs[daemon_spec.service_name]) grafana_ini = self.mgr.template.render( 'services/grafana/grafana.ini.j2', { 'initial_admin_password': spec.initial_admin_password, 'http_port': daemon_spec.ports[0] if daemon_spec.ports else self.DEFAULT_SERVICE_PORT, 'http_addr': daemon_spec.ip if daemon_spec.ip else '' }) config_file = { 'files': { "grafana.ini": grafana_ini, 'provisioning/datasources/ceph-dashboard.yml': grafana_data_sources, 'certs/cert_file': '# generated by cephadm\n%s' % cert, 'certs/cert_key': '# generated by cephadm\n%s' % pkey, } } return config_file, sorted(deps)
def test_mismatched_tls(self): crt, _ = create_self_signed_cert() # generate another key new_key = crypto.PKey() new_key.generate_key(crypto.TYPE_RSA, 2048) new_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, new_key).decode('utf-8') self.assertRaises(SSL.Error, verify_tls, crt, new_key)
def set_mgr_created_self_signed_cert(self): cert, pkey = create_self_signed_cert('IT', 'ceph-dashboard') result = HandleCommandResult(*self.set_ssl_certificate(inbuf=cert)) if result.retval != 0: return result result = HandleCommandResult(*self.set_ssl_certificate_key(inbuf=pkey)) if result.retval != 0: return result return 0, 'Self-signed certificate created', ''
def generate_config( self, daemon_spec: CephadmDaemonSpec ) -> Tuple[Dict[str, Any], List[str]]: assert self.TYPE == daemon_spec.daemon_type deps = [] # type: List[str] prom_services = [] # type: List[str] for dd in self.mgr.cache.get_daemons_by_service('prometheus'): assert dd.hostname is not None prom_services.append(dd.hostname) deps.append(dd.name()) grafana_data_sources = self.mgr.template.render( 'services/grafana/ceph-dashboard.yml.j2', {'hosts': prom_services}) cert = self.mgr.get_store('grafana_crt') pkey = self.mgr.get_store('grafana_key') if cert and pkey: try: verify_tls(cert, pkey) except ServerConfigException as e: logger.warning('Provided grafana TLS certificates invalid: %s', str(e)) cert, pkey = None, None if not (cert and pkey): cert, pkey = create_self_signed_cert('Ceph', 'cephadm') self.mgr.set_store('grafana_crt', cert) self.mgr.set_store('grafana_key', pkey) self.mgr.check_mon_command({ 'prefix': 'dashboard set-grafana-api-ssl-verify', 'value': 'false', }) grafana_ini = self.mgr.template.render( 'services/grafana/grafana.ini.j2', {'http_port': self.DEFAULT_SERVICE_PORT}) config_file = { 'files': { "grafana.ini": grafana_ini, 'provisioning/datasources/ceph-dashboard.yml': grafana_data_sources, 'certs/cert_file': '# generated by cephadm\n%s' % cert, 'certs/cert_key': '# generated by cephadm\n%s' % pkey, } } return config_file, sorted(deps)
def generate_config(self): # type: () -> Tuple[Dict[str, Any], List[str]] deps = [] # type: List[str] def generate_grafana_ds_config(hosts: List[str]) -> str: config = '''# generated by cephadm deleteDatasources: {delete_data_sources} datasources: {data_sources} ''' delete_ds_template = ''' - name: '{name}' orgId: 1\n'''.lstrip('\n') ds_template = ''' - name: '{name}' type: 'prometheus' access: 'proxy' orgId: 1 url: 'http://{host}:9095' basicAuth: false isDefault: {is_default} editable: false\n'''.lstrip('\n') delete_data_sources = '' data_sources = '' for i, host in enumerate(hosts): name = "Dashboard %d" % (i + 1) data_sources += ds_template.format( name=name, host=host, is_default=str(i == 0).lower()) delete_data_sources += delete_ds_template.format(name=name) return config.format( delete_data_sources=delete_data_sources, data_sources=data_sources, ) prom_services = [] # type: List[str] for dd in self.mgr.cache.get_daemons_by_service('prometheus'): prom_services.append(dd.hostname) deps.append(dd.name()) cert = self.mgr.get_store('grafana_crt') pkey = self.mgr.get_store('grafana_key') if cert and pkey: try: verify_tls(cert, pkey) except ServerConfigException as e: logger.warning('Provided grafana TLS certificates invalid: %s', str(e)) cert, pkey = None, None if not (cert and pkey): cert, pkey = create_self_signed_cert('Ceph', 'cephadm') self.mgr.set_store('grafana_crt', cert) self.mgr.set_store('grafana_key', pkey) self.mgr.check_mon_command({ 'prefix': 'dashboard set-grafana-api-ssl-verify', 'value': 'false', }) config_file = { 'files': { "grafana.ini": """# generated by cephadm [users] default_theme = light [auth.anonymous] enabled = true org_name = 'Main Org.' org_role = 'Viewer' [server] domain = 'bootstrap.storage.lab' protocol = https cert_file = /etc/grafana/certs/cert_file cert_key = /etc/grafana/certs/cert_key http_port = 3000 [security] admin_user = admin admin_password = admin allow_embedding = true """, 'provisioning/datasources/ceph-dashboard.yml': generate_grafana_ds_config(prom_services), 'certs/cert_file': '# generated by cephadm\n%s' % cert, 'certs/cert_key': '# generated by cephadm\n%s' % pkey, } } return config_file, sorted(deps)
def create_self_signed_cert(self): cert, pkey = create_self_signed_cert('IT', 'ceph-dashboard') self.set_store('crt', cert) self.set_store('key', pkey)
def test_defaults(self): crt, key = create_self_signed_cert() verify_tls(crt, key)
def test_invalid_key(self): crt, key = create_self_signed_cert() # fudge the key, to force an error to be detected during verify_tls fudged = f"{key[:-35]}c0ffee==\n{key[-25:]}".encode('utf-8') self.assertRaises(ServerConfigException, verify_tls, crt, fudged)
def test_specific_dname(self): crt, key = create_self_signed_cert(dname={ 'O': 'Ceph', 'OU': 'testsuite' }) verify_tls(crt, key)