diff options
author | James Tanner <tanner.jc@gmail.com> | 2014-02-11 12:03:11 -0500 |
---|---|---|
committer | James Tanner <tanner.jc@gmail.com> | 2014-02-18 15:35:12 -0500 |
commit | 427b8dc78de43aa02be968bbbcb2f10ed487fe1e (patch) | |
tree | 815a69e3db1dc6480e3e29a4c3536c8c97985350 /bin/ansible-vault | |
parent | 30611eaac5dfee722afd1085bceb3b742bf73583 (diff) | |
download | ansible-427b8dc78de43aa02be968bbbcb2f10ed487fe1e.tar.gz |
Ansible vault: a framework for encrypting any playbook or var file.
Diffstat (limited to 'bin/ansible-vault')
-rwxr-xr-x | bin/ansible-vault | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/bin/ansible-vault b/bin/ansible-vault new file mode 100755 index 0000000000..9fd19bda2e --- /dev/null +++ b/bin/ansible-vault @@ -0,0 +1,187 @@ +#!/usr/bin/env python + +# (c) 2014, James Tanner <tanner.jc@gmail.com> +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see <http://www.gnu.org/licenses/>. +# +# ansible-pull is a script that runs ansible in local mode +# after checking out a playbooks directory from source repo. There is an +# example playbook to bootstrap this script in the examples/ dir which +# installs ansible and sets it up to run on cron. + +import sys +import traceback + +from ansible import utils +from ansible import errors +from ansible.utils.vault import * +from ansible.utils.vault import Vault + +from optparse import OptionParser + +#------------------------------------------------------------------------------------- +# Utility functions for parsing actions/options +#------------------------------------------------------------------------------------- + +VALID_ACTIONS = ("create", "decrypt", "edit", "encrypt", "rekey") + +def build_option_parser(action): + """ + Builds an option parser object based on the action + the user wants to execute. + """ + + usage = "usage: %%prog [%s] [--help] [options] file_name" % "|".join(VALID_ACTIONS) + epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0]) + OptionParser.format_epilog = lambda self, formatter: self.epilog + parser = OptionParser(usage=usage, epilog=epilog) + + if not action: + parser.print_help() + sys.exit() + + # options for all actions + #parser.add_option('-p', '--password', help="encryption key") + #parser.add_option('-c', '--cipher', dest='cipher', default="AES", help="cipher to use") + parser.add_option('-d', '--debug', dest='debug', action="store_true", help="debug") + + # options specific to actions + if action == "create": + parser.set_usage("usage: %prog create [options] file_name") + elif action == "decrypt": + parser.set_usage("usage: %prog decrypt [options] file_name") + elif action == "edit": + parser.set_usage("usage: %prog edit [options] file_name") + elif action == "encrypt": + parser.set_usage("usage: %prog encrypt [options] file_name") + elif action == "rekey": + parser.set_usage("usage: %prog rekey [options] file_name") + + # done, return the parser + return parser + +def get_action(args): + """ + Get the action the user wants to execute from the + sys argv list. + """ + for i in range(0,len(args)): + arg = args[i] + if arg in VALID_ACTIONS: + del args[i] + return arg + return None + +def get_opt(options, k, defval=""): + """ + Returns an option from an Optparse values instance. + """ + try: + data = getattr(options, k) + except: + return defval + if k == "roles_path": + if os.pathsep in data: + data = data.split(os.pathsep)[0] + return data + +#------------------------------------------------------------------------------------- +# Command functions +#------------------------------------------------------------------------------------- + +def _get_vault(filename, options, password): + this_vault = Vault() + this_vault.filename = filename + this_vault.vault_password = password + this_vault.password = password + return this_vault + +def execute_create(args, options, parser): + + if len(args) > 1: + raise errors.AnsibleError("create does not accept more than one filename") + + password, new_password = utils.ask_vaultpasswords(ask_vault_pass=True, confirm_vault=True) + + this_vault = _get_vault(args[0], options, password) + if not hasattr(options, 'cipher'): + this_vault.cipher = 'AES' + this_vault.create() + +def execute_decrypt(args, options, parser): + + password, new_password = utils.ask_vaultpasswords(ask_vault_pass=True) + + for f in args: + this_vault = _get_vault(f, options, password) + this_vault.decrypt() + + print "Decryption successful" + +def execute_edit(args, options, parser): + + if len(args) > 1: + raise errors.AnsibleError("create does not accept more than one filename") + + password, new_password = utils.ask_vaultpasswords(ask_vault_pass=True) + + for f in args: + this_vault = _get_vault(f, options, password) + this_vault.edit() + +def execute_encrypt(args, options, parser): + + password, new_password = utils.ask_vaultpasswords(ask_vault_pass=True, confirm_vault=True) + + for f in args: + this_vault = _get_vault(f, options, password) + if not hasattr(options, 'cipher'): + this_vault.cipher = 'AES' + this_vault.encrypt() + + print "Encryption successful" + +def execute_rekey(args, options, parser): + + password, new_password = utils.ask_vaultpasswords(ask_vault_pass=True, ask_new_vault_pass=True, confirm_new=True) + + for f in args: + this_vault = _get_vault(f, options, password) + this_vault.rekey(new_password) + + print "Rekey successful" + +#------------------------------------------------------------------------------------- +# MAIN +#------------------------------------------------------------------------------------- + +def main(): + + action = get_action(sys.argv) + parser = build_option_parser(action) + (options, args) = parser.parse_args() + + # execute the desired action + try: + fn = globals()["execute_%s" % action] + fn(args, options, parser) + except Exception, err: + if options.debug: + print traceback.format_exc() + print "ERROR:",err + sys.exit(1) + +if __name__ == "__main__": + main() + |