summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalazs Gibizer <balazs.gibizer@ericsson.com>2014-02-20 16:00:53 +0100
committerIldiko Vancsa <ildiko.vancsa@ericsson.com>2014-03-18 14:57:39 +0100
commit10686a6189fca0a30167e6ee07b7482894677a00 (patch)
treea49a2bca92b09f0da8c0d011c1ff8d3fd60ed7d6
parent08e644110aff268d5110c77b2b590d503252e6ef (diff)
downloadpython-ceilometerclient-10686a6189fca0a30167e6ee07b7482894677a00.tar.gz
Add complex query support for alarms
Change-Id: I3305d679d128562f7794a5cf460093981a601f7c
-rw-r--r--ceilometerclient/tests/v2/test_query_alarms.py72
-rw-r--r--ceilometerclient/tests/v2/test_query_samples.py4
-rw-r--r--ceilometerclient/tests/v2/test_shell.py67
-rw-r--r--ceilometerclient/v2/client.py6
-rw-r--r--ceilometerclient/v2/query.py (renamed from ceilometerclient/v2/query_samples.py)21
-rw-r--r--ceilometerclient/v2/shell.py28
6 files changed, 187 insertions, 11 deletions
diff --git a/ceilometerclient/tests/v2/test_query_alarms.py b/ceilometerclient/tests/v2/test_query_alarms.py
new file mode 100644
index 0000000..199caa7
--- /dev/null
+++ b/ceilometerclient/tests/v2/test_query_alarms.py
@@ -0,0 +1,72 @@
+# Copyright Ericsson AB 2014. All rights reserved
+#
+# Author: Balazs Gibizer <balazs.gibizer@ericsson.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from ceilometerclient.tests import utils
+from ceilometerclient.v2 import query
+
+
+ALARM = {"alarm_actions": ["http://site:8000/alarm"],
+ "alarm_id": None,
+ "combination_rule": {
+ "alarm_ids": [
+ "739e99cb-c2ec-4718-b900-332502355f38",
+ "153462d0-a9b8-4b5b-8175-9e4b05e9b856"],
+ "operator": "or"},
+ "description": "An alarm",
+ "enabled": True,
+ "insufficient_data_actions": ["http://site:8000/nodata"],
+ "name": "SwiftObjectAlarm",
+ "ok_actions": ["http://site:8000/ok"],
+ "project_id": "c96c887c216949acbdfbd8b494863567",
+ "repeat_actions": False,
+ "state": "ok",
+ "state_timestamp": "2014-02-20T10:37:15.589860",
+ "threshold_rule": None,
+ "timestamp": "2014-02-20T10:37:15.589856",
+ "type": "combination",
+ "user_id": "c96c887c216949acbdfbd8b494863567"}
+
+QUERY = {"filter": {"and": [{"!=": {"state": "ok"}},
+ {"=": {"type": "combination"}}]},
+ "orderby": [{"state_timestamp": "desc"}],
+ "limit": 10}
+
+base_url = '/v2/query/alarms'
+fixtures = {
+ base_url:
+ {
+ 'POST': (
+ {},
+ [ALARM],
+ ),
+ },
+}
+
+
+class QueryAlarmsManagerTest(utils.BaseTestCase):
+
+ def setUp(self):
+ super(QueryAlarmsManagerTest, self).setUp()
+ self.api = utils.FakeAPI(fixtures)
+ self.mgr = query.QueryAlarmsManager(self.api)
+
+ def test_query(self):
+ alarms = self.mgr.query(**QUERY)
+ expect = [
+ ('POST', '/v2/query/alarms', {}, QUERY),
+ ]
+ self.assertEqual(expect, self.api.calls)
+ self.assertEqual(1, len(alarms))
diff --git a/ceilometerclient/tests/v2/test_query_samples.py b/ceilometerclient/tests/v2/test_query_samples.py
index 854056c..b12a508 100644
--- a/ceilometerclient/tests/v2/test_query_samples.py
+++ b/ceilometerclient/tests/v2/test_query_samples.py
@@ -15,7 +15,7 @@
# under the License.
from ceilometerclient.tests import utils
-from ceilometerclient.v2 import query_samples
+from ceilometerclient.v2 import query
SAMPLE = {u'id': u'b55d1526-9929-11e3-a3f6-02163e5df1e6',
@@ -54,7 +54,7 @@ class QuerySamplesManagerTest(utils.BaseTestCase):
def setUp(self):
super(QuerySamplesManagerTest, self).setUp()
self.api = utils.FakeAPI(fixtures)
- self.mgr = query_samples.QuerySamplesManager(self.api)
+ self.mgr = query.QuerySamplesManager(self.api)
def test_query(self):
samples = self.mgr.query(**QUERY)
diff --git a/ceilometerclient/tests/v2/test_shell.py b/ceilometerclient/tests/v2/test_shell.py
index 47ad578..3d8aca2 100644
--- a/ceilometerclient/tests/v2/test_shell.py
+++ b/ceilometerclient/tests/v2/test_shell.py
@@ -469,3 +469,70 @@ class ShellQuerySamplesCommandTest(utils.BaseTestCase):
+--------------------------------------+----------+-------+--------+---------\
-+----------------------------+
''', output.getvalue())
+
+
+class ShellQueryAlarmsCommandTest(utils.BaseTestCase):
+
+ ALARM = [{"alarm_actions": ["http://site:8000/alarm"],
+ "alarm_id": "768ff714-8cfb-4db9-9753-d484cb33a1cc",
+ "combination_rule": {
+ "alarm_ids": [
+ "739e99cb-c2ec-4718-b900-332502355f38",
+ "153462d0-a9b8-4b5b-8175-9e4b05e9b856"],
+ "operator": "or"},
+ "description": "An alarm",
+ "enabled": True,
+ "insufficient_data_actions": ["http://site:8000/nodata"],
+ "name": "SwiftObjectAlarm",
+ "ok_actions": ["http://site:8000/ok"],
+ "project_id": "c96c887c216949acbdfbd8b494863567",
+ "repeat_actions": False,
+ "state": "ok",
+ "state_timestamp": "2014-02-20T10:37:15.589860",
+ "threshold_rule": None,
+ "timestamp": "2014-02-20T10:37:15.589856",
+ "type": "combination",
+ "user_id": "c96c887c216949acbdfbd8b494863567"}]
+
+ QUERY = {"filter": {"and": [{"!=": {"state": "ok"}},
+ {"=": {"type": "combination"}}]},
+ "orderby": [{"state_timestamp": "desc"}],
+ "limit": 10}
+
+ def setUp(self):
+ super(ShellQueryAlarmsCommandTest, self).setUp()
+ self.cc = mock.Mock()
+ self.args = mock.Mock()
+ self.args.filter = self.QUERY["filter"]
+ self.args.orderby = self.QUERY["orderby"]
+ self.args.limit = self.QUERY["limit"]
+
+ def test_query(self):
+
+ ret_alarm = [alarms.Alarm(mock.Mock(), alarm)
+ for alarm in self.ALARM]
+ self.cc.query_alarms.query.return_value = ret_alarm
+ org_stdout = sys.stdout
+ try:
+ sys.stdout = output = six.StringIO()
+ ceilometer_shell.do_query_alarms(self.cc, self.args)
+ finally:
+ sys.stdout = org_stdout
+
+ self.assertEqual('''\
++--------------------------------------+------------------+-------+---------\
++------------+--------------------------------------------------------------\
+----------------------------------------+
+| Alarm ID | Name | State | Enabled \
+| Continuous | Alarm condition \
+ |
++--------------------------------------+------------------+-------+---------\
++------------+--------------------------------------------------------------\
+----------------------------------------+
+| 768ff714-8cfb-4db9-9753-d484cb33a1cc | SwiftObjectAlarm | ok | True \
+| False | combinated states (OR) of 739e99cb-c2ec-4718-b900-332502355f3\
+8, 153462d0-a9b8-4b5b-8175-9e4b05e9b856 |
++--------------------------------------+------------------+-------+---------\
++------------+--------------------------------------------------------------\
+----------------------------------------+
+''', output.getvalue())
diff --git a/ceilometerclient/v2/client.py b/ceilometerclient/v2/client.py
index bf76deb..b6aadbf 100644
--- a/ceilometerclient/v2/client.py
+++ b/ceilometerclient/v2/client.py
@@ -19,7 +19,7 @@ from ceilometerclient.v2 import alarms
from ceilometerclient.v2 import event_types
from ceilometerclient.v2 import events
from ceilometerclient.v2 import meters
-from ceilometerclient.v2 import query_samples
+from ceilometerclient.v2 import query
from ceilometerclient.v2 import resources
from ceilometerclient.v2 import samples
from ceilometerclient.v2 import statistics
@@ -50,5 +50,7 @@ class Client(object):
self.traits = traits.TraitManager(self.http_client)
self.trait_info = trait_descriptions.\
TraitDescriptionManager(self.http_client)
- self.query_samples = query_samples.QuerySamplesManager(
+ self.query_samples = query.QuerySamplesManager(
+ self.http_client)
+ self.query_alarms = query.QueryAlarmsManager(
self.http_client)
diff --git a/ceilometerclient/v2/query_samples.py b/ceilometerclient/v2/query.py
index d0b1f30..97608a7 100644
--- a/ceilometerclient/v2/query_samples.py
+++ b/ceilometerclient/v2/query.py
@@ -15,15 +15,12 @@
# under the License.
from ceilometerclient.common import base
+from ceilometerclient.v2 import alarms
from ceilometerclient.v2 import samples
-class QuerySamplesManager(base.Manager):
- resource_class = samples.Sample
-
- @staticmethod
- def _path():
- return '/v2/query/samples'
+class QueryManager(base.Manager):
+ path_suffix = None
def query(self, filter, orderby, limit):
query = {}
@@ -34,7 +31,7 @@ class QuerySamplesManager(base.Manager):
if limit:
query["limit"] = limit
- url = self._path()
+ url = '/v2/query%s' % self.path_suffix
resp, body = self.api.json_request('POST',
url,
body=query)
@@ -42,3 +39,13 @@ class QuerySamplesManager(base.Manager):
return [self.resource_class(self, b) for b in body]
else:
return []
+
+
+class QuerySamplesManager(QueryManager):
+ resource_class = samples.Sample
+ path_suffix = '/samples'
+
+
+class QueryAlarmsManager(QueryManager):
+ resource_class = alarms.Alarm
+ path_suffix = '/alarms'
diff --git a/ceilometerclient/v2/shell.py b/ceilometerclient/v2/shell.py
index 2eeef27..1a4dfdd 100644
--- a/ceilometerclient/v2/shell.py
+++ b/ceilometerclient/v2/shell.py
@@ -671,3 +671,31 @@ def do_query_samples(cc, args):
'volume', 'unit', 'timestamp']
utils.print_list(samples, fields, field_labels,
sortby=None)
+
+
+@utils.arg('-f', '--filter', metavar='<FILTER>',
+ help=('{complex_op: [{simple_op: {field_name: value}}]} '
+ 'The complex_op is one of: ' + str(COMPLEX_OPERATORS) + ', '
+ 'simple_op is one of: ' + str(SIMPLE_OPERATORS) + '.'))
+@utils.arg('-o', '--orderby', metavar='<ORDERBY>',
+ help=('[{field_name: direction}, {field_name: direction}] '
+ 'The direction is one of: ' + str(ORDER_DIRECTIONS) + '.'))
+@utils.arg('-l', '--limit', metavar='<LIMIT>',
+ help='Maximum number of alarms to return.')
+def do_query_alarms(cc, args):
+ '''Query Alarms.'''
+ fields = {'filter': args.filter,
+ 'orderby': args.orderby,
+ 'limit': args.limit}
+ try:
+ alarms = cc.query_alarms.query(**fields)
+ except exc.HTTPNotFound:
+ raise exc.CommandError('Alarms not found')
+ else:
+ field_labels = ['Alarm ID', 'Name', 'State', 'Enabled', 'Continuous',
+ 'Alarm condition']
+ fields = ['alarm_id', 'name', 'state', 'enabled', 'repeat_actions',
+ 'rule']
+ utils.print_list(alarms, fields, field_labels,
+ formatters={'rule': alarm_rule_formatter},
+ sortby=None)