---
# Copyright kubeinit contributors
# All Rights Reserved.
#
# 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.
- name: Omit from documentation grapher
block:
- name: Stop the deployment if required
block:
- name: "Stop before 'task-gather-facts' when requested"
ansible.builtin.add_host:
name: "kubeinit-facts"
playbook_terminated: true
- name: End play
ansible.builtin.meta: end_play
when: kubeinit_stop_before_task is defined and kubeinit_stop_before_task == 'task-gather-facts'
tags: omit_from_grapher
#
# Gather facts needed to create the kubeinit_hypervisors group
#
- name: Add playbook context facts
ansible.builtin.add_host:
name: 'kubeinit-facts'
groups: 'kubeinit_facts'
container_run: "{{ kubeinit_container_run | default(false) | bool }}"
- name: Load kubeinit_env group
ansible.builtin.add_host:
name: 'kubeinit-env'
groups: 'kubeinit_env'
- name: Gather kubeinit secrets
ansible.builtin.include_role:
name: kubeinit.kubeinit.kubeinit_prepare
tasks_from: gather_kubeinit_secrets.yml
public: true
vars:
_param_secret_names:
- kubeinit-ssh-key
- name: Lookup remote_user from command-line
ansible.builtin.set_fact:
kubeinit_cli_remote_user: "{{ lookup('kubeinit.kubeinit.cli_args', 'remote_user') }}"
- name: Check for empty remote user when running from kubeinit container
ansible.builtin.assert:
msg:
- "You must provide the user for the playbook when running from the kubeinit container."
- "e.g. --user root"
that: not hostvars['kubeinit-facts'].container_run or kubeinit_cli_remote_user|length > 0
- name: Define kubeinit remote_user
ansible.builtin.add_host:
name: "kubeinit-facts"
local_user: "{{ ansible_facts.user_id }}"
local_home: "{{ ansible_facts.user_dir }}"
remote_user: "{{ kubeinit_cli_remote_user if (kubeinit_cli_remote_user|length > 0) else ansible_facts.user_id }}"
ssh_keytype: "{{ hostvars['kubeinit-env'].ssh_keytype }}"
- name: Prepare cluster topology using kubeinit_spec command-line specification
ansible.builtin.set_fact:
kubeinit_spec_parts: "{{ kubeinit_spec.split('-') | default([]) }}"
- name: Assert we have a minimum number of spec parts
ansible.builtin.assert:
msg: "Usage: -e kubeinit_spec=<distro>-<driver>-<controllers>-<computes>-<hypervisors>[-<ignored>]"
that: kubeinit_spec_parts|length >= 5
- name: Set facts from spec parts
ansible.builtin.set_fact:
kubeinit_spec_distro: "{{ kubeinit_spec_parts[0] }}"
kubeinit_spec_driver: "{{ kubeinit_spec_parts[1] }}"
kubeinit_spec_controller_count: "{{ kubeinit_spec_parts[2] }}"
kubeinit_spec_compute_count: "{{ kubeinit_spec_parts[3] }}"
kubeinit_spec_hypervisor_count: "{{ kubeinit_spec_parts[4] }}"
- name: Set fact for the spec distro role
ansible.builtin.set_fact:
kubeinit_distro_role: "{{ hostvars['kubeinit-facts'].distro_facts[kubeinit_spec_distro].role }}"
when: hostvars['kubeinit-facts'].distro_facts[kubeinit_spec_distro] is defined
- name: Assert spec constraints
ansible.builtin.assert:
that:
- kubeinit_distro_role is defined
- kubeinit_spec_driver in ['libvirt']
- kubeinit_spec_controller_count in ['1', '3', '5']
- kubeinit_spec_compute_count|int >= 0
- kubeinit_spec_hypervisor_count|int >= 1
- name: Load kubeinit_cluster_spec from yaml into a dictionary
ansible.builtin.set_fact:
kubeinit_cluster_map: "{{ kubeinit_cluster_spec | from_yaml }}"
when: kubeinit_cluster_spec is defined
- name: Assert kubeinit_cluster group and kubeinit_cluster_spec have same name when both defined
ansible.builtin.assert:
msg: "Cluster name from inventory and command-line specification must match."
that: kubeinit_cluster_map['cluster_name'] == groups['kubeinit_cluster'][0]
when: kubeinit_cluster_map['cluster_name'] | default('') | length > 0 and groups['kubeinit_cluster'][0] | default('') | length > 0
- name: Define kubeinit_cluster_name
ansible.builtin.set_fact:
kubeinit_cluster_name: "{{ kubeinit_cluster_map['cluster_name'] | default(groups['kubeinit_cluster'][0]) | default(kubeinit_spec_distro + 'cluster') }}"
- name: Add kubeinit_cluster_name to kubeinit-facts
ansible.builtin.add_host:
name: "kubeinit-facts"
cluster_name: "{{ kubeinit_cluster_name }}"
- name: Create kubeinit_cluster group
ansible.builtin.add_host:
name: "{{ kubeinit_cluster_name }}"
group: 'kubeinit_cluster'
when: groups['kubeinit_cluster'] | default([]) | length == 0
- name: Create .ssh folder if needed
ansible.builtin.file:
path: "{{ hostvars['kubeinit-facts'].local_home + '/.ssh' }}"
state: directory
mode: 0700
- name: Gather additional facts from localhost for kubeinit
ansible.builtin.include_role:
name: kubeinit.kubeinit.kubeinit_libvirt
tasks_from: gather_host_facts.yml
public: true
vars:
_param_gather_host: 'localhost'
- name: Generate an OpenSSH keypair on localhost
community.crypto.openssh_keypair:
path: "~/.ssh/{{ hostvars['kubeinit-facts'].cluster_name }}_id_{{ hostvars['kubeinit-facts'].ssh_keytype }}"
type: "{{ hostvars['kubeinit-facts'].ssh_keytype }}"
comment: "{{ hostvars['kubeinit-facts'].cluster_name }} ansible-controller"
regenerate: 'never'
register: _result_keypair
delegate_to: 'localhost'
- name: Create authorized_key from keypair
ansible.builtin.set_fact:
authorized_key: "{{ _result_keypair.public_key + ' ' + _result_keypair.comment }}"
delegate_to: 'localhost'
delegate_facts: true
- name: Add kubeinit_cluster_map entries to kubeinit_cluster group
ansible.builtin.add_host:
name: "{{ kubeinit_cluster_name }}"
groups: 'kubeinit_cluster'
cluster_domain: "{{ kubeinit_cluster_map['cluster_domain'] | default(omit) }}"
hypervisor_name_pattern: "{{ kubeinit_cluster_map['hypervisor_name_pattern'] | default(omit) }}"
controller_name_pattern: "{{ kubeinit_cluster_map['controller_name_pattern'] | default(omit) }}"
compute_name_pattern: "{{ kubeinit_cluster_map['compute_name_pattern'] | default(omit) }}"
when: kubeinit_cluster_map is defined
- name: Load post_deployment_services_spec from yaml into a list
ansible.builtin.set_fact:
post_deployment_services_list: "{{ post_deployment_services_spec | from_yaml }}"
when: post_deployment_services_spec is defined
- name: Add post_deployment_services_list to kubeinit_cluster group
ansible.builtin.add_host:
name: "{{ kubeinit_cluster_name }}"
groups: 'kubeinit_cluster'
post_deployment_services: "{{ post_deployment_services_list }}"
when: post_deployment_services_list | default([]) | length > 0
- name: Load extra_roles_spec from yaml into a list
ansible.builtin.set_fact:
extra_roles_list: "{{ extra_roles_spec | from_yaml }}"
when: extra_roles_spec is defined
- name: Add extra_roles_list to kubeinit_cluster group
ansible.builtin.add_host:
name: "{{ kubeinit_cluster_name }}"
groups: 'kubeinit_cluster'
extra_roles: "{{ extra_roles_list }}"
when: extra_roles_list | default([]) | length > 0
- name: Load hypervisor_hosts_spec from yaml into a list of dictionaries
ansible.builtin.set_fact:
hypervisor_hosts_map_list: "{{ hypervisor_hosts_spec | from_yaml }}"
when: hypervisor_hosts_spec is defined
- name: Assert hypervisor_hosts group and hypervisor_hosts_spec have same names when both defined
ansible.builtin.assert:
msg: "Hypervisor names from inventory and command-line specification must match."
that: hypervisor_hosts_map_list[ansible_loop.index0]['host'] == groups['hypervisor_hosts'][ansible_loop.index0]
loop: "{{ range(kubeinit_spec_hypervisor_count|int) | list }}"
loop_control:
extended: true
when: hypervisor_hosts_map_list[ansible_loop.index0]['host'] | default('') | length > 0 and groups['hypervisor_hosts'][ansible_loop.index0] | default('') | length > 0
- name: Create names and defaults for new cluster hypervisors
ansible.builtin.add_host:
name: "{{ hypervisor_hosts_map_list[ansible_loop.index0]['host'] | default(hostvars[kubeinit_cluster_name].hypervisor_name_pattern | format(ansible_loop.index)) }}"
groups:
- 'hypervisor_hosts'
- 'kubeinit_hypervisors'
ansible_connection: 'smart'
ansible_user: "{{ hostvars['kubeinit-facts'].remote_user }}"
loop: "{{ range(kubeinit_spec_hypervisor_count|int) | list }}"
loop_control:
extended: true
when: groups['hypervisor_hosts'] | default([]) | length == 0
- name: Assign defaults to existing cluster hypervisors
ansible.builtin.add_host:
name: "{{ groups['hypervisor_hosts'][ansible_loop.index0] }}"
groups: 'kubeinit_hypervisors'
ansible_connection: 'smart'
ansible_user: "{{ hostvars['kubeinit-facts'].remote_user }}"
loop: "{{ range(kubeinit_spec_hypervisor_count|int) | list }}"
loop_control:
extended: true
- name: Add remaining spec vars to kubeinit_hypervisors group
ansible.builtin.add_host:
name: "{{ item }}"
groups: 'kubeinit_hypervisors'
ansible_host: "{{ hypervisor_hosts_map_list[ansible_loop.index0]['ansible_host'] | default(omit) }}"
ssh_hostname: "{{ hypervisor_hosts_map_list[ansible_loop.index0]['ssh_hostname'] | default(omit) }}"
ssh_username: "{{ hypervisor_hosts_map_list[ansible_loop.index0]['ssh_username'] | default(omit) }}"
loop: "{{ groups['kubeinit_hypervisors'] }}"
loop_control:
extended: true
when: hypervisor_hosts_map_list is defined
- name: Add kubeinit_spec facts to cluster facts
ansible.builtin.add_host:
name: "{{ kubeinit_cluster_name }}"
groups: 'kubeinit_cluster'
distro: "{{ kubeinit_spec_distro }}"
distro_role: "{{ kubeinit_distro_role }}"
controller_count: "{{ kubeinit_spec_controller_count }}"
compute_count: "{{ kubeinit_spec_compute_count }}"
- name: Set more cluster facts from inventory groups and kubeinit_spec
ansible.builtin.set_fact:
kubeinit_cluster_distro: "{{ kubeinit_spec_distro }}"
kubeinit_cluster_distro_role: "{{ kubeinit_distro_role }}"
kubeinit_cluster_fqdn: "{{ kubeinit_cluster_name }}.{{ hostvars[kubeinit_cluster_name].cluster_domain }}"
- name: Set kubeinit_cluster_ssh_config fact
ansible.builtin.set_fact:
kubeinit_cluster_ssh_config: "{{ hostvars['kubeinit-facts'].local_home + '/.ssh/' + kubeinit_cluster_name + '_config' }}"
kubeinit_cluster_keypair_path: "{{ hostvars['kubeinit-facts'].local_home + '/.ssh/kubeinit_id_' + hostvars['kubeinit-facts'].ssh_keytype }}"
- name: Add ansible_ssh_extra_args to kubeinit_hypervisors group
ansible.builtin.add_host:
name: "{{ item }}"
groups: 'kubeinit_hypervisors'
ansible_ssh_extra_args: "-i {{ kubeinit_cluster_keypair_path }} -F {{ kubeinit_cluster_ssh_config }}"
loop: "{{ groups['kubeinit_hypervisors'] }}"
- name: Copy ssh key secret into ~/.ssh
ansible.builtin.copy:
content: "{{ lookup('unvault', hostvars['kubeinit-secrets'].secrets['kubeinit-ssh-key']) }}"
dest: "~/.ssh/kubeinit_id_{{ hostvars['kubeinit-facts'].ssh_keytype }}"
mode: '0600'
when: hostvars['kubeinit-facts'].container_run|bool
- name: Check if kubeinit ssh config exists
ansible.builtin.stat:
path: "{{ hostvars['kubeinit-facts'].local_home + '/.ssh/kubeinit_config' }}"
register: _result_kubeinit_ssh_config_stat
- name: Check if ssh config exists
ansible.builtin.stat:
path: "{{ hostvars['kubeinit-facts'].local_home + '/.ssh/config' }}"
register: _result_ssh_config_stat
when: not _result_kubeinit_ssh_config_stat.stat.exists
- name: Set kubeinit_cluster_ssh_include_paths
ansible.builtin.set_fact:
kubeinit_cluster_ssh_include_paths:
"{{ [_result_kubeinit_ssh_config_stat.stat.path] if (_result_kubeinit_ssh_config_stat.stat.exists) else [_result_ssh_config_stat.stat.path] if (_result_ssh_config_stat.stat.exists) else [] }}"
- name: Create ssh config file from template
ansible.builtin.include_role:
name: kubeinit.kubeinit.kubeinit_prepare
tasks_from: create_host_ssh_config.yml
public: true
vars:
_param_hosts: "{{ groups['kubeinit_hypervisors'] }}"
_param_ssh_keytype: "{{ hostvars['kubeinit-facts'].ssh_keytype }}"
_param_keypair_path: "{{ kubeinit_cluster_keypair_path }}"
_param_dest_path: "{{ kubeinit_cluster_ssh_config }}"
_param_include_paths: "{{ kubeinit_cluster_ssh_include_paths }}"