Skip to content

Commit

Permalink
sort external config data for hash consistency
Browse files Browse the repository at this point in the history
Signed-off-by: gazarenkov <[email protected]>
  • Loading branch information
gazarenkov committed Jan 8, 2025
1 parent 972e346 commit 8bc4088
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
13 changes: 13 additions & 0 deletions internal/controller/preprocessor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,16 @@ func TestExtConfigChanged(t *testing.T) {
assert.Equal(t, "false", cm.Labels[model.ExtConfigSyncLabel])

}

// TestExtConfigChanged tests if concatData returns the same data when the order of the keys is different
func TestExtConcatData(t *testing.T) {
cm := corev1.ConfigMap{}

cm.Data = map[string]string{"key1": "value1", "key2": "value2", "key3": "value3", "key4": "value4"}
original := []byte("original")
data1 := concatData(original, &cm)

cm.Data = map[string]string{"key4": "value4", "key2": "value2", "key3": "value3", "key1": "value1"}
assert.Equal(t, data1, concatData(original, &cm))

}
37 changes: 26 additions & 11 deletions internal/controller/spec_preprocessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/sha256"
"fmt"
"os"
"sort"
"strconv"

"github.com/redhat-developer/rhdh-operator/pkg/utils"
Expand Down Expand Up @@ -70,7 +71,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
if bsSpec.Application.AppConfig != nil {
for _, ac := range bsSpec.Application.AppConfig.ConfigMaps {
cm := &corev1.ConfigMap{Data: map[string]string{}}
if hashingData, err = r.addExtConfig(&result, ctx, cm, backstage.Name, ac.Name, ns, addToWatch(ac), hashingData); err != nil {
if hashingData, err = r.addExtConfig(ctx, cm, backstage.Name, ac.Name, ns, addToWatch(ac), hashingData); err != nil {
return result, err
}
result.AppConfigKeys[ac.Name] = maps.Keys(cm.Data)
Expand All @@ -81,7 +82,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
if bsSpec.Application.ExtraFiles != nil && bsSpec.Application.ExtraFiles.ConfigMaps != nil {
for _, ef := range bsSpec.Application.ExtraFiles.ConfigMaps {
cm := &corev1.ConfigMap{Data: map[string]string{}, BinaryData: map[string][]byte{}}
if hashingData, err = r.addExtConfig(&result, ctx, cm, backstage.Name, ef.Name, ns, addToWatch(ef), hashingData); err != nil {
if hashingData, err = r.addExtConfig(ctx, cm, backstage.Name, ef.Name, ns, addToWatch(ef), hashingData); err != nil {
return result, err
}
result.ExtraFileConfigMapKeys[ef.Name] = model.NewDataObjectKeys(cm.Data, cm.BinaryData)
Expand All @@ -92,7 +93,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
if bsSpec.Application.ExtraFiles != nil && bsSpec.Application.ExtraFiles.Secrets != nil {
for _, ef := range bsSpec.Application.ExtraFiles.Secrets {
secret := &corev1.Secret{Data: map[string][]byte{}, StringData: map[string]string{}}
if hashingData, err = r.addExtConfig(&result, ctx, secret, backstage.Name, ef.Name, ns, addToWatch(ef), hashingData); err != nil {
if hashingData, err = r.addExtConfig(ctx, secret, backstage.Name, ef.Name, ns, addToWatch(ef), hashingData); err != nil {
return result, err
}
result.ExtraFileSecretKeys[ef.Name] = model.NewDataObjectKeys(secret.StringData, secret.Data)
Expand All @@ -103,7 +104,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
if bsSpec.Application.ExtraEnvs != nil && bsSpec.Application.ExtraEnvs.ConfigMaps != nil {
for _, ee := range bsSpec.Application.ExtraEnvs.ConfigMaps {
cm := &corev1.ConfigMap{Data: map[string]string{}, BinaryData: map[string][]byte{}}
if hashingData, err = r.addExtConfig(&result, ctx, cm, backstage.Name, ee.Name, ns, true, hashingData); err != nil {
if hashingData, err = r.addExtConfig(ctx, cm, backstage.Name, ee.Name, ns, true, hashingData); err != nil {
return result, err
}
result.ExtraEnvConfigMapKeys[ee.Name] = model.NewDataObjectKeys(cm.Data, cm.BinaryData)
Expand All @@ -114,7 +115,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
if bsSpec.Application.ExtraEnvs != nil && bsSpec.Application.ExtraEnvs.Secrets != nil {
for _, ee := range bsSpec.Application.ExtraEnvs.Secrets {
secret := &corev1.Secret{Data: map[string][]byte{}, StringData: map[string]string{}}
if hashingData, err = r.addExtConfig(&result, ctx, secret, backstage.Name, ee.Name, ns, true, hashingData); err != nil {
if hashingData, err = r.addExtConfig(ctx, secret, backstage.Name, ee.Name, ns, true, hashingData); err != nil {
return result, err
}
//result.ExtraEnvSecrets[secret.Name] = *secret
Expand All @@ -137,7 +138,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
// Process DynamicPlugins
if bsSpec.Application.DynamicPluginsConfigMapName != "" {
cm := &corev1.ConfigMap{}
if hashingData, err = r.addExtConfig(&result, ctx, cm, backstage.Name, bsSpec.Application.DynamicPluginsConfigMapName, ns, true, hashingData); err != nil {
if hashingData, err = r.addExtConfig(ctx, cm, backstage.Name, bsSpec.Application.DynamicPluginsConfigMapName, ns, true, hashingData); err != nil {
return result, err
}
result.DynamicPlugins = *cm
Expand All @@ -153,7 +154,7 @@ func (r *BackstageReconciler) preprocessSpec(ctx context.Context, backstage bsv1
// addExtConfig makes object watchable by Operator adding ExtConfigSyncLabel label and BackstageNameAnnotation
// and adding its content (marshalled object) to make it watchable by Operator and able to refresh the Pod if needed
// (Pod refresh will be called if external configuration hash changed)
func (r *BackstageReconciler) addExtConfig(config *model.ExternalConfig, ctx context.Context, obj client.Object, backstageName, objectName, ns string, addToWatch bool, hashingData []byte) ([]byte, error) {
func (r *BackstageReconciler) addExtConfig(ctx context.Context, obj client.Object, backstageName, objectName, ns string, addToWatch bool, hashingData []byte) ([]byte, error) {

lg := log.FromContext(ctx)

Expand Down Expand Up @@ -232,13 +233,27 @@ func concatData(original []byte, obj client.Object) []byte {
binaryData = v.Data
}

for k, v := range stringData {
data = append(data, []byte(k+v)...)
// sort the keys to make sure the order and the hash eventually is consistent
stringKeys := make([]string, 0, len(stringData))
for k := range stringData {
stringKeys = append(stringKeys, k)
}
sort.Strings(stringKeys)

for k, v := range binaryData {
binaryKeys := make([]string, 0, len(binaryData))
for k := range binaryData {
binaryKeys = append(binaryKeys, k)
}
sort.Strings(binaryKeys)

// append the data to the original data
for _, k := range stringKeys {
data = append(data, []byte(k+stringData[k])...)
}

for _, k := range binaryKeys {
data = append(data, []byte(k)...)
data = append(data, v...)
data = append(data, binaryData[k]...)
}

return data
Expand Down

0 comments on commit 8bc4088

Please sign in to comment.