-
Notifications
You must be signed in to change notification settings - Fork 54
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
K8SPG-555: fix updating CA secrets to 2.5.0 #906
Changes from 5 commits
377374a
48b8ba6
73eecbc
cdaec4b
55d5a39
f9207d5
9692e44
5cc226a
75f148f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -213,6 +213,10 @@ | |
return reconcile.Result{}, nil | ||
} | ||
|
||
if err := r.reconcileTLS(ctx, cr); err != nil { | ||
return reconcile.Result{}, errors.Wrap(err, "reconcile TLS") | ||
} | ||
|
||
if err := r.reconcileExternalWatchers(ctx, cr); err != nil { | ||
return reconcile.Result{}, errors.Wrap(err, "start external watchers") | ||
} | ||
|
@@ -282,6 +286,99 @@ | |
return ctrl.Result{}, nil | ||
} | ||
|
||
func (r *PGClusterReconciler) reconcileTLS(ctx context.Context, cr *v2.PerconaPGCluster) error { | ||
checkSecretProjection := func(p *corev1.SecretProjection, requiredPaths ...string) error { | ||
if p == nil { | ||
return nil | ||
} | ||
|
||
if p.Name == "" { | ||
return errors.New("secret name is not specified") | ||
} | ||
|
||
secret := new(corev1.Secret) | ||
nn := types.NamespacedName{Name: p.Name, Namespace: cr.Namespace} | ||
if err := r.Client.Get(ctx, nn, secret); err != nil { | ||
return errors.Wrapf(err, "failed to get secret %s", nn.Name) | ||
} | ||
|
||
pathMap := make(map[string]struct{}) | ||
for _, item := range p.Items { | ||
if _, ok := secret.Data[item.Key]; !ok { | ||
return errors.Errorf("key %s doesn't exist in secret %s", item.Key, secret.Name) | ||
} | ||
pathMap[item.Path] = struct{}{} | ||
} | ||
|
||
for _, path := range requiredPaths { | ||
if _, ok := pathMap[path]; !ok { | ||
return errors.Errorf("required path %s was not found", path) | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
if err := checkSecretProjection(cr.Spec.Secrets.CustomRootCATLSSecret, "root.crt", "root.key"); err != nil { | ||
return errors.Wrap(err, "failed to validate .spec.customRootCATLSSecret") | ||
} | ||
|
||
certPaths := []string{"tls.key", "tls.crt"} | ||
if cr.Spec.Secrets.CustomRootCATLSSecret == nil { | ||
certPaths = append(certPaths, "ca.crt") | ||
} | ||
if err := checkSecretProjection(cr.Spec.Secrets.CustomTLSSecret, certPaths...); err != nil { | ||
return errors.Wrap(err, "failed to validate .spec.customTLSSecret") | ||
} | ||
if err := checkSecretProjection(cr.Spec.Secrets.CustomReplicationClientTLSSecret, certPaths...); err != nil { | ||
return errors.Wrap(err, "failed to validate .spec.customReplicationTLSSecret") | ||
} | ||
|
||
oldCASecret := &corev1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: naming.RootCertSecret, | ||
Check failure on line 339 in percona/controller/pgcluster/controller.go GitHub Actions / runner / suggester / golangci-lint
|
||
Namespace: cr.Namespace, | ||
}, | ||
} | ||
err := r.Client.Get(ctx, client.ObjectKeyFromObject(oldCASecret), oldCASecret) | ||
if client.IgnoreNotFound(err) != nil { | ||
return errors.Wrap(err, "failed to get old ca secret") | ||
} | ||
|
||
if cr.CompareVersion("2.5.0") < 0 { | ||
if k8serrors.IsNotFound(err) { | ||
// K8SPG-555: We should create an empty secret with old name, so that crunchy part can populate it | ||
// instead of creating secrets unique to the cluster | ||
// TODO: remove when 2.4.0 will become unsupported | ||
if err := r.Client.Create(ctx, oldCASecret); err != nil { | ||
return errors.Wrap(err, "failed to create ca secret") | ||
} | ||
} | ||
return nil | ||
} | ||
if k8serrors.IsNotFound(err) { | ||
return nil | ||
} | ||
|
||
// K8SPG-555: Previously we used a single CA secret for all clusters in a namespace. | ||
// We should copy the contents of the old CA secret, if it exists, to the new one, which is unique for each cluster. | ||
// TODO: remove when 2.4.0 will become unsupported | ||
newCASecret := &corev1.Secret{ | ||
ObjectMeta: naming.PostgresRootCASecret(&v1beta1.PostgresCluster{ObjectMeta: metav1.ObjectMeta{Name: cr.Name, Namespace: cr.Namespace}}), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we break this into multiple lines? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
err = r.Client.Get(ctx, client.ObjectKeyFromObject(newCASecret), new(corev1.Secret)) | ||
if client.IgnoreNotFound(err) != nil { | ||
return errors.Wrap(err, "failed to get new ca secret") | ||
} | ||
if k8serrors.IsNotFound(err) { | ||
newCASecret.Data = oldCASecret.Data | ||
if err := r.Client.Create(ctx, newCASecret); err != nil { | ||
return errors.Wrap(err, "failed to create updated CA secret") | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (r *PGClusterReconciler) reconcilePMM(ctx context.Context, cr *v2.PerconaPGCluster) error { | ||
if !cr.PMMEnabled() { | ||
return nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we merge these two conditions:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't merge it, because we have to return if the version is lower than 2.5.0, even if secret was found.