MDSAuthCaps: print a special error message for wrong permissions

Permissions mentioned in MDS caps flags can either begin with "r" or
"rw", or can be "*" and "all". But it can't start with or be just "w" or
something else. This is confusing for some CephFS users since MON caps
can be just "w".

Command "ceph fs authorize" complains about this to the user. But other
commands (specifically, "ceph auth add", "ceph auth caps",
"ceph auth get-or-create" and "ceph auth get-or-create-key") don't. Make
these commands too print a helpful message, the way "ceph fs authorize"
command does.

Fixes: https://tracker.ceph.com/issues/61666
Signed-off-by: Rishabh Dave <ridave@redhat.com>
This commit is contained in:
Rishabh Dave 2023-06-10 00:24:12 +05:30
parent f72b217e35
commit f163dd3ef1
2 changed files with 67 additions and 4 deletions

View File

@ -1765,3 +1765,61 @@ class TestFsBalRankMask(CephFSTestCase):
self.fs.set_bal_rank_mask(bal_rank_mask)
except CommandFailedError as e:
self.assertEqual(e.exitstatus, errno.EINVAL)
class TestPermErrMsg(CephFSTestCase):
CLIENT_NAME = 'client.testuser'
FS1_NAME, FS2_NAME, FS3_NAME = 'abcd', 'efgh', 'ijkl'
EXPECTED_ERRNO = 22
EXPECTED_ERRMSG = ("Permission flags in MDS caps must start with 'r' or "
"'rw' or be '*' or 'all'")
MONCAP = f'allow r fsname={FS1_NAME}'
OSDCAP = f'allow rw tag cephfs data={FS1_NAME}'
MDSCAPS = [
'allow w',
f'allow w fsname={FS1_NAME}',
f'allow rw fsname={FS1_NAME}, allow w fsname={FS2_NAME}',
f'allow w fsname={FS1_NAME}, allow rw fsname={FS2_NAME}',
f'allow w fsname={FS1_NAME}, allow w fsname={FS2_NAME}',
(f'allow rw fsname={FS1_NAME}, allow rw fsname={FS2_NAME}, allow '
f'w fsname={FS3_NAME}'),
# without space after comma
f'allow rw fsname={FS1_NAME},allow w fsname={FS2_NAME}',
'allow wr',
f'allow wr fsname={FS1_NAME}',
f'allow rw fsname={FS1_NAME}, allow wr fsname={FS2_NAME}',
f'allow wr fsname={FS1_NAME}, allow rw fsname={FS2_NAME}',
f'allow wr fsname={FS1_NAME}, allow wr fsname={FS2_NAME}',
(f'allow rw fsname={FS1_NAME}, allow rw fsname={FS2_NAME}, allow '
f'wr fsname={FS3_NAME}'),
# without space after comma
f'allow rw fsname={FS1_NAME},allow wr fsname={FS2_NAME}']
def _negtestcmd(self, SUBCMD, MDSCAP):
return self.negtest_ceph_cmd(
args=(f'{SUBCMD} {self.CLIENT_NAME} '
f'mon "{self.MONCAP}" osd "{self.OSDCAP}" mds "{MDSCAP}"'),
retval=self.EXPECTED_ERRNO, errmsgs=self.EXPECTED_ERRMSG)
def test_auth_add(self):
for mdscap in self.MDSCAPS:
self._negtestcmd('auth add', mdscap)
def test_auth_get_or_create(self):
for mdscap in self.MDSCAPS:
self._negtestcmd('auth get-or-create', mdscap)
def test_auth_get_or_create_key(self):
for mdscap in self.MDSCAPS:
self._negtestcmd('auth get-or-create-key', mdscap)

View File

@ -354,10 +354,15 @@ bool MDSAuthCaps::parse(string_view str, ostream *err)
// Make sure no grants are kept after parsing failed!
grants.clear();
if (err)
*err << "mds capability parse failed, stopped at '"
<< string(iter, end)
<< "' of '" << str << "'";
if (err) {
if (string(iter, end).find("allow") != string::npos) {
*err << "Permission flags in MDS caps must start with 'r' or " <<
"'rw' or be '*' or 'all'";
} else {
*err << "mds capability parse failed, stopped at '"
<< string(iter, end) << "' of '" << str << "'";
}
}
return false;
}
}