summaryrefslogtreecommitdiff
path: root/v1/bin/ansible-vault
diff options
context:
space:
mode:
Diffstat (limited to 'v1/bin/ansible-vault')
-rwxr-xr-xv1/bin/ansible-vault241
1 files changed, 241 insertions, 0 deletions
diff --git a/v1/bin/ansible-vault b/v1/bin/ansible-vault
new file mode 100755
index 0000000000..22cfc0e148
--- /dev/null
+++ b/v1/bin/ansible-vault
@@ -0,0 +1,241 @@
+#!/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-vault is a script that encrypts/decrypts YAML files. See
+# http://docs.ansible.com/playbooks_vault.html for more details.
+
+__requires__ = ['ansible']
+try:
+ import pkg_resources
+except Exception:
+ # Use pkg_resources to find the correct versions of libraries and set
+ # sys.path appropriately when there are multiversion installs. But we
+ # have code that better expresses the errors in the places where the code
+ # is actually used (the deps are optional for many code paths) so we don't
+ # want to fail here.
+ pass
+
+import os
+import sys
+import traceback
+
+import ansible.constants as C
+
+from ansible import utils
+from ansible import errors
+from ansible.utils.vault import VaultEditor
+
+from optparse import OptionParser
+
+#-------------------------------------------------------------------------------------
+# Utility functions for parsing actions/options
+#-------------------------------------------------------------------------------------
+
+VALID_ACTIONS = ("create", "decrypt", "edit", "encrypt", "rekey", "view")
+
+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('-c', '--cipher', dest='cipher', default="AES256", help="cipher to use")
+ parser.add_option('--debug', dest='debug', action="store_true", help="debug")
+ parser.add_option('--vault-password-file', dest='password_file',
+ help="vault password file", default=C.DEFAULT_VAULT_PASSWORD_FILE)
+
+ # 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 == "view":
+ parser.set_usage("usage: %prog view [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 execute_create(args, options, parser):
+ if len(args) > 1:
+ raise errors.AnsibleError("'create' does not accept more than one filename")
+
+ if not options.password_file:
+ password, new_password = utils.ask_vault_passwords(ask_vault_pass=True, confirm_vault=True)
+ else:
+ password = utils.read_vault_file(options.password_file)
+
+ cipher = 'AES256'
+ if hasattr(options, 'cipher'):
+ cipher = options.cipher
+
+ this_editor = VaultEditor(cipher, password, args[0])
+ this_editor.create_file()
+
+def execute_decrypt(args, options, parser):
+
+ if not options.password_file:
+ password, new_password = utils.ask_vault_passwords(ask_vault_pass=True)
+ else:
+ password = utils.read_vault_file(options.password_file)
+
+ cipher = 'AES256'
+ if hasattr(options, 'cipher'):
+ cipher = options.cipher
+
+ for f in args:
+ this_editor = VaultEditor(cipher, password, f)
+ this_editor.decrypt_file()
+
+ print "Decryption successful"
+
+def execute_edit(args, options, parser):
+
+ if len(args) > 1:
+ raise errors.AnsibleError("edit does not accept more than one filename")
+
+ if not options.password_file:
+ password, new_password = utils.ask_vault_passwords(ask_vault_pass=True)
+ else:
+ password = utils.read_vault_file(options.password_file)
+
+ cipher = None
+
+ for f in args:
+ this_editor = VaultEditor(cipher, password, f)
+ this_editor.edit_file()
+
+def execute_view(args, options, parser):
+
+ if len(args) > 1:
+ raise errors.AnsibleError("view does not accept more than one filename")
+
+ if not options.password_file:
+ password, new_password = utils.ask_vault_passwords(ask_vault_pass=True)
+ else:
+ password = utils.read_vault_file(options.password_file)
+
+ cipher = None
+
+ for f in args:
+ this_editor = VaultEditor(cipher, password, f)
+ this_editor.view_file()
+
+def execute_encrypt(args, options, parser):
+
+ if not options.password_file:
+ password, new_password = utils.ask_vault_passwords(ask_vault_pass=True, confirm_vault=True)
+ else:
+ password = utils.read_vault_file(options.password_file)
+
+ cipher = 'AES256'
+ if hasattr(options, 'cipher'):
+ cipher = options.cipher
+
+ for f in args:
+ this_editor = VaultEditor(cipher, password, f)
+ this_editor.encrypt_file()
+
+ print "Encryption successful"
+
+def execute_rekey(args, options, parser):
+
+ if not options.password_file:
+ password, __ = utils.ask_vault_passwords(ask_vault_pass=True)
+ else:
+ password = utils.read_vault_file(options.password_file)
+
+ __, new_password = utils.ask_vault_passwords(ask_vault_pass=False, ask_new_vault_pass=True, confirm_new=True)
+
+ cipher = None
+ for f in args:
+ this_editor = VaultEditor(cipher, password, f)
+ this_editor.rekey_file(new_password)
+
+ print "Rekey successful"
+
+#-------------------------------------------------------------------------------------
+# MAIN
+#-------------------------------------------------------------------------------------
+
+def main():
+
+ action = get_action(sys.argv)
+ parser = build_option_parser(action)
+ (options, args) = parser.parse_args()
+
+ if not len(args):
+ raise errors.AnsibleError(
+ "The '%s' command requires a filename as the first argument" % action
+ )
+
+ # 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()