Skip to content

Commit

Permalink
Factor out StrategicMerge into a generic function and add a test
Browse files Browse the repository at this point in the history
  • Loading branch information
lllamnyp committed Apr 17, 2024
1 parent 9f3f24c commit fbe5ebf
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 17 deletions.
20 changes: 3 additions & 17 deletions internal/controller/factory/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@ package factory

import (
"context"
"encoding/json"
"fmt"

appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/strategicpatch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

etcdaenixiov1alpha1 "github.com/aenix-io/etcd-operator/api/v1alpha1"
"github.com/aenix-io/etcd-operator/internal/k8sutils"
)

const (
Expand Down Expand Up @@ -75,25 +74,12 @@ func CreateOrUpdateStatefulSet(
Containers: []corev1.Container{generateContainer(cluster)},
Volumes: volumes,
}
basePodSpecBytes, err := json.Marshal(basePodSpec)
if err != nil {
return fmt.Errorf("cannot marshal generated base pod spec to JSON: %w", err)
}
if cluster.Spec.PodTemplate.Spec.Containers == nil {
cluster.Spec.PodTemplate.Spec.Containers = make([]corev1.Container, 0)
}
overridePodSpecBytes, err := json.Marshal(cluster.Spec.PodTemplate.Spec)
if err != nil {
return fmt.Errorf("cannot marshal field podTemplate.spec to JSON: %w", err)
}
finalPodSpecBytes, err := strategicpatch.StrategicMergePatch(basePodSpecBytes, overridePodSpecBytes, &corev1.PodSpec{})
if err != nil {
return fmt.Errorf("cannot patch base pod spec with podTemplate.spec: %w", err)
}
finalPodSpec := corev1.PodSpec{}
err = json.Unmarshal(finalPodSpecBytes, &finalPodSpec)
finalPodSpec, err := k8sutils.StrategicMerge(basePodSpec, cluster.Spec.PodTemplate.Spec)
if err != nil {
return fmt.Errorf("cannot unmarshal finalized podspec from JSON: %w", err)
return fmt.Errorf("cannot strategic-merge base podspec with podTemplate.spec: %w", err)
}

statefulSet := &appsv1.StatefulSet{
Expand Down
32 changes: 32 additions & 0 deletions internal/k8sutils/strategicmerge.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package k8sutils

import (
"encoding/json"
"fmt"

"k8s.io/apimachinery/pkg/util/strategicpatch"
)

func StrategicMerge[K any](base, patch K) (merged K, err error) {
baseBytes, err := json.Marshal(base)
if err != nil {
return merged, fmt.Errorf("cannot marshal base object to JSON: %w", err)
}

patchBytes, err := json.Marshal(patch)
if err != nil {
return merged, fmt.Errorf("cannot marshal patch object to JSON: %w", err)
}

mergedBytes, err := strategicpatch.StrategicMergePatch(baseBytes, patchBytes, &merged)
if err != nil {
return merged, fmt.Errorf("cannot patch base pod spec with podTemplate.spec: %w", err)
}

err = json.Unmarshal(mergedBytes, &merged)
if err != nil {
return merged, fmt.Errorf("cannot unmarshal merged object from JSON: %w", err)
}

return merged, nil
}
19 changes: 19 additions & 0 deletions internal/k8sutils/strategicmerge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package k8sutils

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
)

var _ = Describe("StrategicMerge handler", func() {
When("Merging two podspecs", func() {
It("Should merge two empty podspecs into an empty podspec", func() {
p1 := corev1.PodSpec{}
p2 := corev1.PodSpec{}
p, err := StrategicMerge(p1, p2)
Expect(err).NotTo(HaveOccurred())
Expect(p).To(Equal(p1))
})
})
})
13 changes: 13 additions & 0 deletions internal/k8sutils/suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package k8sutils

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestK8SUtils(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "K8SUtils Suite")
}

0 comments on commit fbe5ebf

Please sign in to comment.