diff --git a/library/radosgw_user.py b/library/radosgw_user.py index 78addd0cd..c4a38a5d1 100644 --- a/library/radosgw_user.py +++ b/library/radosgw_user.py @@ -195,6 +195,24 @@ def generate_radosgw_cmd(cluster, args, container_image=None): return cmd +def generate_caps_cmd(cluster, args, container_image=None): + ''' + Generate 'radosgw' command line to execute for caps + ''' + + cmd = pre_generate_radosgw_cmd(container_image=container_image) + + base_cmd = [ + '--cluster', + cluster, + 'caps' + ] + + cmd.extend(base_cmd + args) + + return cmd + + def exec_commands(module, cmd): ''' Execute command(s) @@ -223,6 +241,7 @@ def create_user(module, container_image=None): zone = module.params.get('zone', None) system = module.params.get('system', False) admin = module.params.get('admin', False) + caps = module.params.get('caps') args = ['create', '--uid=' + name, '--display_name=' + display_name] @@ -250,6 +269,10 @@ def create_user(module, container_image=None): if admin: args.append('--admin') + if caps: + caps_args = [f"{cap['type']}={cap['perm']}" for cap in caps] + args.extend(['--caps', ';'.join(caps_args)]) + cmd = generate_radosgw_cmd(cluster=cluster, args=args, container_image=container_image) @@ -257,6 +280,70 @@ def create_user(module, container_image=None): return cmd +def caps_add(module, caps, container_image=None): + ''' + Create a new user + ''' + + cluster = module.params.get('cluster') + name = module.params.get('name') + realm = module.params.get('realm', None) + zonegroup = module.params.get('zonegroup', None) + zone = module.params.get('zone', None) + + args = ['add', '--uid=' + name] + + if realm: + args.extend(['--rgw-realm=' + realm]) + + if zonegroup: + args.extend(['--rgw-zonegroup=' + zonegroup]) + + if zone: + args.extend(['--rgw-zone=' + zone]) + + caps_args = [f"{cap['type']}={cap['perm']}" for cap in caps] + args.extend(['--caps', ';'.join(caps_args)]) + + cmd = generate_caps_cmd(cluster=cluster, + args=args, + container_image=container_image) + + return cmd + + +def caps_rm(module, caps, container_image=None): + ''' + Create a new user + ''' + + cluster = module.params.get('cluster') + name = module.params.get('name') + realm = module.params.get('realm', None) + zonegroup = module.params.get('zonegroup', None) + zone = module.params.get('zone', None) + + args = ['rm', '--uid=' + name] + + if realm: + args.extend(['--rgw-realm=' + realm]) + + if zonegroup: + args.extend(['--rgw-zonegroup=' + zonegroup]) + + if zone: + args.extend(['--rgw-zone=' + zone]) + + caps_args = [f"{cap['type']}={cap['perm']}" for cap in caps] + args.extend(['--caps', ';'.join(caps_args)]) + + cmd = generate_caps_cmd(cluster=cluster, + args=args, + container_image=container_image) + + return cmd + + def modify_user(module, container_image=None): ''' Modify an existing user @@ -398,7 +485,8 @@ def run_module(): zonegroup=dict(type='str', required=False), zone=dict(type='str', required=False), system=dict(type='bool', required=False, default=False), - admin=dict(type='bool', required=False, default=False) + admin=dict(type='bool', required=False, default=False), + caps=dict(type='list', required=False), ) module = AnsibleModule( @@ -417,6 +505,7 @@ def run_module(): secret_key = module.params.get('secret_key') system = module.params.get('system') admin = module.params.get('admin') + caps = module.params.get('caps') startd = datetime.datetime.now() changed = False @@ -431,16 +520,19 @@ def run_module(): current = { 'display_name': user['display_name'], 'system': user.get('system', False), - 'admin': user.get('admin', False) + 'admin': user.get('admin', False), } asked = { 'display_name': display_name, 'system': system, - 'admin': admin + 'admin': admin, } if email: current['email'] = user['email'] asked['email'] = email + if caps: + current['caps'] = user['caps'] + asked['caps'] = caps if access_key and secret_key: asked['access_key'] = access_key @@ -453,7 +545,15 @@ def run_module(): changed = current != asked if changed and not module.check_mode: - rc, cmd, out, err = exec_commands(module, modify_user(module, container_image=container_image)) # noqa: E501 + rc, cmd, out, err = exec_commands(module, modify_user(module, container_image=container_image)) + + if caps: + missing_caps = [cap for cap in asked['caps'] if cap not in current['caps']] + extra_caps = [cap for cap in current['caps'] if cap not in asked['caps']] + if extra_caps: + rc, cmd, out, err = exec_commands(module, caps_rm(module, extra_caps, container_image=container_image)) + if missing_caps: + rc, cmd, out, err = exec_commands(module, caps_add(module, missing_caps, container_image=container_image)) else: changed = True if not module.check_mode: diff --git a/tests/library/test_radosgw_user.py b/tests/library/test_radosgw_user.py index a5d629cdb..374c51219 100644 --- a/tests/library/test_radosgw_user.py +++ b/tests/library/test_radosgw_user.py @@ -149,3 +149,57 @@ class TestRadosgwUserModule(object): ] assert radosgw_user.remove_user(fake_module) == expected_cmd + + def test_caps_add(self): + fake_module = MagicMock() + fake_module.params = fake_params + expected_cmd = [ + fake_binary, + '--cluster', fake_cluster, + 'caps', 'add', + '--uid=' + fake_user, + '--rgw-realm=' + fake_realm, + '--rgw-zonegroup=' + fake_zonegroup, + '--rgw-zone=' + fake_zone, + '--caps=metadata=read;buckets=read' + ] + + caps = [ + { + 'type': 'metadata', + 'perm': 'read', + }, + { + 'type': 'buckets', + 'perm': 'read', + }, + ] + + assert radosgw_user.caps_add(fake_module, caps) == expected_cmd + + def test_caps_rm(self): + fake_module = MagicMock() + fake_module.params = fake_params + expected_cmd = [ + fake_binary, + '--cluster', fake_cluster, + 'caps', 'rm', + '--uid=' + fake_user, + '--rgw-realm=' + fake_realm, + '--rgw-zonegroup=' + fake_zonegroup, + '--rgw-zone=' + fake_zone, + '--caps=metadata=read;buckets=read' + ] + + caps = [ + { + 'type': 'metadata', + 'perm': 'read', + }, + { + 'type': 'buckets', + 'perm': 'read', + }, + ] + + assert radosgw_user.caps_rm(fake_module, caps) == expected_cmd