Use yaml.safe_load instead of yaml.load
[osm/MON.git] / osm_mon / collector / vnf_collectors / openstack.py
index 5119f33..aba4788 100644 (file)
@@ -76,19 +76,27 @@ INTERFACE_METRICS = [
     "packets_sent",
 ]
 
+INSTANCE_DISK = [
+    "disk_read_ops",
+    "disk_write_ops",
+    "disk_read_bytes",
+    "disk_write_bytes",
+]
+
 
 class MetricType(Enum):
     INSTANCE = "instance"
     INTERFACE_ALL = "interface_all"
     INTERFACE_ONE = "interface_one"
+    INSTANCEDISK = 'instancedisk'
 
 
 class OpenstackCollector(BaseVimCollector):
-    def __init__(self, config: Config, vim_account_id: str):
+    def __init__(self, config: Config, vim_account_id: str, vim_session: object):
         super().__init__(config, vim_account_id)
         self.common_db = CommonDbClient(config)
         vim_account = self.common_db.get_vim_account(vim_account_id)
-        self.backend = self._get_backend(vim_account)
+        self.backend = self._get_backend(vim_account, vim_session)
 
     def _build_keystone_client(self, vim_account: dict) -> keystone_client.Client:
         sess = OpenstackUtils.get_session(vim_account)
@@ -182,21 +190,24 @@ class OpenstackCollector(BaseVimCollector):
                         log.info("Error in metric collection: %s" % e)
         return metrics
 
-    def _get_backend(self, vim_account: dict):
+    def _get_backend(self, vim_account: dict, vim_session: object):
         try:
-            gnocchi = GnocchiBackend(vim_account)
+            gnocchi = GnocchiBackend(vim_account, vim_session)
             gnocchi.client.metric.list(limit=1)
             log.info("Using gnocchi backend to collect metric")
             return gnocchi
         except (HTTPException, EndpointNotFound):
-            ceilometer = CeilometerBackend(vim_account)
+            ceilometer = CeilometerBackend(vim_account, vim_session)
             ceilometer.client.capabilities.get()
             log.info("Using ceilometer backend to collect metric")
             return ceilometer
 
     def _get_metric_type(self, metric_name: str) -> MetricType:
         if metric_name not in INTERFACE_METRICS:
-            return MetricType.INSTANCE
+            if metric_name not in INSTANCE_DISK:
+                return MetricType.INSTANCE
+            else:
+                return MetricType.INSTANCEDISK
         else:
             return MetricType.INTERFACE_ALL
 
@@ -209,17 +220,15 @@ class OpenstackBackend:
 
 
 class GnocchiBackend(OpenstackBackend):
-    def __init__(self, vim_account: dict):
-        self.client = self._build_gnocchi_client(vim_account)
-        self.neutron = self._build_neutron_client(vim_account)
+    def __init__(self, vim_account: dict, vim_session: object):
+        self.client = self._build_gnocchi_client(vim_account, vim_session)
+        self.neutron = self._build_neutron_client(vim_account, vim_session)
 
-    def _build_gnocchi_client(self, vim_account: dict) -> gnocchi_client.Client:
-        sess = OpenstackUtils.get_session(vim_account)
-        return gnocchi_client.Client(session=sess)
+    def _build_gnocchi_client(self, vim_account: dict, vim_session: object) -> gnocchi_client.Client:
+        return gnocchi_client.Client(session=vim_session)
 
-    def _build_neutron_client(self, vim_account: dict) -> neutron_client.Client:
-        sess = OpenstackUtils.get_session(vim_account)
-        return neutron_client.Client(session=sess)
+    def _build_neutron_client(self, vim_account: dict, vim_session: object) -> neutron_client.Client:
+        return neutron_client.Client(session=vim_session)
 
     def collect_metric(
         self, metric_type: MetricType, metric_name: str, resource_id: str
@@ -230,6 +239,9 @@ class GnocchiBackend(OpenstackBackend):
         elif metric_type == MetricType.INSTANCE:
             return self._collect_instance_metric(metric_name, resource_id)
 
+        elif metric_type == MetricType.INSTANCEDISK:
+            return self._collect_instance_disk_metric(metric_name, resource_id)
+
         else:
             raise Exception("Unknown metric type %s" % metric_type.value)
 
@@ -258,6 +270,25 @@ class GnocchiBackend(OpenstackBackend):
                 )
         return total_measure
 
+    def _collect_instance_disk_metric(self, openstack_metric_name, resource_id):
+        value = None
+        instances = self.client.resource.search(
+            resource_type='instance_disk',
+            query={'=': {'instance_id': resource_id}},
+        )
+        for instance in instances:
+            try:
+                measures = self.client.metric.get_measures(
+                    openstack_metric_name, resource_id=instance['id'], limit=1
+                )
+                if measures:
+                    value = measures[-1][2]
+
+            except gnocchiclient.exceptions.NotFound as e:
+                log.debug("No metric %s found for instance disk %s: %s", openstack_metric_name,
+                          instance['id'], e)
+        return value
+
     def _collect_instance_metric(self, openstack_metric_name, resource_id):
         value = None
         try:
@@ -322,12 +353,11 @@ class GnocchiBackend(OpenstackBackend):
 
 
 class CeilometerBackend(OpenstackBackend):
-    def __init__(self, vim_account: dict):
-        self.client = self._build_ceilometer_client(vim_account)
+    def __init__(self, vim_account: dict, vim_session: object):
+        self.client = self._build_ceilometer_client(vim_account, vim_session)
 
-    def _build_ceilometer_client(self, vim_account: dict) -> ceilometer_client.Client:
-        sess = OpenstackUtils.get_session(vim_account)
-        return ceilometer_client.Client("2", session=sess)
+    def _build_ceilometer_client(self, vim_account: dict, vim_session: object) -> ceilometer_client.Client:
+        return ceilometer_client.Client("2", session=vim_session)
 
     def collect_metric(
         self, metric_type: MetricType, metric_name: str, resource_id: str