for dd in daemon_descrs:
assert dd.hostname is not None
+ service_name = dd.service_name()
if not spec:
- logger.warning(f'No ServiceSpec found for {dd.service_name()}')
+ logger.warning(f'No ServiceSpec found for {service_name}')
continue
ip = utils.resolve_ip(self.mgr.inventory.get_addr(dd.hostname))
cmd_dicts.append({
'prefix': 'dashboard nvmeof-gateway-add',
'inbuf': service_url,
- 'name': dd.hostname
+ 'name': service_name
})
return cmd_dicts
"""
# to clean the keyring up
super().post_remove(daemon, is_failed_deploy=is_failed_deploy)
+ service_name = daemon.service_name()
# remove config for dashboard nvmeof gateways if any
ret, out, err = self.mgr.mon_command({
'prefix': 'dashboard nvmeof-gateway-rm',
- 'name': daemon.hostname,
+ 'name': service_name,
})
if not ret:
logger.info(f'{daemon.hostname} removed from nvmeof gateways dashboard config')
def __init__(self):
logger.info("Initiating nvmeof gateway connection...")
-
- self.gateway_addr = list(
- NvmeofGatewaysConfig.get_gateways_config()["gateways"].values()
- )[0]["service_url"]
- self.channel = grpc.insecure_channel("{}".format(self.gateway_addr))
- logger.info("Found nvmeof gateway at %s", self.gateway_addr)
+ service_name, self.gateway_addr = NvmeofGatewaysConfig.get_service_info()
+
+ root_ca_cert = NvmeofGatewaysConfig.get_root_ca_cert(service_name)
+ client_key = NvmeofGatewaysConfig.get_client_key(service_name)
+ client_cert = NvmeofGatewaysConfig.get_client_cert(service_name)
+
+ if root_ca_cert and client_key and client_cert:
+ logger.info('Securely connecting to: %s', self.gateway_addr)
+ credentials = grpc.ssl_channel_credentials(
+ root_certificates=root_ca_cert,
+ private_key=client_key,
+ certificate_chain=client_cert,
+ )
+ self.channel = grpc.secure_channel(self.gateway_addr, credentials)
+ else:
+ logger.info("Insecurely connecting to: %s", self.gateway_addr)
+ self.channel = grpc.insecure_channel(self.gateway_addr)
self.stub = pb2_grpc.GatewayStub(self.channel)
def make_namedtuple_from_object(cls: Type[NamedTuple], obj: Any) -> NamedTuple:
import json
+from orchestrator import OrchestratorError
+
from .. import mgr
+from ..exceptions import DashboardException
+from ..services.orchestrator import OrchClient
class NvmeofGatewayAlreadyExists(Exception):
raise NvmeofGatewayDoesNotExist(name)
del config['gateways'][name]
cls._save_config(config)
+
+ @classmethod
+ def get_service_info(cls):
+ try:
+ config = cls.get_gateways_config()
+ service_name = list(config['gateways'].keys())[0]
+ addr = config['gateways'][service_name]['service_url']
+ return service_name, addr
+ except (KeyError, IndexError) as e:
+ raise DashboardException(
+ msg=f'NVMe-oF configuration is not set: {e}',
+ )
+
+ @classmethod
+ def get_client_cert(cls, service_name: str):
+ client_cert = cls.from_cert_store('nvmeof_client_cert', service_name)
+ return client_cert.encode() if client_cert else None
+
+ @classmethod
+ def get_client_key(cls, service_name: str):
+ client_key = cls.from_cert_store('nvmeof_client_key', service_name, key=True)
+ return client_key.encode() if client_key else None
+
+ @classmethod
+ def get_root_ca_cert(cls, service_name: str):
+ root_ca_cert = cls.from_cert_store('nvmeof_root_ca_cert', service_name)
+ return root_ca_cert.encode() if root_ca_cert else None
+
+ @classmethod
+ def from_cert_store(cls, entity: str, service_name: str, key=False):
+ try:
+ orch = OrchClient.instance()
+ if orch.available():
+ if key:
+ return orch.cert_store.get_key(entity, service_name)
+ return orch.cert_store.get_cert(entity, service_name)
+ return None
+ except OrchestratorError as e:
+ raise DashboardException(
+ msg=f'Failed to get {entity} for {service_name}: {e}',
+ )
return self.api.node_proxy_common(category, hostname=hostname)
+class CertStoreManager(ResourceManager):
+
+ @wait_api_result
+ def get_cert(self, entity: str, service_name: Optional[str] = None,
+ hostname: Optional[str] = None) -> str:
+ return self.api.cert_store_get_cert(entity, service_name, hostname)
+
+ @wait_api_result
+ def get_key(self, entity: str, service_name: Optional[str] = None,
+ hostname: Optional[str] = None) -> str:
+ return self.api.cert_store_get_key(entity, service_name, hostname)
+
+
class OrchClient(object):
_instance = None
self.daemons = DaemonManager(self.api)
self.upgrades = UpgradeManager(self.api)
self.hardware = HardwareManager(self.api)
+ self.cert_store = CertStoreManager(self.api)
def available(self, features: Optional[List[str]] = None) -> bool:
available = self.status()['available']