Skip to content

Commit bf9b95d

Browse files
address copilot optimizations
Signed-off-by: Mayank Shah <mayank.shah@percona.com>
1 parent ca07b3c commit bf9b95d

1 file changed

Lines changed: 69 additions & 57 deletions

File tree

pkg/controller/ps/controller.go

Lines changed: 69 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,12 @@ func (r *PerconaServerMySQLReconciler) SetupWithManager(mgr ctrl.Manager) error
104104
}
105105

106106
const (
107-
fieldSecretsName = ".spec.secretsName"
107+
fieldSecretsName = ".spec.secretsName"
108+
fieldEncryptionKeySecretName = ".spec.backup.encryptionKeySecret.name"
108109
)
109110

110111
func setupFieldIndexers(mgr ctrl.Manager) error {
112+
// Index cluster secrets field
111113
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &apiv1.PerconaServerMySQL{}, fieldSecretsName, func(o client.Object) []string {
112114
cluster, ok := o.(*apiv1.PerconaServerMySQL)
113115
if !ok {
@@ -121,6 +123,34 @@ func setupFieldIndexers(mgr ctrl.Manager) error {
121123
}); err != nil {
122124
return errors.Wrapf(err, "index field %s", fieldSecretsName)
123125
}
126+
127+
// Index cluster backup encryption key secrets field
128+
if err := mgr.GetFieldIndexer().IndexField(
129+
context.Background(),
130+
&apiv1.PerconaServerMySQL{},
131+
fieldEncryptionKeySecretName,
132+
func(rawObj client.Object) []string {
133+
cluster := rawObj.(*apiv1.PerconaServerMySQL)
134+
if cluster.Spec.Backup == nil {
135+
return nil
136+
}
137+
result := []string{}
138+
139+
if cluster.Spec.Backup.EncryptionKeySecret != nil {
140+
result = append(result, cluster.Spec.Backup.EncryptionKeySecret.Name)
141+
}
142+
143+
for _, storage := range cluster.Spec.Backup.Storages {
144+
if storage == nil || storage.EncryptionKeySecret == nil {
145+
continue
146+
}
147+
result = append(result, storage.EncryptionKeySecret.Name)
148+
}
149+
return result
150+
},
151+
); err != nil {
152+
return errors.Wrapf(err, "unable to index field %s", fieldEncryptionKeySecretName)
153+
}
124154
return nil
125155
}
126156

@@ -161,38 +191,21 @@ func enqueueClusterFromEncryptionKeySecret(c client.Client) handler.EventHandler
161191
}
162192
clusters := &apiv1.PerconaServerMySQLList{}
163193
log := logf.FromContext(ctx)
164-
if err := c.List(ctx, clusters, client.InNamespace(secret.Namespace)); err != nil {
194+
if err := c.List(ctx, clusters, client.InNamespace(secret.Namespace), client.MatchingFields{
195+
fieldEncryptionKeySecretName: secret.Name,
196+
}); err != nil {
165197
log.Error(err, "failed to list clusters")
166198
return nil
167199
}
168200

169201
var requests []reconcile.Request
170202
for _, cluster := range clusters.Items {
171-
if cluster.Spec.Backup == nil {
172-
continue
173-
}
174-
175-
if cluster.Spec.Backup.EncryptionKeySecret != nil && cluster.Spec.Backup.EncryptionKeySecret.Name == secret.Name {
176-
requests = append(requests, reconcile.Request{
177-
NamespacedName: types.NamespacedName{
178-
Name: cluster.Name,
179-
Namespace: cluster.Namespace,
180-
},
181-
})
182-
continue
183-
}
184-
185-
for _, storage := range cluster.Spec.Backup.Storages {
186-
if storage != nil && storage.EncryptionKeySecret != nil && storage.EncryptionKeySecret.Name == secret.Name {
187-
requests = append(requests, reconcile.Request{
188-
NamespacedName: types.NamespacedName{
189-
Name: cluster.Name,
190-
Namespace: cluster.Namespace,
191-
},
192-
})
193-
break
194-
}
195-
}
203+
requests = append(requests, reconcile.Request{
204+
NamespacedName: types.NamespacedName{
205+
Name: cluster.Name,
206+
Namespace: cluster.Namespace,
207+
},
208+
})
196209
}
197210
return requests
198211
})
@@ -1821,8 +1834,6 @@ func (r *PerconaServerMySQLReconciler) reconcileInternalEncryptionKeySecret(ctx
18211834
return nil
18221835
}
18231836

1824-
log := logf.FromContext(ctx)
1825-
18261837
secret := &corev1.Secret{
18271838
ObjectMeta: metav1.ObjectMeta{
18281839
Name: naming.EncryptionKeyInternalSecretName(cr.Name),
@@ -1842,43 +1853,44 @@ func (r *PerconaServerMySQLReconciler) reconcileInternalEncryptionKeySecret(ctx
18421853
return nil
18431854
}
18441855

1845-
opResult, err := controllerutil.CreateOrUpdate(ctx, r.Client, secret, func() error {
1846-
if version, ok := secret.Data[naming.InternalEncryptionKeyVersionFileName]; ok {
1847-
data[naming.InternalEncryptionKeyVersionFileName] = version
1856+
if _, err := controllerutil.CreateOrUpdate(ctx, r.Client, secret, func() error {
1857+
if err := controllerutil.SetControllerReference(cr, secret, r.Scheme); err != nil {
1858+
return errors.Wrap(err, "set controller reference")
18481859
}
1849-
secret.Data = data
18501860
secret.Labels = cr.GlobalLabels()
18511861
secret.Annotations = cr.GlobalAnnotations()
18521862

1853-
if err := controllerutil.SetControllerReference(cr, secret, r.Scheme); err != nil {
1854-
return errors.Wrap(err, "set controller reference")
1863+
if encryptionKeyDataEqual(secret.Data, data) {
1864+
return nil
18551865
}
1856-
return nil
1857-
})
1858-
if err != nil {
1859-
return errors.Wrap(err, "create or update encryption key secret")
1860-
}
18611866

1862-
if opResult == controllerutil.OperationResultNone {
1867+
// Store a version of the data along with the keys. The version is the timestamp at which
1868+
// the data was last modified. This version is used to signal the sidecar whether to wait
1869+
// for the data to be synced from the Secret to the pod.
1870+
// The sidecar reads the version file from its mounted Secret volume; when it matches this value,
1871+
// kubelet has refreshed the projected data and the sidecar can safely use the
1872+
// encryption keys.
1873+
version := []byte(strconv.FormatInt(time.Now().UTC().UnixNano(), 10))
1874+
1875+
secret.Data = data
1876+
secret.Data[naming.InternalEncryptionKeyVersionFileName] = version
1877+
18631878
return nil
1879+
}); err != nil {
1880+
return errors.Wrap(err, "create or update encryption key secret")
18641881
}
1882+
return nil
1883+
}
18651884

1866-
// Store the Secret resourceVersion in the Secret data so backup requests can
1867-
// tell the xtrabackup sidecar which key version to wait for. The sidecar reads
1868-
// the version file from its mounted Secret volume; when it matches this value,
1869-
// kubelet has refreshed the projected data and the sidecar can safely use the
1870-
// encryption key. Use APIReader here to avoid reading a stale cache; this path
1871-
// is only hit when encryption key data changes, so the direct read is fine.
1872-
if err := r.APIReader.Get(ctx, client.ObjectKeyFromObject(secret), secret); err != nil {
1873-
return errors.Wrap(err, "get encryption key secret")
1885+
func encryptionKeyDataEqual(current, desired map[string][]byte) bool {
1886+
if len(current) != len(desired)+1 {
1887+
return false
18741888
}
1875-
secret.Data[naming.InternalEncryptionKeyVersionFileName] = []byte(secret.GetResourceVersion())
1876-
1877-
if err := r.Update(ctx, secret); err != nil {
1878-
return errors.Wrap(err, "update encryption key secret")
1889+
for key, desiredValue := range desired {
1890+
if !bytes.Equal(current[key], desiredValue) {
1891+
return false
1892+
}
18791893
}
1880-
1881-
log.Info("Created or updated internal backup encryption key secret", "name", secret.Name, "version", secret.GetResourceVersion())
1882-
1883-
return nil
1894+
_, ok := current[naming.InternalEncryptionKeyVersionFileName]
1895+
return ok
18841896
}

0 commit comments

Comments
 (0)