From 8665b0638a1d3a70f985126b0f007a26c81273cb Mon Sep 17 00:00:00 2001 From: James Tanner Date: Sat, 11 Jan 2014 10:35:33 -0500 Subject: [PATCH] Add an "accept_hostkey" parameter to the git module to help automatically accept hostkeys for git repos and prevent task hangs when the key is unknown --- lib/ansible/module_utils/known_hosts.py | 58 +++++++++++++++++++++++++ library/source_control/git | 14 ++++++ 2 files changed, 72 insertions(+) create mode 100644 lib/ansible/module_utils/known_hosts.py diff --git a/lib/ansible/module_utils/known_hosts.py b/lib/ansible/module_utils/known_hosts.py new file mode 100644 index 00000000000..9b00af0660f --- /dev/null +++ b/lib/ansible/module_utils/known_hosts.py @@ -0,0 +1,58 @@ +def add_git_host_key(module, url, accept_hostkey=True): + + """ idempotently add a git url hostkey """ + + if accept_hostkey: + + fqdn = get_fqdn(module.params['repo']) + + if fqdn: + known_host = check_hostkey(module, fqdn) + if not known_host: + rc, out, err = add_host_key(module, fqdn) + if rc != 0: + module.fail_json(msg="failed to add %s hostkey: %s" % (fqdn, out + err)) + +def get_fqdn(repo_url): + + """ chop the hostname out of a giturl """ + + result = None + if "@" in repo_url: + repo_url = repo_url.split("@", 1)[1] + if ":" in repo_url: + repo_url = repo_url.split(":")[0] + result = repo_url + elif "/" in repo_url: + repo_url = repo_url.split("/")[0] + result = repo_url + + return result + + +def check_hostkey(module, fqdn): + + """ use ssh-keygen to check if key is known """ + + result = False + keygen_cmd = module.get_bin_path('ssh-keygen', True) + this_cmd = keygen_cmd + " -H -F " + fqdn + rc, out, err = module.run_command(this_cmd) + + if rc == 0: + if out != "": + result = True + + return result + +def add_host_key(module, fqdn, key_type="rsa"): + + """ use ssh-keyscan to add the hostkey """ + + result = False + keyscan_cmd = module.get_bin_path('ssh-keyscan', True) + this_cmd = "%s -t %s %s >> ~/.ssh/known_hosts" % (keyscan_cmd, key_type, fqdn) + rc, out, err = module.run_command(this_cmd) + + return rc, out, err + diff --git a/library/source_control/git b/library/source_control/git index 61ef24e1485..320414a35cf 100644 --- a/library/source_control/git +++ b/library/source_control/git @@ -43,6 +43,12 @@ options: - What version of the repository to check out. This can be the full 40-character I(SHA-1) hash, the literal string C(HEAD), a branch name, or a tag name. + accept_hostkey: + required: false + default: true + version_added: "1.5" + description: + - Add the hostkey for the repo url if not already added. reference: required: false default: null @@ -118,6 +124,7 @@ EXAMPLES = ''' import re import tempfile + def get_version(git_path, dest, ref="HEAD"): ''' samples the version of the git repo ''' os.chdir(dest) @@ -352,6 +359,7 @@ def main(): force=dict(default='yes', type='bool'), depth=dict(default=None, type='int'), update=dict(default='yes', type='bool'), + accept_hostkey=dict(default='yes', type='bool'), executable=dict(default=None), bare=dict(default='no', type='bool'), ), @@ -369,6 +377,10 @@ def main(): reference = module.params['reference'] git_path = module.params['executable'] or module.get_bin_path('git', True) + # add the git repo's hostkey + if module.params['accept_hostkey']: + add_git_host_key(module, repo, accept_hostkey=True) + if bare: gitconfig = os.path.join(dest, 'config') else: @@ -430,4 +442,6 @@ def main(): # import module snippets from ansible.module_utils.basic import * +from ansible.module_utils.known_hosts import * + main()