Ejemplo n.º 1
0
    def __init__(self, **kwargs):
        self.fields = objects.storage_tier.fields.keys()
        for k in self.fields:
            setattr(self, k, kwargs.get(k))

        if not self.uuid:
            self.uuid = uuidutils.generate_uuid()
Ejemplo n.º 2
0
 def _create_many_test_ihosts(self):
     uuids = []
     for i in range(1, 6):
         n = self._create_test_ihost(id=i, uuid=uuidutils.generate_uuid())
         uuids.append(n['uuid'])
     uuids.sort()
     return uuids
Ejemplo n.º 3
0
    def test_init_fsid_update_on_unlock(self):
        storage_0 = self._create_storage_ihost('storage-0')

        # Mock the fsid call so that we don't have to wait for the timeout
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=False), None)
            self.service.start()
            mock_fsid.assert_called()
        self.assertIsNone(self.service._ceph.cluster_ceph_uuid)
        self.assertIsNotNone(self.service._ceph.cluster_db_uuid)

        # save the current values
        saved_db_uuid = self.service._ceph.cluster_db_uuid

        # Add host
        cluster_uuid = uuidutils.generate_uuid()
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
            self.service._ceph.update_ceph_cluster(storage_0)
        self.assertIsNotNone(self.service._ceph.cluster_ceph_uuid)
        self.assertIsNotNone(self.service._ceph.cluster_db_uuid)
        self.assertEqual(saved_db_uuid, self.service._ceph.cluster_db_uuid)
        # self.assertEqual(self.service._ceph._cluster_ceph_uuid, self.service._ceph._cluster_db_uuid)

        # make sure the host addition produces the correct peer
        ihost_0 = self.dbapi.ihost_get(storage_0.id)
        self.assertEqual(storage_0.id, ihost_0.id)
        peer = self.dbapi.peer_get(ihost_0.peer_id)
        self.assertEqual(peer.name, 'group-0')
        self.assertEqual(peer.hosts, [storage_0.hostname])
Ejemplo n.º 4
0
    def test_add_storage_1(self):
        # Mock fsid with a faux cluster_uuid
        cluster_uuid = uuidutils.generate_uuid()
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
            self.service.start()
            mock_fsid.assert_called()

        clusters = self.dbapi.clusters_get_all(
            type=constants.CINDER_BACKEND_CEPH)
        self.assertEqual(len(clusters), 1)
        self.assertEqual(clusters[0].cluster_uuid, cluster_uuid)

        storage_0 = self._create_storage_ihost('storage-0')
        self.service._ceph.update_ceph_cluster(storage_0)

        peers = self.dbapi.peers_get_all_by_cluster(clusters[0].id)
        self.assertEqual(
            set([(p.name, tuple(sorted(p.hosts))) for p in peers]),
            {('group-0', ('storage-0', ))})

        storage_1 = self._create_storage_ihost('storage-1')
        self.service._ceph.update_ceph_cluster(storage_1)
        ihost = self.dbapi.ihost_get(storage_1.id)
        self.assertEqual(storage_1.id, ihost.id)
        peer = self.dbapi.peer_get(ihost.peer_id)
        self.assertEqual(peer.name, 'group-0')
        self.assertIn(ihost.hostname, peer.hosts)

        # check no other (unexpected) peers exist
        peers = self.dbapi.peers_get_all_by_cluster(clusters[0].id)
        self.assertEqual(
            set([(p.name, tuple(sorted(p.hosts))) for p in peers]),
            {('group-0', ('storage-0', 'storage-1'))})
Ejemplo n.º 5
0
 def _create_storage_mon(self, hostname, ihost_id):
     self.mon_index += 1
     ceph_mon_dict = dbutils.get_test_mon(
         id=self.mon_index,
         uuid=uuidutils.generate_uuid(),
         state=constants.SB_STATE_CONFIGURED,
         task=constants.SB_TASK_NONE,
         forihostid=ihost_id,
         hostname=hostname)
     return self.dbapi.ceph_mon_create(ceph_mon_dict)
Ejemplo n.º 6
0
    def __init__(self, **kwargs):
        self.fields = list(objects.lvg.fields.keys())
        for k in self.fields:
            setattr(self, k, kwargs.get(k))

        if not self.uuid:
            self.uuid = uuidutils.generate_uuid()

        self.fields.append('lvm_vg_avail_size')
        setattr(self, 'lvm_vg_avail_size', kwargs.get('lvm_vg_avail_size', 0))
Ejemplo n.º 7
0
    def __init__(self, **kwargs):
        self.fields = list(objects.storage.fields.keys())
        for k in self.fields:
            setattr(self, k, kwargs.get(k))

        if not self.uuid:
            self.uuid = uuidutils.generate_uuid()

        self.fields.append('journal_node')
        setattr(self, 'journal_node', kwargs.get('journal_node', None))
Ejemplo n.º 8
0
 def test_ihost_links(self):
     uuid = uuidutils.generate_uuid()
     ndict = dbutils.get_test_ihost(id=1,
                                    uuid=uuid,
                                    forisystemid=self.system.id)
     self.dbapi.ihost_create(ndict)
     data = self.get_json('/ihosts/1')
     self.assertIn('links', data.keys())
     self.assertEqual(len(data['links']), 2)
     self.assertIn(uuid, data['links'][0]['href'])
Ejemplo n.º 9
0
    def __init__(self, **kwargs):

        defaults = {'state': constants.SB_STATE_CONFIGURED,
                    'task': constants.SB_TASK_NONE}

        self.fields = list(objects.ceph_mon.fields.keys())

        for k in self.fields:
            setattr(self, k, kwargs.get(k, defaults.get(k)))

        if not self.uuid:
            self.uuid = uuidutils.generate_uuid()
Ejemplo n.º 10
0
 def test_init_fsid_available(self):
     # Mock fsid with a faux cluster_uuid
     cluster_uuid = uuidutils.generate_uuid()
     with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
         mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
         self.service.start()
         mock_fsid.assert_called()
     self.assertIsNotNone(self.service._ceph.cluster_ceph_uuid)
     self.assertIsNotNone(self.service._ceph.cluster_db_uuid)
     self.assertIsNotNone(self.service._ceph.cluster_id)
     self.assertEqual(self.service._ceph.cluster_ceph_uuid,
                      self.service._ceph.cluster_db_uuid)
Ejemplo n.º 11
0
    def test_add_valid_mix_tiers(self):
        hosts = [
            self._create_storage_ihost('storage-0'),
            self._create_storage_ihost('storage-1'),
            self._create_storage_ihost('storage-2'),
            self._create_storage_ihost('storage-3'),
            self._create_storage_ihost('storage-4'),
            self._create_storage_ihost('storage-5'),
            self._create_storage_ihost('storage-6'),
            self._create_storage_ihost('storage-7')
        ]

        expected_groups = {
            'storage-0': 'group-0',
            'storage-1': 'group-0',
            'storage-2': 'group-1',
            'storage-3': 'group-1',
            'storage-4': 'group-2',
            'storage-5': 'group-2',
            'storage-6': 'group-3',
            'storage-7': 'group-3'
        }

        expected_peer_hosts = {
            'storage-0': {'storage-0'},
            'storage-1': {'storage-0', 'storage-1'},
            'storage-2': {'storage-2'},
            'storage-3': {'storage-2', 'storage-3'},
            'storage-4': {'storage-4'},
            'storage-5': {'storage-4', 'storage-5'},
            'storage-6': {'storage-6'},
            'storage-7': {'storage-6', 'storage-7'}
        }

        # Mock fsid with a faux cluster_uuid
        cluster_uuid = uuidutils.generate_uuid()
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
            self.service.start()
            mock_fsid.assert_called()

        for h in hosts:
            # unlock host
            self.service._ceph.update_ceph_cluster(h)
            ihost = self.dbapi.ihost_get(h.id)
            self.assertEqual(h.id, ihost.id)
            peer = self.dbapi.peer_get(ihost.peer_id)
            self.assertEqual(peer.name, expected_groups[h.hostname])
            self.assertEqual(set(peer.hosts), expected_peer_hosts[h.hostname])
Ejemplo n.º 12
0
 def _create_storage_ihost(self, hostname):
     self.host_index += 1
     ihost_dict = dbutils.get_test_ihost(
         id=self.host_index,
         forisystemid=self.system.id,
         hostname=hostname,
         uuid=uuidutils.generate_uuid(),
         mgmt_mac="{}-{}".format(hostname, self.host_index),
         mgmt_ip="{}-{}".format(hostname, self.host_index),
         personality='storage',
         administrative='locked',
         operational='disabled',
         availability='online',
         invprovision='unprovisioned')
     return self.dbapi.ihost_create(ihost_dict)
Ejemplo n.º 13
0
    def test_collection_links(self):
        ihosts = []
        for id in range(100):
            ndict = dbutils.get_test_ihost(id=id,
                                           hostname=id,
                                           mgmt_mac=id,
                                           forisystemid=self.system.id,
                                           mgmt_ip="%s.%s.%s.%s" %
                                           (id, id, id, id),
                                           uuid=uuidutils.generate_uuid())
            ihost = self.dbapi.ihost_create(ndict)
            ihosts.append(ihost['uuid'])
        data = self.get_json('/ihosts/?limit=100')
        self.assertEqual(len(data['ihosts']), 100)

        next_marker = data['ihosts'][-1]['uuid']
        self.assertIn(next_marker, data['next'])
Ejemplo n.º 14
0
    def test_many(self):
        ihosts = []
        for id in range(1000):  # there is a limit of 1000 returned by json
            ndict = dbutils.get_test_ihost(id=id,
                                           hostname=id,
                                           mgmt_mac=id,
                                           forisystemid=self.system.id,
                                           mgmt_ip="%s.%s.%s.%s" %
                                           (id, id, id, id),
                                           uuid=uuidutils.generate_uuid())
            s = self.dbapi.ihost_create(ndict)
            ihosts.append(s['uuid'])
        data = self.get_json('/ihosts')
        self.assertEqual(len(ihosts), len(data['ihosts']))

        uuids = [n['uuid'] for n in data['ihosts']]
        self.assertEqual(ihosts.sort(), uuids.sort())  # uuids.sort
Ejemplo n.º 15
0
    def __init__(self, **kwargs):
        defaults = {'uuid': uuidutils.generate_uuid(),
                    'state': constants.SB_STATE_CONFIGURING,
                    'task': constants.SB_TASK_NONE,
                    'capabilities': {},
                    'services': None,
                    'confirmed': False}

        self.fields = list(objects.storage_file.fields.keys())

        # 'confirmed' is not part of objects.storage_backend.fields
        # (it's an API-only attribute)
        self.fields.append('confirmed')

        # Set the value for any of the field
        for k in self.fields:
            setattr(self, k, kwargs.get(k, defaults.get(k)))
Ejemplo n.º 16
0
    def test_ports_subresource(self):
        ndict = dbutils.get_test_ihost(forisystemid=self.system.id)
        self.dbapi.ihost_create(ndict)

        for id in range(2):
            pdict = dbutils.get_test_port(id=id,
                                          host_id=ndict['id'],
                                          pciaddr=id,
                                          uuid=uuidutils.generate_uuid())
            ihost_id = ndict['id']
            self.dbapi.ethernet_port_create(ihost_id, pdict)

        data = self.get_json('/ihosts/%s/ports' % ndict['uuid'])
        self.assertEqual(len(data['ports']), 2)
        self.assertNotIn('next', data.keys())

        # Test collection pagination
        data = self.get_json('/ihosts/%s/ports?limit=1' % ndict['uuid'])
        self.assertEqual(len(data['ports']), 1)
        self.assertIn('next', data.keys())
Ejemplo n.º 17
0
def generate_request_id():
    return 'req-%s' % uuidutils.generate_uuid()
Ejemplo n.º 18
0
    def test_cgts_7208(self):
        hosts = [
            self._create_storage_ihost('storage-0'),
            self._create_storage_ihost('storage-1'),
            self._create_storage_ihost('storage-2'),
            self._create_storage_ihost('storage-3')
        ]

        expected_groups = {
            'storage-0': 'group-0',
            'storage-1': 'group-0',
            'storage-2': 'group-1',
            'storage-3': 'group-1'
        }

        expected_peer_hosts = {
            'storage-0': {'storage-0'},
            'storage-1': {'storage-0', 'storage-1'},
            'storage-2': {'storage-2'},
            'storage-3': {'storage-2', 'storage-3'}
        }

        saved_ihosts = []
        expected_peer_hosts2 = {
            'storage-0': {'storage-0', 'storage-1'},
            'storage-1': {'storage-0', 'storage-1'},
            'storage-2': {'storage-2', 'storage-3'},
            'storage-3': {'storage-2', 'storage-3'}
        }

        # Mock fsid with a faux cluster_uuid
        cluster_uuid = uuidutils.generate_uuid()
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
            self.service.start()
            mock_fsid.assert_called()

        for h in hosts:
            # unlock host
            self.service._ceph.update_ceph_cluster(h)
            ihost = self.dbapi.ihost_get(h.id)
            self.assertEqual(h.id, ihost.id)
            peer = self.dbapi.peer_get(ihost.peer_id)
            self.assertEqual(peer.name, expected_groups[h.hostname])
            self.assertEqual(set(peer.hosts), expected_peer_hosts[h.hostname])
            saved_ihosts.append(ihost)

        # On a swact we get a new conductor and an fresh CephOperator
        saved_ceph_uuid = self.service._ceph.cluster_ceph_uuid
        saved_db_uuid = self.service._ceph.cluster_db_uuid
        saved_cluster_id = self.service._ceph.cluster_id

        del self.service._ceph
        self.service._ceph = iceph.CephOperator(self.service.dbapi)
        self.assertEqual(self.service._ceph.cluster_ceph_uuid, saved_ceph_uuid)
        self.assertEqual(self.service._ceph.cluster_db_uuid, saved_db_uuid)
        self.assertEqual(self.service._ceph.cluster_id, saved_cluster_id)

        for h in saved_ihosts:
            # unlock host
            self.service._ceph.update_ceph_cluster(h)
            peer = self.dbapi.peer_get(h.peer_id)
            self.assertEqual(peer.name, expected_groups[h.hostname])
            self.assertEqual(set(peer.hosts), expected_peer_hosts2[h.hostname])
Ejemplo n.º 19
0
    def test_cluster_tier_host_osd(self):
        storage_0 = self._create_storage_ihost('storage-0')
        disk_0 = dbutils.create_test_idisk(
            device_node='/dev/sda',
            device_path='/dev/disk/by-path/pci-0000:00:0d.0-ata-1.0',
            forihostid=storage_0.id)
        disk_1 = dbutils.create_test_idisk(
            device_node='/dev/sdb',
            device_path='/dev/disk/by-path/pci-0000:00:0d.0-ata-2.0',
            forihostid=storage_0.id)

        self._create_storage_mon('storage-0', storage_0['id'])

        # Mock the fsid call so that we don't have to wait for the timeout
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=False), None)
            self.service.start()
            mock_fsid.assert_called()
        self.assertIsNone(self.service._ceph.cluster_ceph_uuid)
        self.assertIsNotNone(self.service._ceph.cluster_db_uuid)

        # Make sure default storage tier is present
        tier_list = self.get_json('/storage_tiers', expect_errors=False)
        self.assertEqual(
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            tier_list['storage_tiers'][0]['name'])
        self.assertEqual(constants.SB_TIER_STATUS_DEFINED,
                         tier_list['storage_tiers'][0]['status'])

        # save the current values
        saved_cluster_db_uuid = self.service._ceph.cluster_db_uuid

        # Add host
        cluster_uuid = uuidutils.generate_uuid()
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
            self.service._ceph.update_ceph_cluster(storage_0)
        self.assertIsNotNone(self.service._ceph.cluster_ceph_uuid)
        self.assertIsNotNone(self.service._ceph.cluster_db_uuid)
        self.assertEqual(saved_cluster_db_uuid,
                         self.service._ceph.cluster_db_uuid)
        # self.assertEqual(self.service._ceph._cluster_ceph_uuid, self.service._ceph._cluster_db_uuid)

        # make sure the host addition produces the correct peer
        ihost_0 = self.dbapi.ihost_get(storage_0.id)
        self.assertEqual(storage_0.id, ihost_0.id)
        peer = self.dbapi.peer_get(ihost_0.peer_id)
        self.assertEqual(peer.name, 'group-0')
        self.assertEqual(peer.hosts, [storage_0.hostname])

        # Add the default ceph backend
        values = {
            'backend':
            constants.SB_TYPE_CEPH,
            'capabilities': {
                'test_bparam3': 'one',
                'test_cparam3': 'two',
                'test_gparam3': 'three',
                'test_sparam1': 'four'
            },
            'services':
            "%s,%s" % (constants.SB_SVC_CINDER, constants.SB_SVC_GLANCE),
            'confirmed':
            True
        }
        with nested(
                mock.patch.object(
                    StorageBackendConfig,
                    'get_ceph_mon_ip_addresses')) as (mock_ceph_mon):
            response = self.post_json('/storage_backend',
                                      values,
                                      expect_errors=False)
        self.assertEqual(http_client.OK, response.status_int)
        self.assertEqual(
            'ceph',  # Expected
            self.get_json('/storage_backend/%s/' %
                          response.json['uuid'])['backend'])  # Result

        # update the DB to make sure that the backend set to be configured
        self.dbapi.storage_backend_update(
            response.json['uuid'], {'state': constants.SB_STATE_CONFIGURED})

        # Make sure default storage tier is in use
        tier_list = self.get_json('/storage_tiers', expect_errors=False)
        self.assertEqual(
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            tier_list['storage_tiers'][0]['name'])
        self.assertEqual(constants.SB_TIER_STATUS_IN_USE,
                         tier_list['storage_tiers'][0]['status'])
        default_tier_uuid = tier_list['storage_tiers'][0]['uuid']

        # add a stor
        values = {'ihost_uuid': storage_0.uuid, 'idisk_uuid': disk_0.uuid}

        with nested(
                mock.patch.object(ceph_utils.CephApiOperator,
                                  'get_monitors_status'),
                mock.patch.object(StorageBackendConfig,
                                  'has_backend_configured'),
                mock.patch.object(
                    rpcapi.ConductorAPI,
                    'configure_osd_istor')) as (mock_mon_status,
                                                mock_backend_configured,
                                                mock_osd):

            def fake_configure_osd_istor(context, istor_obj):
                istor_obj['osdid'] = 0
                return istor_obj

            mock_mon_status.return_value = [
                3, 2, ['controller-0', 'controller-1', 'storage-0']
            ]
            mock_osd.side_effect = fake_configure_osd_istor

            response = self.post_json('/istors', values, expect_errors=True)
        self.assertEqual(http_client.OK, response.status_int)
        self.assertEqual(
            default_tier_uuid,
            self.get_json('/istors/%s/' %
                          response.json['uuid'])['tier_uuid'])  # Result

        # Verify the tier state is still in-use
        tier_list = self.get_json('/storage_tiers', expect_errors=False)
        self.assertEqual(
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            tier_list['storage_tiers'][0]['name'])
        self.assertEqual(constants.SB_TIER_STATUS_IN_USE,
                         tier_list['storage_tiers'][0]['status'])

        # Create a second storage tier without a cluster
        values = {}
        response = self.post_json('/storage_tiers', values, expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
        self.assertEqual('application/json', response.content_type)
        self.assertTrue(response.json['error_message'])
        self.assertIn('No cluster information was provided for tier creation.',
                      response.json['error_message'])

        # Create a second storage tier without a name
        values = {'cluster_uuid': saved_cluster_db_uuid}
        response = self.post_json('/storage_tiers', values, expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
        self.assertEqual('application/json', response.content_type)
        self.assertTrue(response.json['error_message'])
        self.assertIn(
            'Storage tier (%s) already present' %
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            response.json['error_message'])

        # Create a second storage tier
        values = {'cluster_uuid': saved_cluster_db_uuid, 'name': 'gold'}
        with mock.patch.object(ceph_utils.CephApiOperator,
                               'crushmap_tiers_add'):
            response = self.post_json('/storage_tiers',
                                      values,
                                      expect_errors=True)
        self.assertEqual(http_client.OK, response.status_int)

        confirm = self.get_json('/storage_tiers/%s/' % response.json['uuid'])
        self.assertEqual(confirm['uuid'], response.json['uuid'])
        self.assertEqual(confirm['name'], 'gold')
        self.assertEqual(confirm['type'], constants.SB_TIER_TYPE_CEPH)
        self.assertEqual(confirm['status'], constants.SB_TIER_STATUS_DEFINED)
        self.assertEqual(confirm['backend_uuid'], None)
        self.assertEqual(confirm['cluster_uuid'], saved_cluster_db_uuid)
        self.assertEqual(confirm['stors'], [])
        self.assertEqual(confirm['capabilities'], {})
        saved_tier_uuid = response.json['uuid']

        # add a stor without specifying a tier
        values = {'ihost_uuid': storage_0.uuid, 'idisk_uuid': disk_1.uuid}

        with nested(
                mock.patch.object(ceph_utils.CephApiOperator,
                                  'get_monitors_status'),
                mock.patch.object(StorageBackendConfig,
                                  'has_backend_configured'),
                mock.patch.object(
                    rpcapi.ConductorAPI,
                    'configure_osd_istor')) as (mock_mon_status,
                                                mock_backend_configured,
                                                mock_osd):

            def fake_configure_osd_istor(context, istor_obj):
                istor_obj['osdid'] = 1
                return istor_obj

            mock_mon_status.return_value = [
                3, 2, ['controller-0', 'controller-1', 'storage-0']
            ]
            mock_osd.side_effect = fake_configure_osd_istor

            response = self.post_json('/istors', values, expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, response.status_int)
        self.assertEqual('application/json', response.content_type)
        self.assertTrue(response.json['error_message'])
        self.assertIn(
            'Multiple storage tiers are present. A tier is required for stor creation.',
            response.json['error_message'])

        # add a stor without specifying a tier
        values = {
            'ihost_uuid': storage_0.uuid,
            'idisk_uuid': disk_1.uuid,
            'tier_uuid': saved_tier_uuid
        }

        with nested(
                mock.patch.object(ceph_utils.CephApiOperator,
                                  'get_monitors_status'),
                mock.patch.object(StorageBackendConfig,
                                  'has_backend_configured'),
                mock.patch.object(
                    rpcapi.ConductorAPI,
                    'configure_osd_istor')) as (mock_mon_status,
                                                mock_backend_configured,
                                                mock_osd):

            def fake_configure_osd_istor(context, istor_obj):
                istor_obj['osdid'] = 1
                return istor_obj

            mock_mon_status.return_value = [
                3, 2, ['controller-0', 'controller-1', 'storage-0']
            ]
            mock_osd.side_effect = fake_configure_osd_istor

            response = self.post_json('/istors', values, expect_errors=True)
        self.assertEqual(http_client.OK, response.status_int)
        self.assertEqual(
            saved_tier_uuid,
            self.get_json('/istors/%s/' %
                          response.json['uuid'])['tier_uuid'])  # Result

        # Verify the tier state has changed
        tier_list = self.get_json('/storage_tiers', expect_errors=False)
        self.assertEqual('gold', tier_list['storage_tiers'][1]['name'])
        self.assertEqual(constants.SB_TIER_STATUS_IN_USE,
                         tier_list['storage_tiers'][1]['status'])

        # validate the cluster view
        cluster_list = self.get_json('/clusters', expect_errors=False)
        self.assertEqual('ceph_cluster', cluster_list['clusters'][0]['name'])

        response = self.get_json('/clusters/%s' %
                                 cluster_list['clusters'][0]['uuid'],
                                 expect_errors=False)
        self.assertEqual(
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            response['tiers'][0]['name'])
        self.assertEqual('gold', response['tiers'][1]['name'])

        # validate the tier view
        tier_list = self.get_json('/storage_tiers', expect_errors=False)
        self.assertEqual(
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            tier_list['storage_tiers'][0]['name'])
        self.assertEqual('gold', tier_list['storage_tiers'][1]['name'])

        response = self.get_json('/storage_tiers/%s' %
                                 tier_list['storage_tiers'][0]['uuid'],
                                 expect_errors=False)
        self.assertEqual(
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            response['name'])
        self.assertEqual([0], response['stors'])

        response = self.get_json('/storage_tiers/%s' %
                                 tier_list['storage_tiers'][1]['uuid'],
                                 expect_errors=False)
        self.assertEqual('gold', response['name'])
        self.assertEqual([1], response['stors'])

        # Add the ceph backend for the new tier without specifying a backend name
        values = {
            'backend': constants.SB_TYPE_CEPH,
            'capabilities': {
                'test_bparam3': 'foo'
            },
            'confirmed': True
        }
        with nested(
                mock.patch.object(
                    StorageBackendConfig,
                    'get_ceph_mon_ip_addresses')) as (mock_ceph_mon):
            response = self.post_json('/storage_ceph',
                                      values,
                                      expect_errors=True)
            self.assertEqual(http_client.BAD_REQUEST, response.status_int)
            self.assertEqual('application/json', response.content_type)
            self.assertTrue(response.json['error_message'])
            self.assertIn(
                'Initial (%s) backend was previously created. Use '
                'the modify API for further provisioning' %
                constants.SB_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
                response.json['error_message'])

        # Add the ceph backend for the new tier without specifying the tier
        values = {
            'backend': constants.SB_TYPE_CEPH,
            'capabilities': {
                'test_bparam3': 'foo'
            },
            'name': 'ceph-gold',
            'confirmed': True
        }
        with nested(
                mock.patch.object(
                    StorageBackendConfig,
                    'get_ceph_mon_ip_addresses')) as (mock_ceph_mon):
            response = self.post_json('/storage_ceph',
                                      values,
                                      expect_errors=True)
            self.assertEqual(http_client.BAD_REQUEST, response.status_int)
            self.assertEqual('application/json', response.content_type)
            self.assertTrue(response.json['error_message'])
            self.assertIn('No tier specified for this backend.',
                          response.json['error_message'])

        # Add the ceph backend for the new tier
        values = {
            'backend': constants.SB_TYPE_CEPH,
            'capabilities': {
                'test_bparam3': 'one',
                'test_cparam3': 'two'
            },
            'services': constants.SB_SVC_CINDER,
            'name': 'ceph-gold',
            'tier_uuid': saved_tier_uuid,
            'confirmed': True
        }
        with nested(
                mock.patch.object(StorageBackendConfig,
                                  'get_ceph_mon_ip_addresses'),
                mock.patch.object(StorageBackendConfig,
                                  'get_ceph_tier_size')) as (mock_ceph_mon,
                                                             mock_space):
            mock_space.return_value = 0

            response = self.post_json('/storage_ceph',
                                      values,
                                      expect_errors=True)
            self.assertEqual(http_client.OK, response.status_int)
            self.assertEqual(
                'ceph-gold',
                self.get_json('/storage_backend/%s/' %
                              response.json['uuid'])['name'])  # Result

        # validate the backend view
        backend_list = self.get_json('/storage_backend', expect_errors=False)
        self.assertEqual(http_client.OK, response.status_int)
        self.assertEqual(
            constants.SB_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            backend_list['storage_backends'][0]['name'])
        self.assertEqual('ceph-gold',
                         backend_list['storage_backends'][1]['name'])
Ejemplo n.º 20
0
    def test_tier_patch(self):
        values = {'cluster_uuid': self.cluster.uuid}

        response = self.post_json('/storage_tiers', values, expect_errors=True)
        self.assertEqual(http_client.OK, response.status_int)

        confirm = self.get_json('/storage_tiers/%s/' % response.json['uuid'])
        self.assertEqual(confirm['uuid'], response.json['uuid'])
        self.assertEqual(
            confirm['name'],
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH])
        self.assertEqual(confirm['type'], constants.SB_TIER_TYPE_CEPH)
        self.assertEqual(confirm['status'], constants.SB_TIER_STATUS_DEFINED)
        self.assertEqual(confirm['backend_uuid'], None)
        self.assertEqual(confirm['cluster_uuid'], self.cluster.uuid)
        self.assertEqual(confirm['stors'], [])
        self.assertEqual(confirm['capabilities'], {})

        # Default: uuid
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              uuid=uuidutils.generate_uuid(),
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            '\'/uuid\' is an internal attribute and can not be updated"',
            patch_response.json['error_message'])

        # Default: name
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              name='newname',
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            'Storage Tier %s cannot be renamed.' %
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            patch_response.json['error_message'])

        # Default: type
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              type='lvm',
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn("Cannot modify 'type' with this operation.",
                      patch_response.json['error_message'])

        # Default: status
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            status=constants.SB_TIER_STATUS_IN_USE,
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn("Cannot modify 'status' with this operation.",
                      patch_response.json['error_message'])

        # Default: capabilities
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            capabilities=jsonutils.dumps({'test_param': 'foo'}),
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            'The capabilities of storage tier %s cannot be changed.' %
            constants.SB_TIER_DEFAULT_NAMES[constants.SB_TIER_TYPE_CEPH],
            patch_response.json['error_message'])

        # Default: backend_uuid
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            backend_uuid=uuidutils.generate_uuid(),
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn('No entry found for storage backend',
                      patch_response.json['error_message'])

        # Default: cluster_uuid
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            cluster_uuid=uuidutils.generate_uuid(),
            expect_errors=True)
        self.assertEqual(http_client.NOT_FOUND, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])

        values = {'cluster_uuid': self.cluster.uuid, 'name': 'gold'}

        with mock.patch.object(ceph_utils.CephApiOperator,
                               'crushmap_tiers_add'):
            response = self.post_json('/storage_tiers',
                                      values,
                                      expect_errors=True)
        self.assertEqual(http_client.OK, response.status_int)

        confirm = self.get_json('/storage_tiers/%s/' % response.json['uuid'])
        self.assertEqual(confirm['uuid'], response.json['uuid'])
        self.assertEqual(confirm['name'], 'gold')
        self.assertEqual(confirm['type'], constants.SB_TIER_TYPE_CEPH)
        self.assertEqual(confirm['status'], constants.SB_TIER_STATUS_DEFINED)
        self.assertEqual(confirm['backend_uuid'], None)
        self.assertEqual(confirm['cluster_uuid'], self.cluster.uuid)
        self.assertEqual(confirm['stors'], [])
        self.assertEqual(confirm['capabilities'], {})

        # Other Defined: uuid
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              uuid=uuidutils.generate_uuid(),
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            '\'/uuid\' is an internal attribute and can not be updated"',
            patch_response.json['error_message'])

        # Other Defined: name
        with mock.patch.object(ceph_utils.CephApiOperator,
                               'crushmap_tier_rename'):
            patch_response = self.patch_dict_json(
                '/storage_tiers/%s' % confirm['uuid'],
                headers={'User-Agent': 'sysinv'},
                name='newname',
                expect_errors=True)
        self.assertEqual(http_client.OK, patch_response.status_int)
        self.assertEqual(
            'newname',  # Expected
            self.get_json('/storage_tiers/%s/' %
                          patch_response.json['uuid'])['name'])  # Result

        # Other Defined: type
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              type='lvm',
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn("Cannot modify 'type' with this operation.",
                      patch_response.json['error_message'])

        # Other Defined: status
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            status=constants.SB_TIER_STATUS_IN_USE,
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn("Cannot modify 'status' with this operation.",
                      patch_response.json['error_message'])

        # Other Defined: capabilities
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            capabilities=jsonutils.dumps({'test_param': 'foo'}),
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            'The capabilities of storage tier newname cannot be changed.',
            patch_response.json['error_message'])

        # Other Defined: backend_uuid
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            backend_uuid=uuidutils.generate_uuid(),
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn('No entry found for storage backend',
                      patch_response.json['error_message'])

        # Other Defined: cluster_uuid
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            cluster_uuid=uuidutils.generate_uuid(),
            expect_errors=True)
        self.assertEqual(http_client.NOT_FOUND, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])

        values = {
            'cluster_uuid': self.cluster.uuid,
            'name': 'platinum',
            'status': constants.SB_TIER_STATUS_IN_USE
        }

        with mock.patch.object(ceph_utils.CephApiOperator,
                               'crushmap_tiers_add'):
            response = self.post_json('/storage_tiers',
                                      values,
                                      expect_errors=True)
        self.assertEqual(http_client.OK, response.status_int)

        confirm = self.get_json('/storage_tiers/%s/' % response.json['uuid'])
        self.assertEqual(confirm['uuid'], response.json['uuid'])
        self.assertEqual(confirm['name'], 'platinum')
        self.assertEqual(confirm['type'], constants.SB_TIER_TYPE_CEPH)
        self.assertEqual(confirm['status'], constants.SB_TIER_STATUS_IN_USE)
        self.assertEqual(confirm['backend_uuid'], None)
        self.assertEqual(confirm['cluster_uuid'], self.cluster.uuid)
        self.assertEqual(confirm['stors'], [])
        self.assertEqual(confirm['capabilities'], {})

        # Other In-Use: uuid
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              uuid=uuidutils.generate_uuid(),
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            '\'/uuid\' is an internal attribute and can not be updated"',
            patch_response.json['error_message'])

        # Other In-Use: name
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              name='newname',
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn('Storage Tier platinum cannot be renamed. It is in-use',
                      patch_response.json['error_message'])

        # Other In-Use: type
        patch_response = self.patch_dict_json('/storage_tiers/%s' %
                                              confirm['uuid'],
                                              headers={'User-Agent': 'sysinv'},
                                              type='lvm',
                                              expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn("Cannot modify 'type' with this operation.",
                      patch_response.json['error_message'])

        # Other In-Use: status
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            status=constants.SB_TIER_STATUS_DEFINED,
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn("Cannot modify 'status' with this operation.",
                      patch_response.json['error_message'])

        # Other In-Use: capabilities
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            capabilities=jsonutils.dumps({'test_param': 'foo'}),
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn(
            'The capabilities of storage tier platinum cannot be changed.',
            patch_response.json['error_message'])

        # Other In-Use: backend_uuid
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            backend_uuid=uuidutils.generate_uuid(),
            expect_errors=True)
        self.assertEqual(http_client.BAD_REQUEST, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
        self.assertIn('No entry found for storage backend',
                      patch_response.json['error_message'])

        # Other In-Use: cluster_uuid
        patch_response = self.patch_dict_json(
            '/storage_tiers/%s' % confirm['uuid'],
            headers={'User-Agent': 'sysinv'},
            cluster_uuid=uuidutils.generate_uuid(),
            expect_errors=True)
        self.assertEqual(http_client.NOT_FOUND, patch_response.status_int)
        self.assertEqual('application/json', patch_response.content_type)
        self.assertTrue(patch_response.json['error_message'])
Ejemplo n.º 21
0
    def test_add_4_mix_bbbb(self):
        # Mock fsid with a faux cluster_uuid
        cluster_uuid = uuidutils.generate_uuid()
        with mock.patch.object(ceph.CephWrapper, 'fsid') as mock_fsid:
            mock_fsid.return_value = (mock.MagicMock(ok=True), cluster_uuid)
            self.service.start()
            mock_fsid.assert_called()

        storage_0 = self._create_storage_ihost('storage-0')
        self.service._ceph.update_ceph_cluster(storage_0)
        ihost = self.dbapi.ihost_get(storage_0.id)
        self.assertEqual(storage_0.id, ihost.id)
        peer = self.dbapi.peer_get(ihost.peer_id)
        self.assertEqual(peer.name, 'group-0')
        self.assertIn(ihost.hostname, peer.hosts)

        peers = self.dbapi.peers_get_all_by_cluster(cluster_uuid)
        self.assertEqual(
            set([(p.name, tuple(sorted(p.hosts))) for p in peers]), {
                ('group-0', ('storage-0', )),
            })

        storage_1 = self._create_storage_ihost('storage-1')
        self.service._ceph.update_ceph_cluster(storage_1)
        ihost = self.dbapi.ihost_get(storage_1.id)
        self.assertEqual(storage_1.id, ihost.id)
        peer = self.dbapi.peer_get(ihost.peer_id)
        self.assertEqual(peer.name, 'group-0')
        self.assertIn(ihost.hostname, peer.hosts)

        peers = self.dbapi.peers_get_all_by_cluster(cluster_uuid)
        self.assertEqual(
            set([(p.name, tuple(sorted(p.hosts))) for p in peers]), {
                ('group-0', ('storage-0', 'storage-1')),
            })

        storage_2 = self._create_storage_ihost('storage-2')
        self.service._ceph.update_ceph_cluster(storage_2)
        ihost = self.dbapi.ihost_get(storage_2.id)
        self.assertEqual(storage_2.id, ihost.id)
        peer = self.dbapi.peer_get(ihost.peer_id)
        self.assertEqual(peer.name, 'group-1')
        self.assertIn(ihost.hostname, peer.hosts)

        peers = self.dbapi.peers_get_all_by_cluster(cluster_uuid)
        self.assertEqual(
            set([(p.name, tuple(sorted(p.hosts))) for p in peers]),
            {('group-0', ('storage-0', 'storage-1')),
             ('group-1', ('storage-2', ))})

        storage_3 = self._create_storage_ihost('storage-3')
        self.service._ceph.update_ceph_cluster(storage_3)
        ihost = self.dbapi.ihost_get(storage_3.id)
        self.assertEqual(storage_3.id, ihost.id)
        peer = self.dbapi.peer_get(ihost.peer_id)
        self.assertEqual(peer.name, 'group-1')
        self.assertIn(ihost.hostname, peer.hosts)

        peers = self.dbapi.peers_get_all_by_cluster(cluster_uuid)
        self.assertEqual(
            set([(p.name, tuple(sorted(p.hosts))) for p in peers]),
            {('group-0', ('storage-0', 'storage-1')),
             ('group-1', ('storage-2', 'storage-3'))})