Skip to content

Commit

Permalink
Merge pull request #8994 from parth-gr/external-cluster-permission
Browse files Browse the repository at this point in the history
security: update auth permissions for external cluster
  • Loading branch information
leseb committed Nov 15, 2021
2 parents ecd7fa7 + 7d106c8 commit 7d87de8
Showing 1 changed file with 111 additions and 30 deletions.
141 changes: 111 additions & 30 deletions cluster/examples/kubernetes/ceph/create-external-cluster-resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ def _init_cmd_output_map(self):
self.cmd_output_map['''{"caps": ["mon", "profile rbd", "mgr", "allow rw", "osd", "profile rbd"], "entity": "client.csi-rbd-provisioner", "format": "json", "prefix": "auth get-or-create"}'''] = '''[{"entity":"client.csi-rbd-provisioner","key":"AQBNgrNe1geyKxAA8ekViRdE+hss5OweYBkwNg==","caps":{"mgr":"allow rw","mon":"profile rbd","osd":"profile rbd"}}]'''
self.cmd_output_map['''{"caps": ["mon", "allow r", "mgr", "allow rw", "osd", "allow rw tag cephfs *=*", "mds", "allow rw"], "entity": "client.csi-cephfs-node", "format": "json", "prefix": "auth get-or-create"}'''] = '''[{"entity":"client.csi-cephfs-node","key":"AQBOgrNeENunKxAAPCmgE7R6G8DcXnaJ1F32qg==","caps":{"mds":"allow rw","mgr":"allow rw","mon":"allow r","osd":"allow rw tag cephfs *=*"}}]'''
self.cmd_output_map['''{"caps": ["mon", "allow r", "mgr", "allow rw", "osd", "allow rw tag cephfs metadata=*"], "entity": "client.csi-cephfs-provisioner", "format": "json", "prefix": "auth get-or-create"}'''] = '''[{"entity":"client.csi-cephfs-provisioner","key":"AQBOgrNeAFgcGBAAvGqKOAD0D3xxmVY0R912dg==","caps":{"mgr":"allow rw","mon":"allow r","osd":"allow rw tag cephfs metadata=*"}}]'''
self.cmd_output_map['''{"caps": ["mon", "allow r", "mgr", "allow rw", "osd", "allow rw tag cephfs metadata=myfs-metadata"], "entity": "client.csi-cephfs-provisioner", "format": "json", "prefix": "auth get-or-create"}'''] = '''[{"entity":"client.csi-cephfs-provisioner","key":"BQBOgrNeAFgcGBAAvGqKOAD0D3xxmVY0R912dg==","caps":{"mgr":"allow rw","mon":"allow r","osd":"allow rw tag cephfs metadata=myfs-metadata"}}]'''
self.cmd_output_map['''{"caps": ["mon", "allow r", "mgr", "allow rw", "osd", "allow rw tag cephfs metadata=myfs-metadata"], "entity": "client.csi-cephfs-provisioner-openshift-storage", "format": "json", "prefix": "auth get-or-create"}'''] = '''[{"entity":"client.csi-cephfs-provisioner-openshift-storage","key":"CQBOgrNeAFgcGBAAvGqKOAD0D3xxmVY0R912dg==","caps":{"mgr":"allow rw","mon":"allow r","osd":"allow rw tag cephfs metadata=myfs-metadata"}}]'''
self.cmd_output_map['''{"caps": ["mon", "allow r, allow command quorum_status, allow command version", "mgr", "allow command config", "osd", "allow rwx pool=default.rgw.meta, allow r pool=.rgw.root, allow rw pool=default.rgw.control, allow rx pool=default.rgw.log, allow x pool=default.rgw.buckets.index"], "entity": "client.healthchecker", "format": "json", "prefix": "auth get-or-create"}'''] = '''[{"entity":"client.healthchecker","key":"AQDFkbNeft5bFRAATndLNUSEKruozxiZi3lrdA==","caps":{"mon": "allow r, allow command quorum_status, allow command version", "mgr": "allow command config", "osd": "allow rwx pool=default.rgw.meta, allow r pool=.rgw.root, allow rw pool=default.rgw.control, allow rx pool=default.rgw.log, allow x pool=default.rgw.buckets.index"}}]'''
self.cmd_output_map['''{"format": "json", "prefix": "mgr services"}'''] = '''{"dashboard": "http://rook-ceph-mgr-a-57cf9f84bc-f4jnl:7000/", "prometheus": "http://rook-ceph-mgr-a-57cf9f84bc-f4jnl:9283/"}'''
self.cmd_output_map['''{"entity": "client.healthchecker", "format": "json", "prefix": "auth get"}'''] = '''{"dashboard": "http://rook-ceph-mgr-a-57cf9f84bc-f4jnl:7000/", "prometheus": "http://rook-ceph-mgr-a-57cf9f84bc-f4jnl:9283/"}'''
Expand Down Expand Up @@ -159,12 +161,14 @@ def gen_arg_parser(cls, args_to_parse=None):
help="Provide a ceph conf file.", type=str)
common_group.add_argument("--run-as-user", "-u", default="", type=str,
help="Provides a user name to check the cluster's health status, must be prefixed by 'client.'")
common_group.add_argument("--cluster-name", default="openshift-storage",
common_group.add_argument("--cluster-name", default="",
help="Ceph cluster name")
common_group.add_argument("--namespace", default="",
help="Namespace where CephCluster is running")
common_group.add_argument("--rgw-pool-prefix", default="",
help="RGW Pool prefix")
common_group.add_argument("--restricted-auth-permission", default=False,
help="Restricted cephCSIKeyrings auth permissions to specific pools and cluster. Mandatory flags that are needed to be set --cephfs-metadata-pool-name, --cephfs-data-pool-name and --rbd-data-pool-name. Note: Restricting the users per pool and per cluster will require to create new users and new secrets for that users.")

output_group = argP.add_argument_group('output')
output_group.add_argument("--format", "-t", choices=["json", "bash"],
Expand All @@ -173,6 +177,8 @@ def gen_arg_parser(cls, args_to_parse=None):
help="Output will be stored into the provided file")
output_group.add_argument("--cephfs-filesystem-name", default="",
help="Provides the name of the Ceph filesystem")
output_group.add_argument("--cephfs-metadata-pool-name", default="",
help="Provides the name of the cephfs metadata pool")
output_group.add_argument("--cephfs-data-pool-name", default="",
help="Provides the name of the cephfs data pool")
output_group.add_argument("--rbd-data-pool-name", default="", required=False,
Expand Down Expand Up @@ -443,11 +449,27 @@ def create_cephCSIKeyring_cephFSProvisioner(self):
'''
command: ceph auth get-or-create client.csi-cephfs-provisioner mon 'allow r' mgr 'allow rw' osd 'allow rw tag cephfs metadata=*'
'''
cmd_json = {"prefix": "auth get-or-create",
"entity": "client.csi-cephfs-provisioner",
"caps": ["mon", "allow r", "mgr", "allow rw",
"osd", "allow rw tag cephfs metadata=*"],
"format": "json"}
metadata_pool = self._arg_parser.cephfs_metadata_pool_name
cluster_name = self._arg_parser.cluster_name
entity = "client.csi-cephfs-provisioner"
if cluster_name:
entity = "client.csi-cephfs-provisioner-{}".format(cluster_name)
cmd_json = {}
if self._arg_parser.restricted_auth_permission:
if metadata_pool == "":
raise ExecutionFailureException(
"'cephfs_metadata_pool_name' not found, please set the '--cephfs-metadata-pool-name' flag")
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "allow r", "mgr", "allow rw",
"osd", "allow rw tag cephfs metadata={}".format(metadata_pool)],
"format": "json"}
else:
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "allow r", "mgr", "allow rw",
"osd", "allow rw tag cephfs metadata=*"],
"format": "json"}
ret_val, json_out, err_msg = self._common_cmd_json_gen(cmd_json)
# if there is an unsuccessful attempt,
if ret_val != 0 or len(json_out) == 0:
Expand All @@ -457,13 +479,31 @@ def create_cephCSIKeyring_cephFSProvisioner(self):
return str(json_out[0]['key'])

def create_cephCSIKeyring_cephFSNode(self):
cmd_json = {"prefix": "auth get-or-create",
"entity": "client.csi-cephfs-node",
"caps": ["mon", "allow r",
"mgr", "allow rw",
"osd", "allow rw tag cephfs *=*",
"mds", "allow rw"],
"format": "json"}
data_pool = self._arg_parser.cephfs_data_pool_name
cluster_name = self._arg_parser.cluster_name
entity = "client.csi-cephfs-node"
if cluster_name:
entity = "client.csi-cephfs-node-{}".format(cluster_name)
cmd_json = {}
if self._arg_parser.restricted_auth_permission:
if data_pool == "":
raise ExecutionFailureException(
"'cephfs_data_pool_name' not found, please set the '--cephfs-data-pool-name' flag")
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "allow r",
"mgr", "allow rw",
"osd", "allow rw tag cephfs data={}".format(data_pool),
"mds", "allow rw"],
"format": "json"}
else:
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "allow r",
"mgr", "allow rw",
"osd", "allow rw tag cephfs *=*",
"mds", "allow rw"],
"format": "json"}
ret_val, json_out, err_msg = self._common_cmd_json_gen(cmd_json)
# if there is an unsuccessful attempt,
if ret_val != 0 or len(json_out) == 0:
Expand All @@ -473,12 +513,29 @@ def create_cephCSIKeyring_cephFSNode(self):
return str(json_out[0]['key'])

def create_cephCSIKeyring_RBDProvisioner(self):
cmd_json = {"prefix": "auth get-or-create",
"entity": "client.csi-rbd-provisioner",
"caps": ["mon", "profile rbd",
"mgr", "allow rw",
"osd", "profile rbd"],
"format": "json"}
rbd_pool_name = self._arg_parser.rbd_data_pool_name
cluster_name = self._arg_parser.cluster_name
entity = "client.csi-rbd-provisioner"
if cluster_name:
entity = "client.csi-rbd-provisioner-{}".format(cluster_name)
cmd_json={}
if self._arg_parser.restricted_auth_permission:
if rbd_pool_name == "":
raise ExecutionFailureException(
"'rbd_data_pool_name' not found, please set the '--rbd-data-pool-name' flag")
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "profile rbd",
"mgr", "allow rw",
"osd", "profile rbd pool={}".format(rbd_pool_name)],
"format": "json"}
else:
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "profile rbd",
"mgr", "allow rw",
"osd", "profile rbd"],
"format": "json"}
ret_val, json_out, err_msg = self._common_cmd_json_gen(cmd_json)
# if there is an unsuccessful attempt,
if ret_val != 0 or len(json_out) == 0:
Expand Down Expand Up @@ -540,8 +597,8 @@ def get_cephfs_data_pool_details(self):
return

if matching_json_out:
self._arg_parser.cephfs_filesystem_name = str(
matching_json_out['name'])
self._arg_parser.cephfs_filesystem_name = str(matching_json_out['name'])
self._arg_parser.cephfs_metadata_pool_name = str(matching_json_out['metadata_pool'])

if type(matching_json_out['data_pools']) == list:
# if the user has already provided data-pool-name,
Expand Down Expand Up @@ -573,11 +630,27 @@ def get_cephfs_data_pool_details(self):
self._arg_parser.cephfs_data_pool_name))

def create_cephCSIKeyring_RBDNode(self):
cmd_json = {"prefix": "auth get-or-create",
"entity": "client.csi-rbd-node",
"caps": ["mon", "profile rbd",
"osd", "profile rbd"],
"format": "json"}
rbd_pool_name = self._arg_parser.rbd_data_pool_name
cluster_name = self._arg_parser.cluster_name
entity = "client.csi-rbd-node"
if cluster_name:
entity = "client.csi-rbd-node-{}".format(cluster_name)
cmd_json={}
if self._arg_parser.restricted_auth_permission:
if rbd_pool_name == "":
raise ExecutionFailureException(
"'rbd_data_pool_name' not found, please set the '--rbd-data-pool-name' flag")
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "profile rbd",
"osd", "profile rbd pool={}".format(rbd_pool_name)],
"format": "json"}
else:
cmd_json = {"prefix": "auth get-or-create",
"entity": entity,
"caps": ["mon", "profile rbd",
"osd", "profile rbd"],
"format": "json"}
ret_val, json_out, err_msg = self._common_cmd_json_gen(cmd_json)
# if there is an unsuccessful attempt,
if ret_val != 0 or len(json_out) == 0:
Expand Down Expand Up @@ -671,13 +744,14 @@ def _gen_output_map(self):
self.out_map['CSI_RBD_NODE_SECRET_SECRET'] = self.create_cephCSIKeyring_RBDNode()
self.out_map['CSI_RBD_PROVISIONER_SECRET'] = self.create_cephCSIKeyring_RBDProvisioner()
self.out_map['CEPHFS_POOL_NAME'] = self._arg_parser.cephfs_data_pool_name
self.out_map['CEPHFS_METADATA_POOL_NAME'] = self._arg_parser.cephfs_metadata_pool_name
self.out_map['CEPHFS_FS_NAME'] = self._arg_parser.cephfs_filesystem_name
self.out_map['RESTRICTED_AUTH_PERMISSION'] = self._arg_parser.restricted_auth_permission
self.out_map['CSI_CEPHFS_NODE_SECRET'] = ''
self.out_map['CSI_CEPHFS_PROVISIONER_SECRET'] = ''
# create CephFS node and provisioner keyring only when MDS exists
if self.out_map['CEPHFS_FS_NAME'] and self.out_map['CEPHFS_POOL_NAME']:
self.out_map['CSI_CEPHFS_NODE_SECRET'] = self.create_cephCSIKeyring_cephFSNode(
)
self.out_map['CSI_CEPHFS_NODE_SECRET'] = self.create_cephCSIKeyring_cephFSNode()
self.out_map['CSI_CEPHFS_PROVISIONER_SECRET'] = self.create_cephCSIKeyring_cephFSProvisioner()
self.out_map['RGW_ENDPOINT'] = self._arg_parser.rgw_endpoint
self.out_map['RGW_TLS_CERT'] = ''
Expand Down Expand Up @@ -931,7 +1005,7 @@ def main(self):
################################################
# inorder to test the package,
# cd <script_directory>
# python -m unittest --verbose <script_name_without_dot_py>
# python3 -m unittest --verbose <script_name_without_dot_py>
class TestRadosJSON(unittest.TestCase):
def setUp(self):
print("\nI am in setup")
Expand Down Expand Up @@ -961,7 +1035,14 @@ def test_method_main_output(self):

def test_method_create_cephCSIKeyring_cephFSProvisioner(self):
csiKeyring = self.rjObj.create_cephCSIKeyring_cephFSProvisioner()
print("{}".format(csiKeyring))
print("cephCSIKeyring without restricting it to a metadata pool. {}".format(csiKeyring))
self.rjObj._arg_parser.restricted_auth_permission = True
self.rjObj._arg_parser.cephfs_metadata_pool_name = "myfs-metadata"
csiKeyring = self.rjObj.create_cephCSIKeyring_cephFSProvisioner()
print("cephCSIKeyring for a specific metadata pool. {}".format(csiKeyring))
self.rjObj._arg_parser.cluster_name = "openshift-storage"
csiKeyring = self.rjObj.create_cephCSIKeyring_cephFSProvisioner()
print("cephCSIKeyring for a specific metadata pool and cluster. {}".format(csiKeyring))

def test_non_zero_return_and_error(self):
self.rjObj.cluster.return_val = 1
Expand Down

0 comments on commit 7d87de8

Please sign in to comment.