diff --git a/watcher/common/cinder_helper.py b/watcher/common/cinder_helper.py index f43207a05..bd98b5a64 100644 --- a/watcher/common/cinder_helper.py +++ b/watcher/common/cinder_helper.py @@ -71,15 +71,13 @@ class CinderHelper(object): return self.cinder.volume_types.list() def get_volume_type_by_backendname(self, backendname): + """Retrun a list of volume type""" volume_type_list = self.get_volume_type_list() - volume_type = [volume_type for volume_type in volume_type_list + volume_type = [volume_type.name for volume_type in volume_type_list if volume_type.extra_specs.get( 'volume_backend_name') == backendname] - if volume_type: - return volume_type[0].name - else: - return "" + return volume_type def get_volume(self, volume): @@ -204,7 +202,7 @@ class CinderHelper(object): volume = self.get_volume(volume) dest_backend = self.backendname_from_poolname(dest_node) dest_type = self.get_volume_type_by_backendname(dest_backend) - if volume.volume_type != dest_type: + if volume.volume_type not in dest_type: raise exception.Invalid( message=(_("Volume type must be same for migrating"))) diff --git a/watcher/decision_engine/model/element/node.py b/watcher/decision_engine/model/element/node.py index fc9e3f2d2..b686dae92 100644 --- a/watcher/decision_engine/model/element/node.py +++ b/watcher/decision_engine/model/element/node.py @@ -56,7 +56,7 @@ class StorageNode(storage_resource.StorageResource): "zone": wfields.StringField(), "status": wfields.StringField(default=ServiceState.ENABLED.value), "state": wfields.StringField(default=ServiceState.ONLINE.value), - "volume_type": wfields.StringField() + "volume_type": wfields.ListOfStringsField() } def accept(self, visitor): diff --git a/watcher/decision_engine/model/model_root.py b/watcher/decision_engine/model/model_root.py index 3b47085cc..17e1db656 100644 --- a/watcher/decision_engine/model/model_root.py +++ b/watcher/decision_engine/model/model_root.py @@ -508,7 +508,13 @@ class StorageModelRoot(nx.DiGraph, base.Model): root = etree.fromstring(data) for cn in root.findall('.//StorageNode'): - node = element.StorageNode(**cn.attrib) + ndata = {} + for attr, val in cn.items(): + ndata[attr] = val + volume_type = ndata.get('volume_type') + if volume_type: + ndata['volume_type'] = [volume_type] + node = element.StorageNode(**ndata) model.add_node(node) for p in root.findall('.//Pool'): diff --git a/watcher/tests/common/test_cinder_helper.py b/watcher/tests/common/test_cinder_helper.py index 872307466..4bb1f22a3 100644 --- a/watcher/tests/common/test_cinder_helper.py +++ b/watcher/tests/common/test_cinder_helper.py @@ -112,7 +112,7 @@ class TestCinderHelper(base.TestCase): volume_type_name = cinder_util.get_volume_type_by_backendname( 'backend') - self.assertEqual(volume_type_name, volume_type1.name) + self.assertEqual(volume_type_name[0], volume_type1.name) def test_get_volume_type_by_backendname_with_no_backend_exist( self, mock_cinder): @@ -122,7 +122,7 @@ class TestCinderHelper(base.TestCase): volume_type_name = cinder_util.get_volume_type_by_backendname( 'nobackend') - self.assertEqual("", volume_type_name) + self.assertEqual([], volume_type_name) @staticmethod def fake_volume(**kwargs): diff --git a/watcher/tests/decision_engine/model/faker_cluster_state.py b/watcher/tests/decision_engine/model/faker_cluster_state.py index fea754185..2d24e69b0 100644 --- a/watcher/tests/decision_engine/model/faker_cluster_state.py +++ b/watcher/tests/decision_engine/model/faker_cluster_state.py @@ -182,7 +182,7 @@ class FakerStorageModelCollector(base.BaseClusterDataModelCollector): for i in range(0, node_count): host = "host_{0}@backend_{0}".format(i) zone = "zone_{0}".format(i) - volume_type = "type_{0}".format(i) + volume_type = ["type_{0}".format(i)] node_attributes = { "host": host, "zone": zone, diff --git a/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py b/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py index 020ef6600..a3c11d531 100644 --- a/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py +++ b/watcher/tests/decision_engine/model/notification/test_cinder_notifications.py @@ -287,8 +287,7 @@ class TestCinderNotifications(NotificationTestCase): side_effect=lambda name: return_node_mock) m_get_volume_type_by_backendname = mock.Mock( - side_effect=lambda name: mock.Mock('backend_2')) - + side_effect=lambda name: [mock.Mock('backend_2')]) m_cinder_helper.return_value = mock.Mock( get_storage_pool_by_name=m_get_storage_pool_by_name, get_storage_node_by_name=m_get_storage_node_by_name, @@ -299,6 +298,7 @@ class TestCinderNotifications(NotificationTestCase): handler = cnotification.CapacityNotificationEndpoint(self.fake_cdmc) message = self.load_message('scenario_1_capacity_node_notfound.json') + # self.assertRaises(exception.StorageNodeNotFound, handler.info, handler.info( ctxt=self.context, publisher_id=message['publisher_id'], @@ -448,7 +448,7 @@ class TestCinderNotifications(NotificationTestCase): side_effect=lambda name: return_node_mock) m_get_volume_type_by_backendname = mock.Mock( - side_effect=lambda name: mock.Mock('backend_2')) + side_effect=lambda name: [mock.Mock('backend_2')]) m_cinder_helper.return_value = mock.Mock( get_storage_pool_by_name=m_get_storage_pool_by_name, diff --git a/watcher/tests/decision_engine/model/test_element.py b/watcher/tests/decision_engine/model/test_element.py index 1df732402..ba4a71599 100644 --- a/watcher/tests/decision_engine/model/test_element.py +++ b/watcher/tests/decision_engine/model/test_element.py @@ -82,7 +82,7 @@ class TestStorageElement(base.TestCase): 'zone': 'zone', 'status': 'enabled', 'state': 'up', - 'volume_type': 'volume_type', + 'volume_type': ['volume_type'], })), ("Pool_with_all_fields", dict( cls=element.Pool,