From 01cabb7a51445fe9a87db0050a79774302ed9142 Mon Sep 17 00:00:00 2001 From: Jahvon Dockery Date: Fri, 8 Oct 2021 12:01:41 -0400 Subject: [PATCH 1/5] Add merge function for cluster snapshot --- pkg/resource/snapshot.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/resource/snapshot.go b/pkg/resource/snapshot.go index 4f6220dc5..4747580b2 100644 --- a/pkg/resource/snapshot.go +++ b/pkg/resource/snapshot.go @@ -71,6 +71,20 @@ func (s Snapshot) Clone(selectors ...GVKSelectorFunc) Snapshot { return clone } +func (s Snapshot) Merge(toMerge Snapshot) Snapshot { + merged := s.Clone() + for gvk, objectsMap := range toMerge { + if _, ok := s[gvk]; ok { + for name, object := range objectsMap { + s[gvk][name] = object + } + } else { + s[gvk] = objectsMap + } + } + return merged +} + // ClusterSnapshot represents a set of snapshots partitioned by cluster type ClusterSnapshot map[string]Snapshot @@ -128,3 +142,15 @@ func (cs ClusterSnapshot) Clone(selectors ...GVKSelectorFunc) ClusterSnapshot { } return clone } + +func (cs ClusterSnapshot) Merge(toMerge ClusterSnapshot) ClusterSnapshot { + merged := cs.Clone() + for cluster, snapshot := range toMerge { + if leftSnap, ok := cs[cluster]; ok { + cs[cluster] = leftSnap.Merge(snapshot) + } else { + cs[cluster] = snapshot + } + } + return merged +} From 8953e628d06d166d2e6fd69cb3cdd7ac1f0799a9 Mon Sep 17 00:00:00 2001 From: Jahvon Dockery Date: Fri, 8 Oct 2021 14:39:24 -0400 Subject: [PATCH 2/5] changelog and test --- changelog/v0.20.1/add-merge-function.yaml | 4 ++ pkg/resource/snapshot.go | 8 ++-- pkg/resource/snapshot_test.go | 49 +++++++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 changelog/v0.20.1/add-merge-function.yaml diff --git a/changelog/v0.20.1/add-merge-function.yaml b/changelog/v0.20.1/add-merge-function.yaml new file mode 100644 index 000000000..ec26eea35 --- /dev/null +++ b/changelog/v0.20.1/add-merge-function.yaml @@ -0,0 +1,4 @@ +changelog: + - type: NEW_FEATURE + description: Adds a `Merge` function to Snapshot and ClusterSnapshot so that two snapshots can be merged. + issueLink: https://github.com/solo-io/skv2/issues/302 diff --git a/pkg/resource/snapshot.go b/pkg/resource/snapshot.go index 4747580b2..426d058c7 100644 --- a/pkg/resource/snapshot.go +++ b/pkg/resource/snapshot.go @@ -76,10 +76,10 @@ func (s Snapshot) Merge(toMerge Snapshot) Snapshot { for gvk, objectsMap := range toMerge { if _, ok := s[gvk]; ok { for name, object := range objectsMap { - s[gvk][name] = object + merged[gvk][name] = object } } else { - s[gvk] = objectsMap + merged[gvk] = objectsMap } } return merged @@ -147,9 +147,9 @@ func (cs ClusterSnapshot) Merge(toMerge ClusterSnapshot) ClusterSnapshot { merged := cs.Clone() for cluster, snapshot := range toMerge { if leftSnap, ok := cs[cluster]; ok { - cs[cluster] = leftSnap.Merge(snapshot) + merged[cluster] = leftSnap.Merge(snapshot) } else { - cs[cluster] = snapshot + merged[cluster] = snapshot } } return merged diff --git a/pkg/resource/snapshot_test.go b/pkg/resource/snapshot_test.go index 0fa5276e4..767f0b936 100644 --- a/pkg/resource/snapshot_test.go +++ b/pkg/resource/snapshot_test.go @@ -225,6 +225,55 @@ var _ = Describe("Snapshot", func() { Expect(controllerutils.ObjectsEqual(copiedPaint, paint)).To(BeFalse()) }) + It("will merge two snapshots properly", func() { + paint := &testv1.Paint{ + ObjectMeta: metav1.ObjectMeta{Name: "paint", Namespace: "x"}, + } + paintOverride := &testv1.Paint{ + ObjectMeta: metav1.ObjectMeta{Name: "override", Namespace: "x"}, + } + paint2 := &testv1.Paint{ + ObjectMeta: metav1.ObjectMeta{Name: "paint2", Namespace: "y"}, + } + name := types.NamespacedName{ + Namespace: "x", + Name: "paint", + } + name2 := types.NamespacedName{ + Namespace: "y", + Name: "paint2", + } + cluster1Name := "cluster1" + cluster2Name := "cluster2" + leftSnapshot := resource.ClusterSnapshot{ + cluster1Name: resource.Snapshot{ + testv1.PaintGVK: map[types.NamespacedName]resource.TypedObject{ + name: paint, + name2: paint2, + }, + }, + } + rightSnapshot := resource.ClusterSnapshot{ + cluster1Name: resource.Snapshot{ + testv1.PaintGVK: map[types.NamespacedName]resource.TypedObject{ + name: paintOverride, + }, + }, + cluster2Name: resource.Snapshot{ + testv1.PaintGVK: map[types.NamespacedName]resource.TypedObject{ + name: paint, + }, + }, + } + + snap := leftSnapshot.Merge(rightSnapshot) + Expect(snap[cluster1Name][testv1.PaintGVK][name].GetName()). + To(Equal(paintOverride.Name)) + Expect(snap[cluster1Name][testv1.PaintGVK][name2].GetName()). + To(Equal(paint2.Name)) + Expect(snap[cluster2Name][testv1.PaintGVK][name].GetName()). + To(Equal(paint.Name)) + }) }) }) From 7f1c6ca04675af0bcafdb9f83a6176416a3e71b3 Mon Sep 17 00:00:00 2001 From: Jahvon Dockery Date: Fri, 8 Oct 2021 15:03:07 -0400 Subject: [PATCH 3/5] comment and reword --- pkg/resource/snapshot.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/resource/snapshot.go b/pkg/resource/snapshot.go index 426d058c7..2e29d986e 100644 --- a/pkg/resource/snapshot.go +++ b/pkg/resource/snapshot.go @@ -74,8 +74,10 @@ func (s Snapshot) Clone(selectors ...GVKSelectorFunc) Snapshot { func (s Snapshot) Merge(toMerge Snapshot) Snapshot { merged := s.Clone() for gvk, objectsMap := range toMerge { - if _, ok := s[gvk]; ok { + if _, ok := merged[gvk]; ok { for name, object := range objectsMap { + // If there is already an object specified here, the object from toMerge + // will replace it merged[gvk][name] = object } } else { @@ -146,8 +148,8 @@ func (cs ClusterSnapshot) Clone(selectors ...GVKSelectorFunc) ClusterSnapshot { func (cs ClusterSnapshot) Merge(toMerge ClusterSnapshot) ClusterSnapshot { merged := cs.Clone() for cluster, snapshot := range toMerge { - if leftSnap, ok := cs[cluster]; ok { - merged[cluster] = leftSnap.Merge(snapshot) + if baseSnap, ok := merged[cluster]; ok { + merged[cluster] = baseSnap.Merge(snapshot) } else { merged[cluster] = snapshot } From a0f132db508a47cfe25f60e21df2f06d2ac73d00 Mon Sep 17 00:00:00 2001 From: Jahvon Dockery Date: Mon, 11 Oct 2021 09:51:37 -0400 Subject: [PATCH 4/5] comment: --- pkg/resource/snapshot.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/resource/snapshot.go b/pkg/resource/snapshot.go index 2e29d986e..f7566c641 100644 --- a/pkg/resource/snapshot.go +++ b/pkg/resource/snapshot.go @@ -71,6 +71,9 @@ func (s Snapshot) Clone(selectors ...GVKSelectorFunc) Snapshot { return clone } +// Merges the Snapshot with a Snapshot passed in as an argument. The values +// in the passed in Snapshot will take precedence when there is an object mapped +// to the same gvk and name in both Snapshots. func (s Snapshot) Merge(toMerge Snapshot) Snapshot { merged := s.Clone() for gvk, objectsMap := range toMerge { @@ -145,6 +148,10 @@ func (cs ClusterSnapshot) Clone(selectors ...GVKSelectorFunc) ClusterSnapshot { return clone } +// Merges the ClusterSnapshot with a ClusterSnapshot passed in as an argument. +// If a cluster exists in both ClusterSnapshots, then both Snapshots for the +// cluster is merged; with the passed in ClusterSnapshot's corresponding Snapshot +// taking precedence in case of conflicts. func (cs ClusterSnapshot) Merge(toMerge ClusterSnapshot) ClusterSnapshot { merged := cs.Clone() for cluster, snapshot := range toMerge { From 0061dfa3b6e9b88161c3ae8da27cfed4fe724ea8 Mon Sep 17 00:00:00 2001 From: Jahvon Dockery Date: Mon, 11 Oct 2021 11:09:07 -0400 Subject: [PATCH 5/5] update changelog --- changelog/{v0.20.1 => v0.21.1}/add-merge-function.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename changelog/{v0.20.1 => v0.21.1}/add-merge-function.yaml (100%) diff --git a/changelog/v0.20.1/add-merge-function.yaml b/changelog/v0.21.1/add-merge-function.yaml similarity index 100% rename from changelog/v0.20.1/add-merge-function.yaml rename to changelog/v0.21.1/add-merge-function.yaml