Introduces a gw_group query-param to gateway and subsystem requests.
Modified the dashboard config to support adding more than one gateway to
the list.
Fixes: https://tracker.ceph.com/issues/67774
Signed-off-by: Nizamudeen A <nia@redhat.com>
cmd_dicts.append({
'prefix': 'dashboard nvmeof-gateway-add',
'inbuf': service_url,
- 'name': service_name
+ 'name': service_name,
+ 'group': spec.group
})
return cmd_dicts
@EndpointDoc("Get information about the NVMeoF gateway")
@map_model(model.GatewayInfo)
@handle_nvmeof_error
- def list(self):
- return NVMeoFClient().stub.get_gateway_info(
+ def list(self, gw_group: Optional[str] = None):
+ return NVMeoFClient(gw_group=gw_group).stub.get_gateway_info(
NVMeoFClient.pb2.get_gateway_info_req()
)
@EndpointDoc("List all NVMeoF subsystems")
@map_collection(model.Subsystem, pick="subsystems")
@handle_nvmeof_error
- def list(self):
- return NVMeoFClient().stub.list_subsystems(
+ def list(self, gw_group: Optional[str] = None):
+ return NVMeoFClient(gw_group=gw_group).stub.list_subsystems(
NVMeoFClient.pb2.list_subsystems_req()
)
)
@map_model(model.Subsystem, first="subsystems")
@handle_nvmeof_error
- def get(self, nqn: str):
- return NVMeoFClient().stub.list_subsystems(
+ def get(self, nqn: str, gw_group: Optional[str] = None):
+ return NVMeoFClient(gw_group=gw_group).stub.list_subsystems(
NVMeoFClient.pb2.list_subsystems_req(subsystem_nqn=nqn)
)
)
@empty_response
@handle_nvmeof_error
- def create(self, nqn: str, enable_ha: bool, max_namespaces: int = 1024):
- return NVMeoFClient().stub.create_subsystem(
+ def create(self, nqn: str, enable_ha: bool, max_namespaces: int = 1024,
+ gw_group: Optional[str] = None):
+ return NVMeoFClient(gw_group=gw_group).stub.create_subsystem(
NVMeoFClient.pb2.create_subsystem_req(
subsystem_nqn=nqn, max_namespaces=max_namespaces, enable_ha=enable_ha
)
)
@empty_response
@handle_nvmeof_error
- def delete(self, nqn: str, force: Optional[str] = "false"):
- return NVMeoFClient().stub.delete_subsystem(
+ def delete(self, nqn: str, force: Optional[str] = "false", gw_group: Optional[str] = None):
+ return NVMeoFClient(gw_group=gw_group).stub.delete_subsystem(
NVMeoFClient.pb2.delete_subsystem_req(
subsystem_nqn=nqn, force=str_to_bool(force)
)
- NFS-Ganesha
/api/nvmeof/gateway:
get:
- parameters: []
+ parameters:
+ - allowEmptyValue: true
+ in: query
+ name: gw_group
+ schema:
+ type: string
responses:
'200':
content:
- NVMe-oF Gateway
/api/nvmeof/subsystem:
get:
- parameters: []
+ parameters:
+ - allowEmptyValue: true
+ in: query
+ name: gw_group
+ schema:
+ type: string
responses:
'200':
content:
enable_ha:
description: Enable high availability
type: boolean
+ gw_group:
+ type: string
max_namespaces:
default: 1024
description: Maximum number of namespaces
name: force
schema:
type: boolean
+ - allowEmptyValue: true
+ in: query
+ name: gw_group
+ schema:
+ type: string
responses:
'202':
content:
required: true
schema:
type: string
+ - allowEmptyValue: true
+ in: query
+ name: gw_group
+ schema:
+ type: string
responses:
'200':
content:
@CLIWriteCommand('dashboard nvmeof-gateway-add')
@CLICheckNonemptyFileInput(desc='NVMe-oF gateway configuration')
-def add_nvmeof_gateway(_, inbuf, name: str):
+def add_nvmeof_gateway(_, inbuf, name: str, group: str):
'''
Add NVMe-oF gateway configuration. Gateway URL read from -i <file>
'''
service_url = inbuf
try:
- NvmeofGatewaysConfig.add_gateway(name, service_url)
+ NvmeofGatewaysConfig.add_gateway(name, service_url, group)
return 0, 'Success', ''
except NvmeofGatewayAlreadyExists as ex:
return -errno.EEXIST, '', str(ex)
class NVMeoFClient(object):
pb2 = pb2
- def __init__(self):
+ def __init__(self, gw_group: Optional[str] = None):
logger.info("Initiating nvmeof gateway connection...")
- service_name, self.gateway_addr = NvmeofGatewaysConfig.get_service_info()
+ try:
+ if not gw_group:
+ service_name, self.gateway_addr = NvmeofGatewaysConfig.get_service_info()
+ else:
+ service_name, self.gateway_addr = NvmeofGatewaysConfig.get_service_info(
+ gw_group
+ )
+ except TypeError as e:
+ raise DashboardException(
+ f'Unable to retrieve the gateway info: {e}'
+ )
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:
+ 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)
return cls._load_config_from_store()
@classmethod
- def add_gateway(cls, name, service_url):
+ def add_gateway(cls, name, service_url, group):
config = cls.get_gateways_config()
- if name in config:
- raise NvmeofGatewayAlreadyExists(name)
- config['gateways'][name] = {'service_url': service_url}
+
+ if name in config.get('gateways', {}):
+ existing_gateways = config['gateways'][name]
+ if any(gateway['service_url'] == service_url for gateway in existing_gateways):
+ return
+
+ if name in config.get('gateways', {}):
+ config['gateways'][name].append({'service_url': service_url, 'group': group})
+ else:
+ config['gateways'][name] = [{'service_url': service_url, 'group': group}]
+
cls._save_config(config)
@classmethod
cls._save_config(config)
@classmethod
- def get_service_info(cls):
+ def get_service_info(cls, group=None):
try:
config = cls.get_gateways_config()
- service_name = list(config['gateways'].keys())[0]
- addr = config['gateways'][service_name]['service_url']
- return service_name, addr
+ gateways = config.get('gateways', {})
+ if not gateways:
+ return None
+
+ if group:
+ for service_name, entries in gateways.items():
+ if group in service_name:
+ entry = next((entry for entry in entries if entry['group'] == group), None)
+ if entry['group'] == group: # type: ignore
+ return service_name, entry['service_url'] # type: ignore
+ return None
+
+ service_name = list(gateways.keys())[0]
+ return service_name, config['gateways'][service_name][0]['service_url']
except (KeyError, IndexError) as e:
raise DashboardException(
msg=f'NVMe-oF configuration is not set: {e}',