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 = ceph_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 = ceph_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 = ceph_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 = ceph_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_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 = ceph_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 = ceph_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 = ceph_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_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 = ceph_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 = ceph_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():
    """Process broker requests from ceph client relations."""
    if ceph.is_quorum():
        settings = relation_get()
        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 = remote_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_settings=data)
    else:
        log('mon cluster not in quorum', level=DEBUG)
def osd_relation(relid=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 = 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')