711 lines
32 KiB
YAML
711 lines
32 KiB
YAML
---
|
|
#
|
|
# Copyright (c) 2019 Wind River Systems, Inc.
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# ROLE DESCRIPTION:
|
|
# This role is to validate and save host (non secure) config.
|
|
#
|
|
|
|
# error check the password section of docker registries
|
|
# check password parameters before trying to hide the password
|
|
# we need to do that here as opposed to with the other docker registry
|
|
# stuff because of the debug log statement.
|
|
# we need to do this all before the debug log statement to not log passwords.
|
|
- name: Check k8s_registry credentials
|
|
fail:
|
|
msg: "k8s registry username and password must both be specified or not at all"
|
|
when: (docker_registries[default_k8s_registry.url].username is defined and
|
|
docker_registries[default_k8s_registry.url].password is not defined) or
|
|
(docker_registries[default_k8s_registry.url].username is not defined and
|
|
docker_registries[default_k8s_registry.url].password is defined)
|
|
|
|
- name: Check gcr_registry credentials
|
|
fail:
|
|
msg: "gcr registry username and password must both be specified or not at all"
|
|
when: (docker_registries[default_gcr_registry.url].username is defined and
|
|
docker_registries[default_gcr_registry.url].password is not defined) or
|
|
(docker_registries[default_gcr_registry.url].username is not defined and
|
|
docker_registries[default_gcr_registry.url].password is defined)
|
|
|
|
- name: Check quay_registry credentials
|
|
fail:
|
|
msg: "quay registry username and password must both be specified or not at all"
|
|
when: (docker_registries[default_quay_registry.url].username is defined and
|
|
docker_registries[default_quay_registry.url].password is not defined) or
|
|
(docker_registries[default_quay_registry.url].username is not defined and
|
|
docker_registries[default_quay_registry.url].password is defined)
|
|
|
|
- name: Check docker_registry credentials
|
|
fail:
|
|
msg: "docker registry username and password must both be specified or not at all"
|
|
when: (docker_registries[default_docker_registry.url].username is defined and
|
|
docker_registries[default_docker_registry.url].password is not defined) or
|
|
(docker_registries[default_docker_registry.url].username is not defined and
|
|
docker_registries[default_docker_registry.url].password is defined)
|
|
|
|
- name: Check elastic_registry credentials
|
|
fail:
|
|
msg: "elastic registry username and password must both be specified or not at all"
|
|
when: (docker_registries[default_elastic_registry.url].username is defined and
|
|
docker_registries[default_elastic_registry.url].password is not defined) or
|
|
(docker_registries[default_elastic_registry.url].username is not defined and
|
|
docker_registries[default_elastic_registry.url].password is defined)
|
|
|
|
- name: Check defaults registry credentials
|
|
fail:
|
|
msg: "defaults registry username and password must both be specified or not at all"
|
|
when: docker_registries['defaults'] is defined and
|
|
((docker_registries['defaults'].username is defined and
|
|
docker_registries['defaults'].password is not defined) or
|
|
(docker_registries['defaults'].username is not defined and
|
|
docker_registries['defaults'].password is defined))
|
|
|
|
# create a copy of docker_registries without passwords for debug logging
|
|
- set_fact:
|
|
docker_registries_with_secrets: "{{ docker_registries }}"
|
|
|
|
- set_fact:
|
|
docker_registries: "{{ docker_registries | combine(hide_pw, recursive=true) }}"
|
|
vars:
|
|
hide_pw: "{ '{{ item.key }}': { 'password': 'secret' } }"
|
|
with_dict: "{{ docker_registries }}"
|
|
no_log: true
|
|
|
|
- debug:
|
|
msg:
|
|
- System mode is {{ system_mode }}
|
|
- Timezone is {{ timezone }}
|
|
- Distributed Cloud Role is {{ distributed_cloud_role }}
|
|
- Region name is {{ region_name }}
|
|
- DNS servers is {{ dns_servers }}
|
|
- PXE boot subnet is {{ pxeboot_subnet }}
|
|
- Management subnet is {{ management_subnet }}
|
|
- Cluster host subnet is {{ cluster_host_subnet }}
|
|
- Cluster pod subnet is {{ cluster_pod_subnet }}
|
|
- Cluster service subnet is {{ cluster_service_subnet }}
|
|
- OAM subnet is {{ external_oam_subnet }}
|
|
- OAM gateway is {{ external_oam_gateway_address }}
|
|
- OAM floating ip is {{ external_oam_floating_address }}
|
|
- Management dynamic address allocation is {{ management_dynamic_address_allocation }}
|
|
- Cluster host dynamic address allocation is {{ cluster_host_dynamic_address_allocation }}
|
|
- Docker registries is {{ docker_registries }}
|
|
- Docker HTTP proxy is {{ docker_http_proxy }}
|
|
- Docker HTTPS proxy is {{ docker_https_proxy }}
|
|
- Docker no proxy list is {{ docker_no_proxy }}
|
|
|
|
# System parameters config validation
|
|
- block:
|
|
- name: Set system mode fact
|
|
set_fact:
|
|
system_mode: "{{ system_mode|lower }}"
|
|
|
|
- block:
|
|
- debug:
|
|
msg: "System type is Standard, system mode will be set to duplex."
|
|
- name: Set system mode to duplex for Standard system
|
|
set_fact:
|
|
system_mode: duplex
|
|
when: system_type == 'Standard'
|
|
|
|
- name: Validate system mode if system type is All-in-one
|
|
fail:
|
|
msg: "Invalid system mode. Valid values are: simplex, duplex or duplex-direct."
|
|
when: >
|
|
(system_mode != 'simplex' and
|
|
system_mode != 'duplex' and
|
|
system_mode != 'duplex-direct') and
|
|
(system_type == 'All-in-one')
|
|
|
|
- name: Validate distributed cloud role
|
|
fail:
|
|
msg: "Invalid distributed cloud role. Valid values are: none, systemcontroller, or subcloud."
|
|
when: >
|
|
(distributed_cloud_role != 'none' and
|
|
distributed_cloud_role != 'systemcontroller' and
|
|
distributed_cloud_role != 'subcloud')
|
|
|
|
- name: Validate system type and system mode if distributed cloud role is system controller
|
|
fail:
|
|
msg: "A simplex All-in-one controller cannot be configured as Distributed Cloud System Controller"
|
|
when: >
|
|
(distributed_cloud_role == 'systemcontroller' and
|
|
system_type == 'All-in-one' and
|
|
system_mode == 'simplex')
|
|
|
|
- name: Checking registered timezones
|
|
stat:
|
|
path: "{{ '/usr/share/zoneinfo/' + timezone }}"
|
|
register: timezone_file
|
|
|
|
- name: Fail if provided timezone is unknown
|
|
fail: msg="The provided timezone {{ timezone }} is invalid."
|
|
when: not timezone_file.stat.exists
|
|
|
|
- name: Fail if the number of dns servers provided is not at least 1 and no more than 3
|
|
fail:
|
|
msg: "The number of DNS servers exceeds maximum allowable number of 3."
|
|
when: (dns_servers | length == 0) or (dns_servers | length > 3)
|
|
|
|
|
|
# DNS servers config validation
|
|
- name: Check format of DNS server IP(s)
|
|
debug:
|
|
msg: "DNS Server: {{ item }}"
|
|
failed_when: item | ipaddr == False
|
|
with_items: "{{ dns_servers }}"
|
|
|
|
|
|
# Networks config validation
|
|
- block:
|
|
- name: Validate provided subnets (both IPv4 & IPv6 notations)
|
|
debug:
|
|
msg: "{{ item.key }}: {{ item.value }}"
|
|
failed_when: item.value|ipaddr == False
|
|
with_dict: "{{ network_params }}"
|
|
|
|
- set_fact:
|
|
ipv4_addressing: "{{ network_params.management_subnet|ipv4 }}"
|
|
ipv6_addressing: "{{ network_params.management_subnet|ipv6 }}"
|
|
|
|
- name: Validate all network subnets are IPv4
|
|
debug:
|
|
msg: "All infrastructure and cluster subnets must be the same IP version"
|
|
failed_when: item|ipv4 == False
|
|
with_items:
|
|
- "{{ network_params.management_subnet }}"
|
|
- "{{ network_params.cluster_host_subnet }}"
|
|
- "{{ network_params.cluster_pod_subnet }}"
|
|
- "{{ network_params.cluster_service_subnet }}"
|
|
- "{{ network_params.external_oam_subnet }}"
|
|
- "{{ network_params.management_multicast_subnet }}"
|
|
when: ipv4_addressing != False
|
|
|
|
- name: Validate all network subnets are IPv6
|
|
debug:
|
|
msg: "All infrastructure and cluster subnets must be the same IP version"
|
|
failed_when: item|ipv6 == False
|
|
with_items:
|
|
- "{{ network_params.management_subnet }}"
|
|
- "{{ network_params.cluster_host_subnet }}"
|
|
- "{{ network_params.cluster_pod_subnet }}"
|
|
- "{{ network_params.cluster_service_subnet }}"
|
|
- "{{ network_params.external_oam_subnet }}"
|
|
- "{{ network_params.management_multicast_subnet }}"
|
|
when: ipv6_addressing != False
|
|
|
|
- name: Validate pxeboot subnet is IPv4
|
|
debug:
|
|
msg: "pxeboot_subnet subnet must always be IPv4"
|
|
failed_when: network_params.pxeboot_subnet|ipv4 == False
|
|
|
|
- name: Generate warning if subnet prefix is not typical for Standard systems
|
|
debug:
|
|
msg: "WARNING: Subnet prefix of less than /24 is not typical. This will affect scaling of the system!"
|
|
when: item|ipaddr('prefix')|int < typical_subnet_prefix and system_type == 'Standard'
|
|
with_items:
|
|
- "{{ network_params.pxeboot_subnet }}"
|
|
- "{{ network_params.management_subnet }}"
|
|
- "{{ network_params.cluster_host_subnet }}"
|
|
- "{{ network_params.external_oam_subnet }}"
|
|
- "{{ network_params.management_multicast_subnet }}"
|
|
|
|
- block:
|
|
- name: Fail if IPv6 prefix length is too short
|
|
fail:
|
|
msg: "IPv6 minimum prefix length is {{ minimum_prefix_length }}"
|
|
when: network_params.management_subnet|ipaddr('prefix')|int < minimum_ipv6_prefix_length
|
|
|
|
when: ipv6_addressing != False
|
|
|
|
- name: Fail if management address allocation is misconfigured
|
|
fail:
|
|
msg: "management_dynamic_address_allocation is misconfigured. Valid value is either 'True' or 'False'."
|
|
when: not management_dynamic_address_allocation | type_debug == 'bool'
|
|
|
|
- name: Fail if cluster-host address allocation is misconfigured
|
|
fail:
|
|
msg: "cluster_host_dynamic_address_allocation is misconfigured. Valid value is either 'True' or 'False'."
|
|
when: not cluster_host_dynamic_address_allocation | type_debug == 'bool'
|
|
|
|
- name: Fail if management start or end address is not configured for System Controller
|
|
fail:
|
|
msg: >-
|
|
management_start_address and management_end_address are required
|
|
for System Controller as this configuration requires address space
|
|
left for gateway address(es).
|
|
when: >
|
|
(distributed_cloud_role == 'systemcontroller' and
|
|
(management_start_address == 'derived' or management_end_address == 'derived'))
|
|
|
|
# The provided subnets have passed validation, set the default addresses
|
|
# based on the subnet values
|
|
- name: Set default start and end addresses based on provided subnets
|
|
set_fact:
|
|
default_pxeboot_start_address: "{{ (pxeboot_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_pxeboot_end_address: "{{ (pxeboot_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_management_start_address: "{{ (management_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_management_end_address: "{{ (management_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_cluster_host_start_address: "{{ (cluster_host_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_cluster_host_end_address: "{{ (cluster_host_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_cluster_pod_start_address: "{{ (cluster_pod_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_cluster_pod_end_address: "{{ (cluster_pod_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_cluster_service_start_address: "{{ (cluster_service_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_cluster_service_end_address: "{{ (cluster_service_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_external_oam_start_address: "{{ (external_oam_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_external_oam_end_address: "{{ (external_oam_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_management_multicast_start_address: "{{ (management_multicast_subnet | ipaddr(1)).split('/')[0] }}"
|
|
default_management_multicast_end_address: "{{ (management_multicast_subnet | ipaddr(-2)).split('/')[0] }}"
|
|
default_external_oam_node_0_address: "{{ external_oam_floating_address | ipmath(1) }}"
|
|
default_external_oam_node_1_address: "{{ external_oam_floating_address | ipmath(2) }}"
|
|
|
|
- name: Build address pairs for validation, merging default and user provided values
|
|
set_fact:
|
|
address_pairs:
|
|
pxeboot:
|
|
start:
|
|
"{{ pxeboot_start_address if pxeboot_start_address != 'derived'
|
|
else default_pxeboot_start_address }}"
|
|
end:
|
|
"{{ pxeboot_end_address if pxeboot_end_address != 'derived'
|
|
else default_pxeboot_end_address }}"
|
|
subnet: "{{ network_params.pxeboot_subnet }}"
|
|
management:
|
|
start:
|
|
"{{ management_start_address if management_start_address != 'derived'
|
|
else default_management_start_address }}"
|
|
end:
|
|
"{{ management_end_address if management_end_address != 'derived'
|
|
else default_management_end_address }}"
|
|
subnet: "{{ network_params.management_subnet }}"
|
|
cluster_host:
|
|
start:
|
|
"{{ cluster_host_start_address if cluster_host_start_address != 'derived'
|
|
else default_cluster_host_start_address }}"
|
|
end:
|
|
"{{ cluster_host_end_address if cluster_host_end_address != 'derived'
|
|
else default_cluster_host_end_address}}"
|
|
subnet: "{{ network_params.cluster_host_subnet }}"
|
|
cluster_pod:
|
|
start:
|
|
"{{ cluster_pod_start_address if cluster_pod_start_address != 'derived'
|
|
else default_cluster_pod_start_address }}"
|
|
end:
|
|
"{{ cluster_pod_end_address if cluster_pod_end_address != 'derived'
|
|
else default_cluster_pod_end_address }}"
|
|
subnet: "{{ network_params.cluster_pod_subnet }}"
|
|
cluster_service:
|
|
start:
|
|
"{{ cluster_service_start_address if cluster_service_start_address != 'derived'
|
|
else default_cluster_service_start_address }}"
|
|
end:
|
|
"{{ cluster_service_end_address if cluster_service_end_address != 'derived'
|
|
else default_cluster_service_end_address }}"
|
|
subnet: "{{ network_params.cluster_service_subnet }}"
|
|
oam:
|
|
start:
|
|
"{{ external_oam_start_address if external_oam_start_address != 'derived'
|
|
else default_external_oam_start_address }}"
|
|
end:
|
|
"{{ external_oam_end_address if external_oam_end_address != 'derived'
|
|
else default_external_oam_end_address }}"
|
|
subnet: "{{ network_params.external_oam_subnet }}"
|
|
multicast:
|
|
start:
|
|
"{{ management_multicast_start_address if management_multicast_start_address != 'derived'
|
|
else default_management_multicast_start_address }}"
|
|
end:
|
|
"{{ management_multicast_end_address if management_multicast_end_address != 'derived'
|
|
else default_management_multicast_end_address }}"
|
|
subnet: "{{ network_params.management_multicast_subnet }}"
|
|
oam_node:
|
|
start:
|
|
"{{ external_oam_node_0_address if external_oam_node_0_address != 'derived'
|
|
else default_external_oam_node_0_address }}"
|
|
end:
|
|
"{{ external_oam_node_1_address if external_oam_node_1_address != 'derived'
|
|
else default_external_oam_node_1_address }}"
|
|
subnet: "{{ network_params.external_oam_subnet }}"
|
|
|
|
- include: validate_address_range.yml
|
|
with_dict: "{{ address_pairs }}"
|
|
|
|
- name: Set floating addresses based on subnets or start addresses
|
|
set_fact:
|
|
# Not sure why ipaddr('address') and ipsubnet filter did not extract
|
|
# the IP from CIDR input. Resort to string split for now.
|
|
controller_floating_address: "{{ address_pairs['management']['start'] }}"
|
|
controller_pxeboot_floating_address: "{{ address_pairs['pxeboot']['start'] }}"
|
|
cluster_floating_address: "{{ address_pairs['cluster_host']['start'] }}"
|
|
|
|
- name: Set derived facts for subsequent tasks/roles
|
|
set_fact:
|
|
derived_network_params:
|
|
'management_interface': lo
|
|
'management_interface_name': lo
|
|
'controller_0_address': "{{ controller_floating_address|ipmath(1) }}"
|
|
'controller_1_address': "{{ controller_floating_address|ipmath(2) }}"
|
|
'nfs_management_address_1': "{{ controller_floating_address|ipmath(3) }}"
|
|
'nfs_management_address_2': "{{ controller_floating_address|ipmath(4) }}"
|
|
'controller_pxeboot_address_0': "{{ controller_pxeboot_floating_address|ipmath(1) }}"
|
|
'controller_pxeboot_address_1': "{{ controller_pxeboot_floating_address|ipmath(2) }}"
|
|
|
|
# Make common facts available to other roles
|
|
config_workdir: "{{ config_workdir }}"
|
|
dns_servers: "{{ dns_servers }}"
|
|
|
|
# Derived network parameters that don't apply to bootstrap_config but are required for
|
|
# subsequent roles
|
|
management_subnet_prefix: "{{ management_subnet | ipaddr('prefix') }}"
|
|
management_broadcast: "{{ management_subnet | ipaddr('broadcast') }}"
|
|
pxe_subnet_prefix: "{{ pxeboot_subnet | ipaddr('prefix') }}"
|
|
cluster_subnet_prefix: "{{ cluster_host_subnet | ipaddr('prefix') }}"
|
|
cluster_broadcast: "{{ cluster_host_subnet | ipaddr('broadcast') }}"
|
|
controller_0_cluster_host: "{{ cluster_floating_address|ipmath(1) }}"
|
|
controller_1_cluster_host: "{{ cluster_floating_address|ipmath(2) }}"
|
|
controller_floating_address_url:
|
|
"{{ controller_floating_address|ipwrap if controller_floating_address|ipv6 != False
|
|
else controller_floating_address}}"
|
|
|
|
|
|
- name: Set facts for IP address provisioning against loopback interface
|
|
set_fact:
|
|
mgmt_virtual: "{{ derived_network_params.controller_0_address }}/{{ management_subnet_prefix }}"
|
|
cluster_virtual: "{{ controller_0_cluster_host }}/{{ cluster_subnet_prefix }}"
|
|
pxe_virtual: "{{ controller_pxeboot_floating_address }}/{{ pxe_subnet_prefix }}"
|
|
cluster_floating_virtual: "{{ cluster_floating_address }}/{{ cluster_subnet_prefix }}"
|
|
mgmt_floating_virtual: "{{ controller_floating_address }}/{{ management_subnet_prefix }}"
|
|
mgmt_nfs_1_virtual: "{{ derived_network_params.nfs_management_address_1 }}/{{ management_subnet_prefix }}"
|
|
mgmt_nfs_2_virtual: "{{ derived_network_params.nfs_management_address_2 }}/{{ management_subnet_prefix }}"
|
|
|
|
# Docker config validation
|
|
- block:
|
|
- set_fact:
|
|
use_default_registries: true
|
|
k8s_registry: "{{ default_k8s_registry }}"
|
|
gcr_registry: "{{ default_gcr_registry }}"
|
|
quay_registry: "{{ default_quay_registry }}"
|
|
docker_registry: "{{ default_docker_registry }}"
|
|
elastic_registry: "{{ default_elastic_registry }}"
|
|
default_no_proxy:
|
|
- localhost
|
|
- 127.0.0.1
|
|
- registry.local
|
|
- "{{ cluster_service_start_address if cluster_service_start_address != 'derived'
|
|
else default_cluster_service_start_address }}"
|
|
- "{{ controller_floating_address }}"
|
|
- "{{ derived_network_params.controller_0_address }}"
|
|
- "{{ external_oam_floating_address }}"
|
|
- "{{ address_pairs['oam_node']['start'] }}"
|
|
non_sx_proxy_addons:
|
|
- "{{ derived_network_params.controller_1_address }}"
|
|
- "{{ address_pairs['oam_node']['end'] }}"
|
|
docker_no_proxy_combined: []
|
|
|
|
- block:
|
|
- name: Set subcloud no proxy list
|
|
set_fact:
|
|
subcloud_no_proxy:
|
|
- registry.central
|
|
- "{{ system_controller_oam_floating_address }}"
|
|
- name: Update default no proxy list for subcloud
|
|
set_fact:
|
|
default_no_proxy: "{{ default_no_proxy + subcloud_no_proxy }}"
|
|
when: distributed_cloud_role == 'subcloud'
|
|
|
|
- block:
|
|
- name: Set default no-proxy address list (non simplex)
|
|
set_fact:
|
|
default_no_proxy: "{{ default_no_proxy + non_sx_proxy_addons }}"
|
|
when: system_mode != 'simplex'
|
|
|
|
- block:
|
|
- name: Validate http proxy urls
|
|
include: validate_url.yml input_url={{ item }}
|
|
with_items:
|
|
- "{{ docker_http_proxy }}"
|
|
- "{{ docker_https_proxy }}"
|
|
|
|
- block:
|
|
- name: Validate no proxy addresses
|
|
include: validate_address.yml input_address={{ item }}
|
|
with_items: "{{ docker_no_proxy }}"
|
|
when: docker_no_proxy|length > 0
|
|
|
|
- name: Add user defined no-proxy address list to default
|
|
set_fact:
|
|
docker_no_proxy_combined: "{{ default_no_proxy | union(docker_no_proxy) | ipwrap | unique }}"
|
|
|
|
when: use_docker_proxy
|
|
|
|
- block:
|
|
- name: Turn on use_defaults_registry flag
|
|
set_fact:
|
|
use_defaults_registry: true
|
|
k8s_registry: "{{ k8s_registry | combine(docker_registries_with_secrets['defaults'], recursive=true) }}"
|
|
gcr_registry: "{{ gcr_registry | combine(docker_registries_with_secrets['defaults'], recursive=true) }}"
|
|
quay_registry: "{{ quay_registry | combine(docker_registries_with_secrets['defaults'], recursive=true) }}"
|
|
docker_registry: "{{ docker_registry | combine(docker_registries_with_secrets['defaults'], recursive=true) }}"
|
|
elastic_registry: "{{ elastic_registry | combine(docker_registries_with_secrets['defaults'], recursive=true) }}"
|
|
|
|
when: docker_registries['defaults'] is defined and docker_registries['defaults'] is not none
|
|
|
|
- set_fact:
|
|
k8s_registry:
|
|
"{{ k8s_registry | combine(docker_registries_with_secrets[default_k8s_registry.url], recursive=true) }}"
|
|
when: (docker_registries[default_k8s_registry.url]['url'] is not defined or
|
|
(docker_registries[default_k8s_registry.url]['url'] is not none and
|
|
docker_registries[default_k8s_registry.url]['url'] != default_k8s_registry.url))
|
|
|
|
- set_fact:
|
|
gcr_registry:
|
|
"{{ gcr_registry | combine(docker_registries_with_secrets[default_gcr_registry.url], recursive=true) }}"
|
|
when: (docker_registries[default_gcr_registry.url]['url'] is not defined or
|
|
(docker_registries[default_gcr_registry.url]['url'] is not none and
|
|
docker_registries[default_gcr_registry.url]['url'] != default_gcr_registry.url))
|
|
|
|
- set_fact:
|
|
quay_registry:
|
|
"{{ quay_registry | combine(docker_registries_with_secrets[default_quay_registry.url], recursive=true) }}"
|
|
when: (docker_registries[default_quay_registry.url]['url'] is not defined or
|
|
(docker_registries[default_quay_registry.url]['url'] is not none and
|
|
docker_registries[default_quay_registry.url]['url'] != default_quay_registry.url))
|
|
|
|
- set_fact:
|
|
docker_registry:
|
|
"{{ docker_registry | combine(docker_registries_with_secrets[default_docker_registry.url], recursive=true) }}"
|
|
when: (docker_registries[default_docker_registry.url]['url'] is not defined or
|
|
(docker_registries[default_docker_registry.url]['url'] is not none and
|
|
docker_registries[default_docker_registry.url]['url'] != default_docker_registry.url))
|
|
|
|
- set_fact:
|
|
elastic_registry:
|
|
"{{ elastic_registry | combine(docker_registries_with_secrets[default_elastic_registry.url], recursive=true) }}"
|
|
when: (docker_registries[default_elastic_registry.url]['url'] is not defined or
|
|
(docker_registries[default_elastic_registry.url]['url'] is not none and
|
|
docker_registries[default_elastic_registry.url]['url'] != default_elastic_registry.url))
|
|
|
|
- name: Update use_default_registries flag
|
|
set_fact:
|
|
use_default_registries: false
|
|
when: use_defaults_registry or
|
|
docker_registries|length != 5 or
|
|
k8s_registry != default_k8s_registry or
|
|
gcr_registry != default_gcr_registry or
|
|
quay_registry != default_quay_registry or
|
|
docker_registry != default_docker_registry or
|
|
elastic_registry != default_elastic_registry
|
|
|
|
- block:
|
|
- name: Validate registry type if specified
|
|
fail:
|
|
msg: "Registry type for {{ item.key }} is not supported. Valid value is either 'docker' or 'aws-ecr'."
|
|
with_dict: "{{ docker_registries }}"
|
|
when: (item.value.type is defined and
|
|
item.value.type not in ['docker', 'aws-ecr'])
|
|
|
|
- name: Fail if secure registry flag is misconfigured
|
|
fail:
|
|
msg: "'secure' parameter of registry {{ item.key }} is misconfigured. Valid value is either 'True' or 'False'."
|
|
with_dict: "{{ docker_registries }}"
|
|
when: (item.value.secure is defined and
|
|
not (item.value.secure|type_debug == 'bool'))
|
|
|
|
- include: validate_address.yml input_address={{ item }}
|
|
with_items:
|
|
- "{{ k8s_registry.url }}"
|
|
- "{{ gcr_registry.url }}"
|
|
- "{{ quay_registry.url }}"
|
|
- "{{ docker_registry.url }}"
|
|
- "{{ elastic_registry.url }}"
|
|
when: not use_default_registries
|
|
|
|
- name: Validate additional_local_registry_images list
|
|
fail:
|
|
msg: "additional_local_registry_images must be a list"
|
|
when: additional_local_registry_images | type_debug != 'list'
|
|
|
|
# Docker images archive source validation
|
|
- block:
|
|
- set_fact:
|
|
images_archive_exists: false
|
|
|
|
- block:
|
|
- name: Check if images archive location exists
|
|
stat:
|
|
path: "{{ docker_images_archive_source }}"
|
|
register: archive_source
|
|
|
|
- block:
|
|
- name: Get list of archived files
|
|
find:
|
|
paths: "{{ docker_images_archive_source }}"
|
|
patterns: "*.tar"
|
|
register: archive_find_output
|
|
|
|
- name: Turn on images archive flag
|
|
set_fact:
|
|
images_archive_exists: true
|
|
when: archive_find_output.matched > 0
|
|
|
|
when: archive_source.stat.exists
|
|
delegate_to: localhost
|
|
when: (docker_images_archive_source is defined) and
|
|
(docker_images_archive_source is not none)
|
|
|
|
- name: Validate apiserver_cert_sans list
|
|
fail:
|
|
msg: "apiserver_cert_sans must be a list"
|
|
when: apiserver_cert_sans | type_debug != 'list'
|
|
|
|
- name: Validate apiserver_cert_sans entries
|
|
include: validate_address.yml input_address={{ item }}
|
|
with_items: "{{ apiserver_cert_sans }}"
|
|
|
|
- name: Verify that either both Kubernetes root ca cert and key are defined or not at all
|
|
fail:
|
|
msg: "k8s_root_ca_cert and k8s_root_ca_key must be provided as a pair"
|
|
when: (k8s_root_ca_cert and not k8s_root_ca_key) or
|
|
(not k8s_root_ca_cert and k8s_root_ca_key)
|
|
|
|
- name: Check for k8s_root_ca_cert file
|
|
fail:
|
|
msg: "k8s_root_ca_cert file not found. ({{ k8s_root_ca_cert }})"
|
|
when: k8s_root_ca_cert and (not k8s_root_ca_cert is file)
|
|
|
|
- name: Check for k8s_root_ca_key file
|
|
fail:
|
|
msg: "k8s_root_ca_key file not found. ({{ k8s_root_ca_key }})"
|
|
when: k8s_root_ca_key and (not k8s_root_ca_key is file)
|
|
|
|
- name: Check for ssl_ca_cert file
|
|
fail:
|
|
msg: "ssl_ca_cert file not found. ({{ ssl_ca_cert }})"
|
|
when: ssl_ca_cert is defined and (not ssl_ca_cert is file)
|
|
|
|
- name: Check OpenID Connect parameters
|
|
fail:
|
|
msg: "OpenID Connect parameters must all be specified or not at all:
|
|
apiserver_oidc: client_id, issuer_url, username_claim"
|
|
when: (apiserver_oidc|length != 0) and
|
|
(apiserver_oidc.client_id is not defined or
|
|
apiserver_oidc.issuer_url is not defined or
|
|
apiserver_oidc.username_claim is not defined)
|
|
|
|
# Wipe ceph osds
|
|
# Note that due to Ansible mishandling of boolean values via extra-vars we are
|
|
# adding supplementary validation here.
|
|
# See: https://github.com/ansible/ansible/issues/17193
|
|
- name: Check for Ceph data wipe flag
|
|
fail:
|
|
msg: "wipe_ceph_osds is misconfigured. Valid value is either 'true' or 'false'"
|
|
when: (mode == "restore") and (not wipe_ceph_osds | type_debug == 'bool') and
|
|
(wipe_ceph_osds != 'true') and
|
|
(wipe_ceph_osds != 'false')
|
|
|
|
- block:
|
|
- name: Wipe ceph osds
|
|
script: wipe_osds.sh
|
|
register: results
|
|
|
|
- name: Result of wiping ceph osds
|
|
debug: var=results.stdout_lines
|
|
|
|
when: (mode == "bootstrap") or
|
|
(mode == "restore" and wipe_ceph_osds|bool)
|
|
|
|
# bootstrap_config ini file generation
|
|
- block:
|
|
- name: Create config workdir
|
|
file:
|
|
path: "{{ config_workdir }}"
|
|
state: directory
|
|
owner: root
|
|
group: root
|
|
mode: 0755
|
|
|
|
- name: Generate config ini file for python sysinv db population script
|
|
lineinfile:
|
|
path: "{{ bootstrap_config_file }}"
|
|
line: "{{ item }}"
|
|
create: yes
|
|
with_items:
|
|
- "[BOOTSTRAP_CONFIG]"
|
|
- "CONTROLLER_HOSTNAME=controller-0"
|
|
- "SYSTEM_TYPE={{ system_type }}"
|
|
- "SYSTEM_MODE={{ system_mode }}"
|
|
- "TIMEZONE={{ timezone }}"
|
|
- "DISTRIBUTED_CLOUD_ROLE={{ distributed_cloud_role }}"
|
|
- "REGION_NAME={{ region_name }}"
|
|
- "SW_VERSION={{ software_version }}"
|
|
- "NAMESERVERS={{ dns_servers| join(',') }}"
|
|
- "PXEBOOT_SUBNET={{ pxeboot_subnet }}"
|
|
- "PXEBOOT_START_ADDRESS={{ address_pairs['pxeboot']['start'] }}"
|
|
- "PXEBOOT_END_ADDRESS={{ address_pairs['pxeboot']['end'] }}"
|
|
- "MANAGEMENT_SUBNET={{ management_subnet }}"
|
|
- "MANAGEMENT_START_ADDRESS={{ address_pairs['management']['start'] }}"
|
|
- "MANAGEMENT_END_ADDRESS={{ address_pairs['management']['end'] }}"
|
|
- "MANAGEMENT_DYNAMIC_ADDRESS_ALLOCATION={{ management_dynamic_address_allocation }}"
|
|
- "MANAGEMENT_INTERFACE=lo"
|
|
- "CONTROLLER_0_ADDRESS={{ derived_network_params.controller_0_address }}"
|
|
- "CLUSTER_HOST_SUBNET={{ cluster_host_subnet }}"
|
|
- "CLUSTER_HOST_START_ADDRESS={{ address_pairs['cluster_host']['start'] }}"
|
|
- "CLUSTER_HOST_END_ADDRESS={{ address_pairs['cluster_host']['end'] }}"
|
|
- "CLUSTER_HOST_DYNAMIC_ADDRESS_ALLOCATION={{ cluster_host_dynamic_address_allocation }}"
|
|
- "CLUSTER_POD_SUBNET={{ cluster_pod_subnet }}"
|
|
- "CLUSTER_POD_START_ADDRESS={{ address_pairs['cluster_pod']['start'] }}"
|
|
- "CLUSTER_POD_END_ADDRESS={{ address_pairs['cluster_pod']['end'] }}"
|
|
- "CLUSTER_SERVICE_SUBNET={{ cluster_service_subnet }}"
|
|
- "CLUSTER_SERVICE_START_ADDRESS={{ address_pairs['cluster_service']['start'] }}"
|
|
- "CLUSTER_SERVICE_END_ADDRESS={{ address_pairs['cluster_service']['end'] }}"
|
|
- "EXTERNAL_OAM_SUBNET={{ external_oam_subnet }}"
|
|
- "EXTERNAL_OAM_START_ADDRESS={{ address_pairs['oam']['start'] }}"
|
|
- "EXTERNAL_OAM_END_ADDRESS={{ address_pairs['oam']['end'] }}"
|
|
- "EXTERNAL_OAM_GATEWAY_ADDRESS={{ external_oam_gateway_address }}"
|
|
- "EXTERNAL_OAM_FLOATING_ADDRESS={{ external_oam_floating_address }}"
|
|
- "EXTERNAL_OAM_0_ADDRESS={{ address_pairs['oam_node']['start'] }}"
|
|
- "EXTERNAL_OAM_1_ADDRESS={{ address_pairs['oam_node']['end'] }}"
|
|
- "MANAGEMENT_MULTICAST_SUBNET={{ management_multicast_subnet }}"
|
|
- "MANAGEMENT_MULTICAST_START_ADDRESS={{ address_pairs['multicast']['start'] }}"
|
|
- "MANAGEMENT_MULTICAST_END_ADDRESS={{ address_pairs['multicast']['end'] }}"
|
|
- "SYSTEM_CONTROLLER_SUBNET={{ system_controller_subnet }}"
|
|
- "SYSTEM_CONTROLLER_FLOATING_ADDRESS={{ system_controller_floating_address }}"
|
|
- "SYSTEM_CONTROLLER_OAM_SUBNET={{ system_controller_oam_subnet }}"
|
|
- "SYSTEM_CONTROLLER_OAM_FLOATING_ADDRESS={{ system_controller_oam_floating_address }}"
|
|
- "DOCKER_HTTP_PROXY={{ docker_http_proxy }}"
|
|
- "DOCKER_HTTPS_PROXY={{ docker_https_proxy }}"
|
|
- "DOCKER_NO_PROXY={{ docker_no_proxy_combined | join(',') }}"
|
|
- "K8S_REGISTRY={{ k8s_registry.url }}"
|
|
- "GCR_REGISTRY={{ gcr_registry.url }}"
|
|
- "QUAY_REGISTRY={{ quay_registry.url }}"
|
|
- "DOCKER_REGISTRY={{ docker_registry.url }}"
|
|
- "ELASTIC_REGISTRY={{ elastic_registry.url }}"
|
|
- "K8S_REGISTRY_TYPE={{ k8s_registry.type | default('docker') }}"
|
|
- "GCR_REGISTRY_TYPE={{ gcr_registry.type | default('docker') }}"
|
|
- "QUAY_REGISTRY_TYPE={{ quay_registry.type | default('docker') }}"
|
|
- "DOCKER_REGISTRY_TYPE={{ docker_registry.type | default('docker') }}"
|
|
- "ELASTIC_REGISTRY_TYPE={{ elastic_registry.type | default('docker') }}"
|
|
- "K8S_REGISTRY_SECURE={{ k8s_registry.secure | default(True) }}"
|
|
- "GCR_REGISTRY_SECURE={{ gcr_registry.secure | default(True) }}"
|
|
- "QUAY_REGISTRY_SECURE={{ quay_registry.secure | default(True) }}"
|
|
- "DOCKER_REGISTRY_SECURE={{ docker_registry.secure | default(True) }}"
|
|
- "ELASTIC_REGISTRY_SECURE={{ elastic_registry.secure | default(True) }}"
|
|
- "K8S_REGISTRY_ADDITIONAL_OVERRIDES={{ k8s_registry.additional_overrides | default('undef') }}"
|
|
- "GCR_REGISTRY_ADDITIONAL_OVERRIDES={{ gcr_registry.additional_overrides | default('undef') }}"
|
|
- "QUAY_REGISTRY_ADDITIONAL_OVERRIDES={{ quay_registry.additional_overrides | default('undef') }}"
|
|
- "DOCKER_REGISTRY_ADDITIONAL_OVERRIDES={{ docker_registry.additional_overrides | default('undef') }}"
|
|
- "ELASTIC_REGISTRY_ADDITIONAL_OVERRIDES={{ elastic_registry.additional_overrides | default('undef') }}"
|
|
- "USE_DEFAULT_REGISTRIES={{ use_default_registries }}"
|
|
- "RECONFIGURE_ENDPOINTS={{ reconfigure_endpoints }}"
|
|
- "INITIAL_DB_POPULATED={{ initial_db_populated }}"
|
|
- "INCOMPLETE_BOOTSTRAP={{ incomplete_bootstrap }}"
|
|
- "APISERVER_SANS={{ apiserver_cert_sans | join(',') }}"
|
|
|
|
- name: Write simplex flag
|
|
file:
|
|
path: /etc/platform/simplex
|
|
state: touch
|
|
|
|
when: save_config_to_db
|