From f682eb5c81c99d88ec4fd63ed88eaefb7225a704 Mon Sep 17 00:00:00 2001 From: ibrahim Date: Sat, 14 Jul 2018 16:20:14 +0200 Subject: [PATCH 1/7] Add node_meta to catalog/register endpoint --- consul/base.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/consul/base.py b/consul/base.py index 16489264..0531d962 100755 --- a/consul/base.py +++ b/consul/base.py @@ -1066,7 +1066,8 @@ def register(self, service=None, check=None, dc=None, - token=None): + token=None, + node_meta=None): """ A low level mechanism for directly registering or updating entries in the catalog. It is usually recommended to use @@ -1116,6 +1117,9 @@ def register(self, *token* is an optional `ACL token`_ to apply to this request. + *node_meta* is an optional meta data used for filtering, a + dictionary formatted as {k1:v1, k2:v2}. + This manipulates the health check entry, but does not setup a script or TTL to actually update the status. The full documentation is `here `_. @@ -1135,6 +1139,10 @@ def register(self, if token: data['WriteRequest'] = {'Token': token} params.append(('token', token)) + if node_meta: + for nodemeta_name, nodemeta_value in node_meta.items(): + params.append(('node-meta', '{}:{}'. + format(nodemeta_name, nodemeta_value))) return self.agent.http.put( CB.bool(), '/v1/catalog/register', From d150e83eb28349e30823026d5853c69b7a67669f Mon Sep 17 00:00:00 2001 From: ibrahim Date: Fri, 20 Jul 2018 22:09:25 +0200 Subject: [PATCH 2/7] Add unittest to node_meta parameter --- tests/test_base.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_base.py b/tests/test_base.py index 33db422c..b8f86c46 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -48,6 +48,18 @@ def _should_support(c): ) +def _should_support_node_meta(c): + return ( + # catalog + c.catalog.nodes, + c.catalog.services, + lambda **kw: c.health.service('foo', **kw), + lambda **kw: c.health.checks('foo', **kw), + lambda **kw: c.health.state('unknown', **kw), + lambda **kw: c.catalog.register('foo', 'bar', **kw), + ) + + class TestIndex(object): """ Tests read requests that should support blocking on an index @@ -80,6 +92,20 @@ def test_implicit(self): assert r(consistency='stale').params == [('stale', '1')] +class TestNodemeta(object): + """ + Tests read requests that should support node_meta + """ + + def test_node_meta(self): + import sys + c = Consul() + for r in _should_support_node_meta(c): + assert r().params == [] + assert r(node_meta={'env': 'prod', 'net': 1}).params == \ + [('node-meta', 'net:1'), ('node-meta', 'env:prod')] + + class TestCB(object): def test_status_200_passes(self): From b5b610035ce846b067e39a1b5bcecd034ef8fe66 Mon Sep 17 00:00:00 2001 From: ibrahim Date: Fri, 20 Jul 2018 22:18:54 +0200 Subject: [PATCH 3/7] Ensure order doesn't affect node_meta unittest --- tests/test_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_base.py b/tests/test_base.py index b8f86c46..186cff27 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -102,8 +102,8 @@ def test_node_meta(self): c = Consul() for r in _should_support_node_meta(c): assert r().params == [] - assert r(node_meta={'env': 'prod', 'net': 1}).params == \ - [('node-meta', 'net:1'), ('node-meta', 'env:prod')] + assert sorted(r(node_meta={'env': 'prod', 'net': 1}).params) == \ + sorted([('node-meta', 'net:1'), ('node-meta', 'env:prod')]) class TestCB(object): From 23df6039bb34b1adbbfa54ff1d211ec3a441eeec Mon Sep 17 00:00:00 2001 From: ibrahim Date: Fri, 20 Jul 2018 22:45:07 +0200 Subject: [PATCH 4/7] Make code compatible with python 2.6 --- consul/base.py | 12 ++++++------ tests/test_base.py | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/consul/base.py b/consul/base.py index 0531d962..9990d74b 100755 --- a/consul/base.py +++ b/consul/base.py @@ -1141,7 +1141,7 @@ def register(self, params.append(('token', token)) if node_meta: for nodemeta_name, nodemeta_value in node_meta.items(): - params.append(('node-meta', '{}:{}'. + params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) return self.agent.http.put( CB.bool(), @@ -1256,7 +1256,7 @@ def nodes( params.append((consistency, '1')) if node_meta: for nodemeta_name, nodemeta_value in node_meta.items(): - params.append(('node-meta', '{}:{}'. + params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) return self.agent.http.get( @@ -1320,7 +1320,7 @@ def services(self, params.append((consistency, '1')) if node_meta: for nodemeta_name, nodemeta_value in node_meta.items(): - params.append(('node-meta', '{}:{}'. + params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) return self.agent.http.get( @@ -1529,7 +1529,7 @@ def service(self, params.append(('token', token)) if node_meta: for nodemeta_name, nodemeta_value in node_meta.items(): - params.append(('node-meta', '{}:{}'. + params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) return self.agent.http.get( @@ -1585,7 +1585,7 @@ def checks( params.append(('token', token)) if node_meta: for nodemeta_name, nodemeta_value in node_meta.items(): - params.append(('node-meta', '{}:{}'. + params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) return self.agent.http.get( @@ -1646,7 +1646,7 @@ def state(self, params.append(('token', token)) if node_meta: for nodemeta_name, nodemeta_value in node_meta.items(): - params.append(('node-meta', '{}:{}'. + params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) return self.agent.http.get( CB.json(index=True), diff --git a/tests/test_base.py b/tests/test_base.py index 186cff27..aad84278 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -98,7 +98,6 @@ class TestNodemeta(object): """ def test_node_meta(self): - import sys c = Consul() for r in _should_support_node_meta(c): assert r().params == [] From 2a43a6ac4a1e4a1ce274ff24c162b1c35f206fc7 Mon Sep 17 00:00:00 2001 From: ibrahim Date: Sat, 21 Jul 2018 09:42:15 +0200 Subject: [PATCH 5/7] Reorder unittests --- tests/test_base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_base.py b/tests/test_base.py index aad84278..8e9d25a8 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -53,10 +53,11 @@ def _should_support_node_meta(c): # catalog c.catalog.nodes, c.catalog.services, + lambda **kw: c.catalog.register('foo', 'bar', **kw), + # health lambda **kw: c.health.service('foo', **kw), lambda **kw: c.health.checks('foo', **kw), lambda **kw: c.health.state('unknown', **kw), - lambda **kw: c.catalog.register('foo', 'bar', **kw), ) From 8753931144208cb333428b29b49824d11bb51aef Mon Sep 17 00:00:00 2001 From: ibrahim Date: Tue, 24 Jul 2018 16:19:54 +0200 Subject: [PATCH 6/7] Add node_meta to 'list nodes per service' --- consul/base.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/consul/base.py b/consul/base.py index 9990d74b..63cb0221 100755 --- a/consul/base.py +++ b/consul/base.py @@ -1258,7 +1258,6 @@ def nodes( for nodemeta_name, nodemeta_value in node_meta.items(): params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) - return self.agent.http.get( CB.json(index=True), '/v1/catalog/nodes', params=params) @@ -1322,7 +1321,6 @@ def services(self, for nodemeta_name, nodemeta_value in node_meta.items(): params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) - return self.agent.http.get( CB.json(index=True), '/v1/catalog/services', params=params) @@ -1406,7 +1404,8 @@ def service( consistency=None, dc=None, near=None, - token=None): + token=None, + node_meta=None): """ Returns a tuple of (*index*, *nodes*) of the nodes providing *service* in the *dc* datacenter. *dc* defaults to the current @@ -1431,6 +1430,9 @@ def service( *token* is an optional `ACL token`_ to apply to this request. + *node_meta* is an optional meta data used for filtering, a + dictionary formatted as {k1:v1, k2:v2}. + The response looks like this:: (index, [ @@ -1462,6 +1464,10 @@ def service( consistency = consistency or self.agent.consistency if consistency in ('consistent', 'stale'): params.append((consistency, '1')) + if node_meta: + for nodemeta_name, nodemeta_value in node_meta.items(): + params.append(('node-meta', '{0}:{1}'. + format(nodemeta_name, nodemeta_value))) return self.agent.http.get( CB.json(index=True), '/v1/catalog/service/%s' % service, @@ -1531,7 +1537,6 @@ def service(self, for nodemeta_name, nodemeta_value in node_meta.items(): params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) - return self.agent.http.get( CB.json(index=True), '/v1/health/service/%s' % service, @@ -1587,7 +1592,6 @@ def checks( for nodemeta_name, nodemeta_value in node_meta.items(): params.append(('node-meta', '{0}:{1}'. format(nodemeta_name, nodemeta_value))) - return self.agent.http.get( CB.json(index=True), '/v1/health/checks/%s' % service, From 77cfdfd91864a91f1821d029cae106f2dc88254c Mon Sep 17 00:00:00 2001 From: ibrahim Date: Wed, 25 Jul 2018 09:20:12 +0200 Subject: [PATCH 7/7] Add 'list nodes per service' to node_meta unittests --- tests/test_base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_base.py b/tests/test_base.py index 8e9d25a8..cd894146 100755 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -53,6 +53,7 @@ def _should_support_node_meta(c): # catalog c.catalog.nodes, c.catalog.services, + lambda **kw: c.catalog.service('foo', **kw), lambda **kw: c.catalog.register('foo', 'bar', **kw), # health lambda **kw: c.health.service('foo', **kw),