chore: move to vexxhost.ceph
diff --git a/.github/workflows/csi.yml b/.github/workflows/csi.yml
new file mode 100644
index 0000000..a0e43c6
--- /dev/null
+++ b/.github/workflows/csi.yml
@@ -0,0 +1,73 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+name: csi
+
+on:
+ pull_request:
+ paths:
+ - .github/workflows/csi.yml
+ - molecule/csi/**
+ - playbooks/csi.yml
+ - playbooks/kubernetes.yml
+ - roles/ceph_csi_rbd/**
+ - roles/csi/**
+ - galaxy.yml
+ push:
+ branches:
+ - main
+ paths:
+ - .github/workflows/csi.yml
+ - molecule/csi/**
+ - playbooks/csi.yml
+ - playbooks/kubernetes.yml
+ - roles/ceph_csi_rbd/**
+ - roles/csi/**
+ - galaxy.yml
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ driver:
+ - rbd
+ steps:
+ - name: Checkout project
+ uses: actions/checkout@v3
+
+ - name: Install Poetry
+ run: pipx install poetry
+
+ - name: Setup Python
+ uses: actions/setup-python@v4
+ with:
+ cache: poetry
+
+ - name: Install dependencies
+ run: poetry install --no-interaction --with dev
+
+ # NOTE(mnaser): LVM commands take a long time if there are any existing
+ # loop devices created by "snapd", so we uninstall it.
+ - name: Uninstall "snapd"
+ run: sudo apt-get purge -y snapd
+
+ - name: Turn off swap
+ run: sudo swapoff -a
+
+ - name: Run Molecule
+ run: poetry run molecule test -s csi
+ env:
+ MOLECULE_CSI_DRIVER: ${{ matrix.driver }}
diff --git a/galaxy.yml b/galaxy.yml
index 618fb6b..62a71eb 100644
--- a/galaxy.yml
+++ b/galaxy.yml
@@ -16,6 +16,7 @@
kubernetes.core: 2.3.2
openstack.cloud: 1.7.0
community.mysql: 3.6.0
+ vexxhost.ceph: 2.0.1
vexxhost.kubernetes: 1.4.0
tags:
- application
diff --git a/roles/ceph_mgr/meta/main.yml b/molecule/csi/cleanup.yml
similarity index 65%
rename from roles/ceph_mgr/meta/main.yml
rename to molecule/csi/cleanup.yml
index cec72d8..45d16dc 100644
--- a/roles/ceph_mgr/meta/main.yml
+++ b/molecule/csi/cleanup.yml
@@ -1,4 +1,4 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
+# Copyright (c) 2023 VEXXHOST, Inc.
#
# 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
@@ -12,16 +12,4 @@
# License for the specific language governing permissions and limitations
# under the License.
-galaxy_info:
- author: VEXXHOST, Inc.
- description: Ansible role for Ceph manager
- license: Apache-2.0
- min_ansible_version: 5.5.0
- standalone: false
- platforms:
- - name: Ubuntu
- versions:
- - focal
-
-dependencies:
- - role: defaults
+- ansible.builtin.import_playbook: vexxhost.ceph.destroy_fake_devices
diff --git a/roles/ceph_mgr/meta/main.yml b/molecule/csi/converge.yml
similarity index 65%
copy from roles/ceph_mgr/meta/main.yml
copy to molecule/csi/converge.yml
index cec72d8..d97e10c 100644
--- a/roles/ceph_mgr/meta/main.yml
+++ b/molecule/csi/converge.yml
@@ -1,4 +1,4 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
+# Copyright (c) 2023 VEXXHOST, Inc.
#
# 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
@@ -12,16 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-galaxy_info:
- author: VEXXHOST, Inc.
- description: Ansible role for Ceph manager
- license: Apache-2.0
- min_ansible_version: 5.5.0
- standalone: false
- platforms:
- - name: Ubuntu
- versions:
- - focal
-
-dependencies:
- - role: defaults
+- ansible.builtin.import_playbook: vexxhost.ceph.site
+- ansible.builtin.import_playbook: vexxhost.atmosphere.kubernetes
+- ansible.builtin.import_playbook: vexxhost.atmosphere.csi
diff --git a/molecule/csi/molecule.yml b/molecule/csi/molecule.yml
new file mode 100644
index 0000000..a1cdf53
--- /dev/null
+++ b/molecule/csi/molecule.yml
@@ -0,0 +1,76 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+dependency:
+ name: galaxy
+driver:
+ name: docker
+platforms:
+ - name: instance
+ image: geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu2004}-ansible:latest
+ command: ${MOLECULE_DOCKER_COMMAND:-""}
+ privileged: true
+ cgroupns_mode: host
+ pre_build_image: true
+ etc_hosts:
+ k8s: 172.17.0.100
+ environment:
+ container: docker
+ security_opts:
+ - apparmor=unconfined
+ volumes:
+ - /dev:/dev
+ - /lib/modules:/lib/modules:ro
+ - /sys/fs/cgroup:/sys/fs/cgroup:rw
+ - /usr/src:/usr/src:ro
+ groups:
+ - controllers
+ - cephs
+provisioner:
+ name: ansible
+ config_options:
+ connection:
+ pipelining: true
+ tags:
+ skip: sysctl,ethtool
+ inventory:
+ group_vars:
+ all:
+ ceph_fsid: ${MOLECULE_CEPH_FSID:-"1dff0e0f-3c44-48da-81cd-4f3c6e8722b2"}
+ ceph_conf_overrides:
+ - section: global
+ option: osd crush chooseleaf type
+ value: 0
+ - section: mon
+ option: auth allow insecure global id reclaim
+ value: false
+ cilium_helm_values:
+ operator:
+ replicas: 1
+ csi_driver: ${MOLECULE_CSI_DRIVER:-"rbd"}
+ ceph_csi_rbd_helm_values:
+ provisioner:
+ replicaCount: 1
+ controllers:
+ kubernetes_keepalived_interface: "{{ ansible_default_ipv4.interface }}"
+ kubernetes_keepalived_vip: 172.17.0.100
+ kubernetes_keepalived_vrid: 42
+ kubernetes_hostname: k8s
+ cephs:
+ ceph_osd_devices:
+ - "/dev/ceph-{{ inventory_hostname_short }}-osd0/data"
+ - "/dev/ceph-{{ inventory_hostname_short }}-osd1/data"
+ - "/dev/ceph-{{ inventory_hostname_short }}-osd2/data"
+verifier:
+ name: ansible
diff --git a/molecule/csi/prepare.yml b/molecule/csi/prepare.yml
new file mode 100644
index 0000000..dac0bc4
--- /dev/null
+++ b/molecule/csi/prepare.yml
@@ -0,0 +1,47 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+- name: Prepare
+ hosts: all
+ become: true
+ pre_tasks:
+ - name: Wait for systemd to complete initialization
+ ansible.builtin.command: systemctl is-system-running
+ register: systemctl_status
+ until: >
+ 'running' in systemctl_status.stdout or
+ 'degraded' in systemctl_status.stdout
+ retries: 30
+ delay: 5
+ changed_when: false
+ failed_when: systemctl_status.rc > 1
+ tasks:
+ - name: Refresh cache
+ ansible.builtin.package:
+ update_cache: true
+
+ # NOTE(mnaser): The base image installs Ansible using `pip` which breaks
+ # the system Python, we uninstall all Python packages.
+ - name: Fix Python installation
+ block:
+ - name: Get all Python packages
+ ansible.builtin.command: pip freeze
+ register: pip_freeze
+
+ - name: Uninstall all Python packages
+ ansible.builtin.pip:
+ name: "{{ pip_freeze.stdout_lines }}"
+ state: absent
+
+- ansible.builtin.import_playbook: vexxhost.ceph.create_fake_devices
diff --git a/molecule/csi/verify.yml b/molecule/csi/verify.yml
new file mode 100644
index 0000000..0add366
--- /dev/null
+++ b/molecule/csi/verify.yml
@@ -0,0 +1,84 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+- name: Verify
+ hosts: controllers
+ become: true
+ tasks:
+ - name: Create a persistent volume
+ kubernetes.core.k8s:
+ state: present
+ definition:
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: test-pvc
+ namespace: default
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 5Gi
+ storageClassName: general
+
+ - name: Create a pod
+ kubernetes.core.k8s:
+ state: present
+ definition:
+ apiVersion: v1
+ kind: Pod
+ metadata:
+ name: test-pvc-pod
+ namespace: default
+ spec:
+ volumes:
+ - name: test-pvc
+ persistentVolumeClaim:
+ claimName: test-pvc
+ containers:
+ - name: test-pvc-pod-container
+ image: nginx
+ volumeMounts:
+ - name: test-pvc
+ mountPath: /usr/share/nginx/html
+ wait: true
+ wait_timeout: 120
+ wait_condition:
+ type: Ready
+ status: "True"
+
+ - name: Delete the pod
+ kubernetes.core.k8s:
+ state: absent
+ definition:
+ apiVersion: v1
+ kind: Pod
+ metadata:
+ name: test-pvc-pod
+ namespace: default
+
+ - name: Delete the persistent volume
+ kubernetes.core.k8s:
+ state: absent
+ definition:
+ apiVersion: v1
+ kind: PersistentVolume
+ metadata:
+ name: test-pv
+ wait: true
+ wait_timeout: 120
+ wait_condition:
+ type: Available
+ status: "True"
diff --git a/playbooks/ceph.yml b/playbooks/ceph.yml
deleted file mode 100644
index 6fb2c9c..0000000
--- a/playbooks/ceph.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-- name: Setup Ceph repository
- hosts: controllers:cephs
- become: true
- roles:
- - role: ceph_repository
- when: atmosphere_ceph_enabled | default(true)
-
-- name: Deploy Ceph monitors & managers
- hosts: controllers
- become: true
- roles:
- - role: ceph_mon
- when: atmosphere_ceph_enabled | default(true)
- - role: ceph_mgr
- when: atmosphere_ceph_enabled | default(true)
-
-- name: Deploy Ceph OSDs
- hosts: cephs
- become: true
- roles:
- - role: ceph_osd
- when: atmosphere_ceph_enabled | default(true)
diff --git a/playbooks/kubernetes.yml b/playbooks/kubernetes.yml
index 056dd2e..47f9a7f 100644
--- a/playbooks/kubernetes.yml
+++ b/playbooks/kubernetes.yml
@@ -17,6 +17,8 @@
roles:
- role: defaults
- role: sysctl
+ tags:
+ - sysctl
- role: ethtool
tags:
- ethtool
diff --git a/playbooks/site.yml b/playbooks/site.yml
index c8fca05..8b7255b 100644
--- a/playbooks/site.yml
+++ b/playbooks/site.yml
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-- import_playbook: vexxhost.atmosphere.ceph
+- import_playbook: vexxhost.ceph.site
- import_playbook: vexxhost.atmosphere.kubernetes
- import_playbook: vexxhost.atmosphere.csi
- import_playbook: vexxhost.atmosphere.openstack
diff --git a/plugins/module_utils/ca_common.py b/plugins/module_utils/ca_common.py
deleted file mode 100644
index 5336582..0000000
--- a/plugins/module_utils/ca_common.py
+++ /dev/null
@@ -1,126 +0,0 @@
-import datetime
-import os
-
-
-def generate_ceph_cmd(
- sub_cmd,
- args,
- user_key=None,
- cluster="ceph",
- user="client.admin",
- container_image=None,
- interactive=False,
-):
- """
- Generate 'ceph' command line to execute
- """
-
- if not user_key:
- user_key = "/etc/ceph/{}.{}.keyring".format(cluster, user)
-
- cmd = pre_generate_ceph_cmd(
- container_image=container_image, interactive=interactive
- )
-
- base_cmd = ["-n", user, "-k", user_key, "--cluster", cluster]
- base_cmd.extend(sub_cmd)
- cmd.extend(base_cmd + args)
-
- return cmd
-
-
-def container_exec(binary, container_image, interactive=False):
- """
- Build the docker CLI to run a command inside a container
- """
-
- container_binary = os.getenv("CEPH_CONTAINER_BINARY")
- command_exec = [container_binary, "run"]
-
- if interactive:
- command_exec.extend(["--interactive"])
-
- command_exec.extend(
- [
- "--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=" + 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 pre_generate_ceph_cmd(container_image=None, interactive=False):
- """
- Generate ceph prefix comaand
- """
- if container_image:
- cmd = container_exec("ceph", container_image, interactive=interactive)
- else:
- cmd = ["ceph"]
-
- return cmd
-
-
-def exec_command(module, cmd, stdin=None):
- """
- Execute command(s)
- """
-
- binary_data = False
- if stdin:
- binary_data = True
- rc, out, err = module.run_command(cmd, data=stdin, binary_data=binary_data)
-
- return rc, cmd, out, err
-
-
-def exit_module(
- module, out, rc, cmd, err, startd, changed=False, diff=dict(before="", after="")
-):
- endd = datetime.datetime.now()
- delta = endd - startd
-
- result = dict(
- cmd=cmd,
- start=str(startd),
- end=str(endd),
- delta=str(delta),
- rc=rc,
- stdout=out.rstrip("\r\n"),
- stderr=err.rstrip("\r\n"),
- changed=changed,
- diff=diff,
- )
- module.exit_json(**result)
-
-
-def fatal(message, module):
- """
- Report a fatal error and exit
- """
-
- if module:
- module.fail_json(msg=message, rc=1)
- else:
- raise (Exception(message))
diff --git a/plugins/modules/ceph_config.py b/plugins/modules/ceph_config.py
deleted file mode 100644
index 968ba8e..0000000
--- a/plugins/modules/ceph_config.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/python3
-
-from ansible.module_utils.basic import AnsibleModule
-
-
-def run_module():
- module_args = dict(
- who=dict(type="str", required=True),
- name=dict(type="str", required=True),
- value=dict(type="str", required=True),
- )
-
- module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
-
- who = module.params["who"]
- name = module.params["name"]
- value = module.params["value"]
-
- changed = False
-
- _, out, _ = module.run_command(["ceph", "config", "get", who, name], check_rc=True)
-
- if out.strip() != value:
- changed = True
-
- if not module.check_mode:
- _, _, _ = module.run_command(
- ["ceph", "config", "set", who, name, value], check_rc=True
- )
-
- module.exit_json(changed=changed)
-
-
-def main():
- run_module()
-
-
-if __name__ == "__main__":
- main()
diff --git a/plugins/modules/ceph_key.py b/plugins/modules/ceph_key.py
deleted file mode 100644
index 33cb13f..0000000
--- a/plugins/modules/ceph_key.py
+++ /dev/null
@@ -1,816 +0,0 @@
-#!/usr/bin/python3
-
-# Copyright 2018, Red Hat, Inc.
-#
-# 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.
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-import base64
-import datetime
-import json
-import os
-import socket
-import struct
-import time
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.vexxhost.atmosphere.plugins.module_utils.ca_common import (
- container_exec,
- fatal,
- generate_ceph_cmd,
- is_containerized,
-)
-
-ANSIBLE_METADATA = {
- "metadata_version": "1.1",
- "status": ["preview"],
- "supported_by": "community",
-}
-
-DOCUMENTATION = """
----
-module: ceph_key
-
-author: Sebastien Han <seb@redhat.com>
-
-short_description: Manage Cephx key(s)
-
-version_added: "2.6"
-
-description:
- - Manage CephX creation, deletion and updates.
- It can also list and get information about keyring(s).
-options:
- cluster:
- description:
- - The ceph cluster name.
- required: false
- default: ceph
- name:
- description:
- - name of the CephX key
- required: true
- user:
- description:
- - entity used to perform operation.
- It corresponds to the -n option (--name)
- required: false
- user_key:
- description:
- - the path to the keyring corresponding to the
- user being used.
- It corresponds to the -k option (--keyring)
- state:
- description:
- - If 'present' is used, the module creates a keyring
- with the associated capabilities.
- If 'present' is used and a secret is provided the module
- will always add the key. Which means it will update
- the keyring if the secret changes, the same goes for
- the capabilities.
- If 'absent' is used, the module will simply delete the keyring.
- If 'list' is used, the module will list all the keys and will
- return a json output.
- If 'info' is used, the module will return in a json format the
- description of a given keyring.
- If 'generate_secret' is used, the module will simply output a cephx keyring.
- required: false
- choices: ['present', 'update', 'absent', 'list', 'info', 'fetch_initial_keys', 'generate_secret']
- default: present
- caps:
- description:
- - CephX key capabilities
- default: None
- required: false
- secret:
- description:
- - keyring's secret value
- required: false
- default: None
- import_key:
- description:
- - Wether or not to import the created keyring into Ceph.
- This can be useful for someone that only wants to generate keyrings
- but not add them into Ceph.
- required: false
- default: True
- dest:
- description:
- - Destination to write the keyring, can a file or a directory
- required: false
- default: /etc/ceph/
- fetch_initial_keys:
- description:
- - Fetch client.admin and bootstrap key.
- This is only needed for Nautilus and above.
- Writes down to the filesystem the initial keys generated by the monitor. # noqa: E501
- This command can ONLY run from a monitor node.
- required: false
- default: false
- output_format:
- description:
- - The key output format when retrieving the information of an
- entity.
- required: false
- default: json
-"""
-
-EXAMPLES = """
-
-keys_to_create:
- - { name: client.key, key: "AQAin8tUUK84ExAA/QgBtI7gEMWdmnvKBzlXdQ==", caps: { mon: "allow rwx", mds: "allow *" } , mode: "0600" } # noqa: E501
- - { name: client.cle, caps: { mon: "allow r", osd: "allow *" } , mode: "0600" } # noqa: E501
-
-caps:
- mon: "allow rwx"
- mds: "allow *"
-
-- name: create ceph admin key
- ceph_key:
- name: client.admin
- state: present
- secret: AQAin8tU2DsKFBAAFIAzVTzkL3+gtAjjpQiomw==
- caps:
- mon: allow *
- osd: allow *
- mgr: allow *
- mds: allow
- mode: 0400
- import_key: False
-
-- name: create monitor initial keyring
- ceph_key:
- name: mon.
- state: present
- secret: AQAin8tUMICVFBAALRHNrV0Z4MXupRw4v9JQ6Q==
- caps:
- mon: allow *
- dest: "/var/lib/ceph/tmp/"
- import_key: False
-
-- name: create cephx key
- ceph_key:
- name: "{{ keys_to_create }}"
- user: client.bootstrap-rgw
- user_key: /var/lib/ceph/bootstrap-rgw/ceph.keyring
- state: present
- caps: "{{ caps }}"
-
-- name: create cephx key but don't import it in Ceph
- ceph_key:
- name: "{{ keys_to_create }}"
- state: present
- caps: "{{ caps }}"
- import_key: False
-
-- name: delete cephx key
- ceph_key:
- name: "my_key"
- state: absent
-
-- name: info cephx key
- ceph_key:
- name: "my_key""
- state: info
-
-- name: info cephx admin key (plain)
- ceph_key:
- name: client.admin
- output_format: plain
- state: info
- register: client_admin_key
-
-- name: list cephx keys
- ceph_key:
- state: list
-
-- name: fetch cephx keys
- ceph_key:
- state: fetch_initial_keys
-"""
-
-RETURN = """# """
-
-
-CEPH_INITIAL_KEYS = [
- "client.admin",
- "client.bootstrap-mds",
- "client.bootstrap-mgr", # noqa: E501
- "client.bootstrap-osd",
- "client.bootstrap-rbd",
- "client.bootstrap-rbd-mirror",
- "client.bootstrap-rgw",
-] # noqa: E501
-
-
-def str_to_bool(val):
- try:
- val = val.lower()
- except AttributeError:
- val = str(val).lower()
- if val == "true":
- return True
- elif val == "false":
- return False
- else:
- raise ValueError("Invalid input value: %s" % val)
-
-
-def generate_secret():
- """
- Generate a CephX secret
- """
-
- key = os.urandom(16)
- header = struct.pack("<hiih", 1, int(time.time()), 0, len(key))
- secret = base64.b64encode(header + key)
-
- return secret
-
-
-def generate_caps(_type, caps):
- """
- Generate CephX capabilities list
- """
-
- caps_cli = []
-
- for k, v in caps.items():
- # makes sure someone didn't pass an empty var,
- # we don't want to add an empty cap
- if len(k) == 0:
- continue
- if _type == "ceph-authtool":
- caps_cli.extend(["--cap"])
- caps_cli.extend([k, v])
-
- return caps_cli
-
-
-def generate_ceph_authtool_cmd(
- cluster, name, secret, caps, dest, container_image=None
-): # noqa: E501
- """
- Generate 'ceph-authtool' command line to execute
- """
-
- if container_image:
- binary = "ceph-authtool"
- cmd = container_exec(binary, container_image)
- else:
- binary = ["ceph-authtool"]
- cmd = binary
-
- base_cmd = [
- "--create-keyring",
- dest,
- "--name",
- name,
- "--add-key",
- secret,
- ]
-
- cmd.extend(base_cmd)
- cmd.extend(generate_caps("ceph-authtool", caps))
-
- return cmd
-
-
-def create_key(
- module,
- result,
- cluster,
- user,
- user_key,
- name,
- secret,
- caps,
- import_key,
- dest,
- container_image=None,
-): # noqa: E501
- """
- Create a CephX key
- """
-
- cmd_list = []
- if not secret:
- secret = generate_secret()
-
- if user == "client.admin":
- args = ["import", "-i", dest]
- else:
- args = ["get-or-create", name]
- args.extend(generate_caps(None, caps))
- args.extend(["-o", dest])
-
- cmd_list.append(
- generate_ceph_authtool_cmd(cluster, name, secret, caps, dest, container_image)
- )
-
- if import_key or user != "client.admin":
- cmd_list.append(
- generate_ceph_cmd(
- sub_cmd=["auth"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
- )
-
- return cmd_list
-
-
-def delete_key(cluster, user, user_key, name, container_image=None):
- """
- Delete a CephX key
- """
-
- cmd_list = []
-
- args = [
- "del",
- name,
- ]
-
- cmd_list.append(
- generate_ceph_cmd(
- sub_cmd=["auth"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
- )
-
- return cmd_list
-
-
-def get_key(cluster, user, user_key, name, dest, container_image=None):
- """
- Get a CephX key (write on the filesystem)
- """
-
- cmd_list = []
-
- args = [
- "get",
- name,
- "-o",
- dest,
- ]
-
- cmd_list.append(
- generate_ceph_cmd(
- sub_cmd=["auth"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
- )
-
- return cmd_list
-
-
-def info_key(
- cluster, name, user, user_key, output_format, container_image=None
-): # noqa: E501
- """
- Get information about a CephX key
- """
-
- cmd_list = []
-
- args = [
- "get",
- name,
- "-f",
- output_format,
- ]
-
- cmd_list.append(
- generate_ceph_cmd(
- sub_cmd=["auth"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
- )
-
- return cmd_list
-
-
-def list_keys(cluster, user, user_key, container_image=None):
- """
- List all CephX keys
- """
-
- cmd_list = []
-
- args = [
- "ls",
- "-f",
- "json",
- ]
-
- cmd_list.append(
- generate_ceph_cmd(
- sub_cmd=["auth"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
- )
-
- return cmd_list
-
-
-def exec_commands(module, cmd_list):
- """
- Execute command(s)
- """
-
- for cmd in cmd_list:
- rc, out, err = module.run_command(cmd)
- if rc != 0:
- return rc, cmd, out, err
-
- return rc, cmd, out, err
-
-
-def lookup_ceph_initial_entities(module, out):
- """
- Lookup Ceph initial keys entries in the auth map
- """
-
- # convert out to json, ansible returns a string...
- try:
- out_dict = json.loads(out)
- except ValueError as e:
- fatal(
- "Could not decode 'ceph auth list' json output: {}".format(e), module
- ) # noqa: E501
-
- entities = []
- if "auth_dump" in out_dict:
- for key in out_dict["auth_dump"]:
- for k, v in key.items():
- if k == "entity":
- if v in CEPH_INITIAL_KEYS:
- entities.append(v)
- else:
- fatal("'auth_dump' key not present in json output:", module) # noqa: E501
-
- if len(entities) != len(CEPH_INITIAL_KEYS) and not str_to_bool(
- os.environ.get("CEPH_ROLLING_UPDATE", False)
- ): # noqa: E501
- # must be missing in auth_dump, as if it were in CEPH_INITIAL_KEYS
- # it'd be in entities from the above test. Report what's missing.
- missing = []
- for e in CEPH_INITIAL_KEYS:
- if e not in entities:
- missing.append(e)
- fatal(
- "initial keyring does not contain keys: " + " ".join(missing), module
- ) # noqa: E501
- return entities
-
-
-def build_key_path(cluster, entity):
- """
- Build key path depending on the key type
- """
-
- if "admin" in entity:
- path = "/etc/ceph"
- keyring_filename = cluster + "." + entity + ".keyring"
- key_path = os.path.join(path, keyring_filename)
- elif "bootstrap" in entity:
- path = "/var/lib/ceph"
- # bootstrap keys show up as 'client.boostrap-osd'
- # however the directory is called '/var/lib/ceph/bootstrap-osd'
- # so we need to substring 'client.'
- entity_split = entity.split(".")[1]
- keyring_filename = cluster + ".keyring"
- key_path = os.path.join(path, entity_split, keyring_filename)
- else:
- return None
-
- return key_path
-
-
-def run_module():
- module_args = dict(
- cluster=dict(type="str", required=False, default="ceph"),
- name=dict(type="str", required=False),
- state=dict(
- type="str",
- required=False,
- default="present",
- choices=[
- "present",
- "update",
- "absent", # noqa: E501
- "list",
- "info",
- "fetch_initial_keys",
- "generate_secret",
- ],
- ), # noqa: E501
- caps=dict(type="dict", required=False, default=None),
- secret=dict(type="str", required=False, default=None, no_log=True),
- import_key=dict(type="bool", required=False, default=True),
- dest=dict(type="str", required=False, default="/etc/ceph/"),
- user=dict(type="str", required=False, default="client.admin"),
- user_key=dict(type="str", required=False, default=None),
- output_format=dict(
- type="str",
- required=False,
- default="json",
- choices=["json", "plain", "xml", "yaml"],
- ), # noqa: E501
- )
-
- module = AnsibleModule(
- argument_spec=module_args,
- supports_check_mode=True,
- add_file_common_args=True,
- )
-
- file_args = module.load_file_common_arguments(module.params)
-
- # Gather module parameters in variables
- state = module.params["state"]
- name = module.params.get("name")
- cluster = module.params.get("cluster")
- caps = module.params.get("caps")
- secret = module.params.get("secret")
- import_key = module.params.get("import_key")
- dest = module.params.get("dest")
- user = module.params.get("user")
- user_key = module.params.get("user_key")
- output_format = module.params.get("output_format")
-
- changed = False
-
- result = dict(
- changed=changed,
- stdout="",
- stderr="",
- rc=0,
- start="",
- end="",
- delta="",
- )
-
- if module.check_mode and state != "info":
- module.exit_json(**result)
-
- 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
- _secret = secret
- _caps = caps
- key_exist = 1
-
- if not user_key:
- user_key_filename = "{}.{}.keyring".format(cluster, user)
- user_key_dir = "/etc/ceph"
- user_key_path = os.path.join(user_key_dir, user_key_filename)
- else:
- user_key_path = user_key
-
- if state in ["present", "update"]:
- # if dest is not a directory, the user wants to change the file's name
- # (e,g: /etc/ceph/ceph.mgr.ceph-mon2.keyring)
- if not os.path.isdir(dest):
- file_path = dest
- else:
- if "bootstrap" in dest:
- # Build a different path for bootstrap keys as there are stored
- # as /var/lib/ceph/bootstrap-rbd/ceph.keyring
- keyring_filename = cluster + ".keyring"
- else:
- keyring_filename = cluster + "." + name + ".keyring"
- file_path = os.path.join(dest, keyring_filename)
-
- file_args["path"] = file_path
-
- if import_key:
- _info_key = []
- rc, cmd, out, err = exec_commands(
- module,
- info_key(
- cluster, name, user, user_key_path, output_format, container_image
- ),
- ) # noqa: E501
- key_exist = rc
- if not caps and key_exist != 0:
- fatal(
- "Capabilities must be provided when state is 'present'", module
- ) # noqa: E501
- if key_exist != 0 and secret is None and caps is None:
- fatal(
- "Keyring doesn't exist, you must provide 'secret' and 'caps'",
- module,
- ) # noqa: E501
- if key_exist == 0:
- _info_key = json.loads(out)
- if not secret:
- secret = _info_key[0]["key"]
- _secret = _info_key[0]["key"]
- if not caps:
- caps = _info_key[0]["caps"]
- _caps = _info_key[0]["caps"]
- if secret == _secret and caps == _caps:
- if not os.path.isfile(file_path):
- rc, cmd, out, err = exec_commands(
- module,
- get_key(
- cluster,
- user,
- user_key_path,
- name,
- file_path,
- container_image,
- ),
- ) # noqa: E501
- result["rc"] = rc
- if rc != 0:
- result[
- "stdout"
- ] = "Couldn't fetch the key {0} at {1}.".format(
- name, file_path
- ) # noqa: E501
- module.exit_json(**result)
- result["stdout"] = "fetched the key {0} at {1}.".format(
- name, file_path
- ) # noqa: E501
-
- result[
- "stdout"
- ] = "{0} already exists and doesn't need to be updated.".format(
- name
- ) # noqa: E501
- result["rc"] = 0
- module.set_fs_attributes_if_different(file_args, False)
- module.exit_json(**result)
- else:
- if os.path.isfile(file_path) and not secret or not caps:
- result[
- "stdout"
- ] = "{0} already exists in {1} you must provide secret *and* caps when import_key is {2}".format(
- name, dest, import_key
- ) # noqa: E501
- result["rc"] = 0
- module.exit_json(**result)
- if (
- key_exist == 0 and (secret != _secret or caps != _caps)
- ) or key_exist != 0: # noqa: E501
- rc, cmd, out, err = exec_commands(
- module,
- create_key(
- module,
- result,
- cluster,
- user,
- user_key_path,
- name,
- secret,
- caps,
- import_key,
- file_path,
- container_image,
- ),
- ) # noqa: E501
- if rc != 0:
- result["stdout"] = "Couldn't create or update {0}".format(name)
- result["stderr"] = err
- module.exit_json(**result)
- module.set_fs_attributes_if_different(file_args, False)
- changed = True
-
- elif state == "absent":
- if key_exist == 0:
- rc, cmd, out, err = exec_commands(
- module, delete_key(cluster, user, user_key_path, name, container_image)
- ) # noqa: E501
- if rc == 0:
- changed = True
- else:
- rc = 0
-
- elif state == "info":
- rc, cmd, out, err = exec_commands(
- module,
- info_key(
- cluster, name, user, user_key_path, output_format, container_image
- ),
- ) # noqa: E501
-
- elif state == "list":
- rc, cmd, out, err = exec_commands(
- module, list_keys(cluster, user, user_key_path, container_image)
- )
-
- elif state == "fetch_initial_keys":
- hostname = socket.gethostname().split(".", 1)[0]
- user = "mon."
- keyring_filename = cluster + "-" + hostname + "/keyring"
- user_key_path = os.path.join("/var/lib/ceph/mon/", keyring_filename)
- rc, cmd, out, err = exec_commands(
- module, list_keys(cluster, user, user_key_path, container_image)
- )
- if rc != 0:
- result["stdout"] = "failed to retrieve ceph keys"
- result["sdterr"] = err
- result["rc"] = 0
- module.exit_json(**result)
-
- entities = lookup_ceph_initial_entities(module, out)
-
- output_format = "plain"
- for entity in entities:
- key_path = build_key_path(cluster, entity)
- if key_path is None:
- fatal("Failed to build key path, no entity yet?", module)
- elif os.path.isfile(key_path):
- # if the key is already on the filesystem
- # there is no need to fetch it again
- continue
-
- extra_args = [
- "-o",
- key_path,
- ]
-
- info_cmd = info_key(
- cluster, entity, user, user_key_path, 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(module, info_cmd) # noqa: E501
-
- file_args = module.load_file_common_arguments(module.params)
- file_args["path"] = key_path
- module.set_fs_attributes_if_different(file_args, False)
- elif state == "generate_secret":
- out = generate_secret().decode()
- cmd = ""
- rc = 0
- err = ""
- changed = True
-
- endd = datetime.datetime.now()
- delta = endd - startd
-
- result = dict(
- cmd=cmd,
- start=str(startd),
- end=str(endd),
- delta=str(delta),
- rc=rc,
- stdout=out.rstrip("\r\n"),
- stderr=err.rstrip("\r\n"),
- changed=changed,
- )
-
- if rc != 0:
- module.fail_json(msg="non-zero return code", **result)
-
- module.exit_json(**result)
-
-
-def main():
- run_module()
-
-
-if __name__ == "__main__":
- main()
diff --git a/plugins/modules/ceph_pool.py b/plugins/modules/ceph_pool.py
deleted file mode 100644
index e749725..0000000
--- a/plugins/modules/ceph_pool.py
+++ /dev/null
@@ -1,751 +0,0 @@
-#!/usr/bin/python3
-
-# Copyright 2020, Red Hat, Inc.
-#
-# 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.
-
-from __future__ import absolute_import, division, print_function
-
-__metaclass__ = type
-
-import datetime
-import json
-import os
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.vexxhost.atmosphere.plugins.module_utils.ca_common import (
- exec_command,
- exit_module,
- generate_ceph_cmd,
- is_containerized,
- pre_generate_ceph_cmd,
-)
-
-ANSIBLE_METADATA = {
- "metadata_version": "1.1",
- "status": ["preview"],
- "supported_by": "community",
-}
-
-DOCUMENTATION = """
----
-module: ceph_pool
-
-author: Guillaume Abrioux <gabrioux@redhat.com>
-
-short_description: Manage Ceph Pools
-
-version_added: "2.8"
-
-description:
- - Manage Ceph pool(s) creation, deletion and updates.
-options:
- cluster:
- description:
- - The ceph cluster name.
- required: false
- default: ceph
- name:
- description:
- - name of the Ceph pool
- required: true
- state:
- description:
- If 'present' is used, the module creates a pool if it doesn't exist
- or update it if it already exists.
- If 'absent' is used, the module will simply delete the pool.
- If 'list' is used, the module will return all details about the
- existing pools. (json formatted).
- required: false
- choices: ['present', 'absent', 'list']
- default: present
- size:
- description:
- - set the replica size of the pool.
- required: false
- default: 3
- min_size:
- description:
- - set the min_size parameter of the pool.
- required: false
- default: default to `osd_pool_default_min_size` (ceph)
- pg_num:
- description:
- - set the pg_num of the pool.
- required: false
- default: default to `osd_pool_default_pg_num` (ceph)
- pgp_num:
- description:
- - set the pgp_num of the pool.
- required: false
- default: default to `osd_pool_default_pgp_num` (ceph)
- pg_autoscale_mode:
- description:
- - set the pg autoscaler on the pool.
- required: false
- default: 'on'
- target_size_ratio:
- description:
- - set the target_size_ratio on the pool
- required: false
- default: None
- pool_type:
- description:
- - set the pool type, either 'replicated' or 'erasure'
- required: false
- default: 'replicated'
- erasure_profile:
- description:
- - When pool_type = 'erasure', set the erasure profile of the pool
- required: false
- default: 'default'
- rule_name:
- description:
- - Set the crush rule name assigned to the pool
- required: false
- default: 'replicated_rule' when pool_type is 'erasure' else None
- expected_num_objects:
- description:
- - Set the expected_num_objects parameter of the pool.
- required: false
- default: '0'
- application:
- description:
- - Set the pool application on the pool.
- required: false
- default: None
-"""
-
-EXAMPLES = """
-
-pools:
- - { name: foo, size: 3, application: rbd, pool_type: 'replicated',
- pg_autoscale_mode: 'on' }
-
-- hosts: all
- become: true
- tasks:
- - name: create a pool
- ceph_pool:
- name: "{{ item.name }}"
- state: present
- size: "{{ item.size }}"
- application: "{{ item.application }}"
- pool_type: "{{ item.pool_type }}"
- pg_autoscale_mode: "{{ item.pg_autoscale_mode }}"
- with_items: "{{ pools }}"
-"""
-
-RETURN = """# """
-
-
-def check_pool_exist(
- cluster, name, user, user_key, output_format="json", container_image=None
-):
- """
- Check if a given pool exists
- """
-
- args = ["stats", name, "-f", output_format]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def generate_get_config_cmd(param, cluster, user, user_key, container_image=None):
- _cmd = pre_generate_ceph_cmd(container_image=container_image)
- args = [
- "-n",
- user,
- "-k",
- user_key,
- "--cluster",
- cluster,
- "config",
- "get",
- "mon.*",
- param,
- ]
- cmd = _cmd + args
- return cmd
-
-
-def get_application_pool(
- cluster, name, user, user_key, output_format="json", container_image=None
-):
- """
- Get application type enabled on a given pool
- """
-
- args = ["application", "get", name, "-f", output_format]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def enable_application_pool(
- cluster, name, application, user, user_key, container_image=None
-):
- """
- Enable application on a given pool
- """
-
- args = ["application", "enable", name, application]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def disable_application_pool(
- cluster, name, application, user, user_key, container_image=None
-):
- """
- Disable application on a given pool
- """
-
- args = ["application", "disable", name, application, "--yes-i-really-mean-it"]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def get_pool_details(
- module, cluster, name, user, user_key, output_format="json", container_image=None
-):
- """
- Get details about a given pool
- """
-
- args = ["ls", "detail", "-f", output_format]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- rc, cmd, out, err = exec_command(module, cmd)
-
- if rc == 0:
- out = [p for p in json.loads(out.strip()) if p["pool_name"] == name][0]
-
- _rc, _cmd, application_pool, _err = exec_command(
- module,
- get_application_pool(
- cluster, # noqa: E501
- name, # noqa: E501
- user, # noqa: E501
- user_key, # noqa: E501
- container_image=container_image,
- ),
- ) # noqa: E501
-
- # This is a trick because "target_size_ratio" isn't present at the same
- # level in the dict
- # ie:
- # {
- # 'pg_num': 8,
- # 'pgp_num': 8,
- # 'pg_autoscale_mode': 'on',
- # 'options': {
- # 'target_size_ratio': 0.1
- # }
- # }
- # If 'target_size_ratio' is present in 'options', we set it, this way we
- # end up with a dict containing all needed keys at the same level.
- if "target_size_ratio" in out["options"].keys():
- out["target_size_ratio"] = out["options"]["target_size_ratio"]
- else:
- out["target_size_ratio"] = None
-
- application = list(json.loads(application_pool.strip()).keys())
-
- if len(application) == 0:
- out["application"] = ""
- else:
- out["application"] = application[0]
-
- return rc, cmd, out, err
-
-
-def compare_pool_config(user_pool_config, running_pool_details):
- """
- Compare user input config pool details with current running pool details
- """
-
- delta = {}
- filter_keys = [
- "pg_num",
- "pg_placement_num",
- "size",
- "pg_autoscale_mode",
- "target_size_ratio",
- ]
- for key in filter_keys:
- if (
- str(running_pool_details[key]) != user_pool_config[key]["value"]
- and user_pool_config[key]["value"] # noqa: E501
- ):
- delta[key] = user_pool_config[key]
-
- if (
- running_pool_details["application"] != user_pool_config["application"]["value"]
- and user_pool_config["application"]["value"]
- ):
- delta["application"] = {}
- delta["application"]["new_application"] = user_pool_config["application"][
- "value"
- ] # noqa: E501
- # to be improved (for update_pools()...)
- delta["application"]["value"] = delta["application"]["new_application"]
- delta["application"]["old_application"] = running_pool_details[
- "application"
- ] # noqa: E501
-
- return delta
-
-
-def list_pools(
- cluster, user, user_key, details, output_format="json", container_image=None
-):
- """
- List existing pools
- """
-
- args = ["ls"]
-
- if details:
- args.append("detail")
-
- args.extend(["-f", output_format])
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def create_pool(cluster, name, user, user_key, user_pool_config, container_image=None):
- """
- Create a new pool
- """
-
- args = [
- "create",
- user_pool_config["pool_name"]["value"],
- user_pool_config["type"]["value"],
- ]
-
- if user_pool_config["pg_autoscale_mode"]["value"] != "on":
- args.extend(
- [
- "--pg_num",
- user_pool_config["pg_num"]["value"],
- "--pgp_num",
- user_pool_config["pgp_num"]["value"]
- or user_pool_config["pg_num"]["value"],
- ]
- )
- elif user_pool_config["target_size_ratio"]["value"]:
- args.extend(
- ["--target_size_ratio", user_pool_config["target_size_ratio"]["value"]]
- )
-
- if user_pool_config["type"]["value"] == "replicated":
- args.extend(
- [
- user_pool_config["crush_rule"]["value"],
- "--expected_num_objects",
- user_pool_config["expected_num_objects"]["value"],
- "--autoscale-mode",
- user_pool_config["pg_autoscale_mode"]["value"],
- ]
- )
-
- if (
- user_pool_config["size"]["value"]
- and user_pool_config["type"]["value"] == "replicated"
- ):
- args.extend(["--size", user_pool_config["size"]["value"]])
-
- elif user_pool_config["type"]["value"] == "erasure":
- args.extend([user_pool_config["erasure_profile"]["value"]])
-
- if user_pool_config["crush_rule"]["value"]:
- args.extend([user_pool_config["crush_rule"]["value"]])
-
- args.extend(
- [
- "--expected_num_objects",
- user_pool_config["expected_num_objects"]["value"],
- "--autoscale-mode",
- user_pool_config["pg_autoscale_mode"]["value"],
- ]
- )
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def remove_pool(cluster, name, user, user_key, container_image=None):
- """
- Remove a pool
- """
-
- args = ["rm", name, name, "--yes-i-really-really-mean-it"]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- return cmd
-
-
-def update_pool(module, cluster, name, user, user_key, delta, container_image=None):
- """
- Update an existing pool
- """
-
- report = ""
-
- for key in delta.keys():
- if key != "application":
- args = ["set", name, delta[key]["cli_set_opt"], delta[key]["value"]]
-
- cmd = generate_ceph_cmd(
- sub_cmd=["osd", "pool"],
- args=args,
- cluster=cluster,
- user=user,
- user_key=user_key,
- container_image=container_image,
- )
-
- rc, cmd, out, err = exec_command(module, cmd)
- if rc != 0:
- return rc, cmd, out, err
-
- else:
- rc, cmd, out, err = exec_command(
- module,
- disable_application_pool(
- cluster,
- name,
- delta["application"]["old_application"],
- user,
- user_key,
- container_image=container_image,
- ),
- ) # noqa: E501
- if rc != 0:
- return rc, cmd, out, err
-
- rc, cmd, out, err = exec_command(
- module,
- enable_application_pool(
- cluster,
- name,
- delta["application"]["new_application"],
- user,
- user_key,
- container_image=container_image,
- ),
- ) # noqa: E501
- if rc != 0:
- return rc, cmd, out, err
-
- report = (
- report
- + "\n"
- + "{} has been updated: {} is now {}".format(name, key, delta[key]["value"])
- ) # noqa: E501
-
- out = report
- return rc, cmd, out, err
-
-
-def run_module():
- module_args = dict(
- cluster=dict(type="str", required=False, default="ceph"),
- name=dict(type="str", required=True),
- state=dict(
- type="str",
- required=False,
- default="present",
- choices=["present", "absent", "list"],
- ),
- details=dict(type="bool", required=False, default=False),
- size=dict(type="str", required=False),
- min_size=dict(type="str", required=False),
- pg_num=dict(type="str", required=False),
- pgp_num=dict(type="str", required=False),
- pg_autoscale_mode=dict(type="str", required=False, default="on"),
- target_size_ratio=dict(type="str", required=False, default=None),
- pool_type=dict(
- type="str",
- required=False,
- default="replicated",
- choices=["replicated", "erasure", "1", "3"],
- ),
- erasure_profile=dict(type="str", required=False, default="default"),
- rule_name=dict(type="str", required=False, default=None),
- expected_num_objects=dict(type="str", required=False, default="0"),
- application=dict(type="str", required=False, default=None),
- )
-
- module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
-
- # Gather module parameters in variables
- cluster = module.params.get("cluster")
- name = module.params.get("name")
- state = module.params.get("state")
- details = module.params.get("details")
- size = module.params.get("size")
- min_size = module.params.get("min_size")
- pg_num = module.params.get("pg_num")
- pgp_num = module.params.get("pgp_num")
- pg_autoscale_mode = module.params.get("pg_autoscale_mode")
- target_size_ratio = module.params.get("target_size_ratio")
- application = module.params.get("application")
-
- if module.params.get("pg_autoscale_mode").lower() in ["true", "on", "yes"]:
- pg_autoscale_mode = "on"
- elif module.params.get("pg_autoscale_mode").lower() in ["false", "off", "no"]:
- pg_autoscale_mode = "off"
- else:
- pg_autoscale_mode = "warn"
-
- if module.params.get("pool_type") == "1":
- pool_type = "replicated"
- elif module.params.get("pool_type") == "3":
- pool_type = "erasure"
- else:
- pool_type = module.params.get("pool_type")
-
- if not module.params.get("rule_name"):
- rule_name = "replicated_rule" if pool_type == "replicated" else None
- else:
- rule_name = module.params.get("rule_name")
-
- erasure_profile = module.params.get("erasure_profile")
- expected_num_objects = module.params.get("expected_num_objects")
- user_pool_config = {
- "pool_name": {"value": name},
- "pg_num": {"value": pg_num, "cli_set_opt": "pg_num"},
- "pgp_num": {"value": pgp_num, "cli_set_opt": "pgp_num"},
- "pg_autoscale_mode": {
- "value": pg_autoscale_mode,
- "cli_set_opt": "pg_autoscale_mode",
- },
- "target_size_ratio": {
- "value": target_size_ratio,
- "cli_set_opt": "target_size_ratio",
- },
- "application": {"value": application},
- "type": {"value": pool_type},
- "erasure_profile": {"value": erasure_profile},
- "crush_rule": {"value": rule_name, "cli_set_opt": "crush_rule"},
- "expected_num_objects": {"value": expected_num_objects},
- "size": {"value": size, "cli_set_opt": "size"},
- "min_size": {"value": min_size},
- }
-
- if module.check_mode:
- module.exit_json(
- changed=False,
- stdout="",
- stderr="",
- rc=0,
- start="",
- end="",
- delta="",
- )
-
- startd = datetime.datetime.now()
- changed = False
-
- # will return either the image name or None
- container_image = is_containerized()
-
- user = "client.admin"
- keyring_filename = cluster + "." + user + ".keyring"
- user_key = os.path.join("/etc/ceph/", keyring_filename)
-
- if state == "present":
- rc, cmd, out, err = exec_command(
- module,
- check_pool_exist(
- cluster, name, user, user_key, container_image=container_image
- ),
- ) # noqa: E501
- if rc == 0:
- running_pool_details = get_pool_details(
- module, cluster, name, user, user_key, container_image=container_image
- ) # noqa: E501
- user_pool_config["pg_placement_num"] = {
- "value": str(running_pool_details[2]["pg_placement_num"]),
- "cli_set_opt": "pgp_num",
- } # noqa: E501
- delta = compare_pool_config(user_pool_config, running_pool_details[2])
- if len(delta) > 0:
- keys = list(delta.keys())
- details = running_pool_details[2]
- if details["erasure_code_profile"] and "size" in keys:
- del delta["size"]
- if details["pg_autoscale_mode"] == "on":
- delta.pop("pg_num", None)
- delta.pop("pgp_num", None)
-
- if len(delta) == 0:
- out = "Skipping pool {}.\nUpdating either 'size' on an erasure-coded pool or 'pg_num'/'pgp_num' on a pg autoscaled pool is incompatible".format( # noqa: E501
- name
- )
- else:
- rc, cmd, out, err = update_pool(
- module,
- cluster,
- name,
- user,
- user_key,
- delta,
- container_image=container_image,
- ) # noqa: E501
- if rc == 0:
- changed = True
- else:
- out = "Pool {} already exists and there is nothing to update.".format(
- name
- ) # noqa: E501
- else:
- rc, cmd, out, err = exec_command(
- module,
- create_pool(
- cluster,
- name,
- user,
- user_key,
- user_pool_config=user_pool_config, # noqa: E501
- container_image=container_image,
- ),
- ) # noqa: E501
- if user_pool_config["application"]["value"]:
- rc, _, _, _ = exec_command(
- module,
- enable_application_pool(
- cluster,
- name,
- user_pool_config["application"]["value"], # noqa: E501
- user,
- user_key,
- container_image=container_image,
- ),
- ) # noqa: E501
- if user_pool_config["min_size"]["value"]:
- # not implemented yet
- pass
- changed = True
-
- elif state == "list":
- rc, cmd, out, err = exec_command(
- module,
- list_pools(
- cluster, name, user, user_key, details, container_image=container_image
- ),
- ) # noqa: E501
- if rc != 0:
- out = "Couldn't list pool(s) present on the cluster"
-
- elif state == "absent":
- rc, cmd, out, err = exec_command(
- module,
- check_pool_exist(
- cluster, name, user, user_key, container_image=container_image
- ),
- ) # noqa: E501
- if rc == 0:
- rc, cmd, out, err = exec_command(
- module,
- remove_pool(
- cluster, name, user, user_key, container_image=container_image
- ),
- ) # noqa: E501
- changed = True
- else:
- rc = 0
- out = "Skipped, since pool {} doesn't exist".format(name)
-
- exit_module(
- module=module, out=out, rc=rc, cmd=cmd, err=err, startd=startd, changed=changed
- )
-
-
-def main():
- run_module()
-
-
-if __name__ == "__main__":
- main()
diff --git a/roles/ceph_csi_rbd/defaults/main.yml b/roles/ceph_csi_rbd/defaults/main.yml
index 708d3a1..c64ad8f 100644
--- a/roles/ceph_csi_rbd/defaults/main.yml
+++ b/roles/ceph_csi_rbd/defaults/main.yml
@@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-ceph_csi_rbd_ceph_fsid: "{{ ceph_mon_fsid }}"
ceph_csi_rbd_mons_group: controllers
ceph_csi_rbd_id: kube
ceph_csi_rbd_user: "client.{{ ceph_csi_rbd_id }}"
diff --git a/roles/ceph_csi_rbd/tasks/main.yml b/roles/ceph_csi_rbd/tasks/main.yml
index f992364..6db53e0 100644
--- a/roles/ceph_csi_rbd/tasks/main.yml
+++ b/roles/ceph_csi_rbd/tasks/main.yml
@@ -22,12 +22,13 @@
- name: Generate fact with list of Ceph monitors
run_once: true
ansible.builtin.set_fact:
+ ceph_csi_rbd_ceph_fsid: "{{ _ceph_mon_dump.stdout | from_json | community.general.json_query('fsid') }}"
ceph_monitors: "{{ _ceph_mon_dump.stdout | from_json | community.general.json_query('mons[*].addr') | map('regex_replace', '(.*):(.*)', '\\1') }}"
- name: Create Ceph pool
delegate_to: "{{ groups[ceph_csi_rbd_mons_group][0] }}"
run_once: true
- vexxhost.atmosphere.ceph_pool:
+ vexxhost.ceph.pool:
name: "{{ ceph_csi_rbd_pool }}"
rule_name: "{{ ceph_csi_rbd_rule_name | default(omit) }}"
application: rbd
@@ -36,7 +37,7 @@
- name: Create user {{ ceph_csi_rbd_user }}
delegate_to: "{{ groups[ceph_csi_rbd_mons_group][0] }}"
run_once: true
- vexxhost.atmosphere.ceph_key:
+ vexxhost.ceph.key:
name: "{{ ceph_csi_rbd_user }}"
caps:
mon: profile rbd
@@ -46,7 +47,7 @@
- name: Retrieve keyring for {{ ceph_csi_rbd_user }}
delegate_to: "{{ groups[ceph_csi_rbd_mons_group][0] }}"
run_once: true
- vexxhost.atmosphere.ceph_key:
+ vexxhost.ceph.key:
name: "{{ ceph_csi_rbd_user }}"
state: info
output_format: json
diff --git a/roles/ceph_mgr/README.md b/roles/ceph_mgr/README.md
deleted file mode 100644
index ccc483a..0000000
--- a/roles/ceph_mgr/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# `ceph_mgr`
diff --git a/roles/ceph_mgr/tasks/main.yml b/roles/ceph_mgr/tasks/main.yml
deleted file mode 100644
index 9ee70ee..0000000
--- a/roles/ceph_mgr/tasks/main.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-- name: Install packages
- ansible.builtin.apt:
- name: ["ceph-mgr"]
- install_recommends: false
-
-- name: Create manager folder
- ansible.builtin.file:
- path: "/var/lib/ceph/mgr/ceph-{{ inventory_hostname_short }}"
- state: directory
- owner: ceph
- group: ceph
- mode: "0700"
-
-- name: Create Ceph manager keyring
- vexxhost.atmosphere.ceph_key:
- name: "mgr.{{ inventory_hostname_short }}"
- dest: "/var/lib/ceph/mgr/ceph-{{ inventory_hostname_short }}/keyring"
- caps:
- mon: allow profile mgr
- osd: allow *
- mds: allow *
- owner: ceph
- group: ceph
-
-- name: Ensure permissions are fixed
- ansible.builtin.file:
- path: "/var/lib/ceph/mon/ceph-{{ inventory_hostname_short }}"
- owner: ceph
- group: ceph
- recurse: true
-
-- name: Enable and start service
- ansible.builtin.service:
- name: "ceph-mgr@{{ inventory_hostname_short }}"
- state: started
- enabled: true
diff --git a/roles/ceph_mon/README.md b/roles/ceph_mon/README.md
deleted file mode 100644
index d742bc2..0000000
--- a/roles/ceph_mon/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# `ceph_mon`
diff --git a/roles/ceph_mon/defaults/main.yml b/roles/ceph_mon/defaults/main.yml
deleted file mode 100644
index 86c1717..0000000
--- a/roles/ceph_mon/defaults/main.yml
+++ /dev/null
@@ -1,25 +0,0 @@
----
-# .. vim: foldmarker=[[[,]]]:foldmethod=marker
-
-# .. Copyright (C) 2022 VEXXHOST, Inc.
-# .. SPDX-License-Identifier: Apache-2.0
-
-# Default variables
-# =================
-
-# .. contents:: Sections
-# :local:
-
-
-# .. envvar:: ceph_mon_group [[[
-#
-# Name of Ansible group that contains all Ceph monitors
-ceph_mon_group: controllers
-
- # ]]]
-# .. envvar:: ceph_mon_cluster_network [[[
-#
-# Cluster (replication) network used by Ceph
-ceph_mon_cluster_network: "{{ ceph_mon_public_network }}"
-
- # ]]]
diff --git a/roles/ceph_mon/meta/main.yml b/roles/ceph_mon/meta/main.yml
deleted file mode 100644
index d59c2bc..0000000
--- a/roles/ceph_mon/meta/main.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-galaxy_info:
- author: VEXXHOST, Inc.
- description: Ansible role for Ceph monitor
- license: Apache-2.0
- min_ansible_version: 5.5.0
- standalone: false
- platforms:
- - name: Ubuntu
- versions:
- - focal
-
-dependencies:
- - role: defaults
diff --git a/roles/ceph_mon/tasks/bootstrap-ceph.yml b/roles/ceph_mon/tasks/bootstrap-ceph.yml
deleted file mode 100644
index dc19f62..0000000
--- a/roles/ceph_mon/tasks/bootstrap-ceph.yml
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-# TODO(mnaser): Move to using vexxhost.atmosphere.ceph_key
-- name: Create monitor keyring
- ansible.builtin.command:
- ceph-authtool --gen-key --create-keyring
- --name mon.
- --cap mon 'allow *'
- /tmp/ceph.mon.keyring
- args:
- creates: /tmp/ceph.mon.keyring
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-# TODO(mnaser): Move to using vexxhost.atmosphere.ceph_key
-- name: Create admin keyring
- ansible.builtin.command:
- ceph-authtool --gen-key --create-keyring
- --name client.admin
- --cap mon 'allow *'
- --cap osd 'allow *'
- --cap mds 'allow *'
- --cap mgr 'allow *'
- /etc/ceph/ceph.client.admin.keyring
- args:
- creates: /etc/ceph/ceph.client.admin.keyring
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-# TODO(mnaser): Move to using vexxhost.atmosphere.ceph_key
-- name: Create bootstrap-osd keyring
- ansible.builtin.command:
- ceph-authtool --gen-key --create-keyring
- --name client.bootstrap-osd
- --cap mon 'profile bootstrap-osd'
- --cap mgr 'allow r'
- /var/lib/ceph/bootstrap-osd/ceph.keyring
- args:
- creates: /var/lib/ceph/bootstrap-osd/ceph.keyring
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-# TODO(mnaser): Move to using vexxhost.atmosphere.ceph_key
-- name: Add admin keyring to monitor
- changed_when: true
- ansible.builtin.command:
- ceph-authtool --import-keyring /etc/ceph/ceph.client.admin.keyring
- /tmp/ceph.mon.keyring
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-# TODO(mnaser): Move to using vexxhost.atmosphere.ceph_key
-- name: Add bootstrap-osd keyring to monitor
- changed_when: true
- ansible.builtin.command:
- ceph-authtool --import-keyring /var/lib/ceph/bootstrap-osd/ceph.keyring
- /tmp/ceph.mon.keyring
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-- name: Create monmap
- ansible.builtin.command:
- monmaptool --create
- --fsid {{ ceph_mon_fsid }}
- --add {{ inventory_hostname_short }} {{ ceph_mon_ip_address }}
- /tmp/monmap
- args:
- creates: /tmp/monmap
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-- name: Create monitor folder
- ansible.builtin.file:
- path: "/var/lib/ceph/mon/ceph-{{ inventory_hostname_short }}"
- state: directory
- owner: ceph
- group: ceph
- mode: "0700"
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-- name: Configure mon initial members
- community.general.ini_file:
- path: /etc/ceph/ceph.conf
- section: global
- option: mon initial members
- value: "{{ inventory_hostname_short }}"
- owner: ceph
- group: ceph
- mode: "0640"
-
-- name: Start monitor
- ansible.builtin.include_tasks: start-monitor.yml
- when:
- - inventory_hostname == groups[ceph_mon_group][0]
-
-- name: Set bootstrap node
- ansible.builtin.set_fact:
- _ceph_mon_bootstrap_node: "{{ groups[ceph_mon_group][0] }}"
diff --git a/roles/ceph_mon/tasks/main.yml b/roles/ceph_mon/tasks/main.yml
deleted file mode 100644
index 5ce89e2..0000000
--- a/roles/ceph_mon/tasks/main.yml
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-- name: Install packages
- ansible.builtin.apt:
- name: ["ceph-mon"]
- install_recommends: false
-
-- name: Set ceph monitor ip address
- ansible.builtin.set_fact:
- ceph_mon_ip_address: "{{ ansible_all_ipv4_addresses | ansible.netcommon.ipaddr(ceph_mon_public_network) | first }}"
-
-- name: Generate basic configuration file
- community.general.ini_file:
- path: /etc/ceph/ceph.conf
- section: global
- option: "{{ item.option }}"
- value: "{{ item.value }}"
- owner: ceph
- group: ceph
- mode: "0640"
- loop:
- - option: fsid
- value: "{{ ceph_mon_fsid }}"
- - option: mon host
- value: "{{ groups[ceph_mon_group] | map('extract', hostvars, ['ceph_mon_ip_address']) | join(',') }}"
- - option: public network
- value: "{{ ceph_mon_public_network }}"
- - option: cluster network
- value: "{{ ceph_mon_cluster_network }}"
-
-- name: Check if any node is bootstrapped
- ansible.builtin.stat:
- path: "/var/lib/ceph/mon/ceph-{{ hostvars[item]['inventory_hostname_short'] }}/store.db"
- register: _ceph_mon_stat
- loop: "{{ groups[ceph_mon_group] }}"
- delegate_to: "{{ item }}"
-
-- name: Select pre-existing bootstrap node if exists
- ansible.builtin.set_fact:
- _ceph_mon_bootstrap_node: "{{ _ceph_mon_stat.results | selectattr('stat.exists', 'equalto', true) | map(attribute='item') | first }}"
- when:
- - _ceph_mon_stat.results | selectattr('stat.exists', 'equalto', true) | length > 0
-
-- name: Bootstrap cluster
- ansible.builtin.include_tasks: bootstrap-ceph.yml
- when:
- - _ceph_mon_stat.results | selectattr('stat.exists', 'equalto', true) | length == 0
-
-- name: Grab admin keyring
- delegate_to: "{{ _ceph_mon_bootstrap_node }}"
- ansible.builtin.slurp:
- src: /etc/ceph/ceph.client.admin.keyring
- register: _ceph_mon_admin_keyring
- when: inventory_hostname != _ceph_mon_bootstrap_node
-
-- name: Upload client.admin keyring
- ansible.builtin.copy:
- content: "{{ _ceph_mon_admin_keyring['content'] | b64decode }}"
- dest: /etc/ceph/ceph.client.admin.keyring
- mode: "0600"
- when: inventory_hostname != _ceph_mon_bootstrap_node
-
-- name: Get monitor keyring
- ansible.builtin.command: ceph auth get mon. -o /tmp/ceph.mon.keyring
- changed_when: false
- when: inventory_hostname != _ceph_mon_bootstrap_node
-
-- name: Get monmap keyring
- ansible.builtin.command: ceph mon getmap -o /tmp/monmap
- changed_when: false
- when: inventory_hostname != _ceph_mon_bootstrap_node
-
-- name: Start monitor
- ansible.builtin.include_tasks: start-monitor.yml
- when: inventory_hostname != _ceph_mon_bootstrap_node
-
-- name: Enable "msgr2"
- ansible.builtin.command: ceph mon enable-msgr2
- changed_when: false
- when: inventory_hostname == _ceph_mon_bootstrap_node
diff --git a/roles/ceph_mon/tasks/start-monitor.yml b/roles/ceph_mon/tasks/start-monitor.yml
deleted file mode 100644
index 308d44b..0000000
--- a/roles/ceph_mon/tasks/start-monitor.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-- name: Create monitor filesystem
- ansible.builtin.shell: |
- ceph-mon --mkfs -i {{ inventory_hostname_short }} --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring
- args:
- creates: "/var/lib/ceph/mon/ceph-{{ inventory_hostname_short }}/store.db"
-
-- name: Ensure permissions are fixed
- ansible.builtin.file:
- path: "/var/lib/ceph/mon/ceph-{{ inventory_hostname_short }}"
- owner: ceph
- group: ceph
- recurse: true
-
-# NOTE(mnaser): https://bugs.launchpad.net/ubuntu/+source/ceph/+bug/1917414/comments/30
-- name: Workaround for aarch64 systems
- community.general.ini_file:
- path: /lib/systemd/system/ceph-mon@.service
- section: Service
- option: MemoryDenyWriteExecute
- value: false
- owner: ceph
- group: ceph
- mode: "0644"
- register: _ceph_aarch64_fix
- when: ansible_architecture == 'aarch64'
-
-- name: Enable and start service
- ansible.builtin.service:
- name: "ceph-mon@{{ inventory_hostname_short }}"
- state: started
- enabled: true
- daemon_reload: "{{ _ceph_aarch64_fix.changed }}"
diff --git a/roles/ceph_osd/README.md b/roles/ceph_osd/README.md
deleted file mode 100644
index e725e9e..0000000
--- a/roles/ceph_osd/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# `ceph_osd`
diff --git a/roles/ceph_osd/defaults/main.yml b/roles/ceph_osd/defaults/main.yml
deleted file mode 100644
index 9671346..0000000
--- a/roles/ceph_osd/defaults/main.yml
+++ /dev/null
@@ -1,19 +0,0 @@
----
-# .. vim: foldmarker=[[[,]]]:foldmethod=marker
-
-# .. Copyright (C) 2022 VEXXHOST, Inc.
-# .. SPDX-License-Identifier: Apache-2.0
-
-# Default variables
-# =================
-
-# .. contents:: Sections
-# :local:
-
-
-# .. envvar:: ceph_osd_mons_group [[[
-#
-# Name of Ansible group that contains all Ceph monitors
-ceph_osd_mons_group: controllers
-
- # ]]]
diff --git a/roles/ceph_osd/meta/main.yml b/roles/ceph_osd/meta/main.yml
deleted file mode 100644
index bd74938..0000000
--- a/roles/ceph_osd/meta/main.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-galaxy_info:
- author: VEXXHOST, Inc.
- description: Ansible role for Ceph OSD
- license: Apache-2.0
- min_ansible_version: 5.5.0
- standalone: false
- platforms:
- - name: Ubuntu
- versions:
- - focal
-
-dependencies:
- - role: defaults
diff --git a/roles/ceph_osd/tasks/main.yml b/roles/ceph_osd/tasks/main.yml
deleted file mode 100644
index 989424d..0000000
--- a/roles/ceph_osd/tasks/main.yml
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-- name: Install packages
- ansible.builtin.apt:
- name: ["udev", "ceph-osd"]
- install_recommends: false
-
-- name: Grab ceph fsid from monitors
- delegate_to: "{{ groups[ceph_osd_mons_group][0] }}"
- register: _ceph_fsid
- changed_when: false
- ansible.builtin.command: ceph fsid
-
-- name: Collect "ceph mon dump" output from a monitor
- delegate_to: "{{ groups[ceph_osd_mons_group][0] }}"
- run_once: true
- ansible.builtin.command: ceph mon dump -f json
- changed_when: false
- register: _ceph_mon_dump
-
-- name: Generate fact with list of Ceph monitors
- run_once: true
- ansible.builtin.set_fact:
- ceph_monitors: "{{ _ceph_mon_dump.stdout | from_json | community.general.json_query('mons[*].addr') | map('regex_replace', '(.*):(.*)', '\\1') }}"
-
-- name: Generate basic configuration file
- community.general.ini_file:
- path: /etc/ceph/ceph.conf
- section: global
- option: "{{ item.option }}"
- value: "{{ item.value }}"
- owner: ceph
- group: ceph
- mode: "0640"
- loop:
- - option: fsid
- value: "{{ _ceph_fsid.stdout | trim }}"
- - option: mon host
- value: "{{ ceph_monitors | join(',') }}"
-
-- name: Grab bootstrap-osd from monitors
- delegate_to: "{{ groups[ceph_osd_mons_group][0] }}"
- register: _ceph_bootstrap_osd_keyring
- changed_when: false
- ansible.builtin.command: ceph auth get client.bootstrap-osd
-
-- name: Install bootstrap-osd keyring
- ansible.builtin.copy:
- content: "{{ _ceph_bootstrap_osd_keyring.stdout }}\n"
- dest: /var/lib/ceph/bootstrap-osd/ceph.keyring
- owner: ceph
- group: ceph
- mode: "0640"
-
-- name: Workaround to allow usage of loop devices
- ansible.builtin.replace:
- path: /usr/lib/python3/dist-packages/ceph_volume/util/disk.py
- regexp: "'mpath']"
- replace: "'mpath', 'loop']"
- owner: ceph
- group: ceph
- mode: "0640"
- when: molecule | default(false)
-
-# NOTE(mnaser): https://bugs.launchpad.net/ubuntu/+source/ceph/+bug/1917414/comments/30
-- name: Workaround for aarch64 systems
- community.general.ini_file:
- path: /lib/systemd/system/ceph-osd@.service
- section: Service
- option: MemoryDenyWriteExecute
- value: false
- owner: ceph
- group: ceph
- mode: "0644"
- register: _ceph_aarch64_fix
- when: ansible_architecture == 'aarch64'
-
-- name: Reload systemd
- ansible.builtin.service:
- daemon_reload: "{{ _ceph_aarch64_fix.changed }}"
-
-- name: Get which devices don't contain osds
- register: _ceph_osd_check
- failed_when: false
- changed_when: false
- ansible.builtin.command: /usr/sbin/ceph-volume lvm list {{ item }}
- loop: "{{ ceph_osd_devices }}"
-
-- name: Create osds for volumes which are not setup
- changed_when: true
- ansible.builtin.command: /usr/sbin/ceph-volume lvm create --data {{ item }}
- loop: "{{ _ceph_osd_check.results | selectattr('rc', 'equalto', 1) | map(attribute='item') }}"
diff --git a/roles/ceph_provisioners/tasks/main.yml b/roles/ceph_provisioners/tasks/main.yml
index 057b75a..775ab28 100644
--- a/roles/ceph_provisioners/tasks/main.yml
+++ b/roles/ceph_provisioners/tasks/main.yml
@@ -77,7 +77,7 @@
- name: Retrieve client.admin keyring
delegate_to: "{{ groups[ceph_provisioners_ceph_mon_group][0] }}"
- vexxhost.atmosphere.ceph_key:
+ vexxhost.ceph.key:
name: client.admin
state: info
output_format: json
diff --git a/roles/ceph_repository/README.md b/roles/ceph_repository/README.md
deleted file mode 100644
index 6e54014..0000000
--- a/roles/ceph_repository/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# `ceph_repository`
diff --git a/roles/ceph_repository/defaults/main.yml b/roles/ceph_repository/defaults/main.yml
deleted file mode 100644
index 63c9290..0000000
--- a/roles/ceph_repository/defaults/main.yml
+++ /dev/null
@@ -1,31 +0,0 @@
----
-# .. vim: foldmarker=[[[,]]]:foldmethod=marker
-
-# .. Copyright (C) 2022 VEXXHOST, Inc.
-# .. SPDX-License-Identifier: Apache-2.0
-
-# Default variables
-# =================
-
-# .. contents:: Sections
-# :local:
-
-
-# .. envvar:: ceph_repository_apt_key [[[
-#
-# Ceph APT repository GPG key
-ceph_repository_apt_key: "https://download.ceph.com/keys/release.asc"
-
- # ]]]
-# .. envvar:: ceph_repository_url [[[
-#
-# Ceph APT repository URL
-ceph_repository_url: https://download.ceph.com/debian-pacific/
-
- # ]]]
-# .. envvar:: ceph_repository_version [[[
-#
-# Ceph version to pin package manager to
-ceph_repository_version: 16.2.9
-
- # ]]]
diff --git a/roles/ceph_repository/meta/main.yml b/roles/ceph_repository/meta/main.yml
deleted file mode 100644
index 2e86618..0000000
--- a/roles/ceph_repository/meta/main.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-galaxy_info:
- author: VEXXHOST, Inc.
- description: Ansible role for Ceph repository
- license: Apache-2.0
- min_ansible_version: 5.5.0
- standalone: false
- platforms:
- - name: Ubuntu
- versions:
- - focal
-
-dependencies:
- - role: defaults
diff --git a/roles/ceph_repository/tasks/main.yml b/roles/ceph_repository/tasks/main.yml
deleted file mode 100644
index e3d184e..0000000
--- a/roles/ceph_repository/tasks/main.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) 2022 VEXXHOST, Inc.
-#
-# 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.
-
-- name: Install packages
- ansible.builtin.apt:
- name: ["gnupg"]
- install_recommends: false
-
-- name: Add apt key
- ansible.builtin.apt_key:
- url: "{{ ceph_repository_apt_key }}"
- state: present
-
-- name: Configure version pinning
- ansible.builtin.template:
- src: apt-preferences.j2
- dest: /etc/apt/preferences.d/ceph
- mode: "0644"
-
-- name: Add apt repository
- ansible.builtin.apt_repository:
- repo: "deb {{ ceph_repository_url }} {{ ansible_distribution_release }} main"
- state: present
diff --git a/roles/ceph_repository/templates/apt-preferences.j2 b/roles/ceph_repository/templates/apt-preferences.j2
deleted file mode 100644
index c197476..0000000
--- a/roles/ceph_repository/templates/apt-preferences.j2
+++ /dev/null
@@ -1,11 +0,0 @@
-Package: ceph-mon
-Pin: version {{ ceph_repository_version }}-*
-Pin-Priority: 1000
-
-Package: ceph-mgr
-Pin: version {{ ceph_repository_version }}-*
-Pin-Priority: 1000
-
-Package: ceph-osd
-Pin: version {{ ceph_repository_version }}-*
-Pin-Priority: 1000
diff --git a/roles/rook_ceph_cluster/tasks/main.yml b/roles/rook_ceph_cluster/tasks/main.yml
index a2ba898..0c8232a 100644
--- a/roles/rook_ceph_cluster/tasks/main.yml
+++ b/roles/rook_ceph_cluster/tasks/main.yml
@@ -22,7 +22,7 @@
- name: Retrieve keyring for client.admin
run_once: true
delegate_to: "{{ groups[rook_ceph_cluster_mon_group][0] }}"
- vexxhost.atmosphere.ceph_key:
+ vexxhost.ceph.key:
name: client.admin
state: info
output_format: json
@@ -31,7 +31,7 @@
- name: Retrieve keyring for monitors
run_once: true
delegate_to: "{{ groups[rook_ceph_cluster_mon_group][0] }}"
- vexxhost.atmosphere.ceph_key:
+ vexxhost.ceph.key:
name: mon.
state: info
output_format: json