python-consul icon indicating copy to clipboard operation
python-consul copied to clipboard

Consul.Session should support tokens

Open akissa opened this issue 7 years ago • 5 comments

The methods under Consul.Session do not work on a system with ACLs enabled and the default ACL policy is deny. This happens even if the token is set in consul.Consul() as self.agent.token is not passed in the params to the http client.

Possible fix:

diff -ruN python-consul-0.7.2.orig/consul/base.py python-consul-0.7.2/consul/base.py
--- python-consul-0.7.2.orig/consul/base.py	2017-08-26 09:35:57.000000000 +0200
+++ python-consul-0.7.2/consul/base.py	2017-09-04 13:56:13.897000258 +0200
@@ -1679,6 +1679,8 @@
             dc = dc or self.agent.dc
             if dc:
                 params['dc'] = dc
+            if self.agent.token:
+                params['token'] = self.agent.token
             data = {}
             if name:
                 data['name'] = name
@@ -1716,6 +1718,8 @@
             dc = dc or self.agent.dc
             if dc:
                 params['dc'] = dc
+            if self.agent.token:
+                params['token'] = self.agent.token
             return self.agent.http.put(
                 CB.bool(),
                 '/v1/session/destroy/%s' % session_id,
@@ -1757,6 +1761,8 @@
             dc = dc or self.agent.dc
             if dc:
                 params['dc'] = dc
+            if self.agent.token:
+                params['token'] = self.agent.token
             if index:
                 params['index'] = index
                 if wait:
@@ -1787,6 +1793,8 @@
             dc = dc or self.agent.dc
             if dc:
                 params['dc'] = dc
+            if self.agent.token:
+                params['token'] = self.agent.token
             if index:
                 params['index'] = index
                 if wait:
@@ -1824,6 +1832,8 @@
             dc = dc or self.agent.dc
             if dc:
                 params['dc'] = dc
+            if self.agent.token:
+                params['token'] = self.agent.token
             if index:
                 params['index'] = index
                 if wait:
@@ -1850,6 +1860,8 @@
             dc = dc or self.agent.dc
             if dc:
                 params['dc'] = dc
+            if self.agent.token:
+                params['token'] = self.agent.token
             return self.agent.http.put(
                 CB.json(one=True, allow_404=False),
                 '/v1/session/renew/%s' % session_id,

akissa avatar Sep 04 '17 11:09 akissa

I only use the standard client, but you can work around this if you set the X-Consul-Token header in the session. I am not sure what token consul will accept if the token query parameter is passed too.

This probably should be added, but then the library is a bit inconsistent. If it were up to me, I'd probably get rid of token passing into methods and just have it when constructing the Consul object. But for now I find this is the easiest, and sometimes only way, to use ACL tokens.

c = consul.Consul()
c.http.session.headers.update({'X-Consul-Token': CONSUL_TOKEN})

dacameron avatar Sep 08 '17 02:09 dacameron

For those using consul.aio, the following ugliness does the trick, at least with aiohttp==3.3.2:

c = consul.Consul()
c.http._session._default_headers.update({'X-Consul-Token': c.token})

kshpytsya avatar Jun 27 '18 19:06 kshpytsya

I only use the standard client, but you can work around this if you set the X-Consul-Token header in the session. I am not sure what token consul will accept if the token query parameter is passed too.

This probably should be added, but then the library is a bit inconsistent. If it were up to me, I'd probably get rid of token passing into methods and just have it when constructing the Consul object. But for now I find this is the easiest, and sometimes only way, to use ACL tokens.

c = consul.Consul()
c.http.session.headers.update({'X-Consul-Token': CONSUL_TOKEN})

You can do that

c = consul.Consul(token="foobar_acl_token")

That works for just about every method except Session. It is the only one void of reference to token. The solution the OP @akissa mentioned does work.

This is how the other Consul sub classes implement it:

token = token or self.agent.token
if token:
    params.append(('token', token))

They all accept token as a parameter so you can override the default ACL token for specific calls.

This has been open for over a year, any chance of getting traction?

rpsiv avatar Sep 24 '18 20:09 rpsiv

@rpsiv I'm also intereseted to implement token for session methods. I opened a PR with a working implementation https://github.com/cablehead/python-consul/pull/238

abarbare avatar Oct 06 '18 11:10 abarbare

I've also made a PR https://github.com/cablehead/python-consul/pull/251

abhisekpadhi avatar Mar 25 '19 15:03 abhisekpadhi