From 769b23b43d856571358aaef5cdc907048049fc8e Mon Sep 17 00:00:00 2001 From: Adrian Moreno Date: Mon, 11 Dec 2017 15:37:27 +0100 Subject: [PATCH] Implement alerts endpoint and add tests for capacity endpoint --- README.rst | 4 +- ecsclient/common/monitoring/alerts.py | 54 ++++++++++++++++++++++++- ecsclient/common/monitoring/capacity.py | 10 ++--- ecsclient/common/util.py | 2 +- ecsclient/schemas.py | 26 ++++++++++++ ecsclient/v2/client.py | 4 +- ecsclient/v2/monitoring/__init__.py | 3 +- ecsclient/v3/client.py | 4 +- ecsclient/v3/monitoring/__init__.py | 3 +- tests/functional/test_alerts.py | 12 ++++++ tests/functional/test_capacity.py | 14 +++++++ 11 files changed, 120 insertions(+), 16 deletions(-) create mode 100644 tests/functional/test_alerts.py create mode 100644 tests/functional/test_capacity.py diff --git a/README.rst b/README.rst index ba2beb7..68a5c5b 100644 --- a/README.rst +++ b/README.rst @@ -163,13 +163,13 @@ The following table shows the supported endpoints per API version. +--------------------------+---------+---------+ | **Monitoring** | +--------------------------+---------+---------+ -| Capacity | ✓* | ✓* | +| Capacity | ✓ | ✓ | +--------------------------+---------+---------+ | Dashboard | ✓* | ✓* | +--------------------------+---------+---------+ | Events | ✓* | ✓* | +--------------------------+---------+---------+ -| Alerts | ✗ | ✗ | +| Alerts | ✓* | ✓* | +--------------------------+---------+---------+ | **Multi-tenancy** | +--------------------------+---------+---------+ diff --git a/ecsclient/common/monitoring/alerts.py b/ecsclient/common/monitoring/alerts.py index fdf35f4..80c8964 100644 --- a/ecsclient/common/monitoring/alerts.py +++ b/ecsclient/common/monitoring/alerts.py @@ -4,5 +4,55 @@ class Alerts(object): - # TODO: implement it - pass + + def __init__(self, connection): + """ + Initialize a new instance + """ + self.conn = connection + + def get_alerts(self, namespace=None, start_time=None, end_time=None, marker=None, limit=None, + severity=None, type=None, acknowledged=None): + """ + Gets the list of alerts with optional filters + + Required role(s): + + SYSTEM_ADMIN + + Example JSON result from the API: + + { + ... + } + + :param namespace: Namespace for which alerts should be listed + :param start_time: Start time for listing alerts + :param end_time: End time for listing alerts + :param marker: Reference to last alert returned + :param limit: Number of alerts requested in current fetch + :param severity: Severity of alerts to be listed + :param type: Type of alerts to be listed + :param acknowledged: Boolean to filter by acknowledgement + """ + + filters = {} + if namespace: + filters['namespace'] = namespace + if start_time: + filters['start_time'] = start_time + if end_time: + filters['end_time'] = end_time + if marker: + filters['marker'] = marker + if limit: + filters['limit'] = limit + if severity: + filters['severity'] = severity + if type: + filters['type'] = type + if acknowledged: + filters['acknowledged'] = acknowledged + + log.info("Getting alerts with filters: %s", (filters,)) + return self.conn.get(url='vdc/alerts', params=filters) diff --git a/ecsclient/common/monitoring/capacity.py b/ecsclient/common/monitoring/capacity.py index f8da6bd..dcc4598 100644 --- a/ecsclient/common/monitoring/capacity.py +++ b/ecsclient/common/monitoring/capacity.py @@ -11,7 +11,7 @@ def __init__(self, connection): """ self.conn = connection - def get_cluster_capacity(self, v_array_id=None): + def get_cluster_capacity(self, storage_pool_id=None): """ Gets the capacity of the cluster. The details includes the provisioned capacity in GB and available capacity in GB. @@ -28,12 +28,12 @@ def get_cluster_capacity(self, v_array_id=None): u'totalProvisioned_gb': 2578400 } - :param v_array_id: Storage pool identifier for which to retrieve + :param storage_pool_id: Storage pool identifier for which to retrieve capacity (optional) """ - if v_array_id: - log.info("Getting capacity of varray '{0}'".format(v_array_id)) - return self.conn.get(url='object/capacity/{0}'.format(v_array_id)) + if storage_pool_id: + log.info("Getting capacity of storage pool '{0}'".format(storage_pool_id)) + return self.conn.get(url='object/capacity/{0}'.format(storage_pool_id)) else: log.info("Getting capacity of storage cluster") return self.conn.get(url='object/capacity') diff --git a/ecsclient/common/util.py b/ecsclient/common/util.py index 8693535..3ebf856 100644 --- a/ecsclient/common/util.py +++ b/ecsclient/common/util.py @@ -42,5 +42,5 @@ def is_valid_response(response, schema): validate(response, schema, format_checker=FormatChecker()) return True except Exception as e: - log.warning("Response is not valid: %s" % (e.msg,)) + log.warning("Response is not valid: %s" % (e,)) return False diff --git a/ecsclient/schemas.py b/ecsclient/schemas.py index 8a763c3..08fd914 100644 --- a/ecsclient/schemas.py +++ b/ecsclient/schemas.py @@ -831,3 +831,29 @@ "node" ] } + +ALERTS = { + "type": "object", + "properties": { + "MaxAlerts": {"type": "number"}, + "Filter": {"type": "string"}, + "alert": {"type": "array"} + }, + "required": [ + "MaxAlerts", + "Filter", + "alert" + ] +} + +CAPACITY = { + "type": "object", + "properties": { + "totalFree_gb": {"type": "number"}, + "totalProvisioned_gb": {"type": "number"} + }, + "required": [ + "totalFree_gb", + "totalProvisioned_gb" + ] +} diff --git a/ecsclient/v2/client.py b/ecsclient/v2/client.py index 04146b9..ff2ebed 100644 --- a/ecsclient/v2/client.py +++ b/ecsclient/v2/client.py @@ -8,7 +8,7 @@ from ecsclient.v2.provisioning import base_url, bucket, data_store, storage_pool, virtual_data_center, node, \ vdc_keystore from ecsclient.v2.metering import billing -from ecsclient.v2.monitoring import capacity, dashboard, events +from ecsclient.v2.monitoring import capacity, dashboard, events, alerts from ecsclient.v2.multitenancy import namespace from ecsclient.v2.user_management import authentication_provider, management_user, object_user, secret_key from ecsclient.v2.other import user_info @@ -46,7 +46,7 @@ def __init__(self, *args, **kwargs): self.capacity = capacity.Capacity(self) self.dashboard = dashboard.Dashboard(self) self.events = events.Events(self) - # TODO: self.alerts = alerts.Alerts(self) + self.alerts = alerts.Alerts(self) # Multi-tenancy self.namespace = namespace.Namespace(self) diff --git a/ecsclient/v2/monitoring/__init__.py b/ecsclient/v2/monitoring/__init__.py index d44dac9..4c7e028 100644 --- a/ecsclient/v2/monitoring/__init__.py +++ b/ecsclient/v2/monitoring/__init__.py @@ -1,5 +1,6 @@ -from ecsclient.common.monitoring import capacity, dashboard, events +from ecsclient.common.monitoring import capacity, dashboard, events, alerts capacity = capacity dashboard = dashboard events = events +alerts = alerts diff --git a/ecsclient/v3/client.py b/ecsclient/v3/client.py index 16ed876..b0e4699 100644 --- a/ecsclient/v3/client.py +++ b/ecsclient/v3/client.py @@ -5,7 +5,7 @@ licensing, feature, syslog, snmp from ecsclient.v3.cas import cas from ecsclient.v3.metering import billing -from ecsclient.v3.monitoring import capacity, dashboard, events +from ecsclient.v3.monitoring import capacity, dashboard, events, alerts from ecsclient.v3.multitenancy import namespace from ecsclient.v3.geo_replication import replication_group, temporary_failed_zone from ecsclient.v3.provisioning import base_url, bucket, data_store, storage_pool, \ @@ -48,7 +48,7 @@ def __init__(self, *args, **kwargs): self.capacity = capacity.Capacity(self) self.dashboard = dashboard.Dashboard(self) self.events = events.Events(self) - # TODO: self.alerts = alerts.Alerts(self) + self.alerts = alerts.Alerts(self) # Multi-tenancy self.namespace = namespace.Namespace(self) diff --git a/ecsclient/v3/monitoring/__init__.py b/ecsclient/v3/monitoring/__init__.py index d44dac9..4c7e028 100644 --- a/ecsclient/v3/monitoring/__init__.py +++ b/ecsclient/v3/monitoring/__init__.py @@ -1,5 +1,6 @@ -from ecsclient.common.monitoring import capacity, dashboard, events +from ecsclient.common.monitoring import capacity, dashboard, events, alerts capacity = capacity dashboard = dashboard events = events +alerts = alerts diff --git a/tests/functional/test_alerts.py b/tests/functional/test_alerts.py new file mode 100644 index 0000000..d1b6831 --- /dev/null +++ b/tests/functional/test_alerts.py @@ -0,0 +1,12 @@ +from ecsclient import schemas +from tests import functional + + +class TestAlerts(functional.BaseTestCase): + def test_alerts_no_params(self): + response = self.client.alerts.get_alerts() + # TODO: complete the schema with alert element validation + self.assertValidSchema(response, schemas.ALERTS) + + def test_alerts_with_params(self): + self.skipTest("Need to test it with params") diff --git a/tests/functional/test_capacity.py b/tests/functional/test_capacity.py new file mode 100644 index 0000000..5417737 --- /dev/null +++ b/tests/functional/test_capacity.py @@ -0,0 +1,14 @@ +from ecsclient import schemas +from tests import functional + + +class TestCapacity(functional.BaseTestCase): + + def test_get_cluster_capacity(self): + response = self.client.capacity.get_cluster_capacity() + self.assertValidSchema(response, schemas.CAPACITY) + + def test_get_cluster_capacity_storage_pool(self): + sps = self.client.storage_pool.list() + response = self.client.capacity.get_cluster_capacity(storage_pool_id=sps['varray'][0]['id']) + self.assertValidSchema(response, schemas.CAPACITY)