Add openldap certificate creation to bootstrap.yml

This change adds the openldap certificate creation process to the
bootstrap.yml playbook. It also adds support for updating it to
the migrate_platform_certificates_to_certmanager playbook.

This change is also renaming the kubernetes Root CA's common name to
starlingx, so that it can be used as the system_local_ca clusterIssuer
which will be used as the Issuer of the openldap certificate.

Test Plan:
PASS: Run the bootstrap playbook and verify that it is able to create
      the openldap certificate and install system_root_ca as a ssl_ca
      certificate in 'system certificate-list'
PASS  Do system unlock and verify that cert-mon is able to pick up and
      install the openldap certificate
PASS: Test migrate_platform_certificates_to_certmanager and verify that
      it is able to update the openldap certificate
PASS: On a DC system (centos only), verify that the bootstrap.yml
      playbook works for 'dcmanager subcloud add'
PASS: On a DC system (centos only), verify that the openldap certificate
      in not created in subclouds
PASS: Verified that the bootstrap.yml playbook can be re-played
      multiple times without error
PASS: Verify remote system bootstrap for debian works

Story: 2009834
Task: 45774

Signed-off-by: Rei Oliveira <Reinildes.JoseMateusOliveira@windriver.com>
Change-Id: Ie4c37026c9d5d4864dfea6fff3f066f3735c9fe2
This commit is contained in:
Rei Oliveira 2022-07-18 14:36:25 -03:00
parent ce510c7b9d
commit 1a1ac09dfd
14 changed files with 238 additions and 83 deletions

View File

@ -4,10 +4,33 @@
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
# This is an example inventory file to be used for
# usr/share/ansible/stx-ansible/playbooks/migrate_platform_certificates_to_certmanager.yml
# playbook.
#
# To run the playbook, the user would define an overrides file (as exemplified here)
# providing the required variable settings and pass it on the ansible command-line as a parameter.
#
# Example ansible command:
# ansible-playbook migrate_platform_certificates_to_certmanager.yml \
# -i @my-inventory-file.yml \
# --extra-vars "target_list=subcloud1 mode=update"
# Use target_list to target individual subclouds, or a comma-separated
# list of subclouds such as 'subcloud1,subcloud2'. To target all online
# subclouds at once use target_list=all_online_subclouds
#
# To target the system controller or standalone systems use target_list=localhost
#
# Note on the example parameters below :
#
# Parameter system_local_ca_cert will be the certificate that will be used as the # Parameter system_local_ca_cert will be the certificate that will be used as the
# issuer for platform certificates (registry.local, https / rest-api, oidc) # issuer for platform certificates (registry.local, https / rest-api, oidc)
# #
# Please make sure that you use a root_ca_cert and system_local_ca_cert certificate # If system_local_ca_cert is an Intermediate CA (recommended), make sure that
# system_root_ca_cert is the Root CA which is its Issuer.
#
# Please make sure that you use a system_root_ca_cert and system_local_ca_cert certificate
# with a long duration. The playbook will fail if any of these CA certificates expire in # with a long duration. The playbook will fail if any of these CA certificates expire in
# less than 3 years. # less than 3 years.
# #
@ -15,19 +38,23 @@
# it by setting a different value to validation parameter ca_duration: # it by setting a different value to validation parameter ca_duration:
# Example: # Example:
# ca_duration: 2 # ca_duration: 2
# Notice that ca_duration is applied to both root_ca_cert and system_local_ca_cert # Notice that ca_duration is applied to both system_root_ca_cert and system_local_ca_cert
# #
# Please also make sure that duration and renewBefore are sensible values # Please also make sure that duration and renewBefore are sensible values
# considering the system_local_ca_cert remaining duration. # considering the system_local_ca_cert remaining duration.
# #
# See: https://docs.starlingx.io/security/kubernetes/migrate-platform-certificates-to-use-cert-manager-c0b1727e4e5d.html
#
all: all:
vars: vars:
root_ca_cert: <base64_cert> # If using an Intermediate CA for system_local_ca_cert (recommended), the value
# It's strongly recommended using an Intermediate CA for system-local-ca_cert # for system_root_ca_cert needs to be the Root CA which is the Issuer of system_local_ca_cert
system_root_ca_cert: <base64_cert>
# It's strongly recommended using an Intermediate CA for system_local_ca_cert
# as that has the advantages of anchoring your certificates to your external Root CA. # as that has the advantages of anchoring your certificates to your external Root CA.
# However, it is possible to simply specify a Root CA for system-local-ca_cert. # However, it is possible to simply specify a Root CA for system_local_ca_cert.
# For that, specify system_local_ca_cert and system_local_ca_key with values from your Root CA. # For that, specify system_local_ca_cert and system_local_ca_key with values from your Root CA.
# Note that system_local_ca_cert and root_ca_cert must be the same for that configuration. # Note: system_local_ca_cert and system_root_ca_cert must be the same for that configuration.
system_local_ca_cert: <base64_cert> system_local_ca_cert: <base64_cert>
system_local_ca_key: <base64_key> system_local_ca_key: <base64_key>
# the ca_duration parameter is optional. If not specified, it defaults to 3. # the ca_duration parameter is optional. If not specified, it defaults to 3.
@ -40,6 +67,7 @@ all:
# Use the below example in hosts to override particulars for a subcloud such as passwords # Use the below example in hosts to override particulars for a subcloud such as passwords
target_group: target_group:
vars: vars:
system_platform_certificate:
dns_domain: xyz.com dns_domain: xyz.com
duration: 2160h # 90d duration: 2160h # 90d
renewBefore: 360h # 15d renewBefore: 360h # 15d

View File

@ -1,6 +1,6 @@
--- ---
# #
# Copyright (c) 2019 Wind River Systems, Inc. # Copyright (c) 2019-2022 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -24,6 +24,8 @@
- { role: bootstrap/persist-config, become: yes } - { role: bootstrap/persist-config, become: yes }
- { role: bootstrap/bringup-essential-services, become: yes } - { role: bootstrap/bringup-essential-services, become: yes }
- { role: bootstrap/bringup-bootstrap-applications, become: yes } - { role: bootstrap/bringup-bootstrap-applications, become: yes }
- { role: bootstrap/install-platform-certificates, become: yes }
- { role: bootstrap/complete-bootstrap, become: yes }
vars: vars:
replayed: false replayed: false

View File

@ -79,10 +79,10 @@
tasks: tasks:
- name: Install certificates as system Trusted CA certificates - name: Install certificates as system Trusted CA certificates
include_role: include_role:
name: migrate-platform-certificates-to-certmanager/install-trusted-ca name: common/install-trusted-ca
with_items: with_items:
- { name: system_local_ca_cert, content: "{{ system_local_ca_cert }}" } - { name: system_local_ca_cert, content: "{{ system_local_ca_cert }}" }
- { name: root_ca_cert, content: "{{ root_ca_cert }}" } - { name: system_root_ca_cert, content: "{{ system_root_ca_cert }}" }
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"

View File

@ -1,6 +1,6 @@
--- ---
# #
# Copyright (c) 2020-21 Wind River Systems, Inc. # Copyright (c) 2020-2022 Wind River Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -157,8 +157,3 @@
# Nested dictionaries are picky about having things on the same line # Nested dictionaries are picky about having things on the same line
- "prev_docker_registries: " - "prev_docker_registries: "
- "{{ docker_registries | to_yaml }}" - "{{ docker_registries | to_yaml }}"
- name: Mark the bootstrap as completed
file:
path: "{{ bootstrap_completed_flag }}"
state: touch

View File

@ -104,7 +104,7 @@
openssl_csr: openssl_csr:
path: "{{ kubeadm_pki_dir }}/ca.csr" path: "{{ kubeadm_pki_dir }}/ca.csr"
privatekey_path: "{{ kubeadm_pki_dir }}/ca.key" privatekey_path: "{{ kubeadm_pki_dir }}/ca.key"
common_name: kubernetes common_name: starlingx
basic_constraints: basic_constraints:
- CA:TRUE - CA:TRUE
- pathlen:1 - pathlen:1

View File

@ -0,0 +1,13 @@
---
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Task to mark the playbook as complete.
# It indicates that the controller was successfully bootstrapped.
#
- name: Mark the bootstrap as completed
file:
path: "{{ bootstrap_completed_flag }}"
state: touch

View File

@ -0,0 +1,62 @@
---
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# These tasks get information from the running system and use it to
# generate a certificate spec file which is going to be applied to
# kubernetes at a later step
#
- name: Read kubernetes Root CA certificate
shell: cat "{{ kubeadm_pki_dir }}/ca.crt" | base64 -w0
register: kubernetes_root_ca_crt
become: true
- name: Read kubernetes Root CA key
shell: cat "{{ kubeadm_pki_dir }}/ca.key" | base64 -w0
register: kubernetes_root_ca_key
become: true
- name: Set Root CA and local CA based on kubernetes Root CA
set_fact:
system_root_ca_cert: "{{ kubernetes_root_ca_crt.stdout }}"
system_local_ca_cert: "{{ kubernetes_root_ca_crt.stdout }}"
system_local_ca_key: "{{ kubernetes_root_ca_key.stdout }}"
- name: Get distributed_cloud role
shell: |
source /etc/platform/openrc
system show | grep distributed_cloud_role | awk '{ print $4 }'
register: distributed_cloud_role
- name: Set which platform certificates to install
set_fact:
install_oidc_auth_apps_certificate: false
install_system_open_ldap_certificate: "{{ true if distributed_cloud_role.stdout == 'systemcontroller' else false }}"
install_system_registry_local_certificate: false
install_system_restapi_gui_certificate: false
- name: Generate kubernetes yaml for cert-manager resources
include_role:
name: common/generate-platform-certificates-template
vars:
destination: /tmp/platform_certificates.yaml
- name: Install system_root_ca_cert as system Trusted CA certificate
include_role:
name: common/install-trusted-ca
with_items:
- { name: system_root_ca_cert, content: "{{ system_root_ca_cert }}" }
loop_control:
label: "{{ item.name }}"
- name: Apply kubernetes yaml to create cert-manager clusterissuer and certificates
command: kubectl apply -f /tmp/platform_certificates.yaml
environment:
KUBECONFIG: /etc/kubernetes/admin.conf
register: create_k8_apply_ep
until: create_k8_apply_ep is not failed
retries: 10
delay: 30

View File

@ -0,0 +1,11 @@
---
#
# Copyright (c) 2022 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
ca_duration: 3
system_platform_certificate:
dns_domain: starlingx.local
duration: 2160h # 90d
renewBefore: 360h # 15d

View File

@ -16,7 +16,17 @@
- name: Get floating management ip - name: Get floating management ip
shell: | shell: |
echo "{{ address_table.stdout }}" | awk '$4 == "management" { print $14 }' echo "{{ address_table.stdout }}" | awk '$4 == "management" { print $14 }'
register: management_ip register: management_floating_ip
- name: Get controller0 floating management ip
shell: |
echo "{{ address_table.stdout }}" | awk '$4 == "management" { print $16 }'
register: management_c0_ip
- name: Get controller1 floating management ip
shell: |
echo "{{ address_table.stdout }}" | awk '$4 == "management" { print $18 }'
register: management_c1_ip
- name: Get floating oam ip - name: Get floating oam ip
shell: | shell: |
@ -42,7 +52,7 @@
shell: | shell: |
source /etc/platform/openrc source /etc/platform/openrc
system show | grep region_name | awk '{ print $4 }' system show | grep region_name | awk '{ print $4 }'
register: region_name register: region_name_register
- name: Get distributed_cloud role - name: Get distributed_cloud role
shell: | shell: |

View File

@ -1,5 +1,5 @@
## strips out any bad character from region name. Only [^A-Za-z0-9-]" is supported ## strips out any bad character from region name. Only [^A-Za-z0-9-]" is supported
{% set clean_region_name = region_name.stdout | replace("_", "-") | regex_replace("[^A-Za-z0-9-]","") | lower %} {% set clean_region_name = region_name_register.stdout | replace("_", "-") | regex_replace("[^A-Za-z0-9-]","") | lower %}
--- ---
apiVersion: v1 apiVersion: v1
data: data:
@ -23,6 +23,7 @@ items:
secretName: system-local-ca secretName: system-local-ca
status: {} status: {}
{% if install_system_restapi_gui_certificate | bool %} {% if install_system_restapi_gui_certificate | bool %}
{% set short_certificate_name = 'system-restapi-gui' %}
- apiVersion: cert-manager.io/v1 - apiVersion: cert-manager.io/v1
kind: Certificate kind: Certificate
metadata: metadata:
@ -32,30 +33,20 @@ items:
spec: spec:
commonName: "{{ oam_ip.stdout }}" commonName: "{{ oam_ip.stdout }}"
dnsNames: dnsNames:
- "{{ clean_region_name }}.{{ dns_domain }}" - "{{ clean_region_name }}.{{ system_platform_certificate.dns_domain }}"
duration: "{{ duration }}" duration: "{{ system_platform_certificate.duration }}"
ipAddresses: ipAddresses:
- "{{ oam_ip.stdout }}" - "{{ oam_ip.stdout }}"
issuerRef: issuerRef:
kind: ClusterIssuer kind: ClusterIssuer
name: system-local-ca name: system-local-ca
renewBefore: "{{ renewBefore }}" renewBefore: "{{ system_platform_certificate.renewBefore }}"
secretName: system-restapi-gui-certificate secretName: system-restapi-gui-certificate
subject: {% include 'subject_snippet.j2' %}
countries:
- "{{ subject_C }}"
localities:
- "{{ subject_L }}"
- "{{ subject_prefix + ':' if subject_prefix is defined else '' }}{{ clean_region_name }}:system-restapi-gui"
organizationalUnits:
- "{{ subject_OU }}"
organizations:
- "{{ subject_O }}"
provinces:
- "{{ subject_ST }}"
status: {} status: {}
{% endif %} {% endif %}
{% if install_system_registry_local_certificate | bool %} {% if install_system_registry_local_certificate | bool %}
{% set short_certificate_name = 'system-registry-local' %}
- apiVersion: cert-manager.io/v1 - apiVersion: cert-manager.io/v1
kind: Certificate kind: Certificate
metadata: metadata:
@ -65,35 +56,25 @@ items:
spec: spec:
commonName: "{{ oam_ip.stdout }}" commonName: "{{ oam_ip.stdout }}"
dnsNames: dnsNames:
- "{{ clean_region_name }}.{{ dns_domain }}" - "{{ clean_region_name }}.{{ system_platform_certificate.dns_domain }}"
- registry.local - registry.local
{% if distributed_cloud_role.stdout == 'systemcontroller' %} {% if distributed_cloud_role.stdout == 'systemcontroller' %}
- registry.central - registry.central
{% endif %} {% endif %}
duration: "{{ duration }}" duration: "{{ system_platform_certificate.duration }}"
ipAddresses: ipAddresses:
- "{{ oam_ip.stdout }}" - "{{ oam_ip.stdout }}"
- "{{ management_ip.stdout }}" - "{{ management_floating_ip.stdout }}"
issuerRef: issuerRef:
kind: ClusterIssuer kind: ClusterIssuer
name: system-local-ca name: system-local-ca
renewBefore: "{{ renewBefore }}" renewBefore: "{{ system_platform_certificate.renewBefore }}"
secretName: system-registry-local-certificate secretName: system-registry-local-certificate
subject: {% include 'subject_snippet.j2' %}
countries:
- "{{ subject_C }}"
localities:
- "{{ subject_L }}"
- "{{ subject_prefix + ':' if subject_prefix is defined else '' }}{{ clean_region_name }}:system-registry-local"
organizationalUnits:
- "{{ subject_OU }}"
organizations:
- "{{ subject_O }}"
provinces:
- "{{ subject_ST }}"
status: {} status: {}
{% endif %} {% endif %}
{% if install_oidc_auth_apps_certificate | bool %} {% if install_oidc_auth_apps_certificate | bool %}
{% set short_certificate_name = 'system-oidc-dex' %}
- apiVersion: cert-manager.io/v1 - apiVersion: cert-manager.io/v1
kind: Certificate kind: Certificate
metadata: metadata:
@ -103,8 +84,8 @@ items:
spec: spec:
commonName: "{{ oam_ip.stdout }}" commonName: "{{ oam_ip.stdout }}"
dnsNames: dnsNames:
- "{{ clean_region_name }}.{{ dns_domain }}" - "{{ clean_region_name }}.{{ system_platform_certificate.dns_domain }}"
duration: "{{ duration }}" duration: "{{ system_platform_certificate.duration }}"
ipAddresses: ipAddresses:
- "{{ oam_ip.stdout }}" - "{{ oam_ip.stdout }}"
# Add kubernetes cluster ip to make sure certificate has issuer ip in san list # Add kubernetes cluster ip to make sure certificate has issuer ip in san list
@ -115,20 +96,35 @@ items:
issuerRef: issuerRef:
kind: ClusterIssuer kind: ClusterIssuer
name: system-local-ca name: system-local-ca
renewBefore: "{{ renewBefore }}" renewBefore: "{{ system_platform_certificate.renewBefore }}"
secretName: oidc-auth-apps-certificate secretName: oidc-auth-apps-certificate
subject: {% include 'subject_snippet.j2' %}
countries: status: {}
- "{{ subject_C }}" {% endif %}
localities: {% if install_system_open_ldap_certificate | bool %}
- "{{ subject_L }}" {% set short_certificate_name = 'system-openldap' %}
- "{{ subject_prefix + ':' if subject_prefix is defined else '' }}{{ clean_region_name }}:system-oidc-dex" - apiVersion: cert-manager.io/v1
organizationalUnits: kind: Certificate
- "{{ subject_OU }}" metadata:
organizations: creationTimestamp: null
- "{{ subject_O }}" name: system-openldap-local-certificate
provinces: namespace: deployment
- "{{ subject_ST }}" spec:
commonName: "{{ short_certificate_name }}"
dnsNames:
- "{{ clean_region_name }}.{{ system_platform_certificate.dns_domain }}"
- controller
duration: "{{ system_platform_certificate.duration }}"
ipAddresses:
- "{{ management_floating_ip.stdout }}"
- "{{ management_c0_ip.stdout }}"
- "{{ management_c1_ip.stdout }}"
issuerRef:
kind: ClusterIssuer
name: system-local-ca
renewBefore: "{{ system_platform_certificate.renewBefore }}"
secretName: system-openldap-local-certificate
{% include 'subject_snippet.j2' %}
status: {} status: {}
{% endif %} {% endif %}
kind: List kind: List

View File

@ -0,0 +1,24 @@
{% if system_platform_certificate is defined %}
subject:
{% if system_platform_certificate.subject_C is defined %}
countries:
- "{{ system_platform_certificate.subject_C }}"
{% endif %}
{% if system_platform_certificate.subject_ST is defined %}
provinces:
- "{{ system_platform_certificate.subject_ST }}"
{% endif %}
{% if system_platform_certificate.subject_L is defined %}
localities:
- "{{ system_platform_certificate.subject_L }}"
- "{{ system_platform_certificate.subject_prefix + ':' if system_platform_certificate.subject_prefix is defined else '' }}{{ clean_region_name }}:{{ short_certificate_name }}"
{% endif %}
{% if system_platform_certificate.subject_O is defined %}
organizations:
- "{{ system_platform_certificate.subject_O }}"
{% endif %}
{% if system_platform_certificate.subject_OU is defined %}
organizationalUnits:
- "{{ system_platform_certificate.subject_OU }}"
{% endif %}
{% endif %}

View File

@ -11,18 +11,19 @@
shell: echo "{{ item.content }}" | base64 -d > /tmp/ca.pem shell: echo "{{ item.content }}" | base64 -d > /tmp/ca.pem
- block: - block:
- name: Check if system_local_ca_cert is signed by root_ca_cert or self-signed - name: Check if system_local_ca_cert is signed by system_root_ca_cert or self-signed
shell: | shell: |
echo "{{ root_ca_cert }}" | base64 -d > /tmp/root.pem echo "{{ system_root_ca_cert }}" | base64 -d > /tmp/root.pem
openssl verify -verbose -CAfile /tmp/root.pem /tmp/ca.pem openssl verify -verbose -CAfile /tmp/root.pem /tmp/ca.pem
register: ca_verification register: ca_verification
# failed_when as false in order to print a better error msg in the task below # failed_when as false in order to print a better error msg in the task below
failed_when: false failed_when: false
- name: Fail when system_local_ca_cert is not signed by root_ca_cert or self-signed - name: Fail when system_local_ca_cert is not signed by system_root_ca_cert or self-signed
fail: fail:
msg: | msg: |
The system_local_ca_cert provided is not signed by root_ca_cert provided or self-signed. The system_local_ca_cert provided is not signed by
system_root_ca_cert provided or self-signed.
Please review your inventory parameters. Please review your inventory parameters.
when: ca_verification.rc | int != 0 when: ca_verification.rc | int != 0
when: item.name == 'system_local_ca_cert' when: item.name == 'system_local_ca_cert'

View File

@ -20,7 +20,14 @@
awk '{ if ($0 == "applied") print "true"; else print "false"; }' awk '{ if ($0 == "applied") print "true"; else print "false"; }'
register: oidc_applied register: oidc_applied
- name: Check if openldap certificate exists
shell: |
source /etc/platform/openrc
system certificate-list | grep openldap
register: openldap_certificate_exists
- set_fact: - set_fact:
install_oidc_auth_apps_certificate: "{{ true if oidc_applied.stdout | bool else false }}"
install_system_open_ldap_certificate: "{{ true if openldap_certificate_exists.stdout | int == 0 else false }}"
install_system_registry_local_certificate: true install_system_registry_local_certificate: true
install_system_restapi_gui_certificate: "{{ true if https_enabled.stdout | bool else false }}" install_system_restapi_gui_certificate: "{{ true if https_enabled.stdout | bool else false }}"
install_oidc_auth_apps_certificate: "{{ true if oidc_applied.stdout | bool else false }}"

View File

@ -57,7 +57,7 @@
- name: Generate kubernetes yaml for cert-manager resources - name: Generate kubernetes yaml for cert-manager resources
include_role: include_role:
name: common/generate-platform-certificates name: common/generate-platform-certificates-template
vars: vars:
destination: /tmp/platform_certificates.yaml destination: /tmp/platform_certificates.yaml
@ -73,16 +73,17 @@
- name: Force certificate renewals - name: Force certificate renewals
include_tasks: delete-kubernetes-objects.yml include_tasks: delete-kubernetes-objects.yml
with_items: with_items:
- { secret: system-openldap-local-certificate, namespace: deployment, type: secret }
- { secret: system-registry-local-certificate, namespace: deployment, type: secret } - { secret: system-registry-local-certificate, namespace: deployment, type: secret }
- { secret: system-restapi-gui-certificate, namespace: deployment, type: secret } - { secret: system-restapi-gui-certificate, namespace: deployment, type: secret }
- { secret: oidc-auth-apps-certificate, namespace: kube-system, type: secret } - { secret: oidc-auth-apps-certificate, namespace: kube-system, type: secret }
- name: Install certificates as system Trusted CA certificates - name: Install certificates as system Trusted CA certificates
include_role: include_role:
name: migrate-platform-certificates-to-certmanager/install-trusted-ca name: common/install-trusted-ca
with_items: with_items:
- { name: system_local_ca_cert, content: "{{ system_local_ca_cert }}" } - { name: system_local_ca_cert, content: "{{ system_local_ca_cert }}" }
- { name: root_ca_cert, content: "{{ root_ca_cert }}" } - { name: system_root_ca_cert, content: "{{ system_root_ca_cert }}" }
loop_control: loop_control:
label: "{{ item.name }}" label: "{{ item.name }}"
@ -173,5 +174,10 @@
namespace: kube-system, namespace: kube-system,
should_run: "{{oidc_applied.stdout}}" should_run: "{{oidc_applied.stdout}}"
} }
- {
secret: system-openldap-local-certificate,
namespace: deployment,
should_run: "{{ true if openldap_certificate_exists.stdout | int == 0 else false }}"
}
when: mode == 'check' when: mode == 'check'