Add some auth handling for etcd

This commit is contained in:
Joseph Hall 2016-02-22 16:02:05 -07:00
parent 87032995ed
commit e3696d5603
2 changed files with 60 additions and 7 deletions

View File

@ -39,6 +39,30 @@ Once the etcd options are configured, the returner may be used:
CLI Example:
salt '*' test.ping --return etcd
A username and password can be set:
.. code-block:: yaml
etcd.username: larry # Optional; requires etcd.password to be set
etcd.password: 123pass # Optional; requires etcd.username to be set
You can also set a TTL (time to live) value for the returner:
.. code-block:: yaml
etcd.ttl: 5
Authentication with username and password, and ttl, currently requires the
``master`` branch of ``python-etcd``.
You may also specify different roles for read and write operations. First,
create the profiles as specified above. Then add:
.. code-block:: yaml
etcd.returner_read_profile: my_etcd_read
etcd.returner_write_profile: my_etcd_write
'''
from __future__ import absolute_import
@ -69,11 +93,12 @@ def __virtual__():
return __virtualname__ if HAS_LIBS else False
def _get_conn(opts):
def _get_conn(opts, profile=None):
'''
Establish a connection to etcd
'''
profile = opts.get('etcd.returner', None)
if profile is None:
profile = opts.get('etcd.returner', None)
path = opts.get('etcd.returner_root', '/salt/return')
return salt.utils.etcd_util.get_conn(opts, profile), path
@ -82,12 +107,18 @@ def returner(ret):
'''
Return data to an etcd server or cluster
'''
client, path = _get_conn(__opts__)
write_profile = __opts__.get('etcd.returner_write_profile', None)
if write_profile:
ttl = __opts__.get(write_profile, {}).get('etcd.ttl')
else:
ttl = __opts__.get('etcd.ttl')
client, path = _get_conn(__opts__, write_profile)
# Make a note of this minion for the external job cache
client.set(
'/'.join((path, 'minions', ret['id'])),
ret['jid'],
ttl=ttl,
)
for field in ret:
@ -99,7 +130,7 @@ def returner(ret):
ret['id'],
field
))
client.set(dest, json.dumps(ret[field]))
client.set(dest, json.dumps(ret[field]), ttl=ttl)
def save_load(jid, load):
@ -107,9 +138,17 @@ def save_load(jid, load):
Save the load to the specified jid
'''
client, path = _get_conn(__opts__)
client.set(
write_profile = __opts__.get('etcd.returner_write_profile', None)
client, path = _get_conn(__opts__, write_profile)
if write_profile:
ttl = __opts__.get(write_profile, {}).get('etcd.ttl')
else:
ttl = __opts__.get('etcd.ttl')
client.set(
'/'.join((path, 'jobs', jid, '.load.p')),
json.dumps(load)
json.dumps(load),
ttl=ttl,
)
@ -117,7 +156,8 @@ def get_load(jid):
'''
Return the load data that marks a specified jid
'''
client, path = _get_conn(__opts__)
read_profile = __opts__.get('etcd.returner_read_profile', None)
client, path = _get_conn(__opts__, read_profile)
return json.loads(client.get('/'.join((path, 'jobs', jid, '.load.p'))))

View File

@ -15,11 +15,15 @@ may be passed in. The following configurations are both valid:
# No profile name
etcd.host: 127.0.0.1
etcd.port: 4001
etcd.username: larry # Optional; requires etcd.password to be set
etcd.password: 123pass # Optional; requires etcd.username to be set
# One or more profiles defined
my_etcd_config:
etcd.host: 127.0.0.1
etcd.port: 4001
etcd.username: larry # Optional; requires etcd.password to be set
etcd.password: 123pass # Optional; requires etcd.username to be set
Once configured, the client() function is passed a set of opts, and optionally,
the name of a profile to be used.
@ -84,9 +88,18 @@ class EtcdClient(object):
host = self.conf.get('etcd.host', '127.0.0.1')
port = self.conf.get('etcd.port', 4001)
username = self.conf.get('etcd.username')
password = self.conf.get('etcd.password')
auth = {}
if username and password:
auth = {
'username': str(username),
'password': str(password)
}
if HAS_LIBS:
self.client = etcd.Client(host, port)
self.client = etcd.Client(host, port, **auth)
else:
raise CommandExecutionError(
'(unable to import etcd, '