Skip to content

Commit 35e40c4

Browse files
committed
mgr/dashboard: adapt to new nvmeof APIs
Fixes: https://tracker.ceph.com/issues/64201 Signed-off-by: Nizamudeen A <[email protected]>
1 parent 1b76833 commit 35e40c4

File tree

15 files changed

+4911
-930
lines changed

15 files changed

+4911
-930
lines changed

ceph.spec.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,8 @@ Requires: ceph-mgr = %{_epoch_prefix}%{version}-%{release}
625625
Requires: ceph-grafana-dashboards = %{_epoch_prefix}%{version}-%{release}
626626
Requires: ceph-prometheus-alerts = %{_epoch_prefix}%{version}-%{release}
627627
Requires: python%{python3_pkgversion}-setuptools
628+
Requires: python%{python3_pkgversion}-grpcio
629+
Requires: python%{python3_pkgversion}-grpcio-tools
628630
%if 0%{?fedora} || 0%{?rhel} || 0%{?openEuler}
629631
Requires: python%{python3_pkgversion}-cherrypy
630632
Requires: python%{python3_pkgversion}-routes

debian/control

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ Build-Depends: automake,
9696
tox <pkg.ceph.check>,
9797
python3-coverage <pkg.ceph.check>,
9898
python3-dateutil <pkg.ceph.check>,
99+
python3-grpcio <pkg.ceph.check>,
99100
python3-openssl <pkg.ceph.check>,
100101
python3-prettytable <pkg.ceph.check>,
101102
python3-requests <pkg.ceph.check>,

src/pybind/mgr/cephadm/services/nvmeof.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def post_remove(self, daemon: DaemonDescription, is_failed_deploy: bool) -> None
121121
'name': daemon.hostname,
122122
})
123123
if not ret:
124-
logger.info(f'{daemon.hostname} removed from iscsi gateways dashboard config')
124+
logger.info(f'{daemon.hostname} removed from nvmeof gateways dashboard config')
125125

126126
# and any certificates being used for mTLS
127127

src/pybind/mgr/dashboard/constraints.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,3 @@ bcrypt~=3.1
44
python3-saml~=1.4
55
requests~=2.26
66
Routes~=2.4
7-
grpcio~=1.48
8-
grpcio-tools~=1.48
Lines changed: 187 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,192 @@
1-
# # import grpc
1+
# -*- coding: utf-8 -*-
2+
import json
3+
from typing import Optional
24

3-
# from .proto import gateway_pb2 as pb2
4-
# from .proto import gateway_pb2_grpc as pb2_grpc
5+
from ..security import Scope
6+
from . import APIDoc, APIRouter, CreatePermission, DeletePermission, Endpoint, \
7+
EndpointDoc, ReadPermission, RESTController
58

9+
try:
10+
from google.protobuf.json_format import MessageToJson
611

7-
# class NVMeoFClient(object):
8-
# def __init__(self):
9-
# self.host = '192.168.100.102'
12+
from ..services.nvmeof_client import NVMeoFClient
13+
except ImportError:
14+
MessageToJson = None
15+
else:
16+
@APIRouter('/nvmeof/namespace', Scope.NVME_OF)
17+
@APIDoc('NVMe-oF Namespace Management API', 'NVMe-oF')
18+
class NvmeofNamespace(RESTController):
19+
@ReadPermission
20+
def list(self, subsystem_nqn: str):
21+
"""
22+
List all NVMeoF namespaces
23+
"""
24+
response = MessageToJson(NVMeoFClient().list_namespaces(subsystem_nqn))
25+
return json.loads(response)
1026

11-
# from ..cephnvmeof.control.cli import GatewayClient
27+
@CreatePermission
28+
def create(self, rbd_pool: str, rbd_image: str, subsystem_nqn: str,
29+
create_image: Optional[bool] = True, image_size: Optional[int] = 1024,
30+
block_size: int = 512, nsid: Optional[int] = 1,
31+
uuid: Optional[str] = None, anagrpid: Optional[int] = 1):
32+
"""
33+
Create a new NVMeoF namespace
34+
:param rbd_pool: RBD pool name
35+
:param rbd_image: RBD image name
36+
:param subsystem_nqn: NVMeoF subsystem NQN
37+
:param create_image: Create RBD image
38+
:param image_size: RBD image size
39+
:param block_size: NVMeoF namespace block size
40+
:param nsid: NVMeoF namespace ID
41+
:param uuid: NVMeoF namespace UUID
42+
:param anagrpid: NVMeoF namespace ANA group ID
43+
"""
44+
response = NVMeoFClient().create_namespace(rbd_pool, rbd_image,
45+
subsystem_nqn, block_size,
46+
nsid, uuid, anagrpid,
47+
create_image, image_size)
48+
return json.loads(MessageToJson(response))
1249

13-
from typing import Optional
14-
from ..security import Scope
15-
from ..services.nvmeof_client import NVMeoFClient
16-
# from ..services.proto import gateway_pb2 as pb2
17-
from . import APIDoc, APIRouter, RESTController, Endpoint, ReadPermission, CreatePermission, \
18-
DeletePermission, allow_empty_body, UpdatePermission
19-
20-
21-
@APIRouter('/nvmeof', Scope.NVME_OF)
22-
@APIDoc('NVMe-oF Management API', 'NVMe-oF')
23-
class Nvmeof(RESTController):
24-
@ReadPermission
25-
def list(self):
26-
"""List all NVMeoF gateways"""
27-
return NVMeoFClient().get_subsystems()
28-
29-
30-
@APIRouter('/nvmeof/bdev', Scope.NVME_OF)
31-
@APIDoc('NVMe-oF Block Device Management API', 'NVMe-oF')
32-
class NvmeofBdev(RESTController):
33-
@CreatePermission
34-
def create(self, name: str, rbd_pool: str, rbd_image: str, block_size: int, uuid: Optional[str] = None):
35-
"""Create a new NVMeoF block device"""
36-
return NVMeoFClient().create_bdev(name, rbd_pool, rbd_image, block_size, uuid)
37-
38-
@DeletePermission
39-
@allow_empty_body
40-
def delete(self, name: str, force: bool):
41-
"""Delete an existing NVMeoF block device"""
42-
return NVMeoFClient().delete_bdev(name, force)
43-
44-
@Endpoint('PUT')
45-
@UpdatePermission
46-
@allow_empty_body
47-
def resize(self, name: str, size: int):
48-
"""Resize an existing NVMeoF block device"""
49-
return NVMeoFClient().resize_bdev(name, size)
50-
51-
52-
@APIRouter('/nvmeof/namespace', Scope.NVME_OF)
53-
@APIDoc('NVMe-oF Namespace Management API', 'NVMe-oF')
54-
class NvmeofNamespace(RESTController):
55-
@CreatePermission
56-
def create(self, subsystem_nqn: str, bdev_name: str, nsid: int, anagrpid: Optional[str] = None):
57-
"""Create a new NVMeoF namespace"""
58-
return NVMeoFClient().create_namespace(subsystem_nqn, bdev_name, nsid, anagrpid)
59-
60-
@Endpoint('DELETE', path='{subsystem_nqn}')
61-
def delete(self, subsystem_nqn: str, nsid: int):
62-
"""Delete an existing NVMeoF namespace"""
63-
return NVMeoFClient().delete_namespace(subsystem_nqn, nsid)
64-
65-
@APIRouter('/nvmeof/subsystem', Scope.NVME_OF)
66-
@APIDoc('NVMe-oF Subsystem Management API', 'NVMe-oF')
67-
class NvmeofSubsystem(RESTController):
68-
@CreatePermission
69-
def create(self, subsystem_nqn: str, serial_number: str, max_namespaces: int,
70-
ana_reporting: bool, enable_ha: bool) :
71-
"""Create a new NVMeoF subsystem"""
72-
return NVMeoFClient().create_subsystem(subsystem_nqn, serial_number, max_namespaces,
73-
ana_reporting, enable_ha)
74-
75-
@Endpoint('DELETE', path='{subsystem_nqn}')
76-
def delete(self, subsystem_nqn: str):
77-
"""Delete an existing NVMeoF subsystem"""
78-
return NVMeoFClient().delete_subsystem(subsystem_nqn)
79-
80-
81-
@APIRouter('/nvmeof/hosts', Scope.NVME_OF)
82-
@APIDoc('NVMe-oF Host Management API', 'NVMe-oF')
83-
class NvmeofHost(RESTController):
84-
@CreatePermission
85-
def create(self, subsystem_nqn: str, host_nqn: str):
86-
"""Create a new NVMeoF host"""
87-
return NVMeoFClient().add_host(subsystem_nqn, host_nqn)
88-
89-
@Endpoint('DELETE')
90-
def delete(self, subsystem_nqn: str, host_nqn: str):
91-
"""Delete an existing NVMeoF host"""
92-
return NVMeoFClient().remove_host(subsystem_nqn, host_nqn)
93-
94-
95-
@APIRouter('/nvmeof/listener', Scope.NVME_OF)
96-
@APIDoc('NVMe-oF Listener Management API', 'NVMe-oF')
97-
class NvmeofListener(RESTController):
98-
@CreatePermission
99-
def create(self, nqn: str, gateway: str, trtype: str, adrfam: str,
100-
traddr: str, trsvcid: str):
101-
"""Create a new NVMeoF listener"""
102-
return NVMeoFClient().create_listener(nqn, gateway, trtype, adrfam, traddr, trsvcid)
103-
104-
@Endpoint('DELETE')
105-
def delete(self, nqn: str, gateway: str, trtype, adrfam,
106-
traddr: str, trsvcid: str):
107-
"""Delete an existing NVMeoF listener"""
108-
return NVMeoFClient().delete_listener(nqn, gateway, trtype, adrfam, traddr, trsvcid)
50+
@Endpoint('DELETE', path='{subsystem_nqn}')
51+
def delete(self, subsystem_nqn: str, nsid: int):
52+
"""
53+
Delete an existing NVMeoF namespace
54+
:param subsystem_nqn: NVMeoF subsystem NQN
55+
:param nsid: NVMeoF namespace ID
56+
"""
57+
response = NVMeoFClient().delete_namespace(subsystem_nqn, nsid)
58+
return json.loads(MessageToJson(response))
59+
60+
@APIRouter('/nvmeof/subsystem', Scope.NVME_OF)
61+
@APIDoc('NVMe-oF Subsystem Management API', 'NVMe-oF')
62+
class NvmeofSubsystem(RESTController):
63+
@ReadPermission
64+
@EndpointDoc("List all NVMeoF gateways",
65+
parameters={
66+
'subsystem_nqn': (str, 'NVMeoF subsystem NQN'),
67+
'serial_number': (str, 'NVMeoF subsystem serial number')
68+
})
69+
def list(self, subsystem_nqn: Optional[str] = None, serial_number: Optional[str] = None):
70+
response = MessageToJson(NVMeoFClient().list_subsystems(
71+
subsystem_nqn=subsystem_nqn, serial_number=serial_number))
72+
73+
return json.loads(response)
74+
75+
@CreatePermission
76+
def create(self, subsystem_nqn: str, serial_number: Optional[str] = None,
77+
max_namespaces: Optional[int] = 256, ana_reporting: Optional[bool] = False,
78+
enable_ha: Optional[bool] = False):
79+
"""
80+
Create a new NVMeoF subsystem
81+
82+
:param subsystem_nqn: NVMeoF subsystem NQN
83+
:param serial_number: NVMeoF subsystem serial number
84+
:param max_namespaces: NVMeoF subsystem maximum namespaces
85+
:param ana_reporting: NVMeoF subsystem ANA reporting
86+
:param enable_ha: NVMeoF subsystem enable HA
87+
"""
88+
response = NVMeoFClient().create_subsystem(subsystem_nqn, serial_number, max_namespaces,
89+
ana_reporting, enable_ha)
90+
return json.loads(MessageToJson(response))
91+
92+
@DeletePermission
93+
@Endpoint('DELETE', path='{subsystem_nqn}')
94+
def delete(self, subsystem_nqn: str):
95+
"""
96+
Delete an existing NVMeoF subsystem
97+
:param subsystem_nqn: NVMeoF subsystem NQN
98+
"""
99+
response = NVMeoFClient().delete_subsystem(subsystem_nqn)
100+
return json.loads(MessageToJson(response))
101+
102+
@APIRouter('/nvmeof/hosts', Scope.NVME_OF)
103+
@APIDoc('NVMe-oF Host Management API', 'NVMe-oF')
104+
class NvmeofHost(RESTController):
105+
@ReadPermission
106+
def list(self, subsystem_nqn: str):
107+
"""
108+
List all NVMeoF hosts
109+
:param subsystem_nqn: NVMeoF subsystem NQN
110+
"""
111+
response = MessageToJson(NVMeoFClient().list_hosts(subsystem_nqn))
112+
return json.loads(response)
113+
114+
@CreatePermission
115+
def create(self, subsystem_nqn: str, host_nqn: str):
116+
"""
117+
Create a new NVMeoF host
118+
:param subsystem_nqn: NVMeoF subsystem NQN
119+
:param host_nqn: NVMeoF host NQN
120+
"""
121+
response = NVMeoFClient().add_host(subsystem_nqn, host_nqn)
122+
return json.loads(MessageToJson(response))
123+
124+
@DeletePermission
125+
def delete(self, subsystem_nqn: str, host_nqn: str):
126+
"""
127+
Delete an existing NVMeoF host
128+
:param subsystem_nqn: NVMeoF subsystem NQN
129+
:param host_nqn: NVMeoF host NQN
130+
"""
131+
response = NVMeoFClient().remove_host(subsystem_nqn, host_nqn)
132+
return json.loads(MessageToJson(response))
133+
134+
@APIRouter('/nvmeof/listener', Scope.NVME_OF)
135+
@APIDoc('NVMe-oF Listener Management API', 'NVMe-oF')
136+
class NvmeofListener(RESTController):
137+
@ReadPermission
138+
def list(self, subsystem_nqn: str):
139+
"""
140+
List all NVMeoF listeners
141+
:param nqn: NVMeoF subsystem NQN
142+
"""
143+
response = MessageToJson(NVMeoFClient().list_listeners(subsystem_nqn))
144+
return json.loads(response)
145+
146+
@CreatePermission
147+
def create(self, nqn: str, gateway: str, traddr: Optional[str] = None,
148+
trtype: Optional[str] = 'TCP', adrfam: Optional[str] = 'IPV4',
149+
trsvcid: Optional[int] = 4420,
150+
auto_ha_state: Optional[str] = 'AUTO_HA_UNSET'):
151+
"""
152+
Create a new NVMeoF listener
153+
:param nqn: NVMeoF subsystem NQN
154+
:param gateway: NVMeoF gateway
155+
:param traddr: NVMeoF transport address
156+
:param trtype: NVMeoF transport type
157+
:param adrfam: NVMeoF address family
158+
:param trsvcid: NVMeoF transport service ID
159+
:param auto_ha_state: NVMeoF auto HA state
160+
"""
161+
response = NVMeoFClient().create_listener(nqn, gateway, traddr,
162+
trtype, adrfam, trsvcid, auto_ha_state)
163+
return json.loads(MessageToJson(response))
164+
165+
@DeletePermission
166+
def delete(self, nqn: str, gateway: str, traddr: Optional[str] = None,
167+
transport_type: Optional[str] = 'TCP', addr_family: Optional[str] = 'IPV4',
168+
transport_svc_id: Optional[int] = 4420):
169+
"""
170+
Delete an existing NVMeoF listener
171+
:param nqn: NVMeoF subsystem NQN
172+
:param gateway: NVMeoF gateway
173+
:param traddr: NVMeoF transport address
174+
:param transport_type: NVMeoF transport type
175+
:param addr_family: NVMeoF address family
176+
:param transport_svc_id: NVMeoF transport service ID
177+
"""
178+
response = NVMeoFClient().delete_listener(nqn, gateway, traddr, transport_type,
179+
addr_family, transport_svc_id)
180+
return json.loads(MessageToJson(response))
181+
182+
@APIRouter('/nvmeof/gateway', Scope.NVME_OF)
183+
@APIDoc('NVMe-oF Gateway Management API', 'NVMe-oF')
184+
class NvmeofGateway(RESTController):
185+
@ReadPermission
186+
@Endpoint()
187+
def info(self):
188+
"""
189+
Get NVMeoF gateway information
190+
"""
191+
response = MessageToJson(NVMeoFClient().gateway_info())
192+
return json.loads(response)

src/pybind/mgr/dashboard/module.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from . import mgr
3030
from .controllers import Router, json_error_page
3131
from .grafana import push_local_dashboards
32+
from .services import nvmeof_cli # noqa # pylint: disable=unused-import
3233
from .services.auth import AuthManager, AuthManagerTool, JwtManager
3334
from .services.exception import dashboard_exception_handler
3435
from .services.rgw_client import configure_rgw_credentials
@@ -37,9 +38,6 @@
3738
from .tools import NotificationQueue, RequestLoggingTool, TaskManager, \
3839
prepare_url_prefix, str_to_bool
3940

40-
# pylint: disable=unused-import
41-
from .services import nvmeof_cli
42-
4341
try:
4442
import cherrypy
4543
from cherrypy._cptools import HandlerWrapperTool

0 commit comments

Comments
 (0)