Changes from Brian Coca's review of this module
These are all the code changes from Brian's review: * change #! line * rename "host" to "name" [keep as alias] * make documentation clearer * imports 1 per line * use get_bin_path to find ssh-keygen * key not actually required when removing host
This commit is contained in:
parent
e76ad916ef
commit
1e21e34e0f
1 changed files with 26 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Ansible module to manage the ssh known_hosts file.
|
Ansible module to manage the ssh known_hosts file.
|
||||||
|
@ -28,15 +28,16 @@ description:
|
||||||
If you have a very large number of host keys to manage, you will find the M(template) module more useful.
|
If you have a very large number of host keys to manage, you will find the M(template) module more useful.
|
||||||
version_added: "1.6"
|
version_added: "1.6"
|
||||||
options:
|
options:
|
||||||
host:
|
name:
|
||||||
|
aliases: [ 'host' ]
|
||||||
description:
|
description:
|
||||||
- The host to add or remove (must match a host specified in key)
|
- The host to add or remove (must match a host specified in key)
|
||||||
required: true
|
required: true
|
||||||
default: null
|
default: null
|
||||||
key:
|
key:
|
||||||
description:
|
description:
|
||||||
- The SSH public host key, as a string (optional if removing the host)
|
- The SSH public host key, as a string (required if state=present, optional when state=absent, in which case all keys for the host are removed)
|
||||||
required: true
|
required: false
|
||||||
default: null
|
default: null
|
||||||
path:
|
path:
|
||||||
description:
|
description:
|
||||||
|
@ -66,12 +67,15 @@ EXAMPLES = '''
|
||||||
#
|
#
|
||||||
# Arguments
|
# Arguments
|
||||||
# =========
|
# =========
|
||||||
# host = hostname whose key should be added
|
# name = hostname whose key should be added (alias: host)
|
||||||
# key = line(s) to add to known_hosts file
|
# key = line(s) to add to known_hosts file
|
||||||
# path = the known_hosts file to edit (default: ~/.ssh/known_hosts)
|
# path = the known_hosts file to edit (default: ~/.ssh/known_hosts)
|
||||||
# state = absent|present (default: present)
|
# state = absent|present (default: present)
|
||||||
|
|
||||||
import os,os.path,tempfile,errno
|
import os
|
||||||
|
import os.path
|
||||||
|
import tempfile
|
||||||
|
import errno
|
||||||
|
|
||||||
def enforce_state(module, params):
|
def enforce_state(module, params):
|
||||||
"""
|
"""
|
||||||
|
@ -83,9 +87,10 @@ def enforce_state(module, params):
|
||||||
port = params.get("port",None)
|
port = params.get("port",None)
|
||||||
#expand the path parameter; otherwise module.add_path_info
|
#expand the path parameter; otherwise module.add_path_info
|
||||||
#(called by exit_json) unhelpfully says the unexpanded path is absent.
|
#(called by exit_json) unhelpfully says the unexpanded path is absent.
|
||||||
params["path"]=os.path.expanduser(params.get("path"))
|
path = os.path.expanduser(params.get("path"))
|
||||||
path = params.get("path")
|
state = params.get("state")
|
||||||
state = params.get("state","present")
|
#Find the ssh-keygen binary
|
||||||
|
sshkeygen = module.get_bin_path("ssh-keygen",True)
|
||||||
|
|
||||||
#trailing newline in files gets lost, so re-add if necessary
|
#trailing newline in files gets lost, so re-add if necessary
|
||||||
if key is not None and key[-1]!='\n':
|
if key is not None and key[-1]!='\n':
|
||||||
|
@ -94,9 +99,9 @@ def enforce_state(module, params):
|
||||||
if key is None and state != "absent":
|
if key is None and state != "absent":
|
||||||
module.fail_json(msg="No key specified when adding a host")
|
module.fail_json(msg="No key specified when adding a host")
|
||||||
|
|
||||||
sanity_check(module,host,key)
|
sanity_check(module,host,key,sshkeygen)
|
||||||
|
|
||||||
current,replace=search_for_host_key(module,host,key,path)
|
current,replace=search_for_host_key(module,host,key,path,sshkeygen)
|
||||||
|
|
||||||
#We will change state if current==True & state!="present"
|
#We will change state if current==True & state!="present"
|
||||||
#or current==False & state=="present"
|
#or current==False & state=="present"
|
||||||
|
@ -109,7 +114,7 @@ def enforce_state(module, params):
|
||||||
|
|
||||||
#First, remove an extant entry if required
|
#First, remove an extant entry if required
|
||||||
if replace==True or (current==True and state=="absent"):
|
if replace==True or (current==True and state=="absent"):
|
||||||
module.run_command(['ssh-keygen','-R',host,'-f',path],
|
module.run_command([sshkeygen,'-R',host,'-f',path],
|
||||||
check_rc=True)
|
check_rc=True)
|
||||||
params['changed'] = True
|
params['changed'] = True
|
||||||
#Next, add a new (or replacing) entry
|
#Next, add a new (or replacing) entry
|
||||||
|
@ -139,12 +144,13 @@ def enforce_state(module, params):
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
def sanity_check(module,host,key):
|
def sanity_check(module,host,key,sshkeygen):
|
||||||
'''Check supplied key is sensible
|
'''Check supplied key is sensible
|
||||||
|
|
||||||
host and key are parameters provided by the user; If the host
|
host and key are parameters provided by the user; If the host
|
||||||
provided is inconsistent with the key supplied, then this function
|
provided is inconsistent with the key supplied, then this function
|
||||||
quits, providing an error to the user.
|
quits, providing an error to the user.
|
||||||
|
sshkeygen is the path to ssh-keygen, found earlier with get_bin_path
|
||||||
'''
|
'''
|
||||||
#If no key supplied, we're doing a removal, and have nothing to check here.
|
#If no key supplied, we're doing a removal, and have nothing to check here.
|
||||||
if key is None:
|
if key is None:
|
||||||
|
@ -162,26 +168,27 @@ def sanity_check(module,host,key):
|
||||||
except IOError,e:
|
except IOError,e:
|
||||||
module.fail_json(msg="Failed to write to temporary file %s: %s" % \
|
module.fail_json(msg="Failed to write to temporary file %s: %s" % \
|
||||||
(outf.name,str(e)))
|
(outf.name,str(e)))
|
||||||
rc,stdout,stderr=module.run_command(['ssh-keygen','-F',host,
|
rc,stdout,stderr=module.run_command([sshkeygen,'-F',host,
|
||||||
'-f',outf.name],
|
'-f',outf.name],
|
||||||
check_rc=True)
|
check_rc=True)
|
||||||
os.remove(outf.name)
|
os.remove(outf.name)
|
||||||
if stdout=='': #host not found
|
if stdout=='': #host not found
|
||||||
module.fail_json(msg="Host parameter does not match hashed host field in supplied key")
|
module.fail_json(msg="Host parameter does not match hashed host field in supplied key")
|
||||||
|
|
||||||
def search_for_host_key(module,host,key,path):
|
def search_for_host_key(module,host,key,path,sshkeygen):
|
||||||
'''search_for_host_key(module,host,key,path) -> (current,replace)
|
'''search_for_host_key(module,host,key,path,sshkeygen) -> (current,replace)
|
||||||
|
|
||||||
Looks up host in the known_hosts file path; if it's there, looks to see
|
Looks up host in the known_hosts file path; if it's there, looks to see
|
||||||
if one of those entries matches key. Returns:
|
if one of those entries matches key. Returns:
|
||||||
current (Boolean): is host found in path?
|
current (Boolean): is host found in path?
|
||||||
replace (Boolean): is the key in path different to that supplied by user?
|
replace (Boolean): is the key in path different to that supplied by user?
|
||||||
if current=False, then replace is always False.
|
if current=False, then replace is always False.
|
||||||
|
sshkeygen is the path to ssh-keygen, found earlier with get_bin_path
|
||||||
'''
|
'''
|
||||||
replace=False
|
replace=False
|
||||||
if os.path.exists(path)==False:
|
if os.path.exists(path)==False:
|
||||||
return False, False
|
return False, False
|
||||||
rc,stdout,stderr=module.run_command(['ssh-keygen','-F',host,'-f',path],
|
rc,stdout,stderr=module.run_command([sshkeygen,'-F',host,'-f',path],
|
||||||
check_rc=True)
|
check_rc=True)
|
||||||
if stdout=='': #host not found
|
if stdout=='': #host not found
|
||||||
return False, False
|
return False, False
|
||||||
|
@ -218,8 +225,8 @@ def main():
|
||||||
|
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
host = dict(required=True, type='str'),
|
name = dict(required=True, type='str', aliases=['host']),
|
||||||
key = dict(required=True, type='str'),
|
key = dict(required=False, type='str'),
|
||||||
path = dict(default="~/.ssh/known_hosts", type='str'),
|
path = dict(default="~/.ssh/known_hosts", type='str'),
|
||||||
state = dict(default='present', choices=['absent','present']),
|
state = dict(default='present', choices=['absent','present']),
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue