- keyring's secret value
required: false
default: None
- containerized:
- description:
- - Wether or not this is a containerized cluster. The value is
- assigned or not depending on how the playbook runs.
- required: false
- default: None
import_key:
description:
- Wether or not to import the created keyring into Ceph.
raise(Exception(message))
+def container_exec(binary, container_image):
+ '''
+ Build the docker CLI to run a command inside a container
+ '''
+
+ command_exec = ['docker',
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ os.path.join('--entrypoint=' + binary),
+ container_image]
+ return command_exec
+
+
+def is_containerized():
+ '''
+ Check if we are running on a containerized cluster
+ '''
+
+ if 'CEPH_CONTAINER_IMAGE' in os.environ:
+ container_image = os.getenv('CEPH_CONTAINER_IMAGE')
+ else:
+ container_image = None
+
+ return container_image
+
+
def generate_secret():
'''
Generate a CephX secret
return cmd
-def generate_ceph_cmd(cluster, args, user, user_key, containerized=None):
+def generate_ceph_cmd(cluster, args, user, user_key, container_image=None):
'''
Generate 'ceph' command line to execute
'''
- cmd = []
+ if container_image:
+ binary = 'ceph'
+ cmd = container_exec(
+ binary, container_image)
+ else:
+ binary = ['ceph']
+ cmd = binary
base_cmd = [
- 'ceph',
'-n',
user,
'-k',
cmd.extend(base_cmd + args)
- if containerized:
- cmd = containerized.split() + cmd
-
return cmd
-def generate_ceph_authtool_cmd(cluster, name, secret, caps, auid, dest, containerized=None): # noqa E501
+def generate_ceph_authtool_cmd(cluster, name, secret, caps, dest, container_image=None): # noqa E501
'''
Generate 'ceph-authtool' command line to execute
'''
- cmd = [
- 'ceph-authtool',
+ if container_image:
+ binary = 'ceph-authtool'
+ cmd = container_exec(
+ binary, container_image)
+ else:
+ binary = ['ceph-authtool']
+ cmd = binary
+
+ base_cmd = [
'--create-keyring',
dest,
'--name',
secret,
]
+ cmd.extend(base_cmd)
+
if auid:
cmd.extend(['--set-uid', auid])
cmd = generate_caps(cmd, "ceph-authtool", caps)
- if containerized:
- cmd = containerized.split() + cmd
-
return cmd
-def create_key(module, result, cluster, name, secret, caps, import_key, auid, dest, containerized=None): # noqa E501
+def create_key(module, result, cluster, name, secret, caps, import_key, dest, container_image=None): # noqa E501
'''
Create a CephX key
'''
secret = generate_secret()
cmd_list.append(generate_ceph_authtool_cmd(
- cluster, name, secret, caps, auid, dest, containerized))
+ cluster, name, secret, caps, auid, dest, container_image))
if import_key:
user = "client.admin"
user_key = os.path.join(
"/etc/ceph/" + cluster + ".client.admin.keyring")
cmd_list.append(generate_ceph_cmd(
- cluster, args, user, user_key, containerized))
+ cluster, args, user, user_key, container_image))
return cmd_list
-def update_key(cluster, name, caps, containerized=None):
+def update_key(cluster, name, caps, container_image=None):
'''
Update a CephX key's capabilities
'''
user_key = os.path.join(
"/etc/ceph/" + cluster + ".client.admin.keyring")
cmd_list.append(generate_ceph_cmd(
- cluster, args, user, user_key, containerized))
+ cluster, args, user, user_key, container_image))
return cmd_list
-def delete_key(cluster, name, containerized=None):
+def delete_key(cluster, name, container_image=None):
'''
Delete a CephX key
'''
user_key = os.path.join(
"/etc/ceph/" + cluster + ".client.admin.keyring")
cmd_list.append(generate_ceph_cmd(
- cluster, args, user, user_key, containerized))
+ cluster, args, user, user_key, container_image))
return cmd_list
-def get_key(cluster, name, dest, containerized=None):
+def get_key(cluster, name, dest, container_image=None):
'''
Get a CephX key (write on the filesystem)
'''
user_key = os.path.join(
"/etc/ceph/" + cluster + ".client.admin.keyring")
cmd_list.append(generate_ceph_cmd(
- cluster, args, user, user_key, containerized))
+ cluster, args, user, user_key, container_image))
return cmd_list
-def info_key(cluster, name, user, user_key, output_format, containerized=None):
+def info_key(cluster, name, user, user_key, output_format, container_image=None): # noqa E501
'''
Get information about a CephX key
'''
]
cmd_list.append(generate_ceph_cmd(
- cluster, args, user, user_key, containerized))
+ cluster, args, user, user_key, container_image))
return cmd_list
-def list_keys(cluster, user, user_key, containerized=None):
+def list_keys(cluster, user, user_key, container_image=None):
'''
List all CephX keys
'''
]
cmd_list.append(generate_ceph_cmd(
- cluster, args, user, user_key, containerized))
+ cluster, args, user, user_key, container_image))
return cmd_list
cluster=dict(type='str', required=False, default='ceph'),
name=dict(type='str', required=False),
state=dict(type='str', required=True),
- containerized=dict(type='str', required=False, default=None),
caps=dict(type='dict', required=False, default=None),
secret=dict(type='str', required=False, default=None),
import_key=dict(type='bool', required=False, default=True),
state = module.params['state']
name = module.params.get('name')
cluster = module.params.get('cluster')
- containerized = module.params.get('containerized')
caps = module.params.get('caps')
secret = module.params.get('secret')
import_key = module.params.get('import_key')
startd = datetime.datetime.now()
+ # will return either the image name or None
+ container_image = is_containerized()
+
# Test if the key exists, if it does we skip its creation
# We only want to run this check when a key needs to be added
# There is no guarantee that any cluster is running and we don't need one
"/etc/ceph/" + cluster + ".client.admin.keyring")
output_format = "json"
rc, cmd, out, err = exec_commands(
- module, info_key(cluster, name, user, user_key, output_format, containerized)) # noqa E501
+ module, info_key(cluster, name, user, user_key, output_format, container_image)) # noqa E501
if state == "present":
if not caps:
if rc == 0 and not secret:
# If the key exists in Ceph we must fetch it on the system
# because nothing tells us it exists on the fs or not
- rc, cmd, out, err = exec_commands(module, get_key(cluster, name, file_path, containerized)) # noqa E501
+ rc, cmd, out, err = exec_commands(module, get_key(cluster, name, file_path, container_image)) # noqa E501
result["stdout"] = "skipped, since {0} already exists, we only fetched the key at {1}. If you want to update a key use 'state: update'".format( # noqa E501
name, file_path)
result['rc'] = rc
module.exit_json(**result)
rc, cmd, out, err = exec_commands(module, create_key(
- module, result, cluster, name, secret, caps, import_key, auid, file_path, containerized)) # noqa E501
+ module, result, cluster, name, secret, caps, import_key, auid, file_path, container_image)) # noqa E501
file_args = module.load_file_common_arguments(module.params)
file_args['path'] = file_path
module.exit_json(**result)
rc, cmd, out, err = exec_commands(
- module, update_key(cluster, name, caps, containerized))
+ module, update_key(cluster, name, caps, container_image))
# After the update we don't need to overwrite the key on the filesystem
# since the secret has not changed
elif state == "absent":
rc, cmd, out, err = exec_commands(
- module, delete_key(cluster, name, containerized))
+ module, delete_key(cluster, name, container_image))
elif state == "info":
if rc != 0:
"/etc/ceph/" + cluster + ".client.admin.keyring")
output_format = "json"
rc, cmd, out, err = exec_commands(
- module, info_key(cluster, name, user, user_key, output_format, containerized)) # noqa E501
+ module, info_key(cluster, name, user, user_key, output_format, container_image)) # noqa E501
elif state == "list":
user = "client.admin"
user_key = os.path.join(
"/etc/ceph/" + cluster + ".client.admin.keyring")
rc, cmd, out, err = exec_commands(
- module, list_keys(cluster, user, user_key, containerized))
+ module, list_keys(cluster, user, user_key, container_image))
elif state == "fetch_initial_keys":
hostname = socket.gethostname()
user_key = os.path.join(
"/var/lib/ceph/mon/" + cluster + "-" + hostname + "/keyring")
rc, cmd, out, err = exec_commands(
- module, list_keys(cluster, user, user_key, containerized))
+ module, list_keys(cluster, user, user_key, container_image))
if rc != 0:
result["stdout"] = "failed to retrieve ceph keys".format(name)
result['rc'] = 0
fatal("Failed to find some of the initial entities", module)
# get ceph's group and user id
- ceph_uid = pwd.getpwnam('ceph').pw_uid
- ceph_grp = grp.getgrnam('ceph').gr_gid
+ if container_image:
+ ceph_uid = os.getenv('CEPH_UID')
+ ceph_grp = os.getenv('CEPH_UID')
+ else:
+ ceph_uid = pwd.getpwnam('ceph').pw_uid
+ ceph_grp = grp.getgrnam('ceph').gr_gid
output_format = "plain"
for entity in entities:
]
info_cmd = info_key(cluster, entity, user,
- user_key, output_format, containerized)
+ user_key, output_format, container_image)
# we use info_cmd[0] because info_cmd is an array made of an array
info_cmd[0].extend(extra_args)
rc, cmd, out, err = exec_commands(
import json
import os
from . import ceph_key
-from ansible.compat.tests.mock import MagicMock
class TestCephKeyModule(object):
fake_args = ['arg']
fake_user = "fake-user"
fake_key = "/tmp/my-key"
- fake_containerized = "docker exec -ti ceph-mon"
- expected_command_list = [
- 'docker',
- 'exec',
- '-ti',
- 'ceph-mon',
- 'ceph',
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = ['docker',
+ 'run',
+ '--rm',
+ '--net=host', # noqa E501
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
'-n',
"fake-user",
'-k',
'--cluster',
fake_cluster,
'auth',
- 'arg'
- ]
+ 'arg']
result = ceph_key.generate_ceph_cmd(
- fake_cluster, fake_args, fake_user, fake_key, fake_containerized)
+ fake_cluster, fake_args, fake_user, fake_key, fake_container_image)
assert result == expected_command_list
def test_generate_ceph_authtool_cmd_non_container_no_auid(self):
fake_cluster = "fake"
fake_name = "client.fake"
fake_secret = "super-secret"
- fake_containerized = "docker exec -ti ceph-mon"
fake_caps = {
'mon': 'allow *',
'osd': 'allow rwx',
fake_auid = None
fake_file_destination = os.path.join(
fake_dest + "/" + fake_cluster + "." + fake_name + ".keyring")
- expected_command_list = [
- 'docker',
- 'exec',
- '-ti',
- 'ceph-mon',
- 'ceph-authtool',
- '--create-keyring',
- fake_file_destination,
- '--name',
- fake_name,
- '--add-key',
- fake_secret,
- '--cap',
- 'mon',
- 'allow *',
- '--cap',
- 'osd',
- 'allow rwx'
- ]
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = ['docker',
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph-authtool',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '--create-keyring',
+ fake_file_destination,
+ '--name',
+ fake_name,
+ '--add-key',
+ fake_secret,
+ '--cap',
+ 'mon',
+ 'allow *',
+ '--cap',
+ 'osd',
+ 'allow rwx']
result = ceph_key.generate_ceph_authtool_cmd(
fake_cluster, fake_name, fake_secret, fake_caps, fake_auid, fake_file_destination, fake_containerized) # noqa E501
assert result == expected_command_list
def test_create_key_non_container(self):
fake_module = "fake"
- fake_result = "fake"
+ fake_result = " fake"
fake_cluster = "fake"
fake_name = "client.fake"
fake_secret = "super-secret"
fake_cluster = "fake"
fake_name = "client.fake"
fake_secret = "super-secret"
- fake_containerized = "docker exec -ti ceph-mon"
fake_caps = {
'mon': 'allow *',
'osd': 'allow rwx',
fake_auid = None
fake_file_destination = os.path.join(
fake_dest + "/" + fake_cluster + "." + fake_name + ".keyring")
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
expected_command_list = [
- ['docker', 'exec', '-ti', 'ceph-mon', 'ceph-authtool', '--create-keyring', fake_file_destination, # noqa E501
- '--name', fake_name, '--add-key', fake_secret, '--cap', 'mon', 'allow *', '--cap', 'osd', 'allow rwx'], # noqa E501
- ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', 'client.admin', '-k', '/etc/ceph/fake.client.admin.keyring', '--cluster', # noqa E501
- fake_cluster, 'auth', 'import', '-i', fake_file_destination],
+ ['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph-authtool',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '--create-keyring', fake_file_destination,
+ '--name', fake_name,
+ '--add-key', fake_secret,
+ '--cap', 'mon', 'allow *',
+ '--cap', 'osd', 'allow rwx'],
+ ['docker',
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '-n', 'client.admin',
+ '-k', '/etc/ceph/fake.client.admin.keyring',
+ '--cluster', fake_cluster,
+ 'auth', 'import',
+ '-i', fake_file_destination]
]
result = ceph_key.create_key(fake_module, fake_result, fake_cluster, fake_name, # noqa E501
fake_secret, fake_caps, fake_import_key, fake_auid, fake_file_destination, fake_containerized) # noqa E501
fake_cluster = "fake"
fake_name = "client.fake"
fake_secret = "super-secret"
- fake_containerized = "docker exec -ti ceph-mon"
fake_caps = {
'mon': 'allow *',
'osd': 'allow rwx',
fake_dest + "/" + fake_cluster + "." + fake_name + ".keyring")
fake_auid = None
# create_key passes (one for ceph-authtool and one for itself) itw own array so the expected result is an array within an array # noqa E501
- expected_command_list = [[
- 'docker',
- 'exec',
- '-ti',
- 'ceph-mon',
- 'ceph-authtool',
- '--create-keyring',
- fake_file_destination,
- '--name',
- fake_name,
- '--add-key',
- fake_secret,
- '--cap',
- 'mon',
- 'allow *',
- '--cap',
- 'osd',
- 'allow rwx', ]
- ]
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = [['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph-authtool',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '--create-keyring',
+ fake_file_destination,
+ '--name',
+ fake_name,
+ '--add-key',
+ fake_secret,
+ '--cap',
+ 'mon',
+ 'allow *',
+ '--cap',
+ 'osd',
+ 'allow rwx']]
result = ceph_key.create_key(fake_module, fake_result, fake_cluster, fake_name, # noqa E501
fake_secret, fake_caps, fake_import_key, fake_auid, fake_file_destination, fake_containerized) # noqa E501
assert result == expected_command_list
def test_update_key_container(self):
fake_cluster = "fake"
fake_name = "client.fake"
- fake_containerized = "docker exec -ti ceph-mon"
fake_caps = {
'mon': 'allow *',
'osd': 'allow rwx',
}
- expected_command_list = [
- ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', 'client.admin', '-k', '/etc/ceph/fake.client.admin.keyring', '--cluster', fake_cluster, # noqa E501
- 'auth', 'caps', fake_name, 'mon', 'allow *', 'osd', 'allow rwx'], # noqa E501
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = [['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '-n', 'client.admin',
+ '-k', '/etc/ceph/fake.client.admin.keyring',
+ '--cluster', fake_cluster,
+ 'auth',
+ 'caps', fake_name,
+ 'mon', 'allow *', 'osd', 'allow rwx']
]
result = ceph_key.update_key(
- fake_cluster, fake_name, fake_caps, fake_containerized)
+ fake_cluster, fake_name, fake_caps, fake_container_image)
assert result == expected_command_list
def test_delete_key_non_container(self):
def test_delete_key_container(self):
fake_cluster = "fake"
fake_name = "client.fake"
- fake_containerized = "docker exec -ti ceph-mon"
- expected_command_list = [
- ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', 'client.admin', '-k', '/etc/ceph/fake.client.admin.keyring', # noqa E501
- '--cluster', fake_cluster, 'auth', 'del', fake_name],
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = [['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '-n', 'client.admin',
+ '-k', '/etc/ceph/fake.client.admin.keyring',
+ '--cluster', fake_cluster,
+ 'auth', 'del', fake_name]
]
result = ceph_key.delete_key(
- fake_cluster, fake_name, fake_containerized)
+ fake_cluster, fake_name, fake_container_image)
assert result == expected_command_list
def test_info_key_non_container(self):
fake_name = "client.fake"
fake_user = "fake-user"
fake_key = "/tmp/my-key"
- fake_containerized = "docker exec -ti ceph-mon"
fake_output_format = "json"
- expected_command_list = [
- ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', "fake-user", '-k', "/tmp/my-key", '--cluster', # noqa E501
- fake_cluster, 'auth', 'get', fake_name, '-f', 'json'],
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = [['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '-n', "fake-user",
+ '-k', "/tmp/my-key",
+ '--cluster', fake_cluster,
+ 'auth', 'get', fake_name,
+ '-f', 'json']
]
result = ceph_key.info_key(
- fake_cluster, fake_name, fake_user, fake_key, fake_output_format, fake_containerized) # noqa E501
+ fake_cluster, fake_name, fake_user, fake_key, fake_output_format, fake_container_image) # noqa E501
assert result == expected_command_list
def test_list_key_non_container(self):
def test_list_key_container_with_mon_key(self):
fake_hostname = "mon01"
fake_cluster = "fake"
- fake_containerized = "docker exec -ti ceph-mon"
fake_user = "mon."
fake_key = os.path.join("/var/lib/ceph/mon/" + fake_cluster + "-" + fake_hostname + "/keyring") # noqa E501
- expected_command_list = [
- ['docker', 'exec', '-ti', 'ceph-mon','ceph', '-n', "mon.", '-k', "/var/lib/ceph/mon/fake-mon01/keyring", # noqa E501
- '--cluster', fake_cluster, 'auth', 'ls', '-f', 'json'],
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = [['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '-n', "mon.",
+ '-k', "/var/lib/ceph/mon/fake-mon01/keyring", # noqa E501
+ '--cluster', fake_cluster,
+ 'auth', 'ls',
+ '-f', 'json'],
]
- result = ceph_key.list_keys(fake_cluster, fake_user, fake_key, fake_containerized) # noqa E501
+ result = ceph_key.list_keys(fake_cluster, fake_user, fake_key, fake_container_image) # noqa E501
assert result == expected_command_list
def test_list_key_container(self):
fake_cluster = "fake"
- fake_containerized = "docker exec -ti ceph-mon"
fake_user = "fake-user"
fake_key = "/tmp/my-key"
- expected_command_list = [
- ['docker', 'exec', '-ti', 'ceph-mon', 'ceph', '-n', "fake-user", '-k', "/tmp/my-key", '--cluster', # noqa E501
- fake_cluster, 'auth', 'ls', '-f', 'json'],
+ fake_container_image = "docker.io/ceph/daemon:latest-luminous"
+ expected_command_list = [['docker', # noqa E128
+ 'run',
+ '--rm',
+ '--net=host',
+ '-v', '/etc/ceph:/etc/ceph:z',
+ '-v', '/var/lib/ceph/:/var/lib/ceph/:z',
+ '-v', '/var/log/ceph/:/var/log/ceph/:z',
+ '--entrypoint=ceph',
+ 'docker.io/ceph/daemon:latest-luminous',
+ '-n', "fake-user",
+ '-k', "/tmp/my-key",
+ '--cluster', fake_cluster,
+ 'auth', 'ls',
+ '-f', 'json'],
]
result = ceph_key.list_keys(
- fake_cluster, fake_user, fake_key, fake_containerized)
+ fake_cluster, fake_user, fake_key, fake_container_image)
assert result == expected_command_list
def test_lookup_ceph_initial_entities(self):