Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: playbook to update the letsencrypt certificate on the ocp cluster #366

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
116 changes: 116 additions & 0 deletions ansible/playbook/README.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
= Ansible Playbooks
Antonio C. <antcosta at redhat dot com>
:revdate: {docdate}
:icons: font
:icon-set: fas
:toc: left
:toclevels: 3
:description: This document describes the implemented playbooks.
ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

== Playbooks

Expand Down Expand Up @@ -147,6 +159,110 @@ For instance, to undo the previous host operation:
ansible-playbook ansible/playbook/passstore_manage_host_groups.yml -e operation=remove -e group_name=k8s_115 -e vm_name=n01-k115
```

=== update_letsencrypt_certificate

[.lead]
Updates the certificates for the openshift ingress console.

[CAUTION]
====
This playbook assumes that the prefix added to the secret updated by the
_Certificate Manager_ is the same name of the OpenShift cluster.

For the sake of the examples the name used is `qshift`.

[source,bash]
----
$ kc --kubeconfig=${HOME}/.kube/snowdrop-k8s-config --namespace snowdrop-site get secret
NAME TYPE DATA AGE
...
qshift-snowdrop-dev-tls kubernetes.io/tls 2 96d
...
----

On the target OpenShift cluster the namespace and secret will be named
`openshift-ingress` and `` accordingly.

[source,bash]
----
$ kc -n openshift-ingress get secret
NAME TYPE DATA AGE
qshift-console kubernetes.io/tls 2 20d
----

====

.Playbook parameters
[%header,cols="25%,75%"]
|===
| Variable | Description

| `cluster_type`

[.fuchsia]#string#

a| Type of cluster where the certificate will be deployed into (target).

* *kubernetes*
* *openshift => Default*

| `site_name`

[.fuchsia]#string# / [.red]#required#

a| Name of the site that will be used to fetch the certificates from.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wording is a bit confusing: "Name of the site". What is a site ? Is it a domain name, something else ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a tough one, it's the name of the prefix given to the TLS secret which coincides with the OCP cluster name.

$ kc --namespace snowdrop-site get secret
...
qshift-snowdrop-dev-tls         kubernetes.io/tls   2      96d
www-snowdrop-dev-tls            kubernetes.io/tls   2      68d

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. That corresponds to a TLS secret which has been created part of a namespace.

Historically the certificate's related stuffs have been created under 2 namespaces using an ansible playbook: snowdrop-site and halkyon-site.

I'm not against the fact to keep this convention and that we create additional secrets, certificates request under the namespace which match a DNS domain (example: snowdrop-site => snowdrop.dev) BUT that should be clear to the user and that they know which namespace they should use. As we only manage one domain name, we could set as default snowdrop-site to avoid issues. WDYT ? @jacobdotcosta


The name of the site will be used to fetch the certificate from the
`snowdrop-site` namespace under the format of `<site_name>-snowdrop-dev-tls`.

| `source_host`

[.fuchsia]#string#

a| Name of the host that will be used to connect to the source cluster.

*Default => `localhost`*

| `source_kubeconfig`

[.fuchsia]#string#

a| `kubeconfig` file for the cluster running the license update feature.

*Default => `${HOME}/.kube/config`*

| `target_host`

[.fuchsia]#string#

a| Name of the host that will be used to connect to the source cluster.

*Default => `localhost`*

| `target_kubeconfig`

[.fuchsia]#string#

a| `kubeconfig` file for the cluster running the license update feature.

*Default => `${HOME}/.kube/config`*

|===

Sample execution of the `update_letsencrypt_certificate.yml` playbook.

[source,bash]
----
ansible-playbook ansible/playbook/update_letsencrypt_certificate.yml \
-e source_kubeconfig=${HOME}/.kube/snowdrop-k8s-config \ <1>
-e target_kubeconfig=${HOME}/.kube/qshift-ocp-cluster-config \ <2>
-e site_name=qshift <3>
----
<1> `kubeconfig` file for the cluster running the certificate renewal. Can be obtained from the passwordstore using `pass show -c openstack/snowdrop-k8s/kubeconfig`.
<2> `kubeconfig` file for the cluster that requires the update. In the example we're using the `qshift` cluster which `kubeconfig` can also be obtained from the passwordstore using `pass show -c openstack/ocp-qshift-drp2b/kubeconfig`.
<3> Name of the Openshift cluster


== Modules

:leveloffset: +2
Expand Down
108 changes: 108 additions & 0 deletions ansible/playbook/update_letsencrypt_certificate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
- name: "Get TLS information"
hosts: "{{ source_host | default(['localhost']) }}"
gather_facts: yes

pre_tasks:
- name: "Check site_name variables"
assert:
that: lookup('varnames', 'site_name') | length > 0
fail_msg: "site_name is not defined."
quiet: true

- name: "Check cluster_type variables"
assert:
that: cluster_type is undefined or cluster_type == 'kubernetes' or cluster_type == 'openshift'
fail_msg: "cluster_type must either be kubernetes or openshift (default: openshift)"
quiet: true

- name: Define Kubeconfig
ansible.builtin.set_fact:
kubeconfig_source: "{{ source_kubeconfig | default('~/.kube/config') }}"
target_cluster_type: "{{ cluster_type | default('openshift') }}"

- name: Source kubeconfig file
ansible.builtin.debug:
var: kubeconfig_source

tasks:

# kubectl -n snowdrop-site get secret www-snowdrop-dev-tls -o json | jq -r '.data["^Cs.key"]'
# k get secret/qshift-snowdrop-dev-tls -n snowdrop-site -ojson | jq -r '.data."tls.crt"' | base64 -d > tls.crt
# k get secret/qshift-snowdrop-dev-tls -n snowdrop-site -ojson | jq -r '.data."tls.key"' | base64 -d > tls.key
- name: Get TLS secret
kubernetes.core.k8s_info:
kubeconfig: "{{ kubeconfig_source }}"
kind: Secret
name: "{{ site_name }}-snowdrop-dev-tls"
namespace: snowdrop-site
register: tls_info

- name: Print TLS secret
ansible.builtin.debug:
var: tls_info

- name: Get TLS certificate and key
ansible.builtin.set_fact:
tls_certificate: "{{ tls_info.resources[0].data['tls.crt'] | b64decode }}"
tls_key: "{{ tls_info.resources[0].data['tls.key'] | b64decode }}"

- name: Print TLS data
ansible.builtin.debug:
msg:
- "{{ tls_certificate }}"
- "{{ tls_key }}"

- name: "Update certificate on target"
hosts: "{{ target_host | default(['localhost']) }}"
gather_facts: yes

pre_tasks:
- name: Define Kubeconfig
ansible.builtin.set_fact:
kubeconfig_target: "{{ target_kubeconfig | default('~/.kube/config') }}"

tasks:
- name: Define target variables for OpenShift
ansible.builtin.set_fact:
target_namespace: openshift-ingress
target_secret_name: "{{ site_name }}-console"
when: target_cluster_type == 'openshift'

- name: Define target variables for Kubernetes (TBD)
ansible.builtin.set_fact:
target_namespace: ingress-nginx
target_secret_name: "{{ site_name }}-console"
when: target_cluster_type == 'kubernetes'

# k -n openshift-ingress delete secret/qshift-console
- name: Remove the ingress console secret
kubernetes.core.k8s:
kubeconfig: "{{ kubeconfig_target }}"
state: absent
api_version: v1
kind: Secret
namespace: openshift-ingress
name: "{{ target_secret_name }}"

# k -n openshift-ingress create secret tls qshift-console --cert=pki/tls.crt --key=pki/tls.key # --dry-run="client" -oyaml
- name: Create the ingress console secret
kubernetes.core.k8s:
kubeconfig: "{{ kubeconfig_target }}"
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ target_secret_name }}"
namespace: openshift-ingress
# labels:
# app: galaxy
# service: web
type: kubernetes.io/tls
data:
tls.crt: "{{ tls_certificate | b64encode }}"
tls.key: "{{ tls_key | b64encode }}"

...
# ansible-playbook ansible/playbook/update_letsencrypt_certificate.yml -e source_kubeconfig=${HOME}/.kube/snowdrop-rhosp-snowdrop-k8s-config --check
3 changes: 3 additions & 0 deletions collections/requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ collections:

- name: ansible.posix
version: 1.5.4

- name: kubernetes.core
version: 2.4.1
...
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ yq ~= 3.2.2
#ansible >=7.0.0,<8.0.0
ansible ~= 8.0.0
ansible-lint
kubernetes >= 12.0.0
PyYAML >= 3.11
jsonpatch
Loading