From 20c5e8fe13ae57ac59c8b536830ee4b133f75d52 Mon Sep 17 00:00:00 2001 From: Jeffrey Zhang Date: Thu, 22 Feb 2018 22:42:47 +0800 Subject: [PATCH] Update ceph client.admin caps during upgrade When upgrade from ceph Jewel to ceph luminous, the client.admin caps should add `mgr 'allow *'` caps Change-Id: Ia4cb7a59d4cf215a1dce1efe31e00f1401e0b753 Closes-Bug: #1750967 --- ansible/library/kolla_ceph_keyring.py | 153 ++++++++++++++++++++++++++ ansible/roles/ceph/defaults/main.yml | 6 + ansible/roles/ceph/tasks/deploy.yml | 7 ++ ansible/roles/ceph/tasks/upgrade.yml | 9 ++ 4 files changed, 175 insertions(+) create mode 100644 ansible/library/kolla_ceph_keyring.py diff --git a/ansible/library/kolla_ceph_keyring.py b/ansible/library/kolla_ceph_keyring.py new file mode 100644 index 0000000000..5041563ecd --- /dev/null +++ b/ansible/library/kolla_ceph_keyring.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +# Copyright 2018 99cloud +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import subprocess # nosec + + +DOCUMENTATION = ''' +--- +module: kolla_ceph_keyring +short_description: > + Module for update ceph client keyring caps in kolla. +description: + - A module used to update ceph client keyring caps in kolla. +options: + name: + description: + - the client name in ceph + required: True + type: str + container_name: + description: + - the ceph mon container name + required: True + default: ceph_mon + type: str + caps: + description: + - the ceph auth caps + required: True + type: dict +author: Jeffrey Zhang +''' + +EXAMPLES = ''' +- name: configure admin client caps + kolla_ceph_keyring: + name: client.admin + container_name: ceph_mon + caps: + mds: 'allow' + mon: 'allow *' + osd: 'allow *' + mgr: 'allow *' +''' + + +class CephKeyring(object): + def __init__(self, name, caps, container_name='ceph_mon'): + self.name = name + self.caps = caps + self.container_name = container_name + self.changed = False + self.message = None + + def _run(self, cmd): + _prefix = ['docker', 'exec', self.container_name] + cmd = _prefix + cmd + proc = subprocess.Popen(cmd, # nosec + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = proc.communicate() + retcode = proc.poll() + if retcode != 0: + output = 'stdout: "%s", stderr: "%s"' % (stdout, stderr) + raise subprocess.CalledProcessError(retcode, cmd, output) + return stdout + + def _format_caps(self): + caps = [] + for obj in sorted(self.caps): + caps.extend([obj, self.caps[obj]]) + return caps + + def parse_stdout(self, stdout): + keyring = json.loads(stdout) + # there should be only one element + return keyring[0] + + def ensure_keyring(self): + try: + stdout = self.get_keyring() + except subprocess.CalledProcessError: + # keyring doesn't exsit, try to create it + stdout = self.create_keyring() + self.changed = True + self.message = 'ceph keyring for %s is created' % self.name + keyring = self.parse_stdout(stdout) + if keyring['caps'] != self.caps: + self.update_caps() + stdout = self.get_keyring() + keyring = self.parse_stdout(stdout) + self.changed = True + self.message = 'ceph keyring for %s is updated' % self.name + self.keyring = keyring + return self.keyring + + def get_keyring(self): + ceph_cmd = ['ceph', '--format', 'json', 'auth', 'get', self.name] + return self._run(ceph_cmd) + + def update_caps(self): + ceph_cmd = ['ceph', '--format', 'json', 'auth', 'caps', self.name] + caps = self._format_caps() + ceph_cmd.extend(caps) + self._run(ceph_cmd) + + def create_keyring(self): + ceph_cmd = ['ceph', '--format', 'json', 'auth', + 'get-or-create', self.name] + caps = self._format_caps() + ceph_cmd.extend(caps) + return self._run(ceph_cmd) + + +def main(): + specs = dict( + name=dict(type='str', required=True), + container_name=dict(type='str', default='ceph_mon'), + caps=dict(type='dict', required=True) + ) + module = AnsibleModule(argument_spec=specs) # noqa + params = module.params + ceph_keyring = CephKeyring(params['name'], + params['caps'], + params['container_name']) + try: + keyring = ceph_keyring.ensure_keyring() + module.exit_json(changed=ceph_keyring.changed, + keyring=keyring, + message=ceph_keyring.message) + except subprocess.CalledProcessError as ex: + msg = ('Failed to call command: %s returncode: %s output: %s' % + (ex.cmd, ex.returncode, ex.output)) + module.fail_json(msg=msg) + + +from ansible.module_utils.basic import * # noqa +if __name__ == "__main__": + main() diff --git a/ansible/roles/ceph/defaults/main.yml b/ansible/roles/ceph/defaults/main.yml index 0655c6724a..25713a95ee 100644 --- a/ansible/roles/ceph/defaults/main.yml +++ b/ansible/roles/ceph/defaults/main.yml @@ -40,6 +40,12 @@ osd_initial_weight: "1" # Increase tcmalloc cache size ceph_tcmalloc_tc_bytes: "134217728" +ceph_client_admin_keyring_caps: + mds: "allow" + mon: "allow *" + osd: "allow *" + mgr: "allow *" + #################### ## Ceph_rgw_keystone #################### diff --git a/ansible/roles/ceph/tasks/deploy.yml b/ansible/roles/ceph/tasks/deploy.yml index 39dc253203..286ca26f5c 100644 --- a/ansible/roles/ceph/tasks/deploy.yml +++ b/ansible/roles/ceph/tasks/deploy.yml @@ -17,6 +17,13 @@ - enable_ceph_nfs | bool - inventory_hostname in groups['ceph-nfs'] +- name: configuring client.admin caps + kolla_ceph_keyring: + name: client.admin + caps: "{{ ceph_client_admin_keyring_caps }}" + run_once: True + delegate_to: "{{ groups['ceph-mon'][0] }}" + - include: bootstrap_osds.yml when: inventory_hostname in groups['ceph-osd'] diff --git a/ansible/roles/ceph/tasks/upgrade.yml b/ansible/roles/ceph/tasks/upgrade.yml index cc703e9ff0..52c2c15527 100644 --- a/ansible/roles/ceph/tasks/upgrade.yml +++ b/ansible/roles/ceph/tasks/upgrade.yml @@ -1,6 +1,15 @@ --- - include: config.yml +# NOTE(jeffrey4l): client.admin caps should be update when upgrade from Jewel +# to Luminous +- name: configuring client.admin caps + kolla_ceph_keyring: + name: client.admin + caps: "{{ ceph_client_admin_keyring_caps }}" + run_once: True + delegate_to: "{{ groups['ceph-mon'][0] }}" + - include: start_mons.yml when: inventory_hostname in groups['ceph-mon']