- radosgw_address_block is defined
- radosgw_address_block != 'subnet'
- - name: update the placement of radosgw hosts
- command: >
- {{ cephadm_cmd }} shell -k /etc/ceph/{{ cluster }}.client.admin.keyring --fsid {{ fsid }} --
- ceph orch apply rgw {{ ansible_facts['hostname'] }}
- --placement='count-per-host:{{ radosgw_num_instances }} {{ ansible_facts['nodename'] }}'
- {{ rgw_subnet if rgw_subnet is defined else '' }}
- --port={{ radosgw_frontend_port }}
- {{ '--ssl' if radosgw_frontend_ssl_certificate else '' }}
- changed_when: false
+ - name: Update the placement of radosgw hosts
+ ceph_orch_apply:
+ fsid: "{{ fsid }}"
+ spec: |
+ service_type: rgw
+ service_id: {{ ansible_facts['hostname'] }}
+ placement:
+ count_per_host: {{ radosgw_num_instances }}
+ hosts:
+ - {{ ansible_facts['nodename'] }}
+ {{ "networks: rgw_subnet" if rgw_subnet is defined }}
+ spec:
+ rgw_frontend_port: {{ radosgw_frontend_port }}
+ {{ "ssl: true" if radosgw_frontend_ssl_certificate }}
+ extra_container_args:
+ - -v
+ - /etc/pki/ca-trust:/etc/pki/ca-trust:ro
delegate_to: "{{ groups[mon_group_name][0] }}"
when: not rgw_multisite | bool
environment:
--- /dev/null
+# Copyright Red Hat
+# SPDX-License-Identifier: Apache-2.0
+# Author: Guillaume Abrioux <gabrioux@redhat.com>
+#
+# 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
+from typing import List, Tuple, Dict
+__metaclass__ = type
+
+import datetime
+import yaml
+
+from ansible.module_utils.basic import AnsibleModule # type: ignore
+try:
+ from ansible.module_utils.ca_common import exit_module, build_base_cmd_orch # type: ignore
+except ImportError:
+ from module_utils.ca_common import exit_module, build_base_cmd_orch
+
+
+ANSIBLE_METADATA = {
+ 'metadata_version': '1.1',
+ 'status': ['preview'],
+ 'supported_by': 'community'
+}
+
+DOCUMENTATION = '''
+---
+module: ceph_orch_apply
+short_description: apply service spec
+version_added: "2.9"
+description:
+ - apply a service spec
+options:
+ fsid:
+ description:
+ - the fsid of the Ceph cluster to interact with.
+ required: false
+ image:
+ description:
+ - The Ceph container image to use.
+ required: false
+ spec:
+ description:
+ - The service spec to apply
+ required: true
+author:
+ - Guillaume Abrioux <gabrioux@redhat.com>
+'''
+
+EXAMPLES = '''
+- name: apply osd spec
+ ceph_orch_apply:
+ spec: |
+ service_type: osd
+ service_id: osd
+ placement:
+ label: osds
+ spec:
+ data_devices:
+ all: true
+'''
+
+
+def parse_spec(spec: str) -> Dict:
+ """ parse spec string to yaml """
+ yaml_spec = yaml.safe_load(spec)
+ return yaml_spec
+
+
+def retrieve_current_spec(module: AnsibleModule, expected_spec: Dict) -> Dict:
+ """ retrieve current config of the service """
+ service: str = expected_spec["service_type"]
+ cmd = build_base_cmd_orch(module)
+ cmd.extend(['ls', service, '--format=yaml'])
+ out = module.run_command(cmd)
+ if isinstance(out, str):
+ # if there is no existing service, cephadm returns the string 'No services reported'
+ return {}
+ else:
+ return yaml.safe_load(out[1])
+
+
+def apply_spec(module: "AnsibleModule",
+ data: str) -> Tuple[int, List[str], str, str]:
+ cmd = build_base_cmd_orch(module)
+ cmd.extend(['apply', '-i', '-'])
+ rc, out, err = module.run_command(cmd, data=data)
+
+ if rc:
+ raise RuntimeError(err)
+
+ return rc, cmd, out, err
+
+
+def run_module() -> None:
+
+ module_args = dict(
+ spec=dict(type='str', required=True),
+ fsid=dict(type='str', required=False),
+ docker=dict(type=bool,
+ required=False,
+ default=False),
+ image=dict(type='str', required=False)
+ )
+
+ module = AnsibleModule(
+ argument_spec=module_args,
+ supports_check_mode=True
+ )
+
+ startd = datetime.datetime.now()
+ spec = module.params.get('spec')
+
+ if module.check_mode:
+ exit_module(
+ module=module,
+ out='',
+ rc=0,
+ cmd=[],
+ err='',
+ startd=startd,
+ changed=False
+ )
+
+ # Idempotency check
+ expected = parse_spec(module.params.get('spec'))
+ current_spec = retrieve_current_spec(module, expected)
+
+ if not current_spec or current_spec != expected:
+ rc, cmd, out, err = apply_spec(module, spec)
+ changed = True
+ else:
+ rc = 0
+ cmd = []
+ out = ''
+ err = ''
+ changed = False
+
+ exit_module(
+ module=module,
+ out=out,
+ rc=rc,
+ cmd=cmd,
+ err=err,
+ startd=startd,
+ changed=changed
+ )
+
+
+def main() -> None:
+ run_module()
+
+
+if __name__ == '__main__':
+ main()
import os
import datetime
+from typing import List
+from ansible.module_utils.basic import AnsibleModule
def generate_cmd(cmd='ceph',
return rc, cmd, out, err
+def build_base_cmd(module: "AnsibleModule") -> List[str]:
+ cmd = ['cephadm']
+ docker = module.params.get('docker')
+ image = module.params.get('image')
+ fsid = module.params.get('fsid')
+
+ if docker:
+ cmd.append('--docker')
+ if image:
+ cmd.extend(['--image', image])
+
+ cmd.append('shell')
+
+ if fsid:
+ cmd.extend(['--fsid', fsid])
+
+ return cmd
+
+
+def build_base_cmd_orch(module: "AnsibleModule") -> List[str]:
+ cmd = build_base_cmd(module)
+ cmd.extend(['ceph', 'orch'])
+
+ return cmd
+
+
def exit_module(module, out, rc, cmd, err, startd, changed=False, diff=dict(before="", after="")): # noqa: E501
endd = datetime.datetime.now()
delta = endd - startd