Skip to content

Commit

Permalink
Add vault_password_file param to PlaybookRunner (#129)
Browse files Browse the repository at this point in the history
* Add vault_password_file param to PlaybookRunner

* Make PlaybookRunner.run docstring clearer
  • Loading branch information
Jan Zmeskal authored May 12, 2020
1 parent da49a0f commit 9a6a787
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 4 deletions.
21 changes: 17 additions & 4 deletions rrmngmnt/playbook_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def _generate_default_inventory(self):
def run(
self, playbook, extra_vars=None, vars_files=None, inventory=None,
verbose_level=1, run_in_check_mode=False, ssh_common_args=None,
upload_playbook=True
upload_playbook=True, vault_password_file=None,
):
"""
Run Ansible playbook on host
Expand All @@ -121,7 +121,8 @@ def run(
vars_files (list): List of additional variable files to be included
using -e@ parameter. If one variable is specified both in
extra_vars and in one of the vars_files, the one in vars_files
takes precedence.
takes precedence. Provide local paths to vars file(s), they
will be uploaded to a remote host automatically.
inventory (str): Path to an inventory file (on your machine) to be
used for playbook execution. If none is provided, default
inventory including only localhost will be generated and used
Expand All @@ -134,8 +135,13 @@ def run(
replace) the list of default options that Ansible uses when
calling ssh/sftp/scp. Example: ["-o StrictHostKeyChecking=no",
"-o UserKnownHostsFile=/dev/null"]
upload_playbook (bool): If the playbook is going to be uploaded
from the local machine (True - Default) or not (False)
upload_playbook (bool): Whether the playbook is going to be
automatically uploaded from the local machine to a remote host
(True - Default) or not (False).
vault_password_file (str): Local path to a vault password file.
It will be automatically uploaded to a remote host,
same as vars_files. This is required if any of the vars_files
are vault-protected.
Returns:
tuple: tuple of (rc, out, err)
Expand All @@ -158,6 +164,13 @@ def run(
for f in vars_files:
self.cmd.append("-e@{}".format(self._upload_file(f)))

if vault_password_file:
self.cmd.append(
"--vault-password-file={}".format(
self._upload_file(vault_password_file)
)
)

self.cmd.append("-i")
if inventory:
self.cmd.append(self._upload_file(inventory))
Expand Down
57 changes: 57 additions & 0 deletions tests/test_playbook_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class PlaybookRunnerBase(object):
playbook_content = ''
vars_file_name = 'my_vars.yml'
vars_file_content = ''
vault_password_file_name = 'key.txt'
vault_password_file_content = ''
inventory_name = 'my_inventory'
inventory_content = ''
ssh_no_strict_host_key_checking = "-o StrictHostKeyChecking=no"
Expand All @@ -36,6 +38,9 @@ class PlaybookRunnerBase(object):
'[ -d {tmp_dir}/{vars_file} ]'.format(
tmp_dir=tmp_dir, vars_file=vars_file_name
): failure,
'[ -d {tmp_dir}/{vault_password_file} ]'.format(
tmp_dir=tmp_dir, vault_password_file=vault_password_file_name,
): failure,
'[ -d {tmp_dir}/{inventory} ]'.format(
tmp_dir=tmp_dir, inventory=inventory_name
): failure,
Expand Down Expand Up @@ -65,6 +70,17 @@ class PlaybookRunnerBase(object):
inventory=PlaybookRunner.default_inventory_name,
playbook=playbook_name
): success,
# Vault password file has been provided
'{bin} -e@{tmp_dir}/{vars_file} '
'--vault-password-file={tmp_dir}/{vault_password_file} '
'-i {tmp_dir}/{inventory} -v {tmp_dir}/{playbook}'.format(
bin=PlaybookRunner.binary,
vars_file=vars_file_name,
vault_password_file=vault_password_file_name,
tmp_dir=tmp_dir,
inventory=PlaybookRunner.default_inventory_name,
playbook=playbook_name
): success,
# Custom inventory has been provided
'{bin} -i {tmp_dir}/{inventory} -v {tmp_dir}/{playbook}'.format(
bin=PlaybookRunner.binary,
Expand Down Expand Up @@ -236,6 +252,47 @@ def test_vars_file(self, playbook_runner, fake_playbook, fake_vars_file):
)


class TestVaultPasswordFile(PlaybookRunnerBase):

files = {}

@pytest.fixture()
def fake_protected_file(self, tmpdir):
fpf = tmpdir.join(self.vars_file_name)
fpf.write(self.vars_file_content)
return str(fpf)

@pytest.fixture()
def fake_vault_password_file(self, tmpdir):
fvpf = tmpdir.join(self.vault_password_file_name)
fvpf.write(self.vault_password_file_content)
return str(fvpf)

def test_vault_password_file(
self, playbook_runner, fake_playbook,
fake_protected_file, fake_vault_password_file
):
"""
User has provided YAML file with variables protected by ansible-vault.
They also provided vault password file unlocking vars file.
"""
rc, _, _ = playbook_runner.run(
playbook=fake_playbook,
vars_files=[fake_protected_file],
vault_password_file=fake_vault_password_file,
)
assert not rc
assert self.check_files_on_host(
[
os.path.join(
self.tmp_dir, PlaybookRunner.default_inventory_name
),
os.path.join(self.tmp_dir, self.vars_file_name),
os.path.join(self.tmp_dir, self.vault_password_file_name)
]
)


class TestInventory(PlaybookRunnerBase):

files = {}
Expand Down

0 comments on commit 9a6a787

Please sign in to comment.