From 7c3e5d7afb1d038652ed863af508b2409aea9889 Mon Sep 17 00:00:00 2001
From: sguazt <marco.guazzone@gmail.com>
Date: Tue, 26 Jan 2021 17:23:59 +0100
Subject: [PATCH] Added handle property to access low-level platform interface

---
 easycloud/common/libcloud.py                  |  4 ++
 easycloud/core/compute.py                     | 14 ++++--
 easycloud/core/metamanager.py                 |  7 +++
 easycloud/core/metamonitor.py                 |  6 +++
 easycloud/modules/aws_awssdk/manager.py       | 17 ++++++--
 easycloud/modules/aws_awssdk/monitor.py       |  6 ++-
 easycloud/modules/aws_libcloud/manager.py     |  5 +++
 easycloud/modules/aws_libcloud/monitor.py     |  6 ++-
 .../modules/chameleon_libcloud/manager.py     |  5 +++
 .../modules/chameleon_libcloud/monitor.py     |  6 ++-
 .../modules/chameleon_openstacksdk/manager.py |  9 ++++
 .../modules/chameleon_openstacksdk/monitor.py |  6 ++-
 easycloud/modules/gcp_googleapi/manager.py    |  9 ++++
 easycloud/modules/gcp_googleapi/monitor.py    |  7 ++-
 easycloud/modules/gcp_libcloud/manager.py     |  5 +++
 easycloud/modules/gcp_libcloud/monitor.py     |  7 ++-
 .../modules/openstack_libcloud/manager.py     |  5 +++
 .../modules/openstack_libcloud/monitor.py     | 41 +++++++++++-------
 .../modules/openstack_openstacksdk/manager.py |  9 ++++
 .../modules/openstack_openstacksdk/monitor.py | 43 ++++++++++++-------
 20 files changed, 170 insertions(+), 47 deletions(-)

diff --git a/easycloud/common/libcloud.py b/easycloud/common/libcloud.py
index 0362417..b48468e 100644
--- a/easycloud/common/libcloud.py
+++ b/easycloud/common/libcloud.py
@@ -8,6 +8,10 @@ class LibcloudInstance(Instance):
         self._node = node
         self._status = InstanceStatus.from_string(node.state)
 
+    @property
+    def handle(self):
+        return self._node
+
     @property
     def id(self):
         return self._node.id
diff --git a/easycloud/core/compute.py b/easycloud/core/compute.py
index 80cb12e..3d75559 100644
--- a/easycloud/core/compute.py
+++ b/easycloud/core/compute.py
@@ -57,6 +57,16 @@ class Instance(ABC):
     #    self._name = name if name is not None else id
     #    self._status = status if status is not Node else InstanceStatus.UNKNOWN
 
+    @property
+    def extra(self):
+        return {}
+
+    @property
+    @abstractmethod
+    def handle(self):
+        """ Returns the low-level handle of this instance. """
+        pass
+
     @property
     @abstractmethod
     def id(self):
@@ -83,10 +93,6 @@ class Instance(ABC):
     def private_ips(self):
         return []
 
-    @property
-    def extra(self):
-        return {}
-
     @abstractmethod
     def destroy(self):
         """ Destroy this instance. """
diff --git a/easycloud/core/metamanager.py b/easycloud/core/metamanager.py
index 49e1067..257ccaa 100755
--- a/easycloud/core/metamanager.py
+++ b/easycloud/core/metamanager.py
@@ -54,6 +54,13 @@ class MetaManager(ABC):
         self._rule_file = rule_file if rule_file else self.DEFAULT_RULE_FILE
         self._read_rules_from_file()
 
+
+    @property
+    @abstractmethod
+    def handle(self):
+        """ Returns the low-level handle of the compute client. """
+        pass
+
     def menu(self):
         """
         Prints the Manager menu
diff --git a/easycloud/core/metamonitor.py b/easycloud/core/metamonitor.py
index 168a12a..7fe6a7a 100755
--- a/easycloud/core/metamonitor.py
+++ b/easycloud/core/metamonitor.py
@@ -93,6 +93,12 @@ class MetaMonitor(ABC):
         ##self._measures_sink_thread.setDaemon(True) #FIXME: is this really necessary? It seems that without it, the EasyCloud app blocks on exit
         #self._measures_sink_thread.daemon = True #FIXME: is this really necessary? It seems that without it, the EasyCloud app blocks on exit
 
+    @property
+    @abstractmethod
+    def handle(self):
+        """ Returns the low-level handle of the telemetry service client. """
+        pass
+
     #[ALTERNATIVE #1]
     """
     def _measures_sink_runner(self, sinks):
diff --git a/easycloud/modules/aws_awssdk/manager.py b/easycloud/modules/aws_awssdk/manager.py
index 0458aa3..c929079 100644
--- a/easycloud/modules/aws_awssdk/manager.py
+++ b/easycloud/modules/aws_awssdk/manager.py
@@ -59,6 +59,14 @@ class AWSInstance(Instance):
                 if 'Association' in priv_ip and 'PublicIp' in priv_ip['Association']:
                     self._public_ips.append(priv_ip['Association']['PublicIp'])
 
+    @property
+    def extra(self):
+        return self._ec2_inst
+
+    @property
+    def handle(self):
+        return self._ec2_inst
+
     @property
     def id(self):
         return self._ec2_inst['InstanceId']
@@ -80,10 +88,6 @@ class AWSInstance(Instance):
     def public_ips(self):
         return self._public_ips
 
-    @property
-    def extra(self):
-        return self._ec2_inst
-
     def destroy(self):
         self._ec2_conn.destroy_instances(InstanceIds=[self._ec2_inst['InstanceId']]) #, DryRun=True)
         return True # Boto3 will raise an exception if an operation fails (see: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/error-handling.html)
@@ -133,8 +137,13 @@ class AWS(MetaManager):
         self.conf = AWSConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.ec2_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.ec2_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/aws_awssdk/monitor.py b/easycloud/modules/aws_awssdk/monitor.py
index ba052cb..eedc335 100644
--- a/easycloud/modules/aws_awssdk/monitor.py
+++ b/easycloud/modules/aws_awssdk/monitor.py
@@ -28,6 +28,7 @@ class AWSMonitor(MetaMonitor):
             metrics_file (str): path to the metrics file
         """
         super().__init__(conf, commands_queue, measurements_queue, metrics_file)
+        self.cloudwatch_client = None
         self._bind_generic_metric_to_getter(name="cpu_load", function=self._get_cpu_measures)
         #
         # No metric available for memory_free
@@ -38,7 +39,10 @@ class AWSMonitor(MetaMonitor):
         # self._bind_generic_metric_to_getter(
         #    name="memory_used", function=self._get_memory_used_measures)
         #
-        logging.debug("[AWS MONITOR GETTERS]: " + str(self._metrics_getters))
+
+    @property
+    def handle(self):
+        return self.cloudwatch_client
 
     def connect(self):
         """
diff --git a/easycloud/modules/aws_libcloud/manager.py b/easycloud/modules/aws_libcloud/manager.py
index a299f44..7cb6ec7 100644
--- a/easycloud/modules/aws_libcloud/manager.py
+++ b/easycloud/modules/aws_libcloud/manager.py
@@ -29,8 +29,13 @@ class AWS(MetaManager):
         self.conf = AWSConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.ec2_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.ec2_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/aws_libcloud/monitor.py b/easycloud/modules/aws_libcloud/monitor.py
index a0d361a..2bef4e7 100644
--- a/easycloud/modules/aws_libcloud/monitor.py
+++ b/easycloud/modules/aws_libcloud/monitor.py
@@ -38,6 +38,7 @@ class AWSMonitor(MetaMonitor):
         """
         super().__init__(conf, commands_queue, measurements_queue)
         self._bind_generic_metric_to_getter(name="cpu_load", function=self._get_cpu_measures)
+        self.cloudwatch_client = None
         #
         # No metric available for memory_free
         # self._bind_generic_metric_to_getter(
@@ -47,7 +48,10 @@ class AWSMonitor(MetaMonitor):
         # self._bind_generic_metric_to_getter(
         #    name="memory_used", function=self._get_memory_used_measures)
         #
-        logging.debug("[AWS MONITOR GETTERS]: " + str(self._metrics_getters))
+
+    @property
+    def handle(self):
+        return self.cloudwatch_client
 
     def connect(self):
         """
diff --git a/easycloud/modules/chameleon_libcloud/manager.py b/easycloud/modules/chameleon_libcloud/manager.py
index ac599a8..33be42f 100644
--- a/easycloud/modules/chameleon_libcloud/manager.py
+++ b/easycloud/modules/chameleon_libcloud/manager.py
@@ -27,8 +27,13 @@ class ChameleonCloud(MetaManager):
         self.conf = ChameleonCloudConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.os_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.os_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/chameleon_libcloud/monitor.py b/easycloud/modules/chameleon_libcloud/monitor.py
index 7cfc8cc..22e7e1b 100644
--- a/easycloud/modules/chameleon_libcloud/monitor.py
+++ b/easycloud/modules/chameleon_libcloud/monitor.py
@@ -38,13 +38,17 @@ class ChameleonCloudMonitor(MetaMonitor):
             metrics_file (str): path to the metrics file
         """
         super().__init__(conf, commands_queue, measurements_queue, metrics_file)
+        self.gnocchi_client = None
         self._bind_generic_metric_to_getter(
             name="cpu_load", function=self._get_cpu_measures)
         self._bind_generic_metric_to_getter(
             name="memory_free", function=self._get_memory_free_measures)
         self._bind_generic_metric_to_getter(
             name="memory_used", function=self._get_memory_used_measures)
-        #logging.debug("[CHAMELEON CLOUD MONITOR GETTERS]: " + str(self._metrics_getters))
+
+    @property
+    def handle(self):
+        return self.gnocchi_client
 
     def connect(self):
         """
diff --git a/easycloud/modules/chameleon_openstacksdk/manager.py b/easycloud/modules/chameleon_openstacksdk/manager.py
index 5253a5c..3a9ada4 100644
--- a/easycloud/modules/chameleon_openstacksdk/manager.py
+++ b/easycloud/modules/chameleon_openstacksdk/manager.py
@@ -60,6 +60,10 @@ class OpenStackInstance(Instance):
     def extra(self):
         return self._os_inst
 
+    @property
+    def handle(self):
+        return self._os_inst
+
     @property
     def id(self):
         return self._os_inst.id
@@ -106,8 +110,13 @@ class ChameleonCloud(MetaManager):
         self.conf = ChameleonCloudConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.os_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.os_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/chameleon_openstacksdk/monitor.py b/easycloud/modules/chameleon_openstacksdk/monitor.py
index 3f725de..1e79a9b 100644
--- a/easycloud/modules/chameleon_openstacksdk/monitor.py
+++ b/easycloud/modules/chameleon_openstacksdk/monitor.py
@@ -34,13 +34,17 @@ class ChameleonCloudMonitor(MetaMonitor):
             metrics_file (str): path to the metrics file
         """
         super().__init__(conf, commands_queue, measurements_queue, metrics_file)
+        self.gnocchi_client = None
         self._bind_generic_metric_to_getter(
             name="cpu_load", function=self._get_cpu_measures)
         self._bind_generic_metric_to_getter(
             name="memory_free", function=self._get_memory_free_measures)
         self._bind_generic_metric_to_getter(
             name="memory_used", function=self._get_memory_used_measures)
-        #logging.debug("[CHAMELEON CLOUD MONITOR GETTERS]: " + str(self._metrics_getters))
+
+    @property
+    def handle(self):
+        return self.gnocchi_client
 
     def connect(self):
         """
diff --git a/easycloud/modules/gcp_googleapi/manager.py b/easycloud/modules/gcp_googleapi/manager.py
index 0bf1dba..ecc6f77 100644
--- a/easycloud/modules/gcp_googleapi/manager.py
+++ b/easycloud/modules/gcp_googleapi/manager.py
@@ -113,6 +113,10 @@ class GCPInstance(Instance):
     def extra(self):
         return self._gce_inst
 
+    @property
+    def handle(self):
+        return self._gce_inst
+
     @property
     def id(self):
         return self._gce_inst['id']
@@ -168,8 +172,13 @@ class GCP(MetaManager):
         self.conf = GCPConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.gcp_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.gcp_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/gcp_googleapi/monitor.py b/easycloud/modules/gcp_googleapi/monitor.py
index 6bad088..7b4f61a 100644
--- a/easycloud/modules/gcp_googleapi/monitor.py
+++ b/easycloud/modules/gcp_googleapi/monitor.py
@@ -39,6 +39,7 @@ class GCPMonitor(MetaMonitor):
                                         the platform RuleEngine
         """
         super().__init__(conf, commands_queue, measurements_queue)
+        self.stackdriver_client = None
 
         # For a list of supported metrics, see:
         #   https://cloud.google.com/monitoring/api/metrics_gcp
@@ -46,8 +47,10 @@ class GCPMonitor(MetaMonitor):
         self._bind_generic_metric_to_getter(name="cpu_load", function=self._get_cpu_measures)
         self._bind_generic_metric_to_getter(name="memory_free", function=self._get_memory_free_measures)
         self._bind_generic_metric_to_getter(name="memory_used", function=self._get_memory_used_measures)
-        #
-        logging.debug("[GCP MONITOR GETTERS]: " + str(self._metrics_getters))
+
+    @property
+    def handle(self):
+        return self.stackdriver_client
 
     def connect(self):
         """
diff --git a/easycloud/modules/gcp_libcloud/manager.py b/easycloud/modules/gcp_libcloud/manager.py
index 79da441..132dfe1 100644
--- a/easycloud/modules/gcp_libcloud/manager.py
+++ b/easycloud/modules/gcp_libcloud/manager.py
@@ -29,8 +29,13 @@ class GCP(MetaManager):
         self.conf = GCPConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.gcp_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.gcp_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/gcp_libcloud/monitor.py b/easycloud/modules/gcp_libcloud/monitor.py
index 6bad088..7b4f61a 100644
--- a/easycloud/modules/gcp_libcloud/monitor.py
+++ b/easycloud/modules/gcp_libcloud/monitor.py
@@ -39,6 +39,7 @@ class GCPMonitor(MetaMonitor):
                                         the platform RuleEngine
         """
         super().__init__(conf, commands_queue, measurements_queue)
+        self.stackdriver_client = None
 
         # For a list of supported metrics, see:
         #   https://cloud.google.com/monitoring/api/metrics_gcp
@@ -46,8 +47,10 @@ class GCPMonitor(MetaMonitor):
         self._bind_generic_metric_to_getter(name="cpu_load", function=self._get_cpu_measures)
         self._bind_generic_metric_to_getter(name="memory_free", function=self._get_memory_free_measures)
         self._bind_generic_metric_to_getter(name="memory_used", function=self._get_memory_used_measures)
-        #
-        logging.debug("[GCP MONITOR GETTERS]: " + str(self._metrics_getters))
+
+    @property
+    def handle(self):
+        return self.stackdriver_client
 
     def connect(self):
         """
diff --git a/easycloud/modules/openstack_libcloud/manager.py b/easycloud/modules/openstack_libcloud/manager.py
index f8fbbda..a414a35 100644
--- a/easycloud/modules/openstack_libcloud/manager.py
+++ b/easycloud/modules/openstack_libcloud/manager.py
@@ -26,8 +26,13 @@ class OpenStack(MetaManager):
         self.conf = OpenStackConfManager()
         self.cloned_instances = []
         # self.snapshots = None
+        self.os_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.os_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/openstack_libcloud/monitor.py b/easycloud/modules/openstack_libcloud/monitor.py
index 0ee6150..7eecd7a 100644
--- a/easycloud/modules/openstack_libcloud/monitor.py
+++ b/easycloud/modules/openstack_libcloud/monitor.py
@@ -41,17 +41,20 @@ class OpenStackMonitor(MetaMonitor):
         super().__init__(conf, commands_queue, measurements_queue)
 
         if conf.os_telemetry_metering == 'ceilometerclient':
-            self.client_ = OpenStackCeilometerClientDriver(conf, message_builder)
+            self._client = OpenStackCeilometerClientDriver(conf, message_builder)
         else: # == 'gnocchi' [default]
-            self.client_ = OpenStackGnocchiClientDriver(conf, message_builder)
+            self._client = OpenStackGnocchiClientDriver(conf, message_builder)
 
         self._bind_generic_metric_to_getter(name="cpu_load",
-                                            function=self.client_.get_cpu_load_measures)
+                                            function=self._client.get_cpu_load_measures)
         self._bind_generic_metric_to_getter(name="memory_free",
-                                            function=self.client_.get_memory_free_measures)
+                                            function=self._client.get_memory_free_measures)
         self._bind_generic_metric_to_getter(name="memory_used",
-                                            function=self.client_.get_memory_used_measures)
-        logging.debug("[OPENSTACK CLOUD MONITOR GETTERS]: " + str(self._metrics_getters))
+                                            function=self._client.get_memory_used_measures)
+
+    @property
+    def handle(self):
+        return self._client.handle
 
     def connect(self):
         """
@@ -76,7 +79,7 @@ class OpenStackMonitor(MetaMonitor):
         samples = []
 
         try:
-            samples = self.client_.get_metric_values(instance_id=instance_id,
+            samples = self._client.get_metric_values(instance_id=instance_id,
                                                      metric=metric,
                                                      granularit=granularity,
                                                      limit=limit)
@@ -116,7 +119,11 @@ class OpenStackCeilometerClientDriver():
         __import__('ceilometer.client')
         self.conf_ = conf
         self.message_builder_ = message_builder
-        self.client_ = None
+        self._client = None
+
+    @property
+    def handle(self):
+        return self._client
 
     def connect(self):
         """
@@ -129,7 +136,7 @@ class OpenStackCeilometerClientDriver():
                                         project_id=self.conf_.os_project_id,
                                         user_domain_name="default")
         #sess = ks_session.Session(auth=_auth, verify=False)
-        self.client_ = ceilometerclient.client.get_client("2", # v2 API
+        self._client = ceilometerclient.client.get_client("2", # v2 API
                                                           #session=sess)
                                                           auth=auth,
                                                           region_name=self.conf_.os_region)
@@ -246,7 +253,7 @@ class OpenStackCeilometerClientDriver():
             dict(field='timestamp', op='ge', value=start_time.strftime("%Y-%m-%dT%H:%M:%S")),
             dict(field='timestamp', op='le', value=end_time.strftime("%Y-%m-%dT%H:%M:%S"))
         ]
-        random_measurements_values = self.client_.samples.list(meter_name=metric,
+        random_measurements_values = self._client.samples.list(meter_name=metric,
                                                                q=query,
                                                                limit=limit)
         # Sort all the data (sometimes data can be unrodered)
@@ -285,7 +292,11 @@ class OpenStackGnocchiClientDriver():
         __import__('gnocchiclient.client')
         self.conf_ = conf
         self.message_builder_ = message_builder
-        self.client_ = None
+        self._client = None
+
+    @property
+    def handle(self):
+        return self._client
 
     def connect(self):
         """
@@ -297,7 +308,7 @@ class OpenStackGnocchiClientDriver():
                                         password=self.conf_.os_password,
                                         project_id=self.conf_.os_project_id,
                                         user_domain_name="default")
-        self.client_ = gnocchiclient.client.Client("1",
+        self._client = gnocchiclient.client.Client("1",
                                                    adapter_options={
                                                         "region_name": self.conf.os_region},
                                                         session_options={"auth": _auth})
@@ -389,10 +400,10 @@ class OpenStackGnocchiClientDriver():
 
         samples = []
 
-        instance_resources = self.client_.resource.get("generic", instance_id)
+        instance_resources = self._client.resource.get("generic", instance_id)
         logging.debug("Instance ID: " + str(instance_id))
         # logging.debug("FETCHING METRIC " + metric + ": " + str(instance_resources))
-        random_measurements_values = self.client_.metric.get_measures(instance_resources["metrics"][metric],
+        random_measurements_values = self._client.metric.get_measures(instance_resources["metrics"][metric],
                                                                       start=start_time_utc,
                                                                       end=end_time_utc,
                                                                       granularity=granularity)
@@ -400,7 +411,7 @@ class OpenStackGnocchiClientDriver():
         random_measurements_values.sort(key=lambda x: x[0])
         # Extract the most recent limit-values
         measurements_values = random_measurements_values[-limit:]
-        metric_unit = self.client_.metric.get(instance_resources["metrics"][metric])["unit"]
+        metric_unit = self._client.metric.get(instance_resources["metrics"][metric])["unit"]
         # Add the measurements to the list that will be returned
         for value in measurements_values:
             samples.append(self.message_builder_(timestamp=value[0],
diff --git a/easycloud/modules/openstack_openstacksdk/manager.py b/easycloud/modules/openstack_openstacksdk/manager.py
index 35dce83..5f3ceb7 100644
--- a/easycloud/modules/openstack_openstacksdk/manager.py
+++ b/easycloud/modules/openstack_openstacksdk/manager.py
@@ -63,6 +63,10 @@ class OpenStackInstance(Instance):
     def id(self):
         return self._os_inst.id
 
+    @property
+    def handle(self):
+        return self._os_inst
+
     @property
     def name(self):
         return self._os_inst.name
@@ -105,8 +109,13 @@ class OpenStack(MetaManager):
         self.conf = OpenStackConfManager(config_file)
         self.cloned_instances = []
         # self.snapshots = None
+        self.os_client = None
         self.connect()
 
+    @property
+    def handle(self):
+        return self.os_client
+
     # =============================================================================================== #
     #                                Platform-specific client creation                                #
     # =============================================================================================== #
diff --git a/easycloud/modules/openstack_openstacksdk/monitor.py b/easycloud/modules/openstack_openstacksdk/monitor.py
index 8ac18e4..9873c4f 100644
--- a/easycloud/modules/openstack_openstacksdk/monitor.py
+++ b/easycloud/modules/openstack_openstacksdk/monitor.py
@@ -35,17 +35,20 @@ class OpenStackMonitor(MetaMonitor):
         super().__init__(conf, commands_queue, measurements_queue)
 
         if conf.os_telemetry_metering == 'ceilometerclient':
-            self.client_ = OpenStackCeilometerClientDriver(conf, message_builder)
+            self._client = OpenStackCeilometerClientDriver(conf, message_builder)
         else: # == 'gnocchi' [default]
-            self.client_ = OpenStackGnocchiClientDriver(conf, message_builder)
+            self._client = OpenStackGnocchiClientDriver(conf, message_builder)
 
         self._bind_generic_metric_to_getter(name="cpu_load",
-                                            function=self.client_.get_cpu_load_measures)
+                                            function=self._client.get_cpu_load_measures)
         self._bind_generic_metric_to_getter(name="memory_free",
-                                            function=self.client_.get_memory_free_measures)
+                                            function=self._client.get_memory_free_measures)
         self._bind_generic_metric_to_getter(name="memory_used",
-                                            function=self.client_.get_memory_used_measures)
-        logging.debug("[OPENSTACK CLOUD MONITOR GETTERS]: " + str(self._metrics_getters))
+                                            function=self._client.get_memory_used_measures)
+
+    @property
+    def handle(self):
+        return self._client.handle
 
     def connect(self):
         """
@@ -70,7 +73,7 @@ class OpenStackMonitor(MetaMonitor):
         samples = []
 
         try:
-            samples = self.client_.get_metric_values(instance_id=instance_id,
+            samples = self._client.get_metric_values(instance_id=instance_id,
                                                      metric=metric,
                                                      granularit=granularity,
                                                      limit=limit)
@@ -110,7 +113,11 @@ class OpenStackCeilometerClientDriver():
         __import__('ceilometer.client')
         self.conf_ = conf
         self.message_builder_ = message_builder
-        self.client_ = None
+        self._client = None
+
+    @property
+    def handle(self):
+        return self._client
 
     def connect(self):
         """
@@ -123,7 +130,7 @@ class OpenStackCeilometerClientDriver():
                                         project_id=self.conf_.os_project_id,
                                         user_domain_name="default")
         #sess = ks_session.Session(auth=_auth, verify=False)
-        self.client_ = ceilometerclient.client.get_client("2", # v2 API
+        self._client = ceilometerclient.client.get_client("2", # v2 API
                                                           #session=sess)
                                                           auth=auth,
                                                           region_name=self.conf_.os_region)
@@ -240,7 +247,7 @@ class OpenStackCeilometerClientDriver():
             dict(field='timestamp', op='ge', value=start_time.strftime("%Y-%m-%dT%H:%M:%S")),
             dict(field='timestamp', op='le', value=end_time.strftime("%Y-%m-%dT%H:%M:%S"))
         ]
-        random_measurements_values = self.client_.samples.list(meter_name=metric,
+        random_measurements_values = self._client.samples.list(meter_name=metric,
                                                                q=query,
                                                                limit=limit)
         # Sort all the data (sometimes data can be unrodered)
@@ -279,7 +286,11 @@ class OpenStackGnocchiClientDriver():
         __import__('gnocchiclient.client')
         self.conf_ = conf
         self.message_builder_ = message_builder
-        self.client_ = None
+        self._client = None
+
+    @property
+    def handle(self):
+        return self._client
 
     def connect(self):
         """
@@ -291,7 +302,7 @@ class OpenStackGnocchiClientDriver():
         #                                password=self.conf_.os_password,
         #                                project_id=self.conf_.os_project_id,
         #                                user_domain_name="default")
-        #self.client_ = gnocchiclient.client.Client("1",
+        #self._client = gnocchiclient.client.Client("1",
         #                                           adapter_options={
         #                                                "region_name": self.conf_.os_region},
         #                                                session_options={"auth": auth})
@@ -302,7 +313,7 @@ class OpenStackGnocchiClientDriver():
                               user_domain_id='default',
                               project_domain_id='default')
         sess = ks_session.Session(auth=auth)
-        self.client_ = gnocchiclient.client.Client("1",
+        self._client = gnocchiclient.client.Client("1",
                                                    session=sess,
                                                    adapter_options={"region_name": self.conf_.os_region})
 
@@ -393,10 +404,10 @@ class OpenStackGnocchiClientDriver():
 
         samples = []
 
-        instance_resources = self.client_.resource.get("generic", instance_id)
+        instance_resources = self._client.resource.get("generic", instance_id)
         logging.debug("Instance ID: " + str(instance_id))
         # logging.debug("FETCHING METRIC " + metric + ": " + str(instance_resources))
-        random_measurements_values = self.client_.metric.get_measures(instance_resources["metrics"][metric],
+        random_measurements_values = self._client.metric.get_measures(instance_resources["metrics"][metric],
                                                                       start=start_time_utc,
                                                                       end=end_time_utc,
                                                                       granularity=granularity)
@@ -404,7 +415,7 @@ class OpenStackGnocchiClientDriver():
         random_measurements_values.sort(key=lambda x: x[0])
         # Extract the most recent limit-values
         measurements_values = random_measurements_values[-limit:]
-        metric_unit = self.client_.metric.get(instance_resources["metrics"][metric])["unit"]
+        metric_unit = self._client.metric.get(instance_resources["metrics"][metric])["unit"]
         # Add the measurements to the list that will be returned
         for value in measurements_values:
             samples.append(self.message_builder_(timestamp=value[0],
-- 
GitLab