You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ansible/bin/ansible-vault

188 lines
5.9 KiB
Python

#!/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_vault_passwords(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_vault_passwords(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_vault_passwords(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_vault_passwords(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_vault_passwords(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()