Skip to content

Commit

Permalink
ETCD-535: Manual CA rotation should rotate all leaf certs
Browse files Browse the repository at this point in the history
Signed-off-by: Thomas Jungblut <tjungblu@redhat.com>
  • Loading branch information
tjungblu committed Feb 8, 2024
1 parent 3c0554d commit 23fcace
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 116 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,6 @@ require (

replace (
github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
github.com/openshift/library-go => github.com/tjungblu/library-go v0.0.0-20240206134916-6b815e5a3a9c
vbom.ml/util => github.com/fvbommel/util v0.0.0-20180919145318-efcd4e0f9787
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,6 @@ github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d h1:RR
github.com/openshift/build-machinery-go v0.0.0-20220913142420-e25cf57ea46d/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
github.com/openshift/client-go v0.0.0-20231218140158-47f6d749b9d9 h1:kjgW3luAkf9NWu+8u+jqNNbexDG+CY82/INw8hGbG14=
github.com/openshift/client-go v0.0.0-20231218140158-47f6d749b9d9/go.mod h1:kKmxYRXTMutfF7XzGppFdbLhNGX1brXkRsZx5ID8c7U=
github.com/openshift/library-go v0.0.0-20240124134907-4dfbf6bc7b11 h1:9alPFotg+mC+HjDM1CgF7jmfpOr4lBgUQK+/5WKYKME=
github.com/openshift/library-go v0.0.0-20240124134907-4dfbf6bc7b11/go.mod h1:dccfc6I7w8HDcCYFgAzyL8xHyzcDra+n8tuSizvsySQ=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
Expand Down Expand Up @@ -408,6 +406,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tjungblu/library-go v0.0.0-20240206134916-6b815e5a3a9c h1:HSng5w56TjTm/IFy/4pX0JzFY9Nvk2t1h4jLqAt7BKA=
github.com/tjungblu/library-go v0.0.0-20240206134916-6b815e5a3a9c/go.mod h1:ePlaOqUiPplRc++6aYdMe+2FmXb2xTNS9Nz5laG2YmI=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE=
Expand Down
10 changes: 9 additions & 1 deletion pkg/operator/etcdcertsigner/etcdcertsignercontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
corev1informers "k8s.io/client-go/informers/core/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
corev1listers "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/klog/v2"
"strings"
"time"

Expand Down Expand Up @@ -79,6 +81,11 @@ func NewEtcdCertSignerController(
eventRecorder events.Recorder,
quorumChecker ceohelpers.QuorumChecker,
) factory.Controller {

// we're only interested in changes to control plane nodes
controlPlaneNodeInformer := corev1informers.NewFilteredNodeInformer(kubeClient, 1*time.Hour, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, func(listOptions *metav1.ListOptions) {
listOptions.LabelSelector = "node-role.kubernetes.io/master"
})
eventRecorder = eventRecorder.WithComponentSuffix("etcd-cert-signer-controller")
cmInformer := kubeInformers.InformersFor(operatorclient.TargetNamespace).Core().V1().ConfigMaps()
cmLister := cmInformer.Lister()
Expand Down Expand Up @@ -133,7 +140,7 @@ func NewEtcdCertSignerController(
livenessChecker.Add("EtcdCertSignerController", syncer)

return factory.New().ResyncEvery(time.Minute).WithInformers(
kubeInformers.InformersFor("").Core().V1().Nodes().Informer(),
controlPlaneNodeInformer,
kubeInformers.InformersFor(operatorclient.GlobalUserSpecifiedConfigNamespace).Core().V1().Secrets().Informer(),
cmInformer.Informer(),
secretInformer.Informer(),
Expand All @@ -142,6 +149,7 @@ func NewEtcdCertSignerController(
}

func (c *EtcdCertSignerController) sync(ctx context.Context, syncCtx factory.SyncContext) error {
klog.Infof("EtcdCertSignerController sync")
safe, err := c.quorumChecker.IsSafeToUpdateRevision()
if err != nil {
return fmt.Errorf("EtcdCertSignerController can't evaluate whether quorum is safe: %w", err)
Expand Down
103 changes: 62 additions & 41 deletions pkg/tlshelpers/tlshelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,13 @@ func CreateSignerCertRotationBundleConfigMap(
recorder events.Recorder) certrotation.CABundleConfigMap {

return certrotation.CABundleConfigMap{
Name: EtcdSignerCaBundleConfigMapName,
Namespace: operatorclient.TargetNamespace,
JiraComponent: EtcdJiraComponentName,
Description: "bundle for etcd signer certificate authorities",
Name: EtcdSignerCaBundleConfigMapName,
Namespace: operatorclient.TargetNamespace,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: "bundle for etcd signer certificate authorities",
AutoRegenerateAfterOfflineExpiry: "",
},
Informer: cmInformer,
Lister: cmLister,
Client: cmGetter,
Expand All @@ -100,10 +103,13 @@ func CreateMetricsSignerCertRotationBundleConfigMap(
recorder events.Recorder) certrotation.CABundleConfigMap {

return certrotation.CABundleConfigMap{
Name: EtcdMetricsSignerCaBundleConfigMapName,
Namespace: operatorclient.TargetNamespace,
JiraComponent: EtcdJiraComponentName,
Description: "bundle for etcd metrics signer certificate authorities",
Name: EtcdMetricsSignerCaBundleConfigMapName,
Namespace: operatorclient.TargetNamespace,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: "bundle for etcd metrics signer certificate authorities",
AutoRegenerateAfterOfflineExpiry: "",
},
Informer: cmInformer,
Lister: cmLister,
Client: cmGetter,
Expand All @@ -118,12 +124,15 @@ func CreateSignerCert(
recorder events.Recorder) certrotation.RotatedSigningCASecret {

return certrotation.RotatedSigningCASecret{
Namespace: operatorclient.TargetNamespace,
Name: EtcdSignerCertSecretName,
JiraComponent: EtcdJiraComponentName,
Description: "etcd signer certificate authorities",
Validity: etcdCaCertValidity,
Refresh: etcdCaCertValidityRefresh,
Namespace: operatorclient.TargetNamespace,
Name: EtcdSignerCertSecretName,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: "etcd signer certificate authorities",
AutoRegenerateAfterOfflineExpiry: "",
},
Validity: etcdCaCertValidity,
Refresh: etcdCaCertValidityRefresh,

Informer: secretInformer,
Lister: secretLister,
Expand All @@ -139,12 +148,15 @@ func CreateMetricsSignerCert(
recorder events.Recorder) certrotation.RotatedSigningCASecret {

return certrotation.RotatedSigningCASecret{
Namespace: operatorclient.TargetNamespace,
Name: EtcdMetricsSignerCertSecretName,
JiraComponent: EtcdJiraComponentName,
Description: "etcd metrics signer certificate authorities",
Validity: etcdCaCertValidity,
Refresh: etcdCaCertValidityRefresh,
Namespace: operatorclient.TargetNamespace,
Name: EtcdMetricsSignerCertSecretName,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: "etcd metrics signer certificate authorities",
AutoRegenerateAfterOfflineExpiry: "",
},
Validity: etcdCaCertValidity,
Refresh: etcdCaCertValidityRefresh,

Informer: secretInformer,
Lister: secretLister,
Expand Down Expand Up @@ -211,13 +223,16 @@ func createCertForNode(description, secretName string, node *corev1.Node,
}

return &certrotation.RotatedSelfSignedCertKeySecret{
Namespace: operatorclient.TargetNamespace,
Name: secretName,
JiraComponent: EtcdJiraComponentName,
Description: description,
Validity: etcdCertValidity,
Refresh: etcdCertValidityRefresh,
CertCreator: creator,
Namespace: operatorclient.TargetNamespace,
Name: secretName,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: description,
AutoRegenerateAfterOfflineExpiry: "",
},
Validity: etcdCertValidity,
Refresh: etcdCertValidityRefresh,
CertCreator: creator,

Informer: secretInformer,
Lister: secretLister,
Expand All @@ -239,13 +254,16 @@ func CreateMetricsClientCert(
}

return certrotation.RotatedSelfSignedCertKeySecret{
Namespace: operatorclient.TargetNamespace,
Name: EtcdMetricsClientCertSecretName,
JiraComponent: EtcdJiraComponentName,
Description: "etcd metrics client certificate",
Validity: etcdCertValidity,
Refresh: etcdCertValidityRefresh,
CertCreator: creator,
Namespace: operatorclient.TargetNamespace,
Name: EtcdMetricsClientCertSecretName,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: "etcd metrics client certificate",
AutoRegenerateAfterOfflineExpiry: "",
},
Validity: etcdCertValidity,
Refresh: etcdCertValidityRefresh,
CertCreator: creator,

Informer: secretInformer,
Lister: secretLister,
Expand All @@ -267,13 +285,16 @@ func CreateEtcdClientCert(
}

return certrotation.RotatedSelfSignedCertKeySecret{
Namespace: operatorclient.TargetNamespace,
Name: EtcdClientCertSecretName,
JiraComponent: EtcdJiraComponentName,
Description: "etcd client certificate",
Validity: etcdCertValidity,
Refresh: etcdCertValidityRefresh,
CertCreator: creator,
Namespace: operatorclient.TargetNamespace,
Name: EtcdClientCertSecretName,
AdditionalAnnotations: certrotation.AdditionalAnnotations{
JiraComponent: EtcdJiraComponentName,
Description: "etcd client certificate",
AutoRegenerateAfterOfflineExpiry: "",
},
Validity: etcdCertValidity,
Refresh: etcdCertValidityRefresh,
CertCreator: creator,

Informer: secretInformer,
Lister: secretLister,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 23fcace

Please sign in to comment.