@ -1,7 +1,7 @@
#!/usr/bin/python
#!/usr/bin/python
#
#
# (c) 2015, Steve Gargan <steve.gargan@gmail.com>
# (c) 2015, Steve Gargan <steve.gargan@gmail.com>
# (c) 201 7, 201 8 Genome Research Ltd.
# (c) 201 8 Genome Research Ltd.
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import , division , print_function
from __future__ import absolute_import , division , print_function
@ -17,7 +17,7 @@ DOCUMENTATION = """
module : consul_kv
module : consul_kv
short_description : Manipulate entries in the key / value store of a consul cluster
short_description : Manipulate entries in the key / value store of a consul cluster
description :
description :
- Allows the addition, modification and deletion of key / value entries in a
- Allows the retrieval, addition, modification and deletion of key / value entries in a
consul cluster via the agent . The entire contents of the record , including
consul cluster via the agent . The entire contents of the record , including
the indices , flags and session are returned as ' value ' .
the indices , flags and session are returned as ' value ' .
- If the key represents a prefix then Note that when a value is removed , the existing
- If the key represents a prefix then Note that when a value is removed , the existing
@ -34,10 +34,10 @@ author:
options :
options :
state :
state :
description :
description :
- The action to take with the supplied key and value . If the state is
- The action to take with the supplied key and value . If the state is ' present ' and ` value ` is set , the key
' present ' , the key contents will be set to the value supplied,
contents will be set to the value supplied and ` changed ` will be set to ` true ` only if the value wa s
' changed ' will be set to true only if the value was different to th e
different to the current contents . If the state is ' present ' and ` value ` is not set , the existing valu e
current contents . The state ' absent ' will remove the key / value pair ,
associated to the key will be returned . The state ' absent ' will remove the key / value pair ,
again ' changed ' will be set to true only if the key actually existed
again ' changed ' will be set to true only if the key actually existed
prior to the removal . An attempt can be made to obtain or free the
prior to the removal . An attempt can be made to obtain or free the
lock associated with a key / value pair with the states ' acquire ' or
lock associated with a key / value pair with the states ' acquire ' or
@ -101,6 +101,13 @@ options:
EXAMPLES = '''
EXAMPLES = '''
# If the key does not exist, the value associated to the "data" property in `retrieved_key` will be `None`
# If the key value is empty string, `retrieved_key["data"]["Value"]` will be `None`
- name : retrieve a value from the key / value store
consul_kv :
key : somekey
register : retrieved_key
- name : Add or update the value associated with a key in the key / value store
- name : Add or update the value associated with a key in the key / value store
consul_kv :
consul_kv :
key : somekey
key : somekey
@ -135,6 +142,11 @@ except ImportError:
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . basic import AnsibleModule
# Note: although the python-consul documentation implies that using a key with a value of `None` with `put` has a
# special meaning (https://python-consul.readthedocs.io/en/latest/#consul-kv), if not set in the subsequently API call,
# the value just defaults to an empty string (https://www.consul.io/api/kv.html#create-update-key)
NOT_SET = None
def _has_value_changed ( consul_client , key , target_value ) :
def _has_value_changed ( consul_client , key , target_value ) :
"""
"""
@ -158,15 +170,19 @@ def _has_value_changed(consul_client, key, target_value):
def execute ( module ) :
def execute ( module ) :
state = module . params . get ( ' state ' )
state = module . params . get ( ' state ' )
if state == ' acquire ' or state == ' release ' :
if state == ' acquire ' or state == ' release ' :
lock ( module , state )
lock ( module , state )
if state == ' present ' :
elif state == ' present ' :
add_value ( module )
if module . params . get ( ' value ' ) is NOT_SET :
else :
get_value ( module )
else :
set_value ( module )
elif state == ' absent ' :
remove_value ( module )
remove_value ( module )
else :
module . exit_json ( msg = " Unsupported state: %s " % ( state , ) )
def lock ( module , state ) :
def lock ( module , state ) :
@ -201,13 +217,24 @@ def lock(module, state):
key = key )
key = key )
def add_value ( module ) :
def get_value ( module ) :
consul_api = get_consul_api ( module )
key = module . params . get ( ' key ' )
index , existing_value = consul_api . kv . get ( key , recurse = module . params . get ( ' recurse ' ) )
module . exit_json ( changed = False , index = index , data = existing_value )
def set_value ( module ) :
consul_api = get_consul_api ( module )
consul_api = get_consul_api ( module )
key = module . params . get ( ' key ' )
key = module . params . get ( ' key ' )
value = module . params . get ( ' value ' )
value = module . params . get ( ' value ' )
if value is NOT_SET :
raise AssertionError ( ' Cannot set value of " %s " to `NOT_SET` ' , ( key , ) )
index , changed = _has_value_changed ( consul_api , key , value )
index , changed = _has_value_changed ( consul_api , key , value )
if changed and not module . check_mode :
if changed and not module . check_mode :
@ -274,13 +301,10 @@ def main():
retrieve = dict ( type = ' bool ' , default = True ) ,
retrieve = dict ( type = ' bool ' , default = True ) ,
state = dict ( type = ' str ' , default = ' present ' , choices = [ ' absent ' , ' acquire ' , ' present ' , ' release ' ] ) ,
state = dict ( type = ' str ' , default = ' present ' , choices = [ ' absent ' , ' acquire ' , ' present ' , ' release ' ] ) ,
token = dict ( type = ' str ' , no_log = True ) ,
token = dict ( type = ' str ' , no_log = True ) ,
value = dict ( type = ' str ' ),
value = dict ( type = ' str ' , default = NOT_SET ),
session = dict ( type = ' str ' ) ,
session = dict ( type = ' str ' ) ,
) ,
) ,
supports_check_mode = False ,
supports_check_mode = False
required_if = [
[ ' state ' , ' present ' , [ ' value ' ] ] ,
] ,
)
)
test_dependencies ( module )
test_dependencies ( module )