1133 lines
48 KiB
Python
1133 lines
48 KiB
Python
# Copyright (c) 2017 StackHPC Ltd.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import argparse
|
|
import errno
|
|
import logging
|
|
import os
|
|
import os.path
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
from kayobe import ansible
|
|
from kayobe import exception
|
|
from kayobe import utils
|
|
from kayobe import vault
|
|
|
|
|
|
@mock.patch.dict(os.environ, clear=True)
|
|
class TestCase(unittest.TestCase):
|
|
|
|
maxDiff = None
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
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"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"-e", "@/etc/kayobe/vars-file1.yml",
|
|
"-e", "@/etc/kayobe/vars-file2.yaml",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
home = os.path.expanduser("~")
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": ":".join([
|
|
"/etc/kayobe/ansible/roles",
|
|
utils.get_data_files_path("ansible", "roles"),
|
|
home + "/.ansible/roles",
|
|
"/usr/share/ansible/roles",
|
|
"/etc/ansible/roles",
|
|
]),
|
|
"ANSIBLE_COLLECTIONS_PATH": ":".join([
|
|
"/etc/kayobe/ansible/collections",
|
|
utils.get_data_files_path("ansible", "collections"),
|
|
home + "/.ansible/collections",
|
|
"/usr/share/ansible/collections",
|
|
]),
|
|
"ANSIBLE_ACTION_PLUGINS": ":".join([
|
|
"/etc/kayobe/ansible/action_plugins",
|
|
utils.get_data_files_path("ansible", "action_plugins"),
|
|
home + "/.ansible/plugins/action",
|
|
"/usr/share/ansible/plugins/action",
|
|
]),
|
|
"ANSIBLE_FILTER_PLUGINS": ":".join([
|
|
"/etc/kayobe/ansible/filter_plugins",
|
|
utils.get_data_files_path("ansible", "filter_plugins"),
|
|
home + "/.ansible/plugins/filter",
|
|
"/usr/share/ansible/plugins/filter",
|
|
]),
|
|
"ANSIBLE_TEST_PLUGINS": ":".join([
|
|
"/etc/kayobe/ansible/test_plugins",
|
|
utils.get_data_files_path("ansible", "test_plugins"),
|
|
home + "/.ansible/plugins/test",
|
|
"/usr/share/ansible/plugins/test",
|
|
]),
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(["/etc/kayobe"])
|
|
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(utils, "is_readable_dir")
|
|
@mock.patch.object(utils, "is_readable_file")
|
|
@mock.patch.object(utils, "run_command")
|
|
def test_reserved_environment(
|
|
self, mock_run, mock_readable,
|
|
mock_readable_file, mock_vars):
|
|
mock_readable_file.return_value = {"result": True}
|
|
mock_readable.return_value = {"result": True}
|
|
mock_vars.return_value = ["/path/to/config/vars-file1.yml",
|
|
"/path/to/config/vars-file2.yaml"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "kayobe",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
with self.assertLogs(level=logging.ERROR) as ctx:
|
|
self.assertRaises(
|
|
SystemExit, ansible.run_playbooks, parsed_args,
|
|
["playbook1.yml"]
|
|
)
|
|
exp = "The environment name 'kayobe' is reserved for internal use."
|
|
log_found = any(exp in t for t in ctx.output)
|
|
assert log_found
|
|
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(utils, "is_readable_dir")
|
|
@mock.patch.object(utils, "is_readable_file")
|
|
@mock.patch.object(utils, "run_command")
|
|
def test_reserved_environment_negative(
|
|
self, mock_run, mock_readable,
|
|
mock_readable_file, mock_vars):
|
|
mock_readable_file.return_value = {"result": True}
|
|
mock_readable.return_value = {"result": True}
|
|
mock_vars.return_value = ["/path/to/config/vars-file1.yml",
|
|
"/path/to/config/vars-file2.yaml"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "kayobe2",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_run_playbooks_all_the_args(self, mock_validate, mock_vars,
|
|
mock_run):
|
|
mock_vars.return_value = ["/path/to/config/vars-file1.yml",
|
|
"/path/to/config/vars-file2.yaml"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"-b",
|
|
"-C",
|
|
"--config-path", "/path/to/config",
|
|
"-D",
|
|
"--environment", "test-env",
|
|
"-e", "ev_name1=ev_value1",
|
|
"-i", "/path/to/inventory",
|
|
"-l", "group1:host",
|
|
"-t", "tag1,tag2",
|
|
"-lt",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"],
|
|
verbose_level=2)
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"-vv",
|
|
"--list-tasks",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/path/to/inventory",
|
|
"-e", "@/path/to/config/vars-file1.yml",
|
|
"-e", "@/path/to/config/vars-file2.yaml",
|
|
"-e", "ev_name1=ev_value1",
|
|
"--become",
|
|
"--check",
|
|
"--diff",
|
|
"--limit", "group1:host",
|
|
"--tags", "tag1,tag2",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
home = os.path.expanduser("~")
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/path/to/config",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"ANSIBLE_ROLES_PATH": ":".join([
|
|
"/path/to/config/ansible/roles",
|
|
utils.get_data_files_path("ansible", "roles"),
|
|
home + "/.ansible/roles",
|
|
"/usr/share/ansible/roles",
|
|
"/etc/ansible/roles",
|
|
]),
|
|
"ANSIBLE_COLLECTIONS_PATH": ":".join([
|
|
"/path/to/config/ansible/collections",
|
|
utils.get_data_files_path("ansible", "collections"),
|
|
home + "/.ansible/collections",
|
|
"/usr/share/ansible/collections",
|
|
]),
|
|
"ANSIBLE_ACTION_PLUGINS": ":".join([
|
|
"/path/to/config/ansible/action_plugins",
|
|
utils.get_data_files_path("ansible", "action_plugins"),
|
|
home + "/.ansible/plugins/action",
|
|
"/usr/share/ansible/plugins/action",
|
|
]),
|
|
"ANSIBLE_FILTER_PLUGINS": ":".join([
|
|
"/path/to/config/ansible/filter_plugins",
|
|
utils.get_data_files_path("ansible", "filter_plugins"),
|
|
home + "/.ansible/plugins/filter",
|
|
"/usr/share/ansible/plugins/filter",
|
|
]),
|
|
"ANSIBLE_TEST_PLUGINS": ":".join([
|
|
"/path/to/config/ansible/test_plugins",
|
|
utils.get_data_files_path("ansible", "test_plugins"),
|
|
home + "/.ansible/plugins/test",
|
|
"/usr/share/ansible/plugins/test",
|
|
]),
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(
|
|
["/path/to/config", "/path/to/config/environments/test-env"])
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
@mock.patch.object(vault, "_ask_vault_pass")
|
|
def test_run_playbooks_all_the_long_args(self, mock_ask, mock_validate,
|
|
mock_vars, mock_run):
|
|
mock_vars.return_value = ["/path/to/config/vars-file1.yml",
|
|
"/path/to/config/vars-file2.yaml"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
mock_ask.return_value = "test-pass"
|
|
args = [
|
|
"--ask-vault-pass",
|
|
"--become",
|
|
"--check",
|
|
"--config-path", "/path/to/config",
|
|
"--diff",
|
|
"--environment", "test-env",
|
|
"--extra-vars", "ev_name1=ev_value1",
|
|
"--inventory", "/path/to/inventory",
|
|
"--limit", "group1:host1",
|
|
"--skip-tags", "tag3,tag4",
|
|
"--tags", "tag1,tag2",
|
|
"--list-tasks",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
mock_run.return_value = "/path/to/kayobe-vault-password-helper"
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--list-tasks",
|
|
"--vault-password-file", "/path/to/kayobe-vault-password-helper",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/path/to/inventory",
|
|
"-e", "@/path/to/config/vars-file1.yml",
|
|
"-e", "@/path/to/config/vars-file2.yaml",
|
|
"-e", "ev_name1=ev_value1",
|
|
"--become",
|
|
"--check",
|
|
"--diff",
|
|
"--limit", "group1:host1",
|
|
"--skip-tags", "tag3,tag4",
|
|
"--tags", "tag1,tag2",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/path/to/config",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"KAYOBE_VAULT_PASSWORD": "test-pass",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
expected_calls = [
|
|
mock.call(["which", "kayobe-vault-password-helper"],
|
|
check_output=True, universal_newlines=True),
|
|
mock.call(expected_cmd, check_output=False, quiet=False,
|
|
env=expected_env)
|
|
]
|
|
self.assertListEqual(expected_calls, mock_run.mock_calls)
|
|
mock_vars.assert_called_once_with(
|
|
["/path/to/config", "/path/to/config/environments/test-env"])
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
@mock.patch.object(vault, "update_environment")
|
|
def test_run_playbooks_vault_password_file(self, mock_update,
|
|
mock_validate,
|
|
mock_vars, mock_run):
|
|
mock_vars.return_value = []
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--vault-password-file", "/path/to/vault/pw",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--vault-password-file", "/path/to/vault/pw",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"playbook1.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_update.assert_called_once_with(mock.ANY, expected_env)
|
|
|
|
@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")
|
|
def test_run_playbooks_vault_password_helper(self, mock_validate,
|
|
mock_vars, mock_run):
|
|
mock_vars.return_value = []
|
|
parser = argparse.ArgumentParser()
|
|
mock_run.return_value = "/path/to/kayobe-vault-password-helper"
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
mock_run.assert_called_once_with(
|
|
["which", "kayobe-vault-password-helper"], check_output=True,
|
|
universal_newlines=True)
|
|
mock_run.reset_mock()
|
|
parsed_args = parser.parse_args([])
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--vault-password-file", "/path/to/kayobe-vault-password-helper",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"playbook1.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"KAYOBE_VAULT_PASSWORD": "test-pass",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_run_playbooks_vault_ask_and_file(self, mock_validate, mock_vars,
|
|
mock_run):
|
|
mock_vars.return_value = []
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--ask-vault-pass",
|
|
"--vault-password-file", "/path/to/vault/pw",
|
|
]
|
|
self.assertRaises(SystemExit, parser.parse_args, args)
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
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"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--extra-vars", "ev_name1=ev_value1",
|
|
"--limit", "group1:host1",
|
|
"--tags", "tag1,tag2",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
kwargs = {
|
|
"extra_vars": {"ev_name2": "ev_value2"},
|
|
"limit": "group2:host2",
|
|
"tags": "tag3,tag4",
|
|
"verbose_level": 0,
|
|
"check": True,
|
|
"diff": True,
|
|
}
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"],
|
|
**kwargs)
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"-e", "@/etc/kayobe/vars-file1.yml",
|
|
"-e", "@/etc/kayobe/vars-file2.yaml",
|
|
"-e", "ev_name1=ev_value1",
|
|
"-e", "ev_name2='ev_value2'",
|
|
"--check",
|
|
"--diff",
|
|
"--limit", "group1:host1:&group2:host2",
|
|
"--tags", "tag1,tag2,tag3,tag4",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
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")
|
|
def test_run_playbooks_ignore_limit(self, mock_validate, mock_vars,
|
|
mock_run):
|
|
mock_vars.return_value = ["/etc/kayobe/vars-file1.yml",
|
|
"/etc/kayobe/vars-file2.yaml"]
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"-l", "group1:host",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"],
|
|
limit="foo", ignore_limit=True)
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"-e", "@/etc/kayobe/vars-file1.yml",
|
|
"-e", "@/etc/kayobe/vars-file2.yaml",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
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")
|
|
def test_run_playbooks_list_tasks_arg(self, mock_validate, mock_vars,
|
|
mock_run):
|
|
mock_vars.return_value = []
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--list-tasks",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
kwargs = {
|
|
"list_tasks": False
|
|
}
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"],
|
|
**kwargs)
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(["/etc/kayobe"])
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(utils, "is_readable_file")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_run_playbooks_ansible_cfg(self, mock_validate, mock_vars,
|
|
mock_readable, mock_run):
|
|
mock_vars.return_value = []
|
|
mock_readable.return_value = {"result": True}
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"playbook1.yml",
|
|
]
|
|
expected_env = {
|
|
"ANSIBLE_CONFIG": "/etc/kayobe/ansible.cfg",
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(["/etc/kayobe"])
|
|
mock_readable.assert_called_once_with("/etc/kayobe/ansible.cfg")
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(utils, "is_readable_file")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_run_playbooks_ansible_cfg_env(self, mock_validate, mock_vars,
|
|
mock_readable, mock_run):
|
|
mock_vars.return_value = []
|
|
mock_readable.return_value = {"result": True}
|
|
os.environ["ANSIBLE_CONFIG"] = "/path/to/ansible.cfg"
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"playbook1.yml",
|
|
]
|
|
expected_env = {
|
|
"ANSIBLE_CONFIG": "/path/to/ansible.cfg",
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(["/etc/kayobe"])
|
|
mock_readable.assert_called_once_with("/etc/kayobe/ansible.cfg")
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_run_playbooks_failure(self, mock_validate, mock_vars, mock_run):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_run.side_effect = subprocess.CalledProcessError(1, "dummy")
|
|
self.assertRaises(SystemExit,
|
|
ansible.run_playbooks, parsed_args, ["command"])
|
|
|
|
@mock.patch.object(shutil, 'rmtree')
|
|
@mock.patch.object(utils, 'read_yaml_file')
|
|
@mock.patch.object(os, 'listdir')
|
|
@mock.patch.object(ansible, 'run_playbook')
|
|
@mock.patch.object(tempfile, 'mkdtemp')
|
|
def test_config_dump(self, mock_mkdtemp, mock_run, mock_listdir, mock_read,
|
|
mock_rmtree):
|
|
parser = argparse.ArgumentParser()
|
|
parsed_args = parser.parse_args([])
|
|
dump_dir = "/path/to/dump"
|
|
mock_mkdtemp.return_value = dump_dir
|
|
mock_listdir.return_value = ["host1.yml", "host2.yml"]
|
|
mock_read.side_effect = [
|
|
{"var1": "value1"},
|
|
{"var2": "value2"}
|
|
]
|
|
result = ansible.config_dump(parsed_args)
|
|
expected_result = {
|
|
"host1": {"var1": "value1"},
|
|
"host2": {"var2": "value2"},
|
|
}
|
|
self.assertEqual(result, expected_result)
|
|
dump_config_path = utils.get_data_files_path(
|
|
"ansible", "dump-config.yml")
|
|
mock_run.assert_called_once_with(parsed_args,
|
|
dump_config_path,
|
|
extra_vars={
|
|
"dump_path": dump_dir,
|
|
},
|
|
check_output=True, tags=None,
|
|
verbose_level=None, check=False,
|
|
list_tasks=False, diff=False)
|
|
mock_rmtree.assert_called_once_with(dump_dir)
|
|
mock_listdir.assert_any_call(dump_dir)
|
|
mock_read.assert_has_calls([
|
|
mock.call(os.path.join(dump_dir, "host1.yml")),
|
|
mock.call(os.path.join(dump_dir, "host2.yml")),
|
|
])
|
|
|
|
@mock.patch.object(utils, 'galaxy_role_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_roles(self, mock_mkdirs, mock_is_readable,
|
|
mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": False}
|
|
|
|
ansible.install_galaxy_roles(parsed_args)
|
|
|
|
mock_install.assert_called_once_with(utils.get_data_files_path(
|
|
"requirements.yml"), utils.get_data_files_path(
|
|
"ansible", "roles"), force=False)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
self.assertFalse(mock_mkdirs.called)
|
|
|
|
@mock.patch.object(utils, 'galaxy_role_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_roles_with_kayobe_config(
|
|
self, mock_mkdirs, mock_is_readable, mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": True}
|
|
|
|
ansible.install_galaxy_roles(parsed_args)
|
|
|
|
expected_calls = [
|
|
mock.call(utils.get_data_files_path("requirements.yml"),
|
|
utils.get_data_files_path("ansible", "roles"),
|
|
force=False),
|
|
mock.call("/etc/kayobe/ansible/requirements.yml",
|
|
"/etc/kayobe/ansible/roles", force=False)]
|
|
self.assertListEqual(expected_calls, mock_install.call_args_list)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/roles")
|
|
|
|
@mock.patch.object(utils, 'galaxy_role_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_roles_with_kayobe_config_forced(
|
|
self, mock_mkdirs, mock_is_readable, mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": True}
|
|
|
|
ansible.install_galaxy_roles(parsed_args, force=True)
|
|
|
|
expected_calls = [
|
|
mock.call(utils.get_data_files_path("requirements.yml"),
|
|
utils.get_data_files_path("ansible", "roles"),
|
|
force=True),
|
|
mock.call("/etc/kayobe/ansible/requirements.yml",
|
|
"/etc/kayobe/ansible/roles", force=True)]
|
|
self.assertListEqual(expected_calls, mock_install.call_args_list)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/roles")
|
|
|
|
@mock.patch.object(utils, 'galaxy_role_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_roles_with_kayobe_config_mkdirs_failure(
|
|
self, mock_mkdirs, mock_is_readable, mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": True}
|
|
mock_mkdirs.side_effect = OSError(errno.EPERM)
|
|
|
|
self.assertRaises(exception.Error,
|
|
ansible.install_galaxy_roles, parsed_args)
|
|
|
|
mock_install.assert_called_once_with(utils.get_data_files_path(
|
|
"requirements.yml"), utils.get_data_files_path("ansible", "roles"),
|
|
force=False)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/roles")
|
|
|
|
@mock.patch.object(utils, 'galaxy_collection_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_collections(self, mock_mkdirs, mock_is_readable,
|
|
mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": False}
|
|
|
|
ansible.install_galaxy_collections(parsed_args)
|
|
|
|
mock_install.assert_called_once_with(utils.get_data_files_path(
|
|
"requirements.yml"), utils.get_data_files_path(
|
|
"ansible", "collections"), force=False)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
self.assertFalse(mock_mkdirs.called)
|
|
|
|
@mock.patch.object(utils, 'galaxy_collection_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_collections_with_kayobe_config(
|
|
self, mock_mkdirs, mock_is_readable, mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": True}
|
|
|
|
ansible.install_galaxy_collections(parsed_args)
|
|
|
|
expected_calls = [
|
|
mock.call(utils.get_data_files_path("requirements.yml"),
|
|
utils.get_data_files_path("ansible", "collections"),
|
|
force=False),
|
|
mock.call("/etc/kayobe/ansible/requirements.yml",
|
|
"/etc/kayobe/ansible/collections", force=False)]
|
|
self.assertListEqual(expected_calls, mock_install.call_args_list)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/collections")
|
|
|
|
@mock.patch.object(utils, 'galaxy_collection_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_collections_with_kayobe_config_forced(
|
|
self, mock_mkdirs, mock_is_readable, mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": True}
|
|
|
|
ansible.install_galaxy_collections(parsed_args, force=True)
|
|
|
|
expected_calls = [
|
|
mock.call(utils.get_data_files_path("requirements.yml"),
|
|
utils.get_data_files_path("ansible", "collections"),
|
|
force=True),
|
|
mock.call("/etc/kayobe/ansible/requirements.yml",
|
|
"/etc/kayobe/ansible/collections", force=True)]
|
|
self.assertListEqual(expected_calls, mock_install.call_args_list)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/collections")
|
|
|
|
@mock.patch.object(utils, 'galaxy_collection_install', autospec=True)
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
@mock.patch.object(os, 'makedirs', autospec=True)
|
|
def test_install_galaxy_collections_with_kayobe_config_mkdirs_failure(
|
|
self, mock_mkdirs, mock_is_readable, mock_install):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": True}
|
|
mock_mkdirs.side_effect = OSError(errno.EPERM)
|
|
|
|
self.assertRaises(exception.Error,
|
|
ansible.install_galaxy_collections, parsed_args)
|
|
|
|
mock_install.assert_called_once_with(
|
|
utils.get_data_files_path("requirements.yml"),
|
|
utils.get_data_files_path("ansible", "collections"), force=False)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/ansible/requirements.yml")
|
|
mock_mkdirs.assert_called_once_with("/etc/kayobe/ansible/collections")
|
|
|
|
@mock.patch.object(utils, 'galaxy_remove', autospec=True)
|
|
def test_prune_galaxy_roles(self, mock_remove):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
|
|
ansible.prune_galaxy_roles(parsed_args)
|
|
|
|
expected_roles = [
|
|
'resmo.ntp',
|
|
'stackhpc.ntp',
|
|
'stackhpc.os-shade',
|
|
'yatesr.timezone',
|
|
]
|
|
mock_remove.assert_called_once_with(expected_roles,
|
|
"ansible/roles")
|
|
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
def test_passwords_yml_exists_false(self, mock_is_readable):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args([])
|
|
mock_is_readable.return_value = {"result": False}
|
|
|
|
result = ansible.passwords_yml_exists(parsed_args)
|
|
|
|
self.assertFalse(result)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/etc/kayobe/kolla/passwords.yml")
|
|
|
|
@mock.patch.object(utils, 'is_readable_file', autospec=True)
|
|
def test_passwords_yml_exists_true(self, mock_is_readable):
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
parsed_args = parser.parse_args(["--config-path", "/path/to/config"])
|
|
mock_is_readable.return_value = {"result": True}
|
|
|
|
result = ansible.passwords_yml_exists(parsed_args)
|
|
|
|
self.assertTrue(result)
|
|
mock_is_readable.assert_called_once_with(
|
|
"/path/to/config/kolla/passwords.yml")
|
|
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_multiple_inventory_args(self, mock_validate, mock_vars, mock_run):
|
|
mock_vars.return_value = []
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"--inventory", "/etc/kayobe/environments/foobar/inventory",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"--inventory", "/etc/kayobe/environments/foobar/inventory",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(["/etc/kayobe"])
|
|
|
|
@mock.patch.object(os.path, "exists")
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_multiple_inventories(self, mock_validate, mock_vars, mock_run,
|
|
mock_exists):
|
|
mock_vars.return_value = []
|
|
|
|
def exists_replacement(path):
|
|
if path == "/etc/kayobe/inventory":
|
|
return True
|
|
if path == "/etc/kayobe/environments/test-env/inventory":
|
|
return True
|
|
return False
|
|
mock_exists.side_effect = exists_replacement
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "test-env",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"--inventory", "/etc/kayobe/environments/test-env/inventory",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(
|
|
["/etc/kayobe", "/etc/kayobe/environments/test-env"])
|
|
|
|
@mock.patch.object(os.path, "exists")
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_shared_inventory_only(self, mock_validate, mock_vars, mock_run,
|
|
mock_exists):
|
|
mock_vars.return_value = []
|
|
|
|
def exists_replacement(path):
|
|
if path == "/etc/kayobe/inventory":
|
|
return True
|
|
return False
|
|
mock_exists.side_effect = exists_replacement
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "test-env",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/inventory",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(
|
|
["/etc/kayobe", "/etc/kayobe/environments/test-env"])
|
|
|
|
@mock.patch.object(os.path, "exists")
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_env_inventory_only(self, mock_validate, mock_vars, mock_run,
|
|
mock_exists):
|
|
mock_vars.return_value = []
|
|
# We only want it to find the inventory in the environment
|
|
|
|
def exists_replacement(path):
|
|
if path == "/etc/kayobe/environments/test-env/inventory":
|
|
return True
|
|
return False
|
|
mock_exists.side_effect = exists_replacement
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "test-env",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/environments/test-env/inventory",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(
|
|
["/etc/kayobe", "/etc/kayobe/environments/test-env"])
|
|
|
|
@mock.patch.object(utils.EnvironmentFinder, "ordered")
|
|
@mock.patch.object(os.path, "exists")
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_multi_env_inventory_only(self, mock_validate, mock_vars,
|
|
mock_run, mock_exists, mock_finder):
|
|
mock_vars.return_value = []
|
|
mock_finder.return_value = ["dependency-env", "test-env"]
|
|
|
|
def exists_replacement(path):
|
|
if path == "/etc/kayobe/environments/test-env/inventory":
|
|
return True
|
|
if path == "/etc/kayobe/environments/dependency-env/inventory":
|
|
return True
|
|
return False
|
|
mock_exists.side_effect = exists_replacement
|
|
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "test-env",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/environments/dependency-env/inventory",
|
|
"--inventory", "/etc/kayobe/environments/test-env/inventory",
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(
|
|
["/etc/kayobe",
|
|
"/etc/kayobe/environments/dependency-env",
|
|
"/etc/kayobe/environments/test-env"]
|
|
)
|
|
|
|
@mock.patch.object(utils.EnvironmentFinder, "ordered")
|
|
@mock.patch.object(os.path, "exists")
|
|
@mock.patch.object(utils, "run_command")
|
|
@mock.patch.object(ansible, "_get_vars_files")
|
|
@mock.patch.object(ansible, "_validate_args")
|
|
def test_multi_env_vars(self, mock_validate, mock_vars,
|
|
mock_run, mock_exists, mock_finder):
|
|
|
|
def get_vars_replacement(paths):
|
|
result = []
|
|
for path in paths:
|
|
if path == "/etc/kayobe/environments/test-env":
|
|
result.extend(
|
|
["vars-test-env-1.yml", "vars-test-env-2.yml"]
|
|
)
|
|
continue
|
|
if path == "/etc/kayobe/environments/dependency-env":
|
|
result.extend(
|
|
["vars-dependency-env-1.yml",
|
|
"vars-dependency-env-2.yml"]
|
|
)
|
|
continue
|
|
if path == "/etc/kayobe":
|
|
result.extend(
|
|
["vars-1.yml", "vars-2.yml"]
|
|
)
|
|
continue
|
|
return result
|
|
mock_vars.side_effect = get_vars_replacement
|
|
|
|
mock_finder.return_value = ["dependency-env", "test-env"]
|
|
|
|
def exists_replacement(path):
|
|
if path == "/etc/kayobe/environments/test-env/inventory":
|
|
return True
|
|
if path == "/etc/kayobe/environments/dependency-env/inventory":
|
|
return True
|
|
return False
|
|
|
|
mock_exists.side_effect = exists_replacement
|
|
|
|
parser = argparse.ArgumentParser()
|
|
ansible.add_args(parser)
|
|
vault.add_args(parser)
|
|
args = [
|
|
"--environment", "test-env",
|
|
]
|
|
parsed_args = parser.parse_args(args)
|
|
ansible.run_playbooks(parsed_args, ["playbook1.yml", "playbook2.yml"])
|
|
expected_cmd = [
|
|
"ansible-playbook",
|
|
"--inventory", utils.get_data_files_path("ansible", "inventory"),
|
|
"--inventory", "/etc/kayobe/environments/dependency-env/inventory",
|
|
"--inventory", "/etc/kayobe/environments/test-env/inventory",
|
|
'-e', '@vars-1.yml',
|
|
'-e', '@vars-2.yml',
|
|
'-e', '@vars-dependency-env-1.yml',
|
|
'-e', '@vars-dependency-env-2.yml',
|
|
'-e', '@vars-test-env-1.yml',
|
|
'-e', '@vars-test-env-2.yml',
|
|
"playbook1.yml",
|
|
"playbook2.yml",
|
|
]
|
|
expected_env = {
|
|
"KAYOBE_CONFIG_PATH": "/etc/kayobe",
|
|
"KAYOBE_ENVIRONMENT": "test-env",
|
|
"ANSIBLE_ROLES_PATH": mock.ANY,
|
|
"ANSIBLE_COLLECTIONS_PATH": mock.ANY,
|
|
"ANSIBLE_ACTION_PLUGINS": mock.ANY,
|
|
"ANSIBLE_FILTER_PLUGINS": mock.ANY,
|
|
"ANSIBLE_TEST_PLUGINS": mock.ANY,
|
|
}
|
|
mock_run.assert_called_once_with(expected_cmd, check_output=False,
|
|
quiet=False, env=expected_env)
|
|
mock_vars.assert_called_once_with(
|
|
["/etc/kayobe",
|
|
"/etc/kayobe/environments/dependency-env",
|
|
"/etc/kayobe/environments/test-env"]
|
|
)
|