From 5ab03f393b6f9cecaa13f0e728b36cb1924c4362 Mon Sep 17 00:00:00 2001 From: Francesco Pantano Date: Fri, 26 Mar 2021 14:22:25 +0100 Subject: [PATCH] Introduce the network(s) parameter in the ceph spec module This change introduces a new option on the CephDaemonSpec definition. Now a list of networks can be specified and rendered using the related top level field. The networks field cannot be logically considered part of extra parameter, because except for the monitors and osds (they have the cluster and public networks defined), all the other daemons should provide this kind of field. The ceph_mkspec module and the rgw tasks are modified accordingly and as per [1] only rgw is supported for now. [1] https://github.com/ceph/ceph/pull/40048 Change-Id: I71f1a0e995c0d92d73625cd863488fc183bda7b3 --- .../ansible_plugins/module_utils/ceph_spec.py | 35 ++++++++++++++++--- .../ansible_plugins/modules/ceph_mkspec.py | 25 +++++++++++-- .../modules/ceph_spec_bootstrap.py | 4 +-- .../roles/tripleo_cephadm/tasks/rgw.yaml | 3 +- 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/tripleo_ansible/ansible_plugins/module_utils/ceph_spec.py b/tripleo_ansible/ansible_plugins/module_utils/ceph_spec.py index 23cbfecdb..a2f83e003 100644 --- a/tripleo_ansible/ansible_plugins/module_utils/ceph_spec.py +++ b/tripleo_ansible/ansible_plugins/module_utils/ceph_spec.py @@ -14,7 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. -import argparse +import ipaddress import json import sys @@ -97,7 +97,6 @@ class CephPlacementSpec(object): else: spec_template = {} - # TODO: Add count to the list of placement parameters return spec_template @@ -136,6 +135,7 @@ class CephDaemonSpec(object): daemon_name: str, hosts: list, placement_pattern: str, + networks: list, spec: dict, labels: list, **kwargs: dict): @@ -147,6 +147,12 @@ class CephDaemonSpec(object): self.placement = placement_pattern self.labels = labels + # network list where the current daemon should be bound + if not networks: + self.networks = [] + else: + self.networks = networks + # extra keywords definition (e.g. data_devices for OSD(s) self.extra = {} for k, v in kwargs.items(): @@ -158,11 +164,22 @@ class CephDaemonSpec(object): def __setattr__(self, key, value): self.__dict__[key] = value + def validate_networks(self): + if len(self.networks) < 1: + return False + + for network in self.networks: + try: + ipaddress.ip_network(network) + except ValueError as e: + raise Exception(f'Cannot parse network {network}: {e}') + return True + def make_daemon_spec(self): - # the placement dictionary + # the placement dict pl = {} - # the spec dictionary + # the spec dict sp = {} place = CephPlacementSpec(self.hosts, self.placement, 0, self.labels) @@ -175,6 +192,14 @@ class CephDaemonSpec(object): 'service_id': self.daemon_id, } + # the networks dict + ntw = {} + + if self.validate_networks(): + ntw = { + 'networks': self.networks + } + # process extra parameters if present if not self.validate_keys(self.extra.keys(), ALLOWED_EXTRA_KEYS): raise Exception("Fatal: the spec should be composed by only allowed keywords") @@ -187,7 +212,7 @@ class CephDaemonSpec(object): raise Exception("Fatal: the spec should be composed by only allowed keywords") # build the resulting daemon template - spec_template = {**spec_template, **self.extra, **pl, **sp} + spec_template = {**spec_template, **ntw, **self.extra, **pl, **sp} return spec_template def validate_keys(self, spec, ALLOWED_KEYS): diff --git a/tripleo_ansible/ansible_plugins/modules/ceph_mkspec.py b/tripleo_ansible/ansible_plugins/modules/ceph_mkspec.py index acece912f..de8e123d4 100644 --- a/tripleo_ansible/ansible_plugins/modules/ceph_mkspec.py +++ b/tripleo_ansible/ansible_plugins/modules/ceph_mkspec.py @@ -85,6 +85,11 @@ options: - The host pattern where the daemon is going to be applied required: false type: str + networks: + description: + - The list of networks on the host where the daemon is bound. + required: false + type: list labels: description: - The list of labels used to apply the daemon on the Ceph custer @@ -144,6 +149,18 @@ EXAMPLES = ''' labels: - "controller" apply: true +- name: create the Ceph RGW daemon spec + ceph_spec: + service_type: rgw + service_id: rgw.default + service_name: rgw.default + networks: + - 1.2.3.0/24 + - 4.5.6.0/24 + render_path: '/home/ceph-admin/specs' + labels: + - "controller" + apply: true ''' RETURN = '''# ''' @@ -187,6 +204,7 @@ def run_module(): service_name = module.params.get('service_name') hosts = module.params.get('hosts') host_pattern = module.params.get('host_pattern') + networks = module.params.get('networks') labels = module.params.get('labels') spec = module.params.get('spec') extra = module.params.get('extra') @@ -225,15 +243,18 @@ def run_module(): if labels is None: labels = [] + # no networks are defined + if networks is None: + networks = [] + d = ceph_spec.CephDaemonSpec(service_type, service_id, service_name, - hosts, host_pattern, spec, labels, **extra) + hosts, host_pattern, networks, spec, labels, **extra) if apply: container_image = is_containerized() render('{}/{}'.format(render_path, service_type), d.make_daemon_spec()) cmd = generate_orch_cli(cluster, '{}/{}'.format(render_path, service_type), container_image) rc, cmd, out, err = exec_command(module, cmd) - # module.exit_json(changed=True, result=cmd) exit_module(module=module, out=out, rc=rc, cmd=cmd, err=err, startd=startd, changed=changed) else: # render the dict as the output of the module diff --git a/tripleo_ansible/ansible_plugins/modules/ceph_spec_bootstrap.py b/tripleo_ansible/ansible_plugins/modules/ceph_spec_bootstrap.py index 0fab3ad64..8329a6318 100644 --- a/tripleo_ansible/ansible_plugins/modules/ceph_spec_bootstrap.py +++ b/tripleo_ansible/ansible_plugins/modules/ceph_spec_bootstrap.py @@ -333,7 +333,7 @@ def get_specs(hosts_to_ips, label_map, ceph_service_types, osd_spec={}): host_list.append(host) if svc in ['mon', 'mgr']: d = ceph_spec.CephDaemonSpec(svc, svc, svc, host_list, - placement_pattern, + placement_pattern, None, spec_dict, labels) if svc in ['osd']: if osd_spec == {}: @@ -346,7 +346,7 @@ def get_specs(hosts_to_ips, label_map, ceph_service_types, osd_spec={}): d = ceph_spec.CephDaemonSpec(svc, 'default_drive_group', 'osd.default_drive_group', host_list, placement_pattern, - spec_dict, labels, **osd_spec) + None, spec_dict, labels, **osd_spec) specs.append(d.make_daemon_spec()) return specs diff --git a/tripleo_ansible/roles/tripleo_cephadm/tasks/rgw.yaml b/tripleo_ansible/roles/tripleo_cephadm/tasks/rgw.yaml index 54325ebe7..c0c624649 100644 --- a/tripleo_ansible/roles/tripleo_cephadm/tasks/rgw.yaml +++ b/tripleo_ansible/roles/tripleo_cephadm/tasks/rgw.yaml @@ -36,10 +36,11 @@ apply: true hosts: "{{ _hosts }}" spec: - rgw_frontend_port: 8080 + rgw_frontend_port: "{{ radosgw_frontend_port }}" rgw_realm: 'default' rgw_zone: 'default' render_path: "{{ tripleo_cephadm_spec_home }}" + networks: "{{ radosgw_address_block }}" register: spc environment: CEPH_CONTAINER_IMAGE: "{{ tripleo_cephadm_container_ns + '/' + tripleo_cephadm_container_image + ':' + tripleo_cephadm_container_tag }}"