Allow --vault-password-file to work with a script as well as a flat file

This commit is contained in:
Matt Martz 2014-06-03 09:34:42 -05:00
parent 375edbd087
commit 19f5ce2c9c
5 changed files with 40 additions and 25 deletions

View file

@ -124,17 +124,8 @@ class Cli(object):
(sshpass, sudopass, su_pass, vault_pass) = utils.ask_passwords(ask_pass=options.ask_pass, ask_sudo_pass=options.ask_sudo_pass, ask_su_pass=options.ask_su_pass, ask_vault_pass=options.ask_vault_pass)
# read vault_pass from a file
if options.vault_password_file:
this_path = os.path.expanduser(options.vault_password_file)
try:
f = open(this_path, "rb")
tmp_vault_pass=f.read().strip()
f.close()
except (OSError, IOError), e:
raise errors.AnsibleError("Could not read %s: %s" % (this_path, e))
if not options.ask_vault_pass:
vault_pass = tmp_vault_pass
if not options.ask_vault_pass and options.vault_password_file:
vault_pass = utils.read_vault_file(options.vault_password_file)
inventory_manager = inventory.Inventory(options.inventory)
if options.subset:

View file

@ -125,17 +125,9 @@ def main(args):
options.sudo_user = options.sudo_user or C.DEFAULT_SUDO_USER
options.su_user = options.su_user or C.DEFAULT_SU_USER
if options.vault_password_file:
this_path = os.path.expanduser(options.vault_password_file)
try:
f = open(this_path, "rb")
tmp_vault_pass=f.read().strip()
f.close()
except (OSError, IOError), e:
raise errors.AnsibleError("Could not read %s: %s" % (this_path, e))
if not options.ask_vault_pass:
vault_pass = tmp_vault_pass
# read vault_pass from a file
if not options.ask_vault_pass and options.vault_password_file:
vault_pass = utils.read_vault_file(options.vault_password_file)
extra_vars = {}
for extra_vars_opt in options.extra_vars:

View file

@ -83,12 +83,16 @@ To run a playbook that contains vault-encrypted data files, you must pass one of
This prompt will then be used to decrypt (in memory only) any vault encrypted files that are accessed. Currently this requires that all passwords be encrypted with the same password.
Alternatively, passwords can be specified with a file. If this is done, be careful to ensure permissions on the file are such that no one else can access your key, and do not add your key to source control::
Alternatively, passwords can be specified with a file or a script. If this is done, be careful to ensure permissions on the file are such that no one else can access your key, and do not add your key to source control::
ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt
ansible-playbook site.yml --vault-password-file ~/.vault_pass.py
The password should be a string stored as a single line in the file.
If you are using a script instead of a flat file, ensure that it is marked as executable, and that the password is printed to STDOUT. If your script needs to prompt for data, prompts can be sent to STDERR.
This is likely something you may wish to do if using Ansible from a continuous integration system like Jenkins.
(The `--vault-password-file` option can also be used with the :ref:`ansible-pull` command if you wish, though this would require distributing the keys to your nodes, so understand the implications -- vault is more intended for push mode).

View file

@ -118,6 +118,7 @@ DEFAULT_SUDO_USER = get_config(p, DEFAULTS, 'sudo_user', 'ANSIBLE
DEFAULT_ASK_SUDO_PASS = get_config(p, DEFAULTS, 'ask_sudo_pass', 'ANSIBLE_ASK_SUDO_PASS', False, boolean=True)
DEFAULT_REMOTE_PORT = get_config(p, DEFAULTS, 'remote_port', 'ANSIBLE_REMOTE_PORT', None, integer=True)
DEFAULT_ASK_VAULT_PASS = get_config(p, DEFAULTS, 'ask_vault_pass', 'ANSIBLE_ASK_VAULT_PASS', False, boolean=True)
DEFAULT_VAULT_PASSWORD_FILE = shell_expand_path(get_config(p, DEFAULTS, 'vault_password_file', 'ANSIBLE_VAULT_PASSWORD_FILE', None))
DEFAULT_TRANSPORT = get_config(p, DEFAULTS, 'transport', 'ANSIBLE_TRANSPORT', 'smart')
DEFAULT_SCP_IF_SSH = get_config(p, 'ssh_connection', 'scp_if_ssh', 'ANSIBLE_SCP_IF_SSH', False, boolean=True)
DEFAULT_MANAGED_STR = get_config(p, DEFAULTS, 'ansible_managed', None, 'Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}')

View file

@ -44,6 +44,7 @@ import traceback
import getpass
import sys
import json
import subprocess
#import vault
from vault import VaultLib
@ -148,6 +149,32 @@ def decrypt(key, msg):
# UTILITY FUNCTIONS FOR COMMAND LINE TOOLS
###############################################################
def read_vault_file(vault_password_file):
"""Read a vault password from a file or if executable, execute the script and
retrieve password from STDOUT
"""
if vault_password_file:
this_path = os.path.realpath(os.path.expanduser(vault_password_file))
if is_executable(this_path):
try:
# STDERR not captured to make it easier for users to prompt for input in their scripts
p = subprocess.Popen(this_path, stdout=subprocess.PIPE)
except OSError, e:
raise errors.AnsibleError("problem running %s (%s)" % (' '.join(this_path), e))
stdout, stderr = p.communicate()
vault_pass = stdout.strip('\r\n')
else:
try:
f = open(this_path, "rb")
vault_pass=f.read().strip()
f.close()
except (OSError, IOError), e:
raise errors.AnsibleError("Could not read %s: %s" % (this_path, e))
return vault_pass
else:
return None
def err(msg):
''' print an error message to stderr '''
@ -757,8 +784,8 @@ def base_parser(constants=C, usage="", output_opts=False, runas_opts=False,
help='ask for su password')
parser.add_option('--ask-vault-pass', default=False, dest='ask_vault_pass', action='store_true',
help='ask for vault password')
parser.add_option('--vault-password-file', default=None, dest='vault_password_file',
help="vault password file")
parser.add_option('--vault-password-file', default=constants.DEFAULT_VAULT_PASSWORD_FILE,
dest='vault_password_file', help="vault password file")
parser.add_option('--list-hosts', dest='listhosts', action='store_true',
help='outputs a list of matching hosts; does not execute anything else')
parser.add_option('-M', '--module-path', dest='module_path',