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
This commit is contained in:
parent
6bfeb06341
commit
5ab03f393b
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 }}"
|
||||||
|
|
Loading…
Reference in New Issue