[lxc-devel] [pylxd/master] [WIP] Added support for filtering events by type

moysesb on Github lxc-bot at linuxcontainers.org
Mon Dec 10 07:00:13 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 388 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181210/ebb63a0c/attachment.bin>
-------------- next part --------------
From ab88e256565c5ba6e028d97b9b9439b9df1eea2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Moys=C3=A9s=20Borges?= <moyses at gmail.com>
Date: Sun, 9 Dec 2018 21:56:25 -0200
Subject: [PATCH] Added support for filtering events by type
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Moysés Borges <moyses at gmail.com>
---
 pylxd/__init__.py          |  2 +-
 pylxd/client.py            | 23 +++++++++++++++++++--
 pylxd/tests/test_client.py | 41 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/pylxd/__init__.py b/pylxd/__init__.py
index 76cef15..53dfe4e 100644
--- a/pylxd/__init__.py
+++ b/pylxd/__init__.py
@@ -16,4 +16,4 @@
 
 __version__ = pbr.version.VersionInfo('pylxd').version_string()
 
-from pylxd.client import Client  # NOQA
+from pylxd.client import Client,EventType  # NOQA
diff --git a/pylxd/client.py b/pylxd/client.py
index e3558f4..d756bb7 100644
--- a/pylxd/client.py
+++ b/pylxd/client.py
@@ -15,6 +15,7 @@
 import os
 import os.path
 from collections import namedtuple
+from enum import Enum
 
 import requests
 import requests_unixsocket
@@ -45,6 +46,16 @@
 )  # pragma: no cover
 
 
+class EventType(Enum):
+    All = 'all'
+    Operation = 'operation'
+    Logging = 'logging'
+    Lifecycle = 'lifecycle'
+
+
+DEFAULT_EVENT_FILTER = {EventType.All}
+
+
 class _APINode(object):
     """An api node object."""
 
@@ -354,7 +365,7 @@ def websocket_url(self):
         url = parse.urlunparse((scheme, host, '', '', '', ''))
         return url
 
-    def events(self, websocket_client=None):
+    def events(self, websocket_client=None, event_types=DEFAULT_EVENT_FILTER):
         """Get a websocket client for getting events.
 
         /events is a websocket url, and so must be handled differently than
@@ -374,6 +385,14 @@ def events(self, websocket_client=None):
 
         client = websocket_client(self.websocket_url)
         parsed = parse.urlparse(self.api.events._api_endpoint)
-        client.resource = parsed.path
+
+        resource = parsed.path
+
+        if event_types and EventType.All not in event_types:
+            query = parse.parse_qs(parsed.query)
+            query.update({'type': ','.join(t.value for t in event_types)})
+            resource = '{}?{}'.format(resource, parse.urlencode(query))
+
+        client.resource = resource
 
         return client
diff --git a/pylxd/tests/test_client.py b/pylxd/tests/test_client.py
index 46dd6f9..4e954f8 100644
--- a/pylxd/tests/test_client.py
+++ b/pylxd/tests/test_client.py
@@ -20,6 +20,8 @@
 import requests
 import requests_unixsocket
 
+from six.moves.urllib import parse
+
 from pylxd import client, exceptions
 from pylxd.tests.testing import requires_ws4py
 
@@ -239,6 +241,45 @@ def test_events_https(self):
 
         WebsocketClient.assert_called_once_with('wss://lxd.local')
 
+    @requires_ws4py
+    def test_events_type_filter(self):
+        """The websocket client can filter events by type."""
+
+        an_client = client.Client()
+
+        # from the itertools recipes documentation
+        def powerset(types):
+            from itertools import chain, combinations
+            pwset = [combinations(types, r) for r in range(len(types) + 1)]
+            return chain.from_iterable(pwset)
+
+        event_path = '/1.0/events'
+
+        for types in powerset(client.EventType):
+            ws_client = an_client.events(event_types=set(types))
+
+            actual_resource = parse.urlparse(ws_client.resource)
+            expect_resource = parse.urlparse(event_path)
+
+            if types and client.EventType.All not in types:
+                type_csl = ','.join([t.value for t in types])
+                query = parse.parse_qs(expect_resource.query)
+                query.update({'type': type_csl})
+                qs = parse.urlencode(query)
+                expect_resource = expect_resource._replace(query=qs)
+
+            self.assertEqual(expect_resource.path, actual_resource.path)
+
+            if types and client.EventType.All not in types:
+                qdict = parse.parse_qs(expect_resource.query)
+                expect_types = set(qdict['type'][0].split(','))
+                qdict = parse.parse_qs(actual_resource.query)
+                actual_types = set(qdict['type'][0].split(','))
+
+                self.assertEqual(expect_types, actual_types)
+            else:
+                self.assertEqual(expect_resource.query, actual_resource.query)
+
     def test_has_api_extension(self):
         a_client = client.Client()
         a_client.host_info = {'api_extensions': ["one", "two"]}


More information about the lxc-devel mailing list