Add operator-native ceph-client library
Change-Id: Id9caf3b385094b9bc4010893034185d0a47c45d4
This commit is contained in:
parent
11b7a7340b
commit
7703ba5c28
|
@ -0,0 +1,208 @@
|
|||
"""Ceph client library
|
||||
"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
from ops.framework import Object
|
||||
from ops.framework import StoredState
|
||||
|
||||
from charmhelpers.contrib.storage.linux.ceph import (
|
||||
send_osd_settings,
|
||||
)
|
||||
import charms_ceph.utils as ceph
|
||||
|
||||
|
||||
from utils import (
|
||||
get_public_addr,
|
||||
get_rbd_features,
|
||||
)
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CephClientProvides(Object):
|
||||
"""
|
||||
Encapsulate the Provides side of the Ceph Client relation.
|
||||
|
||||
Hook events observed:
|
||||
- relation-joined
|
||||
- relation-changed
|
||||
"""
|
||||
|
||||
charm = None
|
||||
_stored = StoredState()
|
||||
|
||||
def __init__(self, charm, relation_name='client'):
|
||||
super().__init__(charm, relation_name)
|
||||
|
||||
self._stored.set_default(processed=[])
|
||||
self.charm = charm
|
||||
self.this_unit = self.model.unit
|
||||
self.relation_name = relation_name
|
||||
self.framework.observe(
|
||||
charm.on[self.relation_name].relation_joined,
|
||||
self._on_relation_changed
|
||||
)
|
||||
self.framework.observe(
|
||||
charm.on[self.relation_name].relation_changed,
|
||||
self._on_relation_changed
|
||||
)
|
||||
|
||||
def notify_all(self):
|
||||
send_osd_settings()
|
||||
if not self.charm.ready_for_service():
|
||||
return
|
||||
for relation in self.model.relations[self.relation_name]:
|
||||
for unit in relation.units:
|
||||
self._handle_client_relation(relation, unit)
|
||||
|
||||
def _on_relation_changed(self, event):
|
||||
"""Prepare relation for data from requiring side."""
|
||||
send_osd_settings()
|
||||
if not self.charm.ready_for_service():
|
||||
return
|
||||
self._handle_client_relation(event.relation, event.unit)
|
||||
|
||||
def _get_ceph_info_from_configs(self):
|
||||
"""Create dictionary of ceph information required to set client relation.
|
||||
|
||||
:returns: Dictionary of ceph configurations needed for client relation
|
||||
:rtype: dict
|
||||
"""
|
||||
public_addr = get_public_addr()
|
||||
rbd_features = get_rbd_features()
|
||||
data = {
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': public_addr
|
||||
}
|
||||
if rbd_features:
|
||||
data['rbd-features'] = rbd_features
|
||||
return data
|
||||
|
||||
def _get_custom_relation_init_data(self):
|
||||
"""Information required for specialised relation.
|
||||
|
||||
:returns: Ceph configurations needed for specialised relation
|
||||
:rtype: dict
|
||||
"""
|
||||
return {}
|
||||
|
||||
def _get_client_application_name(self, relation, unit):
|
||||
"""Retrieve client application name from relation data."""
|
||||
return relation.data[unit].get(
|
||||
'application-name',
|
||||
relation.app)
|
||||
|
||||
def _handle_client_relation(self, relation, unit):
|
||||
"""Handle broker request and set the relation data
|
||||
|
||||
:param relation: Operator relation
|
||||
:type relation: Relation
|
||||
:param unit: Unit to handle
|
||||
:type unit: Unit
|
||||
"""
|
||||
|
||||
# if is_unsupported_cmr(unit):
|
||||
# return
|
||||
|
||||
logger.debug(
|
||||
'mon cluster in quorum and osds bootstrapped '
|
||||
'- providing client with keys, processing broker requests')
|
||||
|
||||
service_name = self._get_client_application_name(relation, unit)
|
||||
data = self._get_ceph_info_from_configs()
|
||||
data.update(self._get_custom_relation_init_data())
|
||||
data.update({'key': ceph.get_named_key(service_name)})
|
||||
|
||||
data.update(
|
||||
self._handle_broker_request(
|
||||
relation, unit, add_legacy_response=True))
|
||||
for k, v in data.items():
|
||||
relation.data[self.this_unit][k] = str(v)
|
||||
|
||||
def _req_already_treated(self, request_id):
|
||||
"""Check if broker request already handled.
|
||||
|
||||
The local relation data holds all the broker request/responses that
|
||||
are handled as a dictionary. There will be a single entry for each
|
||||
unit that makes broker request in the form of broker-rsp-<unit name>:
|
||||
{reqeust-id: <id>, ..}. Verify if request_id exists in the relation
|
||||
data broker response for the requested unit.
|
||||
|
||||
:param request_id: Request ID
|
||||
:type request_id: str
|
||||
:returns: Whether request is already handled
|
||||
:rtype: bool
|
||||
"""
|
||||
return request_id in self._stored.processed
|
||||
|
||||
def _handle_broker_request(
|
||||
self, relation, unit, add_legacy_response=False):
|
||||
"""Retrieve broker request from relation, process, return response data.
|
||||
|
||||
:param event: Operator event for the relation
|
||||
:type relid: Event
|
||||
:param add_legacy_response: (Optional) Adds the legacy ``broker_rsp``
|
||||
key to the response in addition to the
|
||||
new way.
|
||||
:type add_legacy_response: bool
|
||||
:returns: Dictionary of response data ready for use with relation_set.
|
||||
:rtype: dict
|
||||
"""
|
||||
def _get_broker_req_id(request):
|
||||
try:
|
||||
if isinstance(request, str):
|
||||
try:
|
||||
req_key = json.loads(request)['request-id']
|
||||
except (TypeError, json.decoder.JSONDecodeError):
|
||||
logger.warning(
|
||||
'Not able to decode request '
|
||||
'id for broker request {}'.
|
||||
format(request))
|
||||
req_key = None
|
||||
else:
|
||||
req_key = request['request-id']
|
||||
except KeyError:
|
||||
logger.warning(
|
||||
'Not able to decode request id for broker request {}'.
|
||||
format(request))
|
||||
req_key = None
|
||||
|
||||
return req_key
|
||||
|
||||
response = {}
|
||||
|
||||
settings = relation.data[unit]
|
||||
if 'broker_req' in settings:
|
||||
broker_req_id = _get_broker_req_id(settings['broker_req'])
|
||||
if broker_req_id is None:
|
||||
return {}
|
||||
|
||||
if not ceph.is_leader():
|
||||
logger.debug(
|
||||
"Not leader - ignoring broker request {}".format(
|
||||
broker_req_id))
|
||||
return {}
|
||||
|
||||
if self._req_already_treated(broker_req_id):
|
||||
logger.debug(
|
||||
"Ignoring already executed broker request {}".format(
|
||||
broker_req_id))
|
||||
return {}
|
||||
|
||||
rsp = self.charm.process_broker_request(
|
||||
broker_req_id, settings['broker_req'])
|
||||
unit_id = settings.get(
|
||||
'unit-name', unit.name).replace('/', '-')
|
||||
unit_response_key = 'broker-rsp-' + unit_id
|
||||
response.update({unit_response_key: rsp})
|
||||
if add_legacy_response:
|
||||
response.update({'broker_rsp': rsp})
|
||||
processed = self._stored.processed
|
||||
processed.append(broker_req_id)
|
||||
self._stored.processed = processed
|
||||
else:
|
||||
logger.warn('broker_req not in settings: {}'.format(settings))
|
||||
return response
|
|
@ -252,6 +252,12 @@ def update_host_osd_count_report(reset=False):
|
|||
@hooks.hook('config-changed')
|
||||
@harden()
|
||||
def config_changed():
|
||||
'''
|
||||
Handle config-changed
|
||||
|
||||
:returns: Whether or not relations should be notified after completion.
|
||||
:rtype: bool
|
||||
'''
|
||||
# Get the cfg object so we can see if the no-bootstrap value has changed
|
||||
# and triggered this hook invocation
|
||||
cfg = config()
|
||||
|
@ -341,8 +347,7 @@ def config_changed():
|
|||
try_disable_insecure_reclaim()
|
||||
for relid in relation_ids('dashboard'):
|
||||
dashboard_relation(relid)
|
||||
# Update client relations
|
||||
notify_client()
|
||||
return True
|
||||
|
||||
|
||||
def get_mon_hosts():
|
||||
|
@ -393,6 +398,10 @@ def bootstrap_source_relation_changed():
|
|||
the ceph-mon charm. This relation is used to exchange the remote
|
||||
ceph-public-addresses which are used for the mon's, the fsid, and the
|
||||
monitor-secret.
|
||||
|
||||
:returns: Whether or not relations should be notified after completion.
|
||||
:rtype: bool
|
||||
''
|
||||
"""
|
||||
if not config('no-bootstrap'):
|
||||
status_set('blocked', 'Cannot join the bootstrap-source relation when '
|
||||
|
@ -445,7 +454,7 @@ def bootstrap_source_relation_changed():
|
|||
# The leader unit needs to bootstrap itself as it won't receive the
|
||||
# leader-settings-changed hook elsewhere.
|
||||
if curr_fsid:
|
||||
mon_relation()
|
||||
return mon_relation()
|
||||
|
||||
|
||||
@hooks.hook('prometheus-relation-joined',
|
||||
|
@ -488,6 +497,12 @@ def prometheus_left():
|
|||
'leader-settings-changed',
|
||||
'bootstrap-source-relation-departed')
|
||||
def mon_relation():
|
||||
'''
|
||||
Handle the mon relation
|
||||
|
||||
:returns: Whether or not relations should be notified after completion.
|
||||
:rtype: bool
|
||||
'''
|
||||
if leader_get('monitor-secret') is None:
|
||||
log('still waiting for leader to setup keys')
|
||||
status_set('waiting', 'Waiting for leader to setup keys')
|
||||
|
@ -503,9 +518,11 @@ def mon_relation():
|
|||
# the unit handling the broker request will update a nonce on the
|
||||
# mon relation.
|
||||
notify_relations()
|
||||
return True
|
||||
else:
|
||||
if attempt_mon_cluster_bootstrap():
|
||||
notify_relations()
|
||||
return True
|
||||
else:
|
||||
log('Not enough mons ({}), punting.'
|
||||
.format(len(get_mon_hosts())))
|
||||
|
@ -578,7 +595,6 @@ def attempt_mon_cluster_bootstrap():
|
|||
def notify_relations():
|
||||
notify_osds()
|
||||
notify_radosgws()
|
||||
notify_client()
|
||||
notify_rbd_mirrors()
|
||||
notify_prometheus()
|
||||
|
||||
|
@ -613,79 +629,6 @@ def notify_rbd_mirrors():
|
|||
rbd_mirror_relation(relid=relid, unit=unit, recurse=False)
|
||||
|
||||
|
||||
def _get_ceph_info_from_configs():
|
||||
"""Create dictionary of ceph information required to set client relation.
|
||||
|
||||
:returns: Dictionary of ceph configurations needed for client relation
|
||||
:rtpe: dict
|
||||
"""
|
||||
public_addr = get_public_addr()
|
||||
rbd_features = get_rbd_features()
|
||||
data = {
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': public_addr
|
||||
}
|
||||
if rbd_features:
|
||||
data['rbd-features'] = rbd_features
|
||||
return data
|
||||
|
||||
|
||||
def _handle_client_relation(relid, unit, data=None):
|
||||
"""Handle broker request and set the relation data
|
||||
|
||||
:param relid: Relation ID
|
||||
:type relid: str
|
||||
:param unit: Unit name
|
||||
:type unit: str
|
||||
:param data: Initial relation data
|
||||
:type data: dict
|
||||
"""
|
||||
if data is None:
|
||||
data = {}
|
||||
|
||||
if is_unsupported_cmr(unit):
|
||||
return
|
||||
data.update(
|
||||
handle_broker_request(relid, unit, add_legacy_response=True))
|
||||
relation_set(relation_id=relid, relation_settings=data)
|
||||
|
||||
|
||||
def notify_client():
|
||||
send_osd_settings()
|
||||
if not ready_for_service():
|
||||
log("mon cluster is not in quorum, skipping notify_client",
|
||||
level=WARNING)
|
||||
return
|
||||
|
||||
for relid in relation_ids('client'):
|
||||
data = _get_ceph_info_from_configs()
|
||||
|
||||
service_name = None
|
||||
# Loop through all related units until client application name is found
|
||||
# This is done in seperate loop to avoid calling ceph to retreive named
|
||||
# key for every unit
|
||||
for unit in related_units(relid):
|
||||
service_name = get_client_application_name(relid, unit)
|
||||
if service_name:
|
||||
data.update({'key': ceph.get_named_key(service_name)})
|
||||
break
|
||||
|
||||
if not service_name:
|
||||
log('Unable to determine remote service name, deferring processing'
|
||||
' of broker requests for relation {} '.format(relid))
|
||||
# continue with next relid
|
||||
continue
|
||||
|
||||
for unit in related_units(relid):
|
||||
_handle_client_relation(relid, unit, data)
|
||||
|
||||
for relid in relation_ids('admin'):
|
||||
admin_relation_joined(relid)
|
||||
for relid in relation_ids('mds'):
|
||||
for unit in related_units(relid):
|
||||
mds_relation_joined(relid=relid, unit=unit)
|
||||
|
||||
|
||||
def req_already_treated(request_id, relid, req_unit):
|
||||
"""Check if broker request already handled.
|
||||
|
||||
|
@ -911,7 +854,6 @@ def osd_relation(relid=None, unit=None):
|
|||
# NOTE: radosgw key provision is gated on presence of OSD
|
||||
# units so ensure that any deferred hooks are processed
|
||||
notify_radosgws()
|
||||
notify_client()
|
||||
notify_rbd_mirrors()
|
||||
send_osd_settings()
|
||||
|
||||
|
@ -1036,6 +978,16 @@ def radosgw_relation(relid=None, unit=None):
|
|||
@hooks.hook('rbd-mirror-relation-joined')
|
||||
@hooks.hook('rbd-mirror-relation-changed')
|
||||
def rbd_mirror_relation(relid=None, unit=None, recurse=True):
|
||||
'''
|
||||
Handle the rbd mirror relation
|
||||
|
||||
:param recurse: Whether we should call out to update relation functions or
|
||||
not. Mainly used to handle recursion when called from
|
||||
notify_rbd_mirrors()
|
||||
:type recurse: bool
|
||||
:returns: Whether or not relations should be notified after completion.
|
||||
:rtype: bool
|
||||
'''
|
||||
if ready_for_service():
|
||||
log('mon cluster in quorum and osds bootstrapped '
|
||||
'- providing rbd-mirror client with keys')
|
||||
|
@ -1071,7 +1023,7 @@ def rbd_mirror_relation(relid=None, unit=None, recurse=True):
|
|||
# make sure clients are updated with the appropriate RBD features
|
||||
# bitmap.
|
||||
if recurse:
|
||||
notify_client()
|
||||
return True
|
||||
|
||||
|
||||
@hooks.hook('mds-relation-changed')
|
||||
|
@ -1117,26 +1069,6 @@ def admin_relation_joined(relid=None):
|
|||
relation_settings=data)
|
||||
|
||||
|
||||
@hooks.hook('client-relation-changed')
|
||||
@hooks.hook('client-relation-joined')
|
||||
def client_relation(relid=None, unit=None):
|
||||
send_osd_settings()
|
||||
if ready_for_service():
|
||||
log('mon cluster in quorum and osds bootstrapped '
|
||||
'- providing client with keys, processing broker requests')
|
||||
if not unit:
|
||||
unit = remote_unit()
|
||||
service_name = get_client_application_name(relid, unit)
|
||||
if not service_name:
|
||||
log('Unable to determine remote service name, deferring '
|
||||
'processing of broker requests for relation {} '
|
||||
'remote unit {}'.format(relid, unit))
|
||||
return
|
||||
data = _get_ceph_info_from_configs()
|
||||
data.update({'key': ceph.get_named_key(service_name)})
|
||||
_handle_client_relation(relid, unit, data)
|
||||
|
||||
|
||||
@hooks.hook('upgrade-charm.real')
|
||||
@harden()
|
||||
def upgrade_charm():
|
||||
|
|
82
src/charm.py
82
src/charm.py
|
@ -7,15 +7,35 @@ import ceph_status
|
|||
import charms.operator_libs_linux.v0.apt as apt
|
||||
import charms.operator_libs_linux.v1.systemd as systemd
|
||||
|
||||
from ops.charm import CharmEvents
|
||||
from ops.framework import EventBase, EventSource
|
||||
|
||||
import ops_openstack.core
|
||||
import charms_ceph.utils as ceph
|
||||
|
||||
from charms_ceph.broker import (
|
||||
process_requests
|
||||
)
|
||||
import ceph_hooks as hooks
|
||||
import ceph_client
|
||||
import ceph_metrics
|
||||
|
||||
import ops_actions
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NotifyClientEvent(EventBase):
|
||||
def __init__(self, handle):
|
||||
super().__init__(handle)
|
||||
|
||||
|
||||
class CephCharmEvents(CharmEvents):
|
||||
"""Custom charm events."""
|
||||
|
||||
notify_clients = EventSource(NotifyClientEvent)
|
||||
|
||||
|
||||
class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
||||
|
||||
release = 'quincy'
|
||||
|
@ -25,6 +45,8 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
'radosgw', 'lvm2', 'parted', 'smartmontools',
|
||||
]
|
||||
|
||||
on = CephCharmEvents()
|
||||
|
||||
# General charm control callbacks.
|
||||
|
||||
# TODO: Figure out how to do hardening in an operator-framework
|
||||
|
@ -43,7 +65,8 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
pass
|
||||
|
||||
def on_config(self, event):
|
||||
hooks.config_changed()
|
||||
if hooks.config_changed():
|
||||
self.on.notify_clients.emit()
|
||||
|
||||
def on_pre_series_upgrade(self, event):
|
||||
hooks.pre_series_upgrade()
|
||||
|
@ -51,6 +74,7 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
def on_upgrade(self, event):
|
||||
self.metrics_endpoint.update_alert_rules()
|
||||
hooks.upgrade_charm()
|
||||
self.on.notify_clients.emit()
|
||||
|
||||
def on_post_series_upgrade(self, event):
|
||||
hooks.post_series_upgrade()
|
||||
|
@ -60,7 +84,8 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
hooks.mon_relation_joined()
|
||||
|
||||
def on_bootstrap_source_relation_changed(self, event):
|
||||
hooks.bootstrap_source_relation_changed()
|
||||
if hooks.bootstrap_source_relation_changed():
|
||||
self.on.notify_clients.emit()
|
||||
|
||||
def on_prometheus_relation_joined_or_changed(self, event):
|
||||
hooks.prometheus_relation()
|
||||
|
@ -69,10 +94,12 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
hooks.prometheus_left()
|
||||
|
||||
def on_mon_relation(self, event):
|
||||
hooks.mon_relation()
|
||||
if hooks.mon_relation():
|
||||
self.on.notify_clients.emit()
|
||||
|
||||
def on_osd_relation(self, event):
|
||||
hooks.osd_relation()
|
||||
self.on.notify_clients.emit()
|
||||
|
||||
def on_dashboard_relation_joined(self, event):
|
||||
hooks.dashboard_relation()
|
||||
|
@ -81,7 +108,8 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
hooks.radosgw_relation()
|
||||
|
||||
def on_rbd_mirror_relation(self, event):
|
||||
hooks.rbd_mirror_relation()
|
||||
if hooks.rbd_mirror_relation():
|
||||
self.on.notify_clients.emit()
|
||||
|
||||
def on_mds_relation(self, event):
|
||||
hooks.mds_relation_joined()
|
||||
|
@ -89,9 +117,6 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
def on_admin_relation(self, event):
|
||||
hooks.admin_relation_joined()
|
||||
|
||||
def on_client_relation(self, event):
|
||||
hooks.client_relation()
|
||||
|
||||
def on_nrpe_relation(self, event):
|
||||
hooks.update_nrpe_config()
|
||||
|
||||
|
@ -122,6 +147,16 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
remote_block = not self.config['permit-insecure-cmr']
|
||||
return remote_block
|
||||
|
||||
def notify_clients(self, _event):
|
||||
self.clients.notify_all()
|
||||
for relation in self.model.relations['admin']:
|
||||
hooks.admin_relation_joined(str(relation.id))
|
||||
|
||||
for relation in self.model.relations['mds']:
|
||||
for unit in relation.units:
|
||||
hooks.mds_relation_joined(
|
||||
relid=str(relation.id), unit=unit.name)
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
self._stored.is_started = True
|
||||
|
@ -133,6 +168,7 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
|
||||
fw = self.framework
|
||||
|
||||
self.clients = ceph_client.CephClientProvides(self)
|
||||
self.metrics_endpoint = ceph_metrics.CephMetricsEndpointProvider(self)
|
||||
self.ceph_status = ceph_status.StatusAssessor(self)
|
||||
|
||||
|
@ -190,16 +226,36 @@ class CephMonCharm(ops_openstack.core.OSBaseCharm):
|
|||
fw.observe(self.on.admin_relation_joined,
|
||||
self.on_admin_relation)
|
||||
|
||||
fw.observe(self.on.client_relation_changed,
|
||||
self.on_client_relation)
|
||||
fw.observe(self.on.client_relation_joined,
|
||||
self.on_client_relation)
|
||||
|
||||
fw.observe(self.on.nrpe_external_master_relation_joined,
|
||||
self.on_nrpe_relation)
|
||||
fw.observe(self.on.nrpe_external_master_relation_changed,
|
||||
self.on_nrpe_relation)
|
||||
|
||||
fw.observe(self.on.notify_clients, self.notify_clients)
|
||||
|
||||
def ready_for_service(self):
|
||||
return hooks.ready_for_service()
|
||||
|
||||
def process_broker_request(self, broker_req_id, requests, recurse=True):
|
||||
broker_result = process_requests(requests)
|
||||
if hooks.relation_ids('rbd-mirror'):
|
||||
# NOTE(fnordahl): juju relation level data candidate
|
||||
# notify mons to flag that the other mon units should update
|
||||
# their ``rbd-mirror`` relations with information about new
|
||||
# pools.
|
||||
logger.debug('Notifying peers after processing broker'
|
||||
'request {}.'.format(broker_req_id))
|
||||
hooks.notify_mons()
|
||||
# notify_rbd_mirrors is the only case where this is False
|
||||
if recurse:
|
||||
# update ``rbd-mirror`` relations for this unit with
|
||||
# information about new pools.
|
||||
logger.debug(
|
||||
'Notifying this units rbd-mirror relations after '
|
||||
'processing broker request {}.'.format(broker_req_id))
|
||||
hooks.notify_rbd_mirrors()
|
||||
return broker_result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(CephMonCharm)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2022 Canonical Ltd
|
||||
#
|
||||
# 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.
|
||||
|
||||
import unittest.mock as mock
|
||||
from ops.testing import Harness
|
||||
with mock.patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec:
|
||||
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||
lambda *args, **kwargs: f(*args, **kwargs))
|
||||
# src.charm imports ceph_hooks, so we need to workaround the inclusion
|
||||
# of the 'harden' decorator.
|
||||
from src.charm import CephMonCharm
|
||||
|
||||
|
||||
relation_id = int
|
||||
|
||||
|
||||
def add_ceph_client_relation(harness: Harness[CephMonCharm]) -> relation_id:
|
||||
rel_id = harness.add_relation(
|
||||
'client',
|
||||
'glance')
|
||||
harness.add_relation_unit(
|
||||
rel_id,
|
||||
'glance/0')
|
||||
harness.update_relation_data(
|
||||
rel_id,
|
||||
'glance/0',
|
||||
{'ingress-address': '10.0.0.3'})
|
||||
return rel_id
|
||||
|
||||
|
||||
def add_ceph_mds_relation(harness: Harness[CephMonCharm]) -> relation_id:
|
||||
rel_id = harness.add_relation(
|
||||
'mds',
|
||||
'ceph-fs')
|
||||
harness.add_relation_unit(
|
||||
rel_id,
|
||||
'ceph-fs/0')
|
||||
harness.update_relation_data(
|
||||
rel_id,
|
||||
'ceph-fs/0',
|
||||
{'ingress-address': '10.0.0.3'})
|
||||
return rel_id
|
|
@ -0,0 +1,158 @@
|
|||
# Copyright 2022 Canonical Ltd
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Tests for reweight_osd action."""
|
||||
|
||||
# import json
|
||||
import unittest.mock as mock
|
||||
from test_utils import CharmTestCase
|
||||
from ops.testing import Harness
|
||||
from manage_test_relations import (
|
||||
add_ceph_client_relation,
|
||||
add_ceph_mds_relation,
|
||||
)
|
||||
|
||||
with mock.patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec:
|
||||
mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f:
|
||||
lambda *args, **kwargs: f(*args, **kwargs))
|
||||
# src.charm imports ceph_hooks, so we need to workaround the inclusion
|
||||
# of the 'harden' decorator.
|
||||
from src.charm import CephMonCharm
|
||||
|
||||
|
||||
class CephClientTestCase(CharmTestCase):
|
||||
"""Run tests for action."""
|
||||
|
||||
def setUp(self):
|
||||
self.harness = Harness(CephMonCharm)
|
||||
self.addCleanup(self.harness.cleanup)
|
||||
|
||||
@mock.patch("src.charm.ceph_client.ceph.get_named_key")
|
||||
@mock.patch("src.charm.ceph_client.get_rbd_features")
|
||||
@mock.patch("src.charm.ceph_client.get_public_addr")
|
||||
@mock.patch.object(CephMonCharm, "ready_for_service")
|
||||
@mock.patch("src.charm.ceph_client.send_osd_settings")
|
||||
def test_client_relation(
|
||||
self, _send_osd_settings, mock_ready_for_service,
|
||||
mock_get_public_addr, mock_get_rbd_features, mock_get_named_key):
|
||||
mock_get_public_addr.return_value = '127.0.0.1'
|
||||
mock_ready_for_service.return_value = True
|
||||
mock_get_rbd_features.return_value = 42
|
||||
mock_get_named_key.return_value = 'test key'
|
||||
self.harness.begin()
|
||||
self.harness.set_leader()
|
||||
rel_id = add_ceph_client_relation(self.harness)
|
||||
unit_rel_data = self.harness.get_relation_data(
|
||||
rel_id,
|
||||
'ceph-mon/0')
|
||||
self.assertEqual(
|
||||
unit_rel_data,
|
||||
{
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': '127.0.0.1',
|
||||
'key': 'test key',
|
||||
'rbd-features': '42',
|
||||
})
|
||||
|
||||
@mock.patch("src.charm.ceph_client.ceph.is_leader")
|
||||
@mock.patch.object(CephMonCharm, "process_broker_request")
|
||||
@mock.patch("src.charm.ceph_client.ceph.get_named_key")
|
||||
@mock.patch("src.charm.ceph_client.get_rbd_features")
|
||||
@mock.patch("src.charm.ceph_client.get_public_addr")
|
||||
@mock.patch.object(CephMonCharm, "ready_for_service")
|
||||
@mock.patch("src.charm.ceph_client.send_osd_settings")
|
||||
def test_client_relation_broker(
|
||||
self, _send_osd_settings, mock_ready_for_service,
|
||||
mock_get_public_addr, mock_get_rbd_features, mock_get_named_key,
|
||||
mock_process_broker_request, mock_is_leader):
|
||||
mock_get_public_addr.return_value = '127.0.0.1'
|
||||
mock_ready_for_service.return_value = True
|
||||
mock_get_rbd_features.return_value = 42
|
||||
mock_get_named_key.return_value = 'test key'
|
||||
mock_process_broker_request.return_value = 'AOK'
|
||||
mock_is_leader.return_value = True
|
||||
self.harness.begin()
|
||||
self.harness.set_leader()
|
||||
rel_id = add_ceph_client_relation(self.harness)
|
||||
self.harness.update_relation_data(
|
||||
rel_id,
|
||||
'glance/0',
|
||||
{'broker_req': '{"request-id": "req"}'})
|
||||
mock_process_broker_request.assert_called_once_with(
|
||||
'req', '{"request-id": "req"}'
|
||||
)
|
||||
unit_rel_data = self.harness.get_relation_data(
|
||||
rel_id,
|
||||
'ceph-mon/0')
|
||||
self.assertEqual(
|
||||
unit_rel_data,
|
||||
{
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': '127.0.0.1',
|
||||
'key': 'test key',
|
||||
'rbd-features': '42',
|
||||
'broker-rsp-glance-0': 'AOK',
|
||||
'broker_rsp': 'AOK'
|
||||
})
|
||||
mock_process_broker_request.reset_mock()
|
||||
self.harness.update_relation_data(
|
||||
rel_id,
|
||||
'glance/0',
|
||||
{'broker_req': '{"request-id": "req"}'})
|
||||
mock_process_broker_request.assert_not_called()
|
||||
|
||||
@mock.patch("src.charm.hooks.mds_relation_joined")
|
||||
@mock.patch("src.charm.ceph_client.ceph.get_named_key")
|
||||
@mock.patch("src.charm.ceph_client.get_rbd_features")
|
||||
@mock.patch("src.charm.ceph_client.get_public_addr")
|
||||
@mock.patch.object(CephMonCharm, "ready_for_service")
|
||||
@mock.patch("src.charm.ceph_client.send_osd_settings")
|
||||
def test_notify_clients(
|
||||
self, _send_osd_settings, mock_ready_for_service,
|
||||
mock_get_public_addr, mock_get_rbd_features, mock_get_named_key,
|
||||
mock_mds_relation_joined):
|
||||
mock_get_public_addr.return_value = '127.0.0.1'
|
||||
mock_ready_for_service.return_value = True
|
||||
mock_get_rbd_features.return_value = None
|
||||
mock_get_named_key.return_value = 'test key'
|
||||
self.harness.begin()
|
||||
self.harness.set_leader()
|
||||
rel_id = add_ceph_client_relation(self.harness)
|
||||
add_ceph_mds_relation(self.harness)
|
||||
|
||||
unit_rel_data = self.harness.get_relation_data(
|
||||
rel_id,
|
||||
'ceph-mon/0')
|
||||
self.assertEqual(
|
||||
unit_rel_data,
|
||||
{
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': '127.0.0.1',
|
||||
'key': 'test key',
|
||||
})
|
||||
mock_get_rbd_features.return_value = 42
|
||||
self.harness.charm.on.notify_clients.emit()
|
||||
unit_rel_data = self.harness.get_relation_data(
|
||||
rel_id,
|
||||
'ceph-mon/0')
|
||||
self.assertEqual(
|
||||
unit_rel_data,
|
||||
{
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': '127.0.0.1',
|
||||
'key': 'test key',
|
||||
'rbd-features': '42',
|
||||
})
|
||||
|
||||
mock_mds_relation_joined.assert_called_with(
|
||||
relid='1', unit='ceph-fs/0')
|
|
@ -214,12 +214,10 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
@patch.object(ceph_hooks, 'service_pause')
|
||||
@patch.object(ceph_hooks, 'notify_radosgws')
|
||||
@patch.object(ceph_hooks, 'ceph')
|
||||
@patch.object(ceph_hooks, 'notify_client')
|
||||
@patch.object(ceph_hooks, 'config')
|
||||
def test_upgrade_charm_with_nrpe_relation_installs_dependencies(
|
||||
self,
|
||||
mock_config,
|
||||
mock_notify_client,
|
||||
mock_ceph,
|
||||
mock_notify_radosgws,
|
||||
mock_service_pause,
|
||||
|
@ -242,88 +240,11 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
ceph_hooks.upgrade_charm()
|
||||
mocks["apt_install"].assert_called_with(
|
||||
["python-dbus", "lockfile-progs"])
|
||||
mock_notify_client.assert_called_once_with()
|
||||
mock_notify_radosgws.assert_called_once_with()
|
||||
mock_ceph.update_monfs.assert_called_once_with()
|
||||
mock_notify_prometheus.assert_called_once_with()
|
||||
mock_service_pause.assert_called_with('ceph-create-keys')
|
||||
|
||||
@patch.object(ceph_hooks, 'relation_get')
|
||||
@patch.object(ceph_hooks, 'mds_relation_joined')
|
||||
@patch.object(ceph_hooks, 'admin_relation_joined')
|
||||
@patch.object(ceph_hooks, 'relation_set')
|
||||
@patch.object(ceph_hooks, 'handle_broker_request')
|
||||
@patch.object(ceph_hooks, 'config')
|
||||
@patch.object(ceph_hooks, 'related_units')
|
||||
@patch.object(ceph_hooks.ceph, 'get_named_key')
|
||||
@patch.object(ceph_hooks.hookenv, 'remote_service_name')
|
||||
@patch.object(ceph_hooks, 'relation_ids')
|
||||
@patch.object(ceph_hooks.ceph, 'is_leader')
|
||||
@patch.object(ceph_hooks, 'get_rbd_features')
|
||||
@patch.object(ceph_hooks, 'get_public_addr')
|
||||
@patch.object(ceph_hooks, 'ready_for_service')
|
||||
@patch.object(ceph_hooks, 'send_osd_settings')
|
||||
def test_notify_client(self,
|
||||
_send_osd_settings,
|
||||
_ready_for_service,
|
||||
_get_public_addr,
|
||||
_get_rbd_features,
|
||||
_is_leader,
|
||||
_relation_ids,
|
||||
_remote_service_name,
|
||||
_get_named_key,
|
||||
_related_units,
|
||||
_config,
|
||||
_handle_broker_request,
|
||||
_relation_set,
|
||||
_admin_relation_joined,
|
||||
_mds_relation_joined,
|
||||
_relation_get):
|
||||
_relation_ids.return_value = ['arelid']
|
||||
_related_units.return_value = ['aunit/0']
|
||||
_relation_get.return_value = {'application-name': 'aunit'}
|
||||
_remote_service_name.return_value = 'aunit'
|
||||
_is_leader.return_value = True
|
||||
config = copy.deepcopy(CHARM_CONFIG)
|
||||
_config.side_effect = lambda key: config[key]
|
||||
_handle_broker_request.return_value = {}
|
||||
_get_rbd_features.return_value = None
|
||||
|
||||
ceph_hooks.notify_client()
|
||||
_send_osd_settings.assert_called_once_with()
|
||||
_ready_for_service.assert_called_once_with()
|
||||
_get_public_addr.assert_called_once_with()
|
||||
_get_named_key.assert_called_once_with('aunit')
|
||||
_handle_broker_request.assert_called_once_with(
|
||||
'arelid', 'aunit/0', add_legacy_response=True)
|
||||
_relation_set.assert_called_once_with(
|
||||
relation_id='arelid',
|
||||
relation_settings={
|
||||
'key': _get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': _get_public_addr()
|
||||
})
|
||||
|
||||
_relation_ids.assert_has_calls([
|
||||
call('admin'),
|
||||
call('mds'),
|
||||
])
|
||||
_admin_relation_joined.assert_called_once_with('arelid')
|
||||
_mds_relation_joined.assert_called_once_with(relid='arelid',
|
||||
unit='aunit/0')
|
||||
|
||||
_get_rbd_features.return_value = 42
|
||||
_relation_set.reset_mock()
|
||||
ceph_hooks.notify_client()
|
||||
_relation_set.assert_called_once_with(
|
||||
relation_id='arelid',
|
||||
relation_settings={
|
||||
'key': _get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': _get_public_addr(),
|
||||
'rbd-features': 42,
|
||||
})
|
||||
|
||||
@patch.object(ceph_hooks, 'rbd_mirror_relation')
|
||||
@patch.object(ceph_hooks, 'related_units')
|
||||
@patch.object(ceph_hooks, 'relation_ids')
|
||||
|
@ -389,7 +310,6 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
ceph_hooks.get_client_application_name('rel:1', None),
|
||||
'glance')
|
||||
|
||||
@patch.object(ceph_hooks, 'notify_client')
|
||||
@patch.object(ceph_hooks.ceph, 'list_pools')
|
||||
@patch.object(ceph_hooks, 'mgr_enable_module')
|
||||
@patch.object(ceph_hooks, 'emit_cephconf')
|
||||
|
@ -406,15 +326,13 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
create_sysctl,
|
||||
emit_ceph_conf,
|
||||
mgr_enable_module,
|
||||
list_pools,
|
||||
notify_client):
|
||||
list_pools):
|
||||
relations_of_type.return_value = False
|
||||
self.test_config.set('pg-autotune', 'false')
|
||||
self.test_config.set('balancer-mode', '')
|
||||
ceph_hooks.config_changed()
|
||||
mgr_enable_module.assert_not_called()
|
||||
|
||||
@patch.object(ceph_hooks, 'notify_client')
|
||||
@patch.object(ceph_hooks.ceph, 'monitor_key_set')
|
||||
@patch.object(ceph_hooks.ceph, 'list_pools')
|
||||
@patch.object(ceph_hooks, 'mgr_enable_module')
|
||||
|
@ -435,8 +353,7 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
emit_ceph_conf,
|
||||
mgr_enable_module,
|
||||
list_pools,
|
||||
monitor_key_set,
|
||||
notify_client):
|
||||
monitor_key_set):
|
||||
relations_of_type.return_value = False
|
||||
cmp_pkgrevno.return_value = 1
|
||||
self.test_config.set('pg-autotune', 'true')
|
||||
|
@ -445,7 +362,6 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
mgr_enable_module.assert_called_once_with('pg_autoscaler')
|
||||
monitor_key_set.assert_called_once_with('admin', 'autotune', 'true')
|
||||
|
||||
@patch.object(ceph_hooks, 'notify_client')
|
||||
@patch.object(ceph_hooks.ceph, 'list_pools')
|
||||
@patch.object(ceph_hooks, 'mgr_enable_module')
|
||||
@patch.object(ceph_hooks, 'emit_cephconf')
|
||||
|
@ -464,8 +380,7 @@ class CephHooksTestCase(test_utils.CharmTestCase):
|
|||
create_sysctl,
|
||||
emit_ceph_conf,
|
||||
mgr_enable_module,
|
||||
list_pools,
|
||||
notify_client):
|
||||
list_pools):
|
||||
relations_of_type.return_value = False
|
||||
cmp_pkgrevno.return_value = 1
|
||||
self.test_config.set('pg-autotune', 'auto')
|
||||
|
@ -593,130 +508,6 @@ class RelatedUnitsTestCase(unittest.TestCase):
|
|||
call('osd:23')
|
||||
])
|
||||
|
||||
@patch.object(ceph_hooks, 'send_osd_settings')
|
||||
@patch.object(ceph_hooks, 'get_rbd_features')
|
||||
@patch.object(ceph_hooks, 'relation_set')
|
||||
@patch.object(ceph_hooks, 'handle_broker_request')
|
||||
@patch.object(ceph_hooks, 'config')
|
||||
@patch.object(ceph_hooks.ceph, 'get_named_key')
|
||||
@patch.object(ceph_hooks, 'get_public_addr')
|
||||
@patch.object(ceph_hooks, 'get_client_application_name')
|
||||
@patch.object(ceph_hooks, 'ready_for_service')
|
||||
def test_client_relation(self,
|
||||
_ready_for_service,
|
||||
_get_client_application_name,
|
||||
_get_public_addr,
|
||||
_get_named_key,
|
||||
_config,
|
||||
_handle_broker_request,
|
||||
_relation_set,
|
||||
_get_rbd_features,
|
||||
_send_osd_settings):
|
||||
_get_client_application_name.return_value = 'glance'
|
||||
config = copy.deepcopy(CHARM_CONFIG)
|
||||
_config.side_effect = lambda key: config[key]
|
||||
_handle_broker_request.return_value = {}
|
||||
_get_rbd_features.return_value = None
|
||||
ceph_hooks.client_relation(relid='rel1', unit='glance/0')
|
||||
_ready_for_service.assert_called_once_with()
|
||||
_send_osd_settings.assert_called_once_with()
|
||||
_get_public_addr.assert_called_once_with()
|
||||
_get_named_key.assert_called_once_with('glance')
|
||||
_handle_broker_request.assert_called_once_with(
|
||||
'rel1', 'glance/0', add_legacy_response=True)
|
||||
_relation_set.assert_called_once_with(
|
||||
relation_id='rel1',
|
||||
relation_settings={
|
||||
'key': _get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': _get_public_addr()
|
||||
})
|
||||
_get_rbd_features.return_value = 42
|
||||
_relation_set.reset_mock()
|
||||
ceph_hooks.client_relation(relid='rel1', unit='glance/0')
|
||||
_relation_set.assert_called_once_with(
|
||||
relation_id='rel1',
|
||||
relation_settings={
|
||||
'key': _get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': _get_public_addr(),
|
||||
'rbd-features': 42,
|
||||
})
|
||||
|
||||
@patch.object(ceph_hooks, 'req_already_treated')
|
||||
@patch.object(ceph_hooks, 'send_osd_settings')
|
||||
@patch.object(ceph_hooks, 'get_rbd_features')
|
||||
@patch.object(ceph_hooks, 'config')
|
||||
@patch.object(ceph_hooks.ceph, 'get_named_key')
|
||||
@patch.object(ceph_hooks, 'get_public_addr')
|
||||
@patch.object(ceph_hooks.hookenv, 'remote_service_name')
|
||||
@patch.object(ceph_hooks, 'relation_ids', return_value=[])
|
||||
@patch.object(ceph_hooks, 'ready_for_service')
|
||||
@patch.object(ceph_hooks.ceph, 'is_quorum')
|
||||
@patch.object(ceph_hooks, 'remote_unit')
|
||||
@patch.object(ceph_hooks, 'relation_get')
|
||||
@patch.object(ceph_hooks.ceph, 'is_leader')
|
||||
@patch.object(ceph_hooks, 'process_requests')
|
||||
@patch.object(ceph_hooks, 'relation_set')
|
||||
def test_client_relation_non_rel_hook(self, relation_set,
|
||||
process_requests,
|
||||
is_leader,
|
||||
relation_get,
|
||||
remote_unit,
|
||||
is_quorum,
|
||||
ready_for_service,
|
||||
relation_ids,
|
||||
remote_service_name,
|
||||
get_public_addr,
|
||||
get_named_key,
|
||||
_config,
|
||||
_get_rbd_features,
|
||||
_send_osd_settings,
|
||||
req_already_treated):
|
||||
# Check for LP #1738154
|
||||
ready_for_service.return_value = True
|
||||
process_requests.return_value = 'AOK'
|
||||
is_leader.return_value = True
|
||||
relation_get.return_value = {'broker_req': '{"request-id": "req"}'}
|
||||
remote_unit.return_value = None
|
||||
is_quorum.return_value = True
|
||||
config = copy.deepcopy(CHARM_CONFIG)
|
||||
_config.side_effect = lambda key: config[key]
|
||||
_get_rbd_features.return_value = None
|
||||
req_already_treated.return_value = False
|
||||
ceph_hooks.client_relation(relid='rel1', unit='glance/0')
|
||||
_send_osd_settings.assert_called_once_with()
|
||||
relation_set.assert_called_once_with(
|
||||
relation_id='rel1',
|
||||
relation_settings={
|
||||
'key': get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': get_public_addr(),
|
||||
'broker-rsp-glance-0': 'AOK',
|
||||
'broker_rsp': 'AOK'})
|
||||
relation_set.reset_mock()
|
||||
remote_unit.return_value = 'glance/0'
|
||||
ceph_hooks.client_relation()
|
||||
relation_set.assert_called_once_with(
|
||||
relation_id=None,
|
||||
relation_settings={
|
||||
'key': get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': get_public_addr(),
|
||||
'broker-rsp-glance-0': 'AOK',
|
||||
'broker_rsp': 'AOK'})
|
||||
|
||||
# Verify relation_set when broker request is already treated
|
||||
relation_set.reset_mock()
|
||||
req_already_treated.return_value = True
|
||||
ceph_hooks.client_relation(relid='rel1', unit='glance/0')
|
||||
relation_set.assert_called_once_with(
|
||||
relation_id='rel1',
|
||||
relation_settings={
|
||||
'key': get_named_key(),
|
||||
'auth': 'cephx',
|
||||
'ceph-public-address': get_public_addr()})
|
||||
|
||||
@patch.object(ceph_hooks, 'req_already_treated')
|
||||
@patch.object(ceph_hooks, 'relation_ids')
|
||||
@patch.object(ceph_hooks, 'notify_mons')
|
||||
|
@ -880,7 +671,6 @@ class BootstrapSourceTestCase(test_utils.CharmTestCase):
|
|||
self.assertRaises(AssertionError,
|
||||
ceph_hooks.bootstrap_source_relation_changed)
|
||||
|
||||
@patch.object(ceph_hooks, 'notify_client')
|
||||
@patch.object(ceph_hooks.ceph, 'is_bootstrapped')
|
||||
@patch.object(ceph_hooks, 'emit_cephconf')
|
||||
@patch.object(ceph_hooks, 'leader_get')
|
||||
|
@ -897,8 +687,7 @@ class BootstrapSourceTestCase(test_utils.CharmTestCase):
|
|||
_is_leader,
|
||||
_leader_get,
|
||||
_emit_cephconf,
|
||||
_is_bootstrapped,
|
||||
_notify_client):
|
||||
_is_bootstrapped):
|
||||
config = copy.deepcopy(CHARM_CONFIG)
|
||||
_config.side_effect = \
|
||||
lambda key=None: config.get(key, None) if key else config
|
||||
|
@ -915,7 +704,6 @@ class BootstrapSourceTestCase(test_utils.CharmTestCase):
|
|||
])
|
||||
_emit_cephconf.assert_called_once_with()
|
||||
_is_bootstrapped.assert_called_once_with()
|
||||
_notify_client.assert_called_once_with()
|
||||
|
||||
@patch.object(ceph_hooks, 'emit_cephconf')
|
||||
@patch.object(ceph_hooks, 'create_sysctl')
|
||||
|
@ -1086,9 +874,7 @@ class RBDMirrorRelationTestCase(test_utils.CharmTestCase):
|
|||
self.ceph.list_pools_detail.return_value = {'pool': {}}
|
||||
|
||||
@patch.object(ceph_hooks, 'retrieve_client_broker_requests')
|
||||
@patch.object(ceph_hooks, 'notify_client')
|
||||
def test_rbd_mirror_relation(self,
|
||||
_notify_client,
|
||||
_retrieve_client_broker_requests):
|
||||
self.handle_broker_request.return_value = {}
|
||||
base_relation_settings = {
|
||||
|
@ -1112,8 +898,6 @@ class RBDMirrorRelationTestCase(test_utils.CharmTestCase):
|
|||
relation_settings=base_relation_settings)
|
||||
self.test_relation.set(
|
||||
{'unique_id': None})
|
||||
_notify_client.assert_called_once_with()
|
||||
_notify_client.reset_mock()
|
||||
ceph_hooks.rbd_mirror_relation('rbd-mirror:52', 'ceph-rbd-mirror/0',
|
||||
recurse=False)
|
||||
self.relation_set.assert_called_with(
|
||||
|
@ -1121,7 +905,6 @@ class RBDMirrorRelationTestCase(test_utils.CharmTestCase):
|
|||
relation_settings=base_relation_settings)
|
||||
self.test_relation.set(
|
||||
{'unique_id': json.dumps('otherSideIsReactiveEndpoint')})
|
||||
self.assertFalse(_notify_client.called)
|
||||
ceph_hooks.rbd_mirror_relation('rbd-mirror:53', 'ceph-rbd-mirror/0')
|
||||
self.ceph.get_rbd_mirror_key.assert_called_once_with(
|
||||
'rbd-mirror.otherSideIsReactiveEndpoint')
|
||||
|
|
|
@ -24,11 +24,13 @@ class TestCephCharm(unittest.TestCase):
|
|||
self.assertTrue(self.harness.charm.metrics_endpoint)
|
||||
self.assertTrue(self.harness.charm.ceph_status)
|
||||
|
||||
@patch.object(charm.ceph_client.CephClientProvides, 'notify_all')
|
||||
@patch("charm.hooks")
|
||||
def test_on_config_changed(self, hooks):
|
||||
def test_on_config_changed(self, hooks, _notify_all):
|
||||
self.harness.update_config({"permit-insecure-cmr": None})
|
||||
hooks.config_changed.assert_called()
|
||||
|
||||
@patch.object(charm.ceph_client.CephClientProvides, 'notify_all')
|
||||
@patch("charm.ops_openstack.core.apt_install")
|
||||
@patch("charm.ops_openstack.core.apt_update")
|
||||
@patch("charm.ops_openstack.core.add_source")
|
||||
|
@ -45,6 +47,7 @@ class TestCephCharm(unittest.TestCase):
|
|||
_add_source,
|
||||
apt_update,
|
||||
apt_install,
|
||||
_notify_all
|
||||
):
|
||||
self.harness.update_config({"permit-insecure-cmr": None})
|
||||
self.harness.charm.on.install.emit()
|
||||
|
|
Loading…
Reference in New Issue