Implement cat-like filtering behaviour for encrypt/decrypt

This allows the following invocations:

    # Interactive use, like gpg
    ansible-vault encrypt --output x

    # Non-interactive, for scripting
    echo plaintext|ansible-vault encrypt --output x

    # Separate input and output files
    ansible-vault encrypt input.yml --output output.yml

    # Existing usage (in-place encryption) unchanged
    ansible-vault encrypt inout.yml

…and the analogous cases for ansible-vault decrypt as well.

In all cases, the input and output files can be '-' to read from stdin
or write to stdout. This permits sensitive data to be encrypted and
decrypted without ever hitting disk.
This commit is contained in:
Abhijit Menon-Sen 2015-08-26 22:51:20 +05:30
commit e7eebb6954
3 changed files with 44 additions and 23 deletions

View file

@ -63,7 +63,19 @@ class VaultCLI(CLI):
self.options, self.args = self.parser.parse_args()
self.display.verbosity = self.options.verbosity
if len(self.args) == 0:
if self.options.output_file:
if self.action not in ['encrypt','decrypt']:
raise AnsibleOptionsError("The --output option can be used only with ansible-vault encrypt/decrypt")
# This restriction should remain in place until it's possible to
# load multiple YAML records from a single file, or it's too easy
# to create an encrypted file that can't be read back in. But in
# the meanwhile, "cat a b c|ansible-vault encrypt --output x" is
# a workaround.
if len(self.args) > 1:
raise AnsibleOptionsError("At most one input file may be used with the --output option")
elif len(self.args) == 0:
raise AnsibleOptionsError("Vault requires at least one filename as a parameter")
def run(self):
@ -87,6 +99,20 @@ class VaultCLI(CLI):
self.execute()
def execute_encrypt(self):
for f in self.args or ['-']:
self.editor.encrypt_file(f, output_file=self.options.output_file)
self.display.display("Encryption successful", stderr=True)
def execute_decrypt(self):
for f in self.args or ['-']:
self.editor.decrypt_file(f, output_file=self.options.output_file)
self.display.display("Decryption successful", stderr=True)
def execute_create(self):
if len(self.args) > 1:
@ -94,13 +120,6 @@ class VaultCLI(CLI):
self.editor.create_file(self.args[0])
def execute_decrypt(self):
for f in self.args:
self.editor.decrypt_file(f)
self.display.display("Decryption successful", stderr=True)
def execute_edit(self):
for f in self.args:
self.editor.edit_file(f)
@ -110,13 +129,6 @@ class VaultCLI(CLI):
for f in self.args:
self.editor.view_file(f)
def execute_encrypt(self):
for f in self.args:
self.editor.encrypt_file(f)
self.display.display("Encryption successful", stderr=True)
def execute_rekey(self):
for f in self.args:
if not (os.path.isfile(f)):