Add vault password and config path to env vars

This change sets the KAYOBE_VAULT_PASSWORD environment variable when a
vault password file is specified via --vault-password-file. This allows
the kayobe playbooks to use the password to encrypt and decrypt the
kolla ansible passwords.yml file.

We also set the KAYOBE_CONFIG_PATH environment variable, to ensure that
kayobe playbooks set the {{ kayobe_config_path }} variable correctly
when the config path is specified via --config-path.

Change-Id: Id61527ff5e76cac3a485746a1c2898f03ed1bce6
Story: 2001664
Task: 6699
This commit is contained in:
Mark Goddard 2017-11-09 15:12:36 +00:00
parent b80e94ca36
commit 6ab6452345
2 changed files with 60 additions and 10 deletions

View File

@ -150,6 +150,13 @@ def build_args(parsed_args, playbooks,
return cmd
def _read_vault_password_file(vault_password_file):
"""Return the password from a vault password file."""
vault_password = utils.read_file(vault_password_file)
vault_password = vault_password.strip()
return vault_password
def run_playbooks(parsed_args, playbooks,
extra_vars=None, limit=None, tags=None, quiet=False,
verbose_level=None, check=None):
@ -158,8 +165,20 @@ def run_playbooks(parsed_args, playbooks,
cmd = build_args(parsed_args, playbooks,
extra_vars=extra_vars, limit=limit, tags=tags,
verbose_level=verbose_level, check=check)
env = os.environ.copy()
# If the Vault password has been specified via --vault-password-file,
# ensure the environment variable is set, so that it can be referenced by
# playbooks to generate the kolla-ansible passwords.yml file.
if vault.VAULT_PASSWORD_ENV not in env and parsed_args.vault_password_file:
vault_password = _read_vault_password_file(
parsed_args.vault_password_file)
env[vault.VAULT_PASSWORD_ENV] = vault_password
# If the configuration path has been specified via --config-path, ensure
# the environment variable is set, so that it can be referenced by
# playbooks.
env.setdefault(CONFIG_PATH_ENV, parsed_args.config_path)
try:
utils.run_command(cmd, quiet=quiet)
utils.run_command(cmd, quiet=quiet, env=env)
except subprocess.CalledProcessError as e:
LOG.error("Kayobe playbook(s) %s exited %d",
", ".join(playbooks), e.returncode)

View File

@ -31,6 +31,7 @@ class TestCase(unittest.TestCase):
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks(self, mock_validate, mock_vars, mock_run):
mock_vars.return_value = ["/etc/kayobe/vars-file1.yml",
"/etc/kayobe/vars-file2.yaml"]
@ -47,12 +48,15 @@ class TestCase(unittest.TestCase):
"playbook1.yml",
"playbook2.yml",
]
mock_run.assert_called_once_with(expected_cmd, quiet=False)
expected_env = {"KAYOBE_CONFIG_PATH": "/etc/kayobe"}
mock_run.assert_called_once_with(expected_cmd, quiet=False,
env=expected_env)
mock_vars.assert_called_once_with("/etc/kayobe")
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks_all_the_args(self, mock_validate, mock_vars,
mock_run):
mock_vars.return_value = ["/path/to/config/vars-file1.yml",
@ -88,12 +92,15 @@ class TestCase(unittest.TestCase):
"playbook1.yml",
"playbook2.yml",
]
mock_run.assert_called_once_with(expected_cmd, quiet=False)
expected_env = {"KAYOBE_CONFIG_PATH": "/path/to/config"}
mock_run.assert_called_once_with(expected_cmd, quiet=False,
env=expected_env)
mock_vars.assert_called_once_with("/path/to/config")
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks_all_the_long_args(self, mock_validate, mock_vars,
mock_run):
mock_vars.return_value = ["/path/to/config/vars-file1.yml",
@ -131,15 +138,20 @@ class TestCase(unittest.TestCase):
"playbook1.yml",
"playbook2.yml",
]
mock_run.assert_called_once_with(expected_cmd, quiet=False)
expected_env = {"KAYOBE_CONFIG_PATH": "/path/to/config"}
mock_run.assert_called_once_with(expected_cmd, quiet=False,
env=expected_env)
mock_vars.assert_called_once_with("/path/to/config")
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
def test_run_playbooks_vault_password_file(self, mock_validate, mock_vars,
mock_run):
@mock.patch.object(ansible, "_read_vault_password_file")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks_vault_password_file(self, mock_read, mock_validate,
mock_vars, mock_run):
mock_vars.return_value = []
mock_read.return_value = "test-pass"
parser = argparse.ArgumentParser()
ansible.add_args(parser)
vault.add_args(parser)
@ -154,9 +166,13 @@ class TestCase(unittest.TestCase):
"--inventory", "/etc/kayobe/inventory",
"playbook1.yml",
]
mock_run.assert_called_once_with(expected_cmd, quiet=False)
expected_env = {"KAYOBE_CONFIG_PATH": "/etc/kayobe",
"KAYOBE_VAULT_PASSWORD": "test-pass"}
mock_run.assert_called_once_with(expected_cmd, quiet=False,
env=expected_env)
@mock.patch.dict(os.environ, {"KAYOBE_VAULT_PASSWORD": "test-pass"})
@mock.patch.dict(os.environ, {"KAYOBE_VAULT_PASSWORD": "test-pass"},
clear=True)
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@ -178,11 +194,15 @@ class TestCase(unittest.TestCase):
"--inventory", "/etc/kayobe/inventory",
"playbook1.yml",
]
mock_run.assert_called_once_with(expected_cmd, quiet=False)
expected_env = {"KAYOBE_CONFIG_PATH": "/etc/kayobe",
"KAYOBE_VAULT_PASSWORD": "test-pass"}
mock_run.assert_called_once_with(expected_cmd, quiet=False,
env=expected_env)
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks_vault_ask_and_file(self, mock_validate, mock_vars,
mock_run):
mock_vars.return_value = []
@ -198,6 +218,7 @@ class TestCase(unittest.TestCase):
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks_func_args(self, mock_validate, mock_vars, mock_run):
mock_vars.return_value = ["/etc/kayobe/vars-file1.yml",
"/etc/kayobe/vars-file2.yaml"]
@ -232,12 +253,15 @@ class TestCase(unittest.TestCase):
"playbook1.yml",
"playbook2.yml",
]
mock_run.assert_called_once_with(expected_cmd, quiet=False)
expected_env = {"KAYOBE_CONFIG_PATH": "/etc/kayobe"}
mock_run.assert_called_once_with(expected_cmd, quiet=False,
env=expected_env)
mock_vars.assert_called_once_with("/etc/kayobe")
@mock.patch.object(utils, "run_command")
@mock.patch.object(ansible, "_get_vars_files")
@mock.patch.object(ansible, "_validate_args")
@mock.patch.dict(os.environ, clear=True)
def test_run_playbooks_failure(self, mock_validate, mock_vars, mock_run):
parser = argparse.ArgumentParser()
ansible.add_args(parser)
@ -281,3 +305,10 @@ class TestCase(unittest.TestCase):
mock.call(os.path.join(dump_dir, "host1.yml")),
mock.call(os.path.join(dump_dir, "host2.yml")),
])
@mock.patch.object(utils, 'read_file')
def test__read_vault_password_file(self, mock_read):
mock_read.return_value = "test-pass\n"
result = ansible._read_vault_password_file("/path/to/file")
self.assertEqual("test-pass", result)
mock_read.assert_called_once_with("/path/to/file")