]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/nfs: adopt API & unit tests for nfs exports
authorAvan Thakkar <athakkar@redhat.com>
Tue, 27 Aug 2024 06:33:17 +0000 (12:03 +0530)
committerAvan Thakkar <athakkar@redhat.com>
Fri, 6 Dec 2024 06:50:38 +0000 (12:20 +0530)
Signed-off-by: Avan Thakkar <athakkar@redhat.com>
(cherry picked from commit 1abb4113ca121ff4ed152c868eabd9bba7812a9e)

qa/tasks/cephfs/test_nfs.py
src/pybind/mgr/nfs/tests/test_nfs.py

index 2d06cbac7baa1ca251febecb75c87d74de8b5cd6..8d4f70828439cf6fbb778a1fdfba4e6b3a5d6689 100644 (file)
@@ -59,8 +59,9 @@ class TestNFS(MgrTestCase):
          ],
          "fsal": {
            "name": "CEPH",
-           "user_id": "nfs.test.1",
+           "user_id": "nfs.test.nfs-cephfs.3746f603",
            "fs_name": self.fs_name,
+           "cmount_path": "/",
          },
          "clients": []
         }
@@ -118,7 +119,7 @@ class TestNFS(MgrTestCase):
                     return
         self.fail(fail_msg)
 
-    def _check_auth_ls(self, export_id=1, check_in=False):
+    def _check_auth_ls(self, fs_name, check_in=False):
         '''
         Tests export user id creation or deletion.
         :param export_id: Denotes export number
@@ -127,9 +128,9 @@ class TestNFS(MgrTestCase):
         output = self._cmd('auth', 'ls')
         client_id = f'client.nfs.{self.cluster_id}'
         if check_in:
-            self.assertIn(f'{client_id}.{export_id}', output)
+            self.assertIn(f'{client_id}.{fs_name}', output)
         else:
-            self.assertNotIn(f'{client_id}.{export_id}', output)
+            self.assertNotIn(f'{client_id}.{fs_name}', output)
 
     def _test_idempotency(self, cmd_func, cmd_args):
         '''
@@ -216,7 +217,7 @@ class TestNFS(MgrTestCase):
         # Runs the nfs export create command
         self._cmd(*export_cmd)
         # Check if user id for export is created
-        self._check_auth_ls(export_id, check_in=True)
+        self._check_auth_ls(self.fs_name, check_in=True)
         res = self._sys_cmd(['rados', '-p', NFS_POOL_NAME, '-N', self.cluster_id, 'get',
                              f'export-{export_id}', '-'])
         # Check if export object is created
@@ -235,7 +236,7 @@ class TestNFS(MgrTestCase):
         Delete an export.
         '''
         self._nfs_cmd('export', 'rm', self.cluster_id, self.pseudo_path)
-        self._check_auth_ls()
+        self._check_auth_ls(self.fs_name)
 
     def _test_list_export(self):
         '''
@@ -256,19 +257,19 @@ class TestNFS(MgrTestCase):
         self.sample_export['export_id'] = 2
         self.sample_export['pseudo'] = self.pseudo_path + '1'
         self.sample_export['access_type'] = 'RO'
-        self.sample_export['fsal']['user_id'] = f'{self.expected_name}.2'
+        self.sample_export['fsal']['user_id'] = f'{self.expected_name}.{self.fs_name}.3746f603'
         self.assertDictEqual(self.sample_export, nfs_output[1])
         # Export-3 for subvolume with r only
         self.sample_export['export_id'] = 3
         self.sample_export['path'] = sub_vol_path
         self.sample_export['pseudo'] = self.pseudo_path + '2'
-        self.sample_export['fsal']['user_id'] = f'{self.expected_name}.3'
+        self.sample_export['fsal']['user_id'] = f'{self.expected_name}.{self.fs_name}.3746f603'
         self.assertDictEqual(self.sample_export, nfs_output[2])
         # Export-4 for subvolume
         self.sample_export['export_id'] = 4
         self.sample_export['pseudo'] = self.pseudo_path + '3'
         self.sample_export['access_type'] = 'RW'
-        self.sample_export['fsal']['user_id'] = f'{self.expected_name}.4'
+        self.sample_export['fsal']['user_id'] = f'{self.expected_name}.{self.fs_name}.3746f603'
         self.assertDictEqual(self.sample_export, nfs_output[3])
 
     def _get_export(self):
@@ -491,7 +492,7 @@ class TestNFS(MgrTestCase):
         self._test_delete_cluster()
         # Check if rados ganesha conf object is deleted
         self._check_export_obj_deleted(conf_obj=True)
-        self._check_auth_ls()
+        self._check_auth_ls(self.fs_name)
 
     def test_exports_on_mgr_restart(self):
         '''
@@ -920,7 +921,7 @@ class TestNFS(MgrTestCase):
                     "protocols": [4],
                     "fsal": {
                         "name": "CEPH",
-                        "user_id": "nfs.test.1",
+                        "user_id": "nfs.test.nfs-cephfs.3746f603",
                         "fs_name": self.fs_name
                     }
                 },
@@ -933,7 +934,7 @@ class TestNFS(MgrTestCase):
                     "protocols": [4],
                     "fsal": {
                         "name": "CEPH",
-                        "user_id": "nfs.test.2",
+                        "user_id": "nfs.test.nfs-cephfs.3746f603",
                         "fs_name": "invalid_fs_name"  # invalid fs
                     }
                 },
@@ -946,7 +947,7 @@ class TestNFS(MgrTestCase):
                     "protocols": [4],
                     "fsal": {
                         "name": "CEPH",
-                        "user_id": "nfs.test.3",
+                        "user_id": "nfs.test.nfs-cephfs.3746f603",
                         "fs_name": self.fs_name
                     }
                 }
@@ -993,7 +994,7 @@ class TestNFS(MgrTestCase):
                 "protocols": [4],
                 "fsal": {
                     "name": "CEPH",
-                    "user_id": "nfs.test.1",
+                    "user_id": "nfs.test.nfs-cephfs.3746f603",
                     "fs_name": "invalid_fs_name"  # invalid fs
                 }
             }
@@ -1033,7 +1034,7 @@ class TestNFS(MgrTestCase):
                     "protocols": [4],
                     "fsal": {
                         "name": "CEPH",
-                        "user_id": "nfs.test.1",
+                        "user_id": "nfs.test.nfs-cephfs.3746f603",
                         "fs_name": self.fs_name
                     }
                 },
@@ -1046,7 +1047,7 @@ class TestNFS(MgrTestCase):
                     "protocols": [4],
                     "fsal": {
                         "name": "CEPH",
-                        "user_id": "nfs.test.2",
+                        "user_id": "nfs.test.nfs-cephfs.3746f603",
                         "fs_name": self.fs_name
                     }
                 },
@@ -1060,7 +1061,7 @@ class TestNFS(MgrTestCase):
                     "protocols": [4],
                     "fsal": {
                         "name": "CEPH",
-                        "user_id": "nfs.test.3",
+                        "user_id": "nfs.test.nfs-cephfs.3746f603",
                         "fs_name": "invalid_fs_name"
                     }
                 }
index 5b4d5fe7e127f4c79db57a17fb4d634264361f0e..268e51e64c821f3015482bc64b310a9c916982ec 100644 (file)
@@ -76,9 +76,8 @@ EXPORT
 EXPORT {
     FSAL {
         name = "CEPH";
-        user_id = "nfs.foo.1";
         filesystem = "a";
-        secret_access_key = "AQCjU+hgjyReLBAAddJa0Dza/ZHqjX5+JiePMA==";
+        cmount_path = "/";
     }
     export_id = 1;
     path = "/";
@@ -95,9 +94,8 @@ EXPORT {
 EXPORT {
     FSAL {
         name = "CEPH";
-        user_id = "nfs.foo.1";
         filesystem = "a";
-        secret_access_key = "AQCjU+hgjyReLBAAddJa0Dza/ZHqjX5+JiePMA==";
+        cmount_path = "/";
     }
     export_id = 1;
     path = "/secure/me";
@@ -110,6 +108,25 @@ EXPORT {
     protocols = 4;
     transports = "TCP";
 }
+"""
+    export_5 = """
+EXPORT {
+    Export_ID=3;
+    Protocols = 4;
+    Path = /;
+    Pseudo = /cephfs_b/;
+    Access_Type = RW;
+    Protocols = 4;
+    Attr_Expiration_Time = 0;
+
+    FSAL {
+        Name = CEPH;
+        Filesystem = "b";
+        User_Id = "nfs.foo.b.lgudhr";
+        Secret_Access_Key = "YOUR SECRET KEY HERE";
+        cmount_path = "/";
+    }
+}
 """
 
     conf_nfs_foo = f'''
@@ -159,6 +176,7 @@ EXPORT {
             'foo': {
                 'export-1': TestNFS.RObject("export-1", self.export_1),
                 'export-2': TestNFS.RObject("export-2", self.export_2),
+                'export-3': TestNFS.RObject("export-3", self.export_5),
                 'conf-nfs.foo': TestNFS.RObject("conf-nfs.foo", self.conf_nfs_foo)
             }
         }
@@ -382,6 +400,29 @@ NFS_CORE_PARAM {
         export = Export.from_export_block(blocks[0], self.cluster_id)
         self._validate_export_2(export)
 
+    def _validate_export_3(self, export: Export):
+        assert export.export_id == 3
+        assert export.path == "/"
+        assert export.pseudo == "/cephfs_b/"
+        assert export.access_type == "RW"
+        assert export.squash == "no_root_squash"
+        assert export.protocols == [4]
+        assert export.fsal.name == "CEPH"
+        assert export.fsal.user_id == "nfs.foo.b.lgudhr"
+        assert export.fsal.fs_name == "b"
+        assert export.fsal.sec_label_xattr == None
+        assert export.fsal.cmount_path == "/"
+        assert export.cluster_id == 'foo'
+        assert export.attr_expiration_time == 0
+        assert export.security_label == True
+
+    def test_export_parser_3(self) -> None:
+        blocks = GaneshaConfParser(self.export_5).parse()
+        assert isinstance(blocks, list)
+        assert len(blocks) == 1
+        export = Export.from_export_block(blocks[0], self.cluster_id)
+        self._validate_export_3(export)
+
     def test_daemon_conf_parser(self) -> None:
         blocks = GaneshaConfParser(self.conf_nfs_foo).parse()
         assert isinstance(blocks, list)
@@ -404,10 +445,11 @@ NFS_CORE_PARAM {
         ganesha_conf = ExportMgr(nfs_mod)
         exports = ganesha_conf.exports[self.cluster_id]
 
-        assert len(exports) == 2
+        assert len(exports) == 3
 
         self._validate_export_1([e for e in exports if e.export_id == 1][0])
         self._validate_export_2([e for e in exports if e.export_id == 2][0])
+        self._validate_export_3([e for e in exports if e.export_id == 3][0])
 
     def test_config_dict(self) -> None:
         self._do_mock_test(self._do_test_config_dict)
@@ -811,6 +853,9 @@ NFS_CORE_PARAM {
 
     def test_update_export_with_list(self):
         self._do_mock_test(self._do_test_update_export_with_list)
+    
+    def test_update_export_cephfs(self):
+        self._do_mock_test(self._do_test_update_export_cephfs)
 
     def _do_test_update_export_with_list(self):
         nfs_mod = Module('nfs', '', '')
@@ -865,7 +910,7 @@ NFS_CORE_PARAM {
         assert len(r.changes) == 2
 
         export = conf._fetch_export('foo', '/rgw/bucket')
-        assert export.export_id == 3
+        assert export.export_id == 4
         assert export.path == "bucket"
         assert export.pseudo == "/rgw/bucket"
         assert export.access_type == "RW"
@@ -881,7 +926,7 @@ NFS_CORE_PARAM {
         assert export.cluster_id == self.cluster_id
 
         export = conf._fetch_export('foo', '/rgw/bucket2')
-        assert export.export_id == 4
+        assert export.export_id == 5
         assert export.path == "bucket2"
         assert export.pseudo == "/rgw/bucket2"
         assert export.access_type == "RO"
@@ -896,17 +941,50 @@ NFS_CORE_PARAM {
         assert export.clients[0].access_type is None
         assert export.cluster_id == self.cluster_id
 
+    def _do_test_update_export_cephfs(self):
+        nfs_mod = Module('nfs', '', '')
+        conf = ExportMgr(nfs_mod)
+        r = conf.apply_export(self.cluster_id, json.dumps({
+            'export_id': 3,
+            'path': '/',
+            'cluster_id': self.cluster_id,
+            'pseudo': '/cephfs_c',
+            'access_type': 'RW',
+            'squash': 'root_squash',
+            'security_label': True,
+            'protocols': [4],
+            'transports': ['TCP', 'UDP'],
+            'fsal': {
+                'name': 'CEPH',
+                'fs_name': 'c',
+            }
+        }))
+        assert len(r.changes) == 1
+
+        export = conf._fetch_export('foo', '/cephfs_c')
+        assert export.export_id == 3
+        assert export.path == "/"
+        assert export.pseudo == "/cephfs_c"
+        assert export.access_type == "RW"
+        assert export.squash == "root_squash"
+        assert export.protocols == [4]
+        assert export.transports == ["TCP", "UDP"]
+        assert export.fsal.name == "CEPH"
+        assert export.fsal.cmount_path == "/"
+        assert export.fsal.user_id == "nfs.foo.c.02de2980"
+        assert export.cluster_id == self.cluster_id
+    
     def test_remove_export(self) -> None:
         self._do_mock_test(self._do_test_remove_export)
 
     def _do_test_remove_export(self) -> None:
         nfs_mod = Module('nfs', '', '')
         conf = ExportMgr(nfs_mod)
-        assert len(conf.exports[self.cluster_id]) == 2
+        assert len(conf.exports[self.cluster_id]) == 3
         conf.delete_export(cluster_id=self.cluster_id,
                            pseudo_path="/rgw")
         exports = conf.exports[self.cluster_id]
-        assert len(exports) == 1
+        assert len(exports) == 2
         assert exports[0].export_id == 1
 
     def test_create_export_rgw_bucket(self):
@@ -917,7 +995,7 @@ NFS_CORE_PARAM {
         conf = ExportMgr(nfs_mod)
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 2
+        assert len(ls) == 3
 
         r = conf.create_export(
             fsal_type='rgw',
@@ -931,7 +1009,7 @@ NFS_CORE_PARAM {
         assert r["bind"] == "/mybucket"
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 3
+        assert len(ls) == 4
 
         export = conf._fetch_export('foo', '/mybucket')
         assert export.export_id
@@ -959,7 +1037,7 @@ NFS_CORE_PARAM {
         conf = ExportMgr(nfs_mod)
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 2
+        assert len(ls) == 3
 
         r = conf.create_export(
             fsal_type='rgw',
@@ -974,7 +1052,7 @@ NFS_CORE_PARAM {
         assert r["bind"] == "/mybucket"
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 3
+        assert len(ls) == 4
 
         export = conf._fetch_export('foo', '/mybucket')
         assert export.export_id
@@ -1002,7 +1080,7 @@ NFS_CORE_PARAM {
         conf = ExportMgr(nfs_mod)
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 2
+        assert len(ls) == 3
 
         r = conf.create_export(
             fsal_type='rgw',
@@ -1016,7 +1094,7 @@ NFS_CORE_PARAM {
         assert r["bind"] == "/mybucket"
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 3
+        assert len(ls) == 4
 
         export = conf._fetch_export('foo', '/mybucket')
         assert export.export_id
@@ -1038,13 +1116,16 @@ NFS_CORE_PARAM {
 
     def test_create_export_cephfs(self):
         self._do_mock_test(self._do_test_create_export_cephfs)
+    
+    def test_create_export_cephfs_with_cmount_path(self):
+        self._do_mock_test(self._do_test_create_export_cephfs_with_cmount_path)
 
     def _do_test_create_export_cephfs(self):
         nfs_mod = Module('nfs', '', '')
         conf = ExportMgr(nfs_mod)
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 2
+        assert len(ls) == 3
 
         r = conf.create_export(
             fsal_type='cephfs',
@@ -1059,7 +1140,7 @@ NFS_CORE_PARAM {
         assert r["bind"] == "/cephfs2"
 
         ls = conf.list_exports(cluster_id=self.cluster_id)
-        assert len(ls) == 3
+        assert len(ls) == 4
 
         export = conf._fetch_export('foo', '/cephfs2')
         assert export.export_id
@@ -1070,13 +1151,48 @@ NFS_CORE_PARAM {
         assert export.protocols == [4]
         assert export.transports == ["TCP"]
         assert export.fsal.name == "CEPH"
-        assert export.fsal.user_id == "nfs.foo.3"
+        assert export.fsal.user_id == "nfs.foo.myfs.86ca58ef"
         assert export.fsal.cephx_key == "thekeyforclientabc"
         assert len(export.clients) == 1
         assert export.clients[0].squash == 'root'
         assert export.clients[0].access_type == 'rw'
         assert export.clients[0].addresses == ["192.168.1.0/8"]
         assert export.cluster_id == self.cluster_id
+    
+    def _do_test_create_export_cephfs_with_cmount_path(self):
+        nfs_mod = Module('nfs', '', '')
+        conf = ExportMgr(nfs_mod)
+
+        ls = conf.list_exports(cluster_id=self.cluster_id)
+        assert len(ls) == 3
+
+        r = conf.create_export(
+            fsal_type='cephfs',
+            cluster_id=self.cluster_id,
+            fs_name='myfs',
+            path='/',
+            pseudo_path='/cephfs3',
+            read_only=False,
+            squash='root',
+            cmount_path='/',
+            )
+        assert r["bind"] == "/cephfs3"
+
+        ls = conf.list_exports(cluster_id=self.cluster_id)
+        assert len(ls) == 4
+
+        export = conf._fetch_export('foo', '/cephfs3')
+        assert export.export_id
+        assert export.path == "/"
+        assert export.pseudo == "/cephfs3"
+        assert export.access_type == "RW"
+        assert export.squash == "root"
+        assert export.protocols == [4]
+        assert export.fsal.name == "CEPH"
+        assert export.fsal.user_id == "nfs.foo.myfs.86ca58ef"
+        assert export.fsal.cephx_key == "thekeyforclientabc"
+        assert export.fsal.cmount_path == "/"
+        assert export.cluster_id == self.cluster_id
 
     def _do_test_cluster_ls(self):
         nfs_mod = Module('nfs', '', '')