1
0
mirror of https://github.com/rancher/rke.git synced 2025-09-02 15:34:36 +00:00

key rotation as part of ClusterUp, more robust secrets rewrite, improved logging

This commit is contained in:
Ryan Sanna
2020-09-24 11:53:10 -07:00
parent 816d4cd130
commit e42ff49fec
8 changed files with 345 additions and 71 deletions

View File

@@ -8,6 +8,7 @@ import (
"github.com/rancher/rke/hosts"
"github.com/rancher/rke/log"
"github.com/rancher/rke/pki"
"github.com/rancher/rke/pki/cert"
v3 "github.com/rancher/rke/types"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@@ -57,18 +58,25 @@ func rotateEncryptionKeyFromCli(ctx *cli.Context) error {
// setting up the flags
flags := cluster.GetExternalFlags(false, false, false, false, "", filePath)
return RotateEncryptionKey(context.Background(), rkeConfig, hosts.DialersOptions{}, flags)
_, _, _, _, _, err = RotateEncryptionKey(context.Background(), rkeConfig, hosts.DialersOptions{}, flags)
return err
}
func RotateEncryptionKey(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig,
dialersOptions hosts.DialersOptions, flags cluster.ExternalFlags) error {
log.Infof(ctx, "Rotating cluster secrets encryption key..")
func RotateEncryptionKey(
ctx context.Context,
rkeConfig *v3.RancherKubernetesEngineConfig,
dialersOptions hosts.DialersOptions,
flags cluster.ExternalFlags,
) (string, string, string, string, map[string]pki.CertificatePKI, error) {
log.Infof(ctx, "Rotating cluster secrets encryption key")
var APIURL, caCrt, clientCert, clientKey string
stateFilePath := cluster.GetStateFilePath(flags.ClusterFilePath, flags.ConfigDir)
rkeFullState, _ := cluster.ReadStateFile(ctx, stateFilePath)
// We generate the first encryption config in ClusterInit, to store it ASAP. It's written
// to the DesiredState
stateEncryptionConfig := rkeFullState.DesiredState.EncryptionConfig
// We generate the first encryption config in ClusterInit, to store it ASAP. It's written to the DesiredState
stateEncryptionConfig := rkeFullState.DesiredState.EncryptionConfig
// if CurrentState has EncryptionConfig, it means this is NOT the first time we enable encryption, we should use the _latest_ applied value from the current cluster
if rkeFullState.CurrentState.EncryptionConfig != "" {
stateEncryptionConfig = rkeFullState.CurrentState.EncryptionConfig
@@ -76,32 +84,43 @@ func RotateEncryptionKey(ctx context.Context, rkeConfig *v3.RancherKubernetesEng
kubeCluster, err := cluster.InitClusterObject(ctx, rkeConfig, flags, stateEncryptionConfig)
if err != nil {
return err
return APIURL, caCrt, clientCert, clientKey, nil, err
}
if kubeCluster.IsEncryptionCustomConfig() {
return fmt.Errorf("can't rotate encryption keys: Key Rotation is not supported with custom configuration")
return APIURL, caCrt, clientCert, clientKey, nil, fmt.Errorf("can't rotate encryption keys: Key Rotation is not supported with custom configuration")
}
if !kubeCluster.IsEncryptionEnabled() {
return fmt.Errorf("can't rotate encryption keys: Encryption Configuration is disabled")
return APIURL, caCrt, clientCert, clientKey, nil, fmt.Errorf("can't rotate encryption keys: Encryption Configuration is disabled")
}
kubeCluster.Certificates = rkeFullState.DesiredState.CertificatesBundle
if err := kubeCluster.SetupDialers(ctx, dialersOptions); err != nil {
return err
return APIURL, caCrt, clientCert, clientKey, nil, err
}
if err := kubeCluster.TunnelHosts(ctx, flags); err != nil {
return err
return APIURL, caCrt, clientCert, clientKey, nil, err
}
if len(kubeCluster.ControlPlaneHosts) > 0 {
APIURL = fmt.Sprintf("https://%s:6443", kubeCluster.ControlPlaneHosts[0].Address)
}
clientCert = string(cert.EncodeCertPEM(kubeCluster.Certificates[pki.KubeAdminCertName].Certificate))
clientKey = string(cert.EncodePrivateKeyPEM(kubeCluster.Certificates[pki.KubeAdminCertName].Key))
caCrt = string(cert.EncodeCertPEM(kubeCluster.Certificates[pki.CACertName].Certificate))
err = kubeCluster.RotateEncryptionKey(ctx, rkeFullState)
if err != nil {
return err
return APIURL, caCrt, clientCert, clientKey, nil, err
}
// make sure we have the latest state
rkeFullState, _ = cluster.ReadStateFile(ctx, stateFilePath)
log.Infof(ctx, "Reconciling cluster state")
if err := kubeCluster.ReconcileDesiredStateEncryptionConfig(ctx, rkeFullState); err != nil {
return err
return APIURL, caCrt, clientCert, clientKey, nil, err
}
log.Infof(ctx, "Cluster secrets encryption key rotated successfully")
return nil
return APIURL, caCrt, clientCert, clientKey, kubeCluster.Certificates, nil
}

View File

@@ -85,10 +85,9 @@ func ClusterUp(ctx context.Context, dialersOptions hosts.DialersOptions, flags c
if err != nil {
return APIURL, caCrt, clientCert, clientKey, nil, err
}
// We generate the first encryption config in ClusterInit, to store it ASAP. It's written
// to the DesiredState
stateEncryptionConfig := clusterState.DesiredState.EncryptionConfig
// We generate the first encryption config in ClusterInit, to store it ASAP. It's written to the DesiredState
stateEncryptionConfig := clusterState.DesiredState.EncryptionConfig
// if CurrentState has EncryptionConfig, it means this is NOT the first time we enable encryption, we should use the _latest_ applied value from the current cluster
if clusterState.CurrentState.EncryptionConfig != "" {
stateEncryptionConfig = clusterState.CurrentState.EncryptionConfig
@@ -103,6 +102,10 @@ func ClusterUp(ctx context.Context, dialersOptions hosts.DialersOptions, flags c
if kubeCluster.RancherKubernetesEngineConfig.RotateCertificates != nil {
return rebuildClusterWithRotatedCertificates(ctx, dialersOptions, flags, svcOptionsData)
}
// if we need to rotate the encryption key, do so and then return
if kubeCluster.RancherKubernetesEngineConfig.RotateEncryptionKey {
return RotateEncryptionKey(ctx, clusterState.CurrentState.RancherKubernetesEngineConfig.DeepCopy(), dialersOptions, flags)
}
log.Infof(ctx, "Building Kubernetes cluster")
err = kubeCluster.SetupDialers(ctx, dialersOptions)