Skip to content

Commit

Permalink
KubeVirt: create the etcd encryption key secret, if missing
Browse files Browse the repository at this point in the history
To allow creating of KubeVirt hosted cluster using the hosted cluster
API (rather than using the cli).

When creating the hosted cluster using the cli, the cli also creates the
secret. But when creating the hosted cluster using the hosted cluster
API, the secret is not created.

This PR changes hypershift so it now creates the etcd
encryption key secret, if it is not already exist.

Signed-off-by: Nahshon Unna-Tsameret <nunnatsa@redhat.com>
  • Loading branch information
nunnatsa committed Nov 2, 2023
1 parent f6bcddb commit e05a228
Show file tree
Hide file tree
Showing 2 changed files with 453 additions and 14 deletions.
Expand Up @@ -15,6 +15,7 @@ package hostedcluster
import (
"bytes"
"context"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"errors"
Expand Down Expand Up @@ -122,6 +123,8 @@ const (
controlPlaneOperatorManagesMachineAutoscaler = "io.openshift.hypershift.control-plane-operator-manages.cluster-autoscaler"
controlPlaneOperatorAppliesManagementKASNetworkPolicyLabel = "io.openshift.hypershift.control-plane-operator-applies-management-kas-network-policy-label"
useRestrictedPodSecurityLabel = "io.openshift.hypershift.restricted-psa"

etcdEncKeyPostfix = "-etcd-encryption-key"
)

var (
Expand Down Expand Up @@ -491,8 +494,10 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
}
}

createOrUpdate := r.createOrUpdate(req)

// Reconcile platform defaults
if err := r.reconcilePlatformDefaultSettings(ctx, hcluster); err != nil {
if err := r.reconcilePlatformDefaultSettings(ctx, hcluster, createOrUpdate, log); err != nil {
return ctrl.Result{}, err
}

Expand Down Expand Up @@ -1029,8 +1034,6 @@ func (r *HostedClusterReconciler) reconcile(ctx context.Context, req ctrl.Reques
}
}

createOrUpdate := r.createOrUpdate(req)

var pullSecret corev1.Secret
if err := r.Client.Get(ctx, types.NamespacedName{Namespace: hcluster.Namespace, Name: hcluster.Spec.PullSecret.Name}, &pullSecret); err != nil {
return ctrl.Result{}, fmt.Errorf("failed to get pull secret: %w", err)
Expand Down Expand Up @@ -4548,7 +4551,7 @@ func (r *HostedClusterReconciler) serviceAccountSigningKeyBytes(ctx context.Cont
return privateKeyPEMBytes, publicKeyPEMBytes, nil
}

func (r *HostedClusterReconciler) reconcileKubevirtPlatformDefaultSettings(ctx context.Context, hc *hyperv1.HostedCluster) error {
func (r *HostedClusterReconciler) reconcileKubevirtPlatformDefaultSettings(ctx context.Context, hc *hyperv1.HostedCluster, createOrUpdate upsert.CreateOrUpdateFN, logger logr.Logger) error {
if hc.Spec.Platform.Kubevirt == nil {
hc.Spec.Platform.Kubevirt = &hyperv1.KubevirtPlatformSpec{}
}
Expand Down Expand Up @@ -4606,14 +4609,64 @@ func (r *HostedClusterReconciler) reconcileKubevirtPlatformDefaultSettings(ctx c
}
}

return nil
if hc.Spec.SecretEncryption == nil ||
len(hc.Spec.SecretEncryption.Type) == 0 ||
(hc.Spec.SecretEncryption.Type == hyperv1.AESCBC &&
(hc.Spec.SecretEncryption.AESCBC == nil || len(hc.Spec.SecretEncryption.AESCBC.ActiveKey.Name) == 0)) {

logger.Info("no etcd encryption key configuration found; adding", "hostedCluster name", hc.Name, "hostedCluster namespace", hc.Namespace)
etcdEncSec := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: hc.Namespace,
Name: hc.Name + etcdEncKeyPostfix,
},
}

_, err := createOrUpdate(ctx, r.Client, etcdEncSec, func() error {
// don't override existing key just in case something weird happened
_, exists := etcdEncSec.Data[hyperv1.AESCBCKeySecretKey]
if exists {
return nil
}

generatedKey := make([]byte, 32)
_, err := rand.Read(generatedKey)
if err != nil {
return fmt.Errorf("failed to generate the etcd encryption key; %w", err)
}

if etcdEncSec.Data == nil {
etcdEncSec.Data = map[string][]byte{}
}
etcdEncSec.Data[hyperv1.AESCBCKeySecretKey] = generatedKey
etcdEncSec.Type = corev1.SecretTypeOpaque

ownerRef := config.OwnerRefFrom(hc)
ownerRef.ApplyTo(etcdEncSec)
return nil
})

if err != nil {
return fmt.Errorf("failed to create ETCD SecretEncryption key for KubeVirt platform HostedCluster: %w", err)
}

hc.Spec.SecretEncryption = &hyperv1.SecretEncryptionSpec{
Type: hyperv1.AESCBC,
AESCBC: &hyperv1.AESCBCSpec{
ActiveKey: corev1.LocalObjectReference{
Name: etcdEncSec.Name,
},
},
}
}

return nil
}

func (r *HostedClusterReconciler) reconcilePlatformDefaultSettings(ctx context.Context, hc *hyperv1.HostedCluster) error {
func (r *HostedClusterReconciler) reconcilePlatformDefaultSettings(ctx context.Context, hc *hyperv1.HostedCluster, createOrUpdate upsert.CreateOrUpdateFN, logger logr.Logger) error {
switch hc.Spec.Platform.Type {
case hyperv1.KubevirtPlatform:
return r.reconcileKubevirtPlatformDefaultSettings(ctx, hc)
return r.reconcileKubevirtPlatformDefaultSettings(ctx, hc, createOrUpdate, logger)
}
return nil
}
Expand Down

0 comments on commit e05a228

Please sign in to comment.