summaryrefslogtreecommitdiff
path: root/bin/ansible-vault
diff options
context:
space:
mode:
authorJames Tanner <tanner.jc@gmail.com>2014-02-11 12:03:11 -0500
committerJames Tanner <tanner.jc@gmail.com>2014-02-18 15:35:12 -0500
commit427b8dc78de43aa02be968bbbcb2f10ed487fe1e (patch)
tree815a69e3db1dc6480e3e29a4c3536c8c97985350 /bin/ansible-vault
parent30611eaac5dfee722afd1085bceb3b742bf73583 (diff)
downloadansible-427b8dc78de43aa02be968bbbcb2f10ed487fe1e.tar.gz
Ansible vault: a framework for encrypting any playbook or var file.
Diffstat (limited to 'bin/ansible-vault')
-rwxr-xr-xbin/ansible-vault187
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()
+