Merge "Introduce the network(s) parameter in the ceph spec module"

This commit is contained in:
Zuul 2021-04-08 04:10:39 +00:00 committed by Gerrit Code Review
commit 7df7535d34
4 changed files with 57 additions and 10 deletions

View File

@ -14,7 +14,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import argparse import ipaddress
import json import json
import sys import sys
@ -97,7 +97,6 @@ class CephPlacementSpec(object):
else: else:
spec_template = {} spec_template = {}
# TODO: Add count to the list of placement parameters
return spec_template return spec_template
@ -136,6 +135,7 @@ class CephDaemonSpec(object):
daemon_name: str, daemon_name: str,
hosts: list, hosts: list,
placement_pattern: str, placement_pattern: str,
networks: list,
spec: dict, spec: dict,
labels: list, labels: list,
**kwargs: dict): **kwargs: dict):
@ -147,6 +147,12 @@ class CephDaemonSpec(object):
self.placement = placement_pattern self.placement = placement_pattern
self.labels = labels 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) # extra keywords definition (e.g. data_devices for OSD(s)
self.extra = {} self.extra = {}
for k, v in kwargs.items(): for k, v in kwargs.items():
@ -158,11 +164,22 @@ class CephDaemonSpec(object):
def __setattr__(self, key, value): def __setattr__(self, key, value):
self.__dict__[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): def make_daemon_spec(self):
# the placement dictionary # the placement dict
pl = {} pl = {}
# the spec dictionary # the spec dict
sp = {} sp = {}
place = CephPlacementSpec(self.hosts, self.placement, 0, self.labels) place = CephPlacementSpec(self.hosts, self.placement, 0, self.labels)
@ -175,6 +192,14 @@ class CephDaemonSpec(object):
'service_id': self.daemon_id, 'service_id': self.daemon_id,
} }
# the networks dict
ntw = {}
if self.validate_networks():
ntw = {
'networks': self.networks
}
# process extra parameters if present # process extra parameters if present
if not self.validate_keys(self.extra.keys(), ALLOWED_EXTRA_KEYS): if not self.validate_keys(self.extra.keys(), ALLOWED_EXTRA_KEYS):
raise Exception("Fatal: the spec should be composed by only allowed keywords") 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") raise Exception("Fatal: the spec should be composed by only allowed keywords")
# build the resulting daemon template # 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 return spec_template
def validate_keys(self, spec, ALLOWED_KEYS): def validate_keys(self, spec, ALLOWED_KEYS):

View File

@ -85,6 +85,11 @@ options:
- The host pattern where the daemon is going to be applied - The host pattern where the daemon is going to be applied
required: false required: false
type: str type: str
networks:
description:
- The list of networks on the host where the daemon is bound.
required: false
type: list
labels: labels:
description: description:
- The list of labels used to apply the daemon on the Ceph custer - The list of labels used to apply the daemon on the Ceph custer
@ -144,6 +149,18 @@ EXAMPLES = '''
labels: labels:
- "controller" - "controller"
apply: true 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 = '''# ''' RETURN = '''# '''
@ -187,6 +204,7 @@ def run_module():
service_name = module.params.get('service_name') service_name = module.params.get('service_name')
hosts = module.params.get('hosts') hosts = module.params.get('hosts')
host_pattern = module.params.get('host_pattern') host_pattern = module.params.get('host_pattern')
networks = module.params.get('networks')
labels = module.params.get('labels') labels = module.params.get('labels')
spec = module.params.get('spec') spec = module.params.get('spec')
extra = module.params.get('extra') extra = module.params.get('extra')
@ -225,15 +243,18 @@ def run_module():
if labels is None: if labels is None:
labels = [] labels = []
# no networks are defined
if networks is None:
networks = []
d = ceph_spec.CephDaemonSpec(service_type, service_id, service_name, 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: if apply:
container_image = is_containerized() container_image = is_containerized()
render('{}/{}'.format(render_path, service_type), d.make_daemon_spec()) render('{}/{}'.format(render_path, service_type), d.make_daemon_spec())
cmd = generate_orch_cli(cluster, '{}/{}'.format(render_path, service_type), container_image) cmd = generate_orch_cli(cluster, '{}/{}'.format(render_path, service_type), container_image)
rc, cmd, out, err = exec_command(module, cmd) 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) exit_module(module=module, out=out, rc=rc, cmd=cmd, err=err, startd=startd, changed=changed)
else: else:
# render the dict as the output of the module # render the dict as the output of the module

View File

@ -333,7 +333,7 @@ def get_specs(hosts_to_ips, label_map, ceph_service_types, osd_spec={}):
host_list.append(host) host_list.append(host)
if svc in ['mon', 'mgr']: if svc in ['mon', 'mgr']:
d = ceph_spec.CephDaemonSpec(svc, svc, svc, host_list, d = ceph_spec.CephDaemonSpec(svc, svc, svc, host_list,
placement_pattern, placement_pattern, None,
spec_dict, labels) spec_dict, labels)
if svc in ['osd']: if svc in ['osd']:
if osd_spec == {}: 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', d = ceph_spec.CephDaemonSpec(svc, 'default_drive_group',
'osd.default_drive_group', 'osd.default_drive_group',
host_list, placement_pattern, host_list, placement_pattern,
spec_dict, labels, **osd_spec) None, spec_dict, labels, **osd_spec)
specs.append(d.make_daemon_spec()) specs.append(d.make_daemon_spec())
return specs return specs

View File

@ -36,10 +36,11 @@
apply: true apply: true
hosts: "{{ _hosts }}" hosts: "{{ _hosts }}"
spec: spec:
rgw_frontend_port: 8080 rgw_frontend_port: "{{ radosgw_frontend_port }}"
rgw_realm: 'default' rgw_realm: 'default'
rgw_zone: 'default' rgw_zone: 'default'
render_path: "{{ tripleo_cephadm_spec_home }}" render_path: "{{ tripleo_cephadm_spec_home }}"
networks: "{{ radosgw_address_block }}"
register: spc register: spc
environment: environment:
CEPH_CONTAINER_IMAGE: "{{ tripleo_cephadm_container_ns + '/' + tripleo_cephadm_container_image + ':' + tripleo_cephadm_container_tag }}" CEPH_CONTAINER_IMAGE: "{{ tripleo_cephadm_container_ns + '/' + tripleo_cephadm_container_image + ':' + tripleo_cephadm_container_tag }}"