From 98807ffb6b6e790f31e9deb1ddc1a63356e158e3 Mon Sep 17 00:00:00 2001
From: ERIK <bo.jiang@daocloud.io>
Date: Mon, 2 Dec 2024 18:27:00 +0800
Subject: [PATCH] Optimize CA cert hash calculation with community.crypto
 (#11758)

Signed-off-by: bo.jiang <bo.jiang@daocloud.io>
---
 galaxy.yml                                          |  1 +
 requirements.txt                                    |  2 ++
 .../kubernetes/control-plane/defaults/main/main.yml |  5 +++++
 roles/kubernetes/kubeadm/tasks/main.yml             | 13 ++++---------
 .../kubeadm/templates/kubeadm-client.conf.j2        |  4 ++--
 roles/kubespray-defaults/defaults/main/main.yml     |  5 -----
 6 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/galaxy.yml b/galaxy.yml
index c124be9a3..029b94afe 100644
--- a/galaxy.yml
+++ b/galaxy.yml
@@ -14,6 +14,7 @@ documentation: https://kubespray.io
 license_file: LICENSE
 dependencies:
   ansible.utils: '>=2.5.0'
+  community.crypto: '>=2.22.3'
   community.general: '>=7.0.0'
   ansible.netcommon: '>=5.3.0'
   ansible.posix: '>=1.5.4'
diff --git a/requirements.txt b/requirements.txt
index 9b46368e5..a0b298adf 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,6 @@
 ansible==9.12.0
+# Needed for community.crypto module
+cryptography==44.0.0
 # Needed for jinja2 json_query templating
 jmespath==1.0.1
 # Needed for ansible.utils.ipaddr
diff --git a/roles/kubernetes/control-plane/defaults/main/main.yml b/roles/kubernetes/control-plane/defaults/main/main.yml
index d3a28bc21..00da94347 100644
--- a/roles/kubernetes/control-plane/defaults/main/main.yml
+++ b/roles/kubernetes/control-plane/defaults/main/main.yml
@@ -236,3 +236,8 @@ kube_apiserver_tracing_sampling_rate_per_million: 100
 
 # Enable kubeadm file discovery if anonymous access has been removed
 kubeadm_use_file_discovery: "{{ remove_anonymous_access }}"
+
+# Supported asymmetric encryption algorithm types for the cluster's keys and certificates.
+# can be one of RSA-2048(default), RSA-3072, RSA-4096, ECDSA-P256
+# ref: https://kubernetes.io/docs/reference/config-api/kubeadm-config.v1beta4/#kubeadm-k8s-io-v1beta4-ClusterConfiguration
+kube_asymmetric_encryption_algorithm: "RSA-2048"
diff --git a/roles/kubernetes/kubeadm/tasks/main.yml b/roles/kubernetes/kubeadm/tasks/main.yml
index a65d34eea..6e562d8ce 100644
--- a/roles/kubernetes/kubeadm/tasks/main.yml
+++ b/roles/kubernetes/kubeadm/tasks/main.yml
@@ -29,20 +29,15 @@
   delegate_to: "{{ groups['kube_control_plane'][0] }}"
   run_once: true
 
-- name: Calculate kubeadm CA cert hash
-  shell: |
-    set -o pipefail && openssl x509 -pubkey -in {{ kube_cert_dir }}/ca.crt | \
-    openssl {% if 'RSA' in kube_asymmetric_encryption_algorithm %}rsa{% elif 'ECDSA' in kube_asymmetric_encryption_algorithm %}ec{% else %}rsa{% endif %} -pubin -outform der 2>/dev/null | \
-    openssl dgst -sha256 -hex | sed 's/^.* //'
-  args:
-    executable: /bin/bash
-  register: kubeadm_ca_hash
+- name: Fetch CA certificate from control plane node
+  slurp:
+    src: "{{ kube_cert_dir }}/ca.crt"
+  register: ca_cert_content
   when:
     - kubeadm_ca_stat.stat is defined
     - kubeadm_ca_stat.stat.exists
   delegate_to: "{{ groups['kube_control_plane'][0] }}"
   run_once: true
-  changed_when: false
 
 - name: Create kubeadm token for joining nodes with 24h expiration (default)
   command: "{{ bin_dir }}/kubeadm token create"
diff --git a/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2 b/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2
index 3735936f9..3dfe5d1fa 100644
--- a/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2
+++ b/roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2
@@ -13,9 +13,9 @@ discovery:
     apiServerEndpoint: {{ kubeadm_discovery_address }}
 {% endif %}
     token: {{ kubeadm_token }}
-{% if kubeadm_ca_hash.stdout is defined %}
+{% if ca_cert_content is defined %}
     caCertHashes:
-    - sha256:{{ kubeadm_ca_hash.stdout }}
+    - sha256:{{ (ca_cert_content.content | b64decode | community.crypto.x509_certificate_info).public_key_fingerprints.sha256.replace(':', '') }}
 {% else %}
     unsafeSkipCAVerification: true
 {% endif %}
diff --git a/roles/kubespray-defaults/defaults/main/main.yml b/roles/kubespray-defaults/defaults/main/main.yml
index 1210287c8..32a78545a 100644
--- a/roles/kubespray-defaults/defaults/main/main.yml
+++ b/roles/kubespray-defaults/defaults/main/main.yml
@@ -62,11 +62,6 @@ kubeadm_join_phases_skip: >-
 # Set to true to remove the role binding to anonymous users created by kubeadm
 remove_anonymous_access: false
 
-# Supported asymmetric encryption algorithm types for the cluster's keys and certificates.
-# can be one of RSA-2048(default), RSA-3072, RSA-4096, ECDSA-P256
-# ref: https://kubernetes.io/docs/reference/config-api/kubeadm-config.v1beta4/#kubeadm-k8s-io-v1beta4-ClusterConfiguration
-kube_asymmetric_encryption_algorithm: "RSA-2048"
-
 # A string slice of values which specify the addresses to use for NodePorts.
 # Values may be valid IP blocks (e.g. 1.2.3.0/24, 1.2.3.4/32).
 # The default empty string slice ([]) means to use all local addresses.
-- 
GitLab