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()
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
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])
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'))})
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)
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))
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))
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'])
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()
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)
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])
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)
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'])
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
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)))
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())
def generate_request_id(): return 'req-%s' % uuidutils.generate_uuid()
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])
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'])
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'])
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'))})