Skip to content

Commit

Permalink
modules: Add _info modules
Browse files Browse the repository at this point in the history
Validate modules test fails with:

Argument state includes get, list or info as a choice.
Functionality should be in an _info or (if further conditions apply) _facts module.

on modules ceph_crush_rule and ceph_key

With Ansible 2.8 and onwards best practice requires that modules
gathering info to be put in a separate module named _info[1]

[1]https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_general.html#creating-an-info-or-a-facts-module

Signed-off-by: Teoman ONAY <[email protected]>
  • Loading branch information
asm0deuz committed Dec 4, 2024
1 parent 3814c2e commit dac6077
Show file tree
Hide file tree
Showing 21 changed files with 420 additions and 68 deletions.
4 changes: 2 additions & 2 deletions infrastructure-playbooks/ceph-keys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
with_items: "{{ keys_to_delete }}"

- name: Info ceph key(s)
ceph_key:
ceph_key_info:
name: "{{ item }}"
state: info
cluster: "{{ cluster }}"
Expand All @@ -60,7 +60,7 @@
with_items: "{{ keys_to_info }}"

- name: List ceph key(s)
ceph_key:
ceph_key_info:
state: list
cluster: "{{ cluster }}"
containerized: "{{ container_exec_cmd | default(False) }}"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure-playbooks/cephadm-adopt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@
inventory_hostname in groups.get(rbdmirror_group_name, [])

- name: Get the client.admin keyring
ceph_key:
ceph_key_info:
name: client.admin
cluster: "{{ cluster }}"
output_format: plain
Expand Down
6 changes: 2 additions & 4 deletions library/ceph_crush_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,8 @@
If 'present' is used, the module creates a rule if it doesn't
exist or update it if it already exists.
If 'absent' is used, the module will simply delete the rule.
If 'info' is used, the module will return all details about the
existing rule (json formatted).
required: false
choices: ['present', 'absent', 'info']
choices: ['present', 'absent']
default: present
rule_type:
description:
Expand Down Expand Up @@ -192,7 +190,7 @@ def main():
argument_spec=dict(
name=dict(type='str', required=False),
cluster=dict(type='str', required=False, default='ceph'),
state=dict(type='str', required=False, choices=['present', 'absent', 'info'], default='present'), # noqa: E501
state=dict(type='str', required=False, choices=['present', 'absent'], default='present'), # noqa: E501
rule_type=dict(type='str', required=False, choices=['replicated', 'erasure']), # noqa: E501
bucket_root=dict(type='str', required=False),
bucket_type=dict(type='str', required=False, choices=['osd', 'host', 'chassis', 'rack', 'row', 'pdu', 'pod', # noqa: E501
Expand Down
119 changes: 119 additions & 0 deletions library/ceph_crush_rule_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# 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

from ansible.module_utils.basic import AnsibleModule
try:
from ansible.module_utils.ca_common import exit_module, \
generate_cmd, \
is_containerized, \
exec_command
except ImportError:
from module_utils.ca_common import exit_module, \
generate_cmd, \
is_containerized, \
exec_command
import datetime


ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}

DOCUMENTATION = '''
---
module: ceph_crush_rule_info
short_description: Lists Ceph Crush Replicated/Erasure Rules
version_added: "2.8"
description:
- Retrieces Ceph Crush rule(s).
options:
name:
description:
- name of the Ceph Crush rule. If state is 'info' - empty string
can be provided as a value to get all crush rules
required: true
cluster:
description:
- The ceph cluster name.
required: false
default: ceph
author:
- Teoman ONAY <@asm0deuz>
'''

EXAMPLES = '''
- name: get a Ceph Crush rule information
ceph_crush_rule_info:
name: foo
'''

RETURN = '''# '''


def get_rule(module, container_image=None):
'''
Get existing crush rule
'''

cluster = module.params.get('cluster')
name = module.params.get('name')

args = ['dump', name, '--format=json']

cmd = generate_cmd(sub_cmd=['osd', 'crush', 'rule'],
args=args,
cluster=cluster,
container_image=container_image)

return cmd


def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='str', required=False),
cluster=dict(type='str', required=False, default='ceph'),
),
supports_check_mode=True,
)

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()

rc, cmd, out, err = exec_command(module, get_rule(module, container_image=container_image)) # noqa: E501

exit_module(module=module, out=out, rc=rc, cmd=cmd, err=err, startd=startd, changed=changed) # noqa: E501


if __name__ == '__main__':
main()
44 changes: 9 additions & 35 deletions library/ceph_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@
from ansible.module_utils.basic import AnsibleModule
try:
from ansible.module_utils.ca_common import generate_cmd, \
is_containerized, \
container_exec, \
fatal
is_containerized, \
container_exec, \
fatal
except ImportError:
from module_utils.ca_common import generate_cmd, \
is_containerized, \
container_exec, \
fatal
is_containerized, \
container_exec, \
fatal
import datetime
import json
import os
Expand Down Expand Up @@ -85,11 +85,9 @@
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']
choices: ['present', 'update', 'absent', 'fetch_initial_keys', 'generate_secret']
default: present
caps:
description:
Expand Down Expand Up @@ -182,22 +180,6 @@
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
Expand Down Expand Up @@ -487,7 +469,7 @@ def run_module():
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
'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),
Expand Down Expand Up @@ -518,7 +500,7 @@ def run_module():
output_format = module.params.get('output_format')

# Can't use required_if with 'name' for some reason...
if state in ['present', 'absent', 'update', 'info'] and not name:
if state in ['present', 'absent', 'update'] and not name:
fatal(f'"state" is "{state}" but "name" is not defined.', module)

changed = False
Expand Down Expand Up @@ -626,14 +608,6 @@ def run_module():
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."
Expand Down
Loading

0 comments on commit dac6077

Please sign in to comment.