def mds_relation_joined(relid=None, unit=None): if ceph.is_quorum() and related_osds(): log('mon cluster in quorum and OSDs related' '- providing mds client with keys') mds_name = relation_get(attribute='mds-name', rid=relid, unit=unit) if not unit: unit = remote_unit() public_addr = get_public_addr() data = { 'fsid': leader_get('fsid'), 'mds_key': ceph.get_mds_key(name=mds_name), 'auth': config('auth-supported'), 'ceph-public-address': public_addr } settings = relation_get(rid=relid, unit=unit) """Process broker request(s).""" if 'broker_req' in settings: if ceph.is_leader(): rsp = process_requests(settings['broker_req']) unit_id = unit.replace('/', '-') unit_response_key = 'broker-rsp-' + unit_id data[unit_response_key] = rsp else: log("Not leader - ignoring mds broker request", level=DEBUG) relation_set(relation_id=relid, relation_settings=data) else: log('Waiting on mon quorum or min osds before provisioning mds keys')
def radosgw_relation(relid=None, unit=None): # Install radosgw for admin tools apt_install(packages=filter_installed_packages(['radosgw'])) if not unit: unit = remote_unit() # NOTE: radosgw needs some usage OSD storage, so defer key # provision until OSD units are detected. if ceph.is_quorum() and related_osds(): log('mon cluster in quorum and osds related ' '- providing radosgw with keys') public_addr = get_public_addr() data = { 'fsid': leader_get('fsid'), 'radosgw_key': ceph.get_radosgw_key(), 'auth': config('auth-supported'), 'ceph-public-address': public_addr, } settings = relation_get(rid=relid, unit=unit) """Process broker request(s).""" if 'broker_req' in settings: if ceph.is_leader(): rsp = process_requests(settings['broker_req']) unit_id = unit.replace('/', '-') unit_response_key = 'broker-rsp-' + unit_id data[unit_response_key] = rsp else: log("Not leader - ignoring broker request", level=DEBUG) relation_set(relation_id=relid, relation_settings=data) else: log('mon cluster not in quorum or no osds - deferring key provision')
def test_set_invalid_pool_value(self): reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'set-pool-value', 'name': 'foo', 'key': 'size', 'value': 'abc', }]}) rc = broker.process_requests(reqs) self.assertEqual(json.loads(rc)['exit-code'], 1)
def test_process_requests_delete_pool(self, mock_delete_pool): reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'delete-pool', 'name': 'foo', }]}) mock_delete_pool.return_value = {'exit-code': 0} rc = broker.process_requests(reqs) mock_delete_pool.assert_called_with(service='admin', name='foo') self.assertEqual(json.loads(rc), {'exit-code': 0})
def handle_broker_request(relid, unit, add_legacy_response=False, recurse=True): """Retrieve broker request from relation, process, return response data. :param relid: Realtion ID :type relid: str :param unit: Remote unit name :type unit: str :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 :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: Dictionary of response data ready for use with relation_set. :rtype: dict """ response = {} if not unit: unit = remote_unit() settings = relation_get(rid=relid, unit=unit) if 'broker_req' in settings: if not ceph.is_leader(): log("Not leader - ignoring broker request", level=DEBUG) else: rsp = process_requests(settings['broker_req']) unit_id = unit.replace('/', '-') unit_response_key = 'broker-rsp-' + unit_id response.update({unit_response_key: rsp}) if add_legacy_response: response.update({'broker_rsp': rsp}) if 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. log('Notifying peers after processing broker request.', level=DEBUG) notify_mons() if recurse: # update ``rbd-mirror`` relations for this unit with # information about new pools. log( 'Notifying this units rbd-mirror relations after ' 'processing broker request.', level=DEBUG) notify_rbd_mirrors() return response
def test_process_requests_delete_pool(self, mock_delete_pool): reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'delete-pool', 'name': 'foo', }] }) mock_delete_pool.return_value = {'exit-code': 0} rc = broker.process_requests(reqs) mock_delete_pool.assert_called_with(service='admin', name='foo') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_remove_pool_snapshot(self, mock_snapshot_pool): reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'remove-pool-snapshot', 'name': 'foo', 'snapshot-name': 'foo-snap1', }]}) mock_snapshot_pool.return_value = {'exit-code': 0} rc = broker.process_requests(reqs) mock_snapshot_pool.assert_called_with(service='admin', pool_name='foo', snapshot_name='foo-snap1') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_remove_cache_tier(self, mock_pool, mock_pool_exists): mock_pool_exists.return_value = True reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'remove-cache-tier', 'hot-pool': 'foo-ssd', }]}) rc = broker.process_requests(reqs) mock_pool_exists.assert_any_call(service='admin', name='foo-ssd') mock_pool.assert_called_with(cache_pool='foo-ssd') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_set_invalid_pool_value(self): reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'set-pool-value', 'name': 'foo', 'key': 'size', 'value': 'abc', }] }) rc = broker.process_requests(reqs) self.assertEqual(json.loads(rc)['exit-code'], 1)
def test_set_pool_value(self, mock_set_pool): reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'set-pool-value', 'name': 'foo', 'key': 'size', 'value': 3, }]}) mock_set_pool.return_value = {'exit-code': 0} rc = broker.process_requests(reqs) mock_set_pool.assert_called_with(service='admin', pool_name='foo', key='size', value=3) self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_create_erasure_pool(self, mock_profile_exists, mock_erasure_pool, mock_pool_exists): mock_pool_exists.return_value = False reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'create-pool', 'pool-type': 'erasure', 'name': 'foo', 'erasure-profile': 'default' }]}) rc = broker.process_requests(reqs) mock_profile_exists.assert_called_with(service='admin', name='default') mock_pool_exists.assert_called_with(service='admin', name='foo') mock_erasure_pool.assert_called_with() self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_create_replicated_pool(self, mock_replicated_pool, mock_pool_exists): mock_pool_exists.return_value = False reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'create-pool', 'pool-type': 'replicated', 'name': 'foo', 'replicas': 3 }]}) rc = broker.process_requests(reqs) mock_pool_exists.assert_called_with(service='admin', name='foo') calls = [call(name=u'foo', service='admin', replicas=3)] mock_replicated_pool.assert_has_calls(calls) self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_remove_pool_snapshot(self, mock_snapshot_pool): reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'remove-pool-snapshot', 'name': 'foo', 'snapshot-name': 'foo-snap1', }] }) mock_snapshot_pool.return_value = {'exit-code': 0} rc = broker.process_requests(reqs) mock_snapshot_pool.assert_called_with(service='admin', pool_name='foo', snapshot_name='foo-snap1') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_remove_cache_tier(self, mock_pool, mock_pool_exists): mock_pool_exists.return_value = True reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'remove-cache-tier', 'hot-pool': 'foo-ssd', }] }) rc = broker.process_requests(reqs) mock_pool_exists.assert_any_call(service='admin', name='foo-ssd') mock_pool.assert_called_with(cache_pool='foo-ssd') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_create_cache_tier(self, mock_pool, mock_pool_exists): mock_pool_exists.return_value = True reqs = json.dumps({'api-version': 1, 'ops': [{ 'op': 'create-cache-tier', 'cold-pool': 'foo', 'hot-pool': 'foo-ssd', 'mode': 'writeback', 'erasure-profile': 'default' }]}) rc = broker.process_requests(reqs) mock_pool_exists.assert_any_call(service='admin', name='foo') mock_pool_exists.assert_any_call(service='admin', name='foo-ssd') mock_pool.assert_called_with(cache_pool='foo-ssd', mode='writeback') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_set_pool_value(self, mock_set_pool): reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'set-pool-value', 'name': 'foo', 'key': 'size', 'value': 3, }] }) mock_set_pool.return_value = {'exit-code': 0} rc = broker.process_requests(reqs) mock_set_pool.assert_called_with(service='admin', pool_name='foo', key='size', value=3) self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_create_replicated_pool(self, mock_replicated_pool, mock_pool_exists): mock_pool_exists.return_value = False reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'create-pool', 'pool-type': 'replicated', 'name': 'foo', 'replicas': 3 }] }) rc = broker.process_requests(reqs) mock_pool_exists.assert_called_with(service='admin', name='foo') calls = [call(name=u'foo', service='admin', replicas=3)] mock_replicated_pool.assert_has_calls(calls) self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_create_erasure_pool(self, mock_profile_exists, mock_erasure_pool, mock_pool_exists): mock_pool_exists.return_value = False reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'create-pool', 'pool-type': 'erasure', 'name': 'foo', 'erasure-profile': 'default' }] }) rc = broker.process_requests(reqs) mock_profile_exists.assert_called_with(service='admin', name='default') mock_pool_exists.assert_called_with(service='admin', name='foo') mock_erasure_pool.assert_called_with() self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_create_erasure_profile(self, mock_create_erasure): req = json.dumps({'api-version': 1, 'ops': [{ 'op': 'create-erasure-profile', 'name': 'foo', 'erasure-type': 'jerasure', 'failure-domain': 'rack', 'k': 3, 'm': 2, }]}) rc = broker.process_requests(req) mock_create_erasure.assert_called_with(service='admin', profile_name='foo', coding_chunks=2, data_chunks=3, locality=None, failure_domain='rack', erasure_plugin_name='jerasure') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_process_requests_create_cache_tier(self, mock_pool, mock_pool_exists): mock_pool_exists.return_value = True reqs = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'create-cache-tier', 'cold-pool': 'foo', 'hot-pool': 'foo-ssd', 'mode': 'writeback', 'erasure-profile': 'default' }] }) rc = broker.process_requests(reqs) mock_pool_exists.assert_any_call(service='admin', name='foo') mock_pool_exists.assert_any_call(service='admin', name='foo-ssd') mock_pool.assert_called_with(cache_pool='foo-ssd', mode='writeback') self.assertEqual(json.loads(rc), {'exit-code': 0})
def test_create_erasure_profile(self, mock_create_erasure): req = json.dumps({ 'api-version': 1, 'ops': [{ 'op': 'create-erasure-profile', 'name': 'foo', 'erasure-type': 'jerasure', 'failure-domain': 'rack', 'k': 3, 'm': 2, }] }) rc = broker.process_requests(req) mock_create_erasure.assert_called_with(service='admin', profile_name='foo', coding_chunks=2, data_chunks=3, locality=None, failure_domain='rack', erasure_plugin_name='jerasure') self.assertEqual(json.loads(rc), {'exit-code': 0})
def client_relation_changed(relid=None, unit=None): """Process broker requests from ceph client relations.""" if ceph.is_quorum(): if not unit: unit = remote_unit() settings = relation_get(rid=relid, unit=unit) if 'broker_req' in settings: if not ceph.is_leader(): log("Not leader - ignoring broker request", level=DEBUG) else: rsp = process_requests(settings['broker_req']) unit_id = unit.replace('/', '-') unit_response_key = 'broker-rsp-' + unit_id # broker_rsp is being left for backward compatibility, # unit_response_key superscedes it data = { 'broker_rsp': rsp, unit_response_key: rsp, } relation_set(relation_id=relid, relation_settings=data) else: log('mon cluster not in quorum', level=DEBUG)
def osd_relation(relid=None, unit=None): if ceph.is_quorum(): log('mon cluster in quorum - providing fsid & keys') public_addr = get_public_addr() data = { 'fsid': leader_get('fsid'), 'osd_bootstrap_key': ceph.get_osd_bootstrap_key(), 'auth': config('auth-supported'), 'ceph-public-address': public_addr, 'osd_upgrade_key': ceph.get_named_key('osd-upgrade', caps=ceph.osd_upgrade_caps), } unit = unit or remote_unit() settings = relation_get(rid=relid, unit=unit) """Process broker request(s).""" if 'broker_req' in settings: if ceph.is_leader(): rsp = process_requests(settings['broker_req']) unit_id = unit.replace('/', '-') unit_response_key = 'broker-rsp-' + unit_id data[unit_response_key] = rsp else: log("Not leader - ignoring broker request", level=DEBUG) relation_set(relation_id=relid, relation_settings=data) # NOTE: radosgw key provision is gated on presence of OSD # units so ensure that any deferred hooks are processed notify_radosgws() notify_client() else: log('mon cluster not in quorum - deferring fsid provision')