Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions ansible/install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---

- name: Ensure depnedencies are installed
hosts: localhost
gather_facts: true
tags:
- kolla-ansible
- install
tasks:
- name: Install Kayobe dependencies
import_role:
name: bootstrap
tasks_from: install.yml

- name: Install kolla-ansible
import_role:
name: kolla-ansible
tasks_from: install.yml

46 changes: 46 additions & 0 deletions ansible/roles/bootstrap/tasks/install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
- block:
- name: Testing privilege escalation
raw: "true"
become: true
failed_when: false
changed_when: false
register: privilege_escalation_result

- name: Assert that we can escalate privileges
assert:
that:
- privilege_escalation_result is success
- '"password is required" not in privilege_escalation_result.stderr'
fail_msg: >-
Could not escalate privileges. You can either: set kayobe_control_host_become: true,
set ansible_become_password, or set up passwordless sudo.
when: kayobe_control_host_become | bool

- name: Include OS family-specific variables
include_vars: "{{ ansible_facts.os_family }}.yml"

- name: Gather the package facts
ansible.builtin.package_facts:
manager: auto

- block:
- name: Assert that all packages are installed if not using privilege escalation
assert:
that: missing_packages is falsy
fail_msg: >-
The following packages are missing from your system: {{ missing_packages | join(', ') }} and
privilege escalation is disabled. Please get your system administator to install these packages
or enable kayobe_control_host_become.
when: not kayobe_control_host_become | bool

- name: Ensure required packages are installed
package:
name: "{{ bootstrap_package_dependencies }}"
state: present
cache_valid_time: "{{ apt_cache_valid_time if ansible_facts.os_family == 'Debian' else omit }}"
update_cache: "{{ True if ansible_facts.os_family == 'Debian' else omit }}"
become: True
when: missing_packages is truthy
vars:
missing_packages: "{{ bootstrap_package_dependencies | difference(ansible_facts.packages.keys()) }}"
47 changes: 0 additions & 47 deletions ansible/roles/bootstrap/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,50 +1,3 @@
---
- block:
- name: Testing privilege escalation
raw: "true"
become: true
failed_when: false
changed_when: false
register: privilege_escalation_result

- name: Assert that we can escalate privileges
assert:
that:
- privilege_escalation_result is success
- '"password is required" not in privilege_escalation_result.stderr'
fail_msg: >-
Could not escalate privileges. You can either: set kayobe_control_host_become: true,
set ansible_become_password, or set up passwordless sudo.
when: kayobe_control_host_become | bool

- name: Include OS family-specific variables
include_vars: "{{ ansible_facts.os_family }}.yml"

- name: Gather the package facts
ansible.builtin.package_facts:
manager: auto

- block:
- name: Assert that all packages are installed if not using privilege escalation
assert:
that: missing_packages is falsy
fail_msg: >-
The following packages are missing from your system: {{ missing_packages | join(', ') }} and
privilege escalation is disabled. Please get your system administator to install these packages
or enable kayobe_control_host_become.
when: not kayobe_control_host_become | bool

- name: Ensure required packages are installed
package:
name: "{{ bootstrap_package_dependencies }}"
state: present
cache_valid_time: "{{ apt_cache_valid_time if ansible_facts.os_family == 'Debian' else omit }}"
update_cache: "{{ True if ansible_facts.os_family == 'Debian' else omit }}"
become: True
when: missing_packages is truthy
vars:
missing_packages: "{{ bootstrap_package_dependencies | difference(ansible_facts.packages.keys()) }}"

- name: Check whether an SSH key exists
stat:
path: "{{ bootstrap_ssh_private_key_path }}"
Expand Down
6 changes: 0 additions & 6 deletions ansible/roles/kolla-ansible/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
---
# NOTE: Use import_tasks here, since tags are not applied to tasks included via
# include_tasks.
- import_tasks: install.yml
tags:
- install

- import_tasks: config.yml
tags:
- config
18 changes: 18 additions & 0 deletions kayobe/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import os
import re
import sys
import yaml

from cliff.command import Command
from cliff.hooks import CommandHook
Expand Down Expand Up @@ -301,13 +302,30 @@ def get_parser(self, prog_name):
group = parser.add_argument_group("Host Bootstrap")
group.add_argument("--add-known-hosts", action='store_true',
help="add SSH known hosts entries for each host")
group.add_argument(
"--install-only",
action='store_true',
default=yaml.safe_load(os.getenv("KAYOBE_INSTALL_ONLY", "false")),
help=("only install dependencies "
"(default from KAYOBE_INSTALL_ONLY env var)"),
)
return parser

def take_action(self, parsed_args):
self.app.LOG.debug("Bootstrapping Kayobe Ansible control host")
self.handle_kolla_tags_limits_deprecation(parsed_args)
ansible.install_galaxy_roles(parsed_args)
ansible.install_galaxy_collections(parsed_args)

playbooks = _build_playbook_list("install")
self.run_kayobe_playbooks(parsed_args, playbooks, ignore_limit=True)

if parsed_args.install_only:
self.app.LOG.debug("Skipping kolla-ansible installation and "
"configuration generation due to "
"--install-only")
return

playbooks = _build_playbook_list("bootstrap")
self.run_kayobe_playbooks(parsed_args, playbooks, ignore_limit=True)

Expand Down
25 changes: 25 additions & 0 deletions kayobe/tests/unit/cli/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,21 @@ class TestCase(unittest.TestCase):

maxDiff = None

@mock.patch.dict(os.environ, {}, clear=True)
def test_control_host_bootstrap_install_only_default_false(self):
command = commands.ControlHostBootstrap(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
self.assertFalse(parsed_args.install_only)

@mock.patch.dict(os.environ, {"KAYOBE_INSTALL_ONLY": "false"},
clear=True)
def test_control_host_bootstrap_install_only_default_false_from_env(self):
command = commands.ControlHostBootstrap(TestApp(), [])
parser = command.get_parser("test")
parsed_args = parser.parse_args([])
self.assertFalse(parsed_args.install_only)

@mock.patch.object(ansible, "install_galaxy_roles", autospec=True)
@mock.patch.object(ansible, "install_galaxy_collections", autospec=True)
@mock.patch.object(ansible, "passwords_yml_exists", autospec=True)
Expand All @@ -55,6 +70,11 @@ def test_control_host_bootstrap(self, mock_run, mock_passwords,
mock_install_roles.assert_called_once_with(parsed_args)
mock_install_collections.assert_called_once_with(parsed_args)
expected_calls = [
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "install.yml")],
ignore_limit=True,
),
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "bootstrap.yml")],
Expand Down Expand Up @@ -89,6 +109,11 @@ def test_control_host_bootstrap_with_passwords(
mock_install_roles.assert_called_once_with(parsed_args)
mock_install_collections.assert_called_once_with(parsed_args)
expected_calls = [
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "install.yml")],
ignore_limit=True,
),
mock.call(
mock.ANY,
[utils.get_data_files_path("ansible", "bootstrap.yml")],
Expand Down