Skip to content

Commit

Permalink
mgr/dashboard: adapt nfs export code to the new changes in nfs module
Browse files Browse the repository at this point in the history
when you create/edit an nfs export from dashboard it leaves this traceback and error

```
Feb 09 14:15:54 ceph-node-00 ceph-mgr[3235]: [dashboard ERROR taskexec] Error while calling Task(ns=nfs/create, md={'path': 'e2e.nfs.bucket', 'fsal': 'RGW', 'cluster_id': 'testnfs'})
                                             Traceback (most recent call last):
                                               File "/usr/share/ceph/mgr/dashboard/tools.py", line 550, in _run
                                                 val = self.task.fn(*self.task.fn_args, **self.task.fn_kwargs)  # type: ignore
                                               File "/usr/share/ceph/mgr/dashboard/controllers/nfs.py", line 148, in create
                                                 ret, _, err = export_mgr.apply_export(cluster_id, json.dumps(raw_ex))
                                             TypeError: 'AppliedExportResults' object is not iterable
Feb 09 14:15:54 ceph-node-00 ceph-mgr[3235]: [dashboard INFO taskmgr] finished Task(ns=nfs/create, md={'path': 'e2e.nfs.bucket', 'fsal': 'RGW', 'cluster_id': 'testnfs'})
Feb 09 14:15:54 ceph-node-00 ceph-mgr[3235]: [dashboard INFO request] [::ffff:192.168.100.1:43896] [POST] [500] [0.767s] [admin] [172.0B] /api/nfs-ganesha/export
```
This started after ceph#46209, so dashboard code needs to be adapted

Fixes: https://tracker.ceph.com/issues/58681
Signed-off-by: Nizamudeen A <[email protected]>
  • Loading branch information
nizamial09 committed Feb 14, 2023
1 parent c65085e commit dbcf28d
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 12 deletions.
12 changes: 6 additions & 6 deletions src/pybind/mgr/dashboard/controllers/nfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ def create(self, path, cluster_id, pseudo, access_type,
'fsal': fsal,
'clients': clients
}
ret, _, err = export_mgr.apply_export(cluster_id, json.dumps(raw_ex))
if ret == 0:
applied_exports = export_mgr.apply_export(cluster_id, json.dumps(raw_ex))
if not applied_exports.has_error:
return self._get_schema_export(
export_mgr.get_export_by_pseudo(cluster_id, pseudo))
raise NFSException(f"Export creation failed {err}")
raise NFSException(f"Export creation failed {applied_exports.changes[0].msg}")

@EndpointDoc("Get an NFS-Ganesha export",
parameters={
Expand Down Expand Up @@ -192,11 +192,11 @@ def set(self, cluster_id, export_id, path, pseudo, access_type,
}

export_mgr = mgr.remote('nfs', 'fetch_nfs_export_obj')
ret, _, err = export_mgr.apply_export(cluster_id, json.dumps(raw_ex))
if ret == 0:
applied_exports = export_mgr.apply_export(cluster_id, json.dumps(raw_ex))
if not applied_exports.has_error:
return self._get_schema_export(
export_mgr.get_export_by_pseudo(cluster_id, pseudo))
raise NFSException(f"Failed to update export: {err}")
raise NFSException(f"Export creation failed {applied_exports.changes[0].msg}")

@NfsTask('delete', {'cluster_id': '{cluster_id}',
'export_id': '{export_id}'}, 2.0)
Expand Down
19 changes: 13 additions & 6 deletions src/pybind/mgr/dashboard/tests/test_nfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from unittest.mock import Mock, patch
from urllib.parse import urlencode

from nfs.export import AppliedExportResults

from .. import mgr
from ..controllers._version import APIVersion
from ..controllers.nfs import NFSGaneshaExports, NFSGaneshaUi
Expand Down Expand Up @@ -36,6 +38,8 @@ class NFSGaneshaExportsTest(ControllerTestCase):
"clients": []
}

_applied_export = AppliedExportResults()

@classmethod
def setUpClass(cls):
super().setUpClass()
Expand Down Expand Up @@ -71,23 +75,24 @@ def test_get_export(self):
def test_create_export(self):
export_mgr = Mock()
created_nfs_export = deepcopy(self._nfs_module_export)
applied_nfs_export = deepcopy(self._applied_export)
created_nfs_export['pseudo'] = 'new-pseudo'
created_nfs_export['export_id'] = 2
export_mgr.get_export_by_pseudo.side_effect = [None, created_nfs_export]
export_mgr.apply_export.return_value = (0, '', '')
export_mgr.apply_export.return_value = applied_nfs_export
mgr.remote.return_value = export_mgr

export_create_body = deepcopy(self._expected_export)
del export_create_body['export_id']
export_create_body['pseudo'] = created_nfs_export['pseudo']
applied_nfs_export.append(export_create_body)

self._post('/api/nfs-ganesha/export',
export_create_body,
version=APIVersion(2, 0))
self.assertStatus(201)
expected_body = export_create_body
expected_body['export_id'] = created_nfs_export['export_id']
self.assertJsonBody(export_create_body)
applied_nfs_export.changes[0]['export_id'] = created_nfs_export['export_id']
self.assertJsonBody(applied_nfs_export.changes[0])

def test_create_export_with_existing_pseudo_fails(self):
export_mgr = Mock()
Expand All @@ -108,19 +113,21 @@ def test_create_export_with_existing_pseudo_fails(self):
def test_set_export(self):
export_mgr = Mock()
updated_nfs_export = deepcopy(self._nfs_module_export)
applied_nfs_export = deepcopy(self._applied_export)
updated_nfs_export['pseudo'] = 'updated-pseudo'
export_mgr.get_export_by_pseudo.return_value = updated_nfs_export
export_mgr.apply_export.return_value = (0, '', '')
export_mgr.apply_export.return_value = applied_nfs_export
mgr.remote.return_value = export_mgr

updated_export_body = deepcopy(self._expected_export)
updated_export_body['pseudo'] = updated_nfs_export['pseudo']
applied_nfs_export.append(updated_export_body)

self._put('/api/nfs-ganesha/export/myc/2',
updated_export_body,
version=APIVersion(2, 0))
self.assertStatus(200)
self.assertJsonBody(updated_export_body)
self.assertJsonBody(applied_nfs_export.changes[0])

def test_delete_export(self):
mgr.remote = Mock(side_effect=[self._nfs_module_export, None])
Expand Down
2 changes: 2 additions & 0 deletions src/pybind/mgr/nfs/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ def get_export_by_pseudo(
export = self._fetch_export(cluster_id, pseudo_path)
return export.to_dict() if export else None

# This method is used by the dashboard module (../dashboard/controllers/nfs.py)
# Do not change interface without updating the Dashboard code
def apply_export(self, cluster_id: str, export_config: str) -> AppliedExportResults:
try:
exports = self._read_export_config(cluster_id, export_config)
Expand Down

0 comments on commit dbcf28d

Please sign in to comment.