]> git.proxmox.com Git - ceph.git/blob - ceph/qa/tasks/mgr/dashboard/test_ganesha.py
8583f3d66e728c6b8f19da5959277246c3668bd1
[ceph.git] / ceph / qa / tasks / mgr / dashboard / test_ganesha.py
1 # -*- coding: utf-8 -*-
2 # pylint: disable=too-many-public-methods
3
4 from __future__ import absolute_import
5
6
7 from .helper import DashboardTestCase, JList, JObj
8
9
10 class GaneshaTest(DashboardTestCase):
11 CEPHFS = True
12 AUTH_ROLES = ['pool-manager', 'ganesha-manager']
13
14 @classmethod
15 def create_pool(cls, name, pg_num, pool_type, application='rbd'):
16 data = {
17 'pool': name,
18 'pg_num': pg_num,
19 'pool_type': pool_type,
20 'application_metadata': [application]
21 }
22 if pool_type == 'erasure':
23 data['flags'] = ['ec_overwrites']
24 cls._task_post("/api/pool", data)
25
26 @classmethod
27 def setUpClass(cls):
28 super(GaneshaTest, cls).setUpClass()
29 cls.create_pool('ganesha', 2**2, 'replicated')
30 cls._rados_cmd(['-p', 'ganesha', '-N', 'ganesha1', 'create', 'conf-node1'])
31 cls._rados_cmd(['-p', 'ganesha', '-N', 'ganesha1', 'create', 'conf-node2'])
32 cls._rados_cmd(['-p', 'ganesha', '-N', 'ganesha1', 'create', 'conf-node3'])
33 cls._rados_cmd(['-p', 'ganesha', '-N', 'ganesha2', 'create', 'conf-node1'])
34 cls._rados_cmd(['-p', 'ganesha', '-N', 'ganesha2', 'create', 'conf-node2'])
35 cls._rados_cmd(['-p', 'ganesha', '-N', 'ganesha2', 'create', 'conf-node3'])
36 cls._ceph_cmd(['dashboard', 'set-ganesha-clusters-rados-pool-namespace', 'cluster1:ganesha/ganesha1,cluster2:ganesha/ganesha2'])
37
38 # RGW setup
39 cls._radosgw_admin_cmd([
40 'user', 'create', '--uid', 'admin', '--display-name', 'admin',
41 '--system', '--access-key', 'admin', '--secret', 'admin'
42 ])
43 cls._ceph_cmd(['dashboard', 'set-rgw-api-secret-key', 'admin'])
44 cls._ceph_cmd(['dashboard', 'set-rgw-api-access-key', 'admin'])
45
46 @classmethod
47 def tearDownClass(cls):
48 super(GaneshaTest, cls).tearDownClass()
49 cls._radosgw_admin_cmd(['user', 'rm', '--uid', 'admin', '--purge-data'])
50 cls._ceph_cmd(['osd', 'pool', 'delete', 'ganesha', 'ganesha', '--yes-i-really-really-mean-it'])
51
52 @DashboardTestCase.RunAs('test', 'test', [{'rbd-image': ['create', 'update', 'delete']}])
53 def test_read_access_permissions(self):
54 self._get('/api/nfs-ganesha/export')
55 self.assertStatus(403)
56
57 def test_list_daemons(self):
58 daemons = self._get("/api/nfs-ganesha/daemon")
59 self.assertEqual(len(daemons), 6)
60 daemons = [(d['daemon_id'], d['cluster_id']) for d in daemons]
61 self.assertIn(('node1', 'cluster1'), daemons)
62 self.assertIn(('node2', 'cluster1'), daemons)
63 self.assertIn(('node3', 'cluster1'), daemons)
64 self.assertIn(('node1', 'cluster2'), daemons)
65 self.assertIn(('node2', 'cluster2'), daemons)
66 self.assertIn(('node3', 'cluster2'), daemons)
67
68 @classmethod
69 def create_export(cls, path, cluster_id, daemons, fsal, sec_label_xattr=None):
70 if fsal == 'CEPH':
71 fsal = {"name": "CEPH", "user_id": "admin", "fs_name": None, "sec_label_xattr": sec_label_xattr}
72 pseudo = "/cephfs{}".format(path)
73 else:
74 fsal = {"name": "RGW", "rgw_user_id": "admin"}
75 pseudo = "/rgw/{}".format(path if path[0] != '/' else "")
76 ex_json = {
77 "path": path,
78 "fsal": fsal,
79 "cluster_id": cluster_id,
80 "daemons": ["node1", "node3"],
81 "pseudo": pseudo,
82 "tag": None,
83 "access_type": "RW",
84 "squash": "no_root_squash",
85 "security_label": sec_label_xattr is not None,
86 "protocols": [4],
87 "transports": ["TCP"],
88 "clients": [{
89 "addresses": ["10.0.0.0/8"],
90 "access_type": "RO",
91 "squash": "root"
92 }]
93 }
94 return cls._task_post('/api/nfs-ganesha/export', ex_json)
95
96 def tearDown(self):
97 super(GaneshaTest, self).tearDown()
98 exports = self._get("/api/nfs-ganesha/export")
99 if self._resp.status_code != 200:
100 return
101 self.assertIsInstance(exports, list)
102 for exp in exports:
103 self._task_delete("/api/nfs-ganesha/export/{}/{}"
104 .format(exp['cluster_id'], exp['export_id']))
105
106 def _test_create_export(self, cephfs_path):
107 exports = self._get("/api/nfs-ganesha/export")
108 self.assertEqual(len(exports), 0)
109
110 data = self.create_export(cephfs_path, 'cluster1', ['node1', 'node2'], 'CEPH', "security.selinux")
111
112 exports = self._get("/api/nfs-ganesha/export")
113 self.assertEqual(len(exports), 1)
114 self.assertDictEqual(exports[0], data)
115 return data
116
117 def test_create_export(self):
118 self._test_create_export('/foo')
119
120 def test_create_export_for_cephfs_root(self):
121 self._test_create_export('/')
122
123 def test_update_export(self):
124 export = self._test_create_export('/foo')
125 export['access_type'] = 'RO'
126 export['daemons'] = ['node1', 'node3']
127 export['security_label'] = True
128 data = self._task_put('/api/nfs-ganesha/export/{}/{}'
129 .format(export['cluster_id'], export['export_id']),
130 export)
131 exports = self._get("/api/nfs-ganesha/export")
132 self.assertEqual(len(exports), 1)
133 self.assertDictEqual(exports[0], data)
134 self.assertEqual(exports[0]['daemons'], ['node1', 'node3'])
135 self.assertEqual(exports[0]['security_label'], True)
136
137 def test_delete_export(self):
138 export = self._test_create_export('/foo')
139 self._task_delete("/api/nfs-ganesha/export/{}/{}"
140 .format(export['cluster_id'], export['export_id']))
141 self.assertStatus(204)
142
143 def test_get_export(self):
144 exports = self._get("/api/nfs-ganesha/export")
145 self.assertEqual(len(exports), 0)
146
147 data1 = self.create_export("/foo", 'cluster2', ['node1', 'node2'], 'CEPH')
148 data2 = self.create_export("mybucket", 'cluster2', ['node2', 'node3'], 'RGW')
149
150 export1 = self._get("/api/nfs-ganesha/export/cluster2/1")
151 self.assertDictEqual(export1, data1)
152
153 export2 = self._get("/api/nfs-ganesha/export/cluster2/2")
154 self.assertDictEqual(export2, data2)
155
156 def test_invalid_status(self):
157 self._ceph_cmd(['dashboard', 'set-ganesha-clusters-rados-pool-namespace', ''])
158
159 data = self._get('/api/nfs-ganesha/status')
160 self.assertStatus(200)
161 self.assertIn('available', data)
162 self.assertIn('message', data)
163 self.assertFalse(data['available'])
164 self.assertIn(("NFS-Ganesha cluster is not detected. "
165 "Please set the GANESHA_RADOS_POOL_NAMESPACE "
166 "setting or deploy an NFS-Ganesha cluster with the Orchestrator."),
167 data['message'])
168
169 self._ceph_cmd(['dashboard', 'set-ganesha-clusters-rados-pool-namespace', 'cluster1:ganesha/ganesha1,cluster2:ganesha/ganesha2'])
170
171 def test_valid_status(self):
172 data = self._get('/api/nfs-ganesha/status')
173 self.assertStatus(200)
174 self.assertIn('available', data)
175 self.assertIn('message', data)
176 self.assertTrue(data['available'])
177
178 def test_ganesha_fsals(self):
179 data = self._get('/ui-api/nfs-ganesha/fsals')
180 self.assertStatus(200)
181 self.assertIn('CEPH', data)
182
183 def test_ganesha_filesystems(self):
184 data = self._get('/ui-api/nfs-ganesha/cephfs/filesystems')
185 self.assertStatus(200)
186 self.assertSchema(data, JList(JObj({
187 'id': int,
188 'name': str
189 })))
190
191 def test_ganesha_lsdir(self):
192 fss = self._get('/ui-api/nfs-ganesha/cephfs/filesystems')
193 self.assertStatus(200)
194 for fs in fss:
195 data = self._get('/ui-api/nfs-ganesha/lsdir/{}'.format(fs['name']))
196 self.assertStatus(200)
197 self.assertSchema(data, JObj({'paths': JList(str)}))
198 self.assertEqual(data['paths'][0], '/')
199
200 def test_ganesha_buckets(self):
201 data = self._get('/ui-api/nfs-ganesha/rgw/buckets')
202 self.assertStatus(200)
203 schema = JList(str)
204 self.assertSchema(data, schema)
205
206 def test_ganesha_clusters(self):
207 data = self._get('/ui-api/nfs-ganesha/clusters')
208 self.assertStatus(200)
209 schema = JList(str)
210 self.assertSchema(data, schema)
211
212 def test_ganesha_cephx_clients(self):
213 data = self._get('/ui-api/nfs-ganesha/cephx/clients')
214 self.assertStatus(200)
215 schema = JList(str)
216 self.assertSchema(data, schema)