Skip to content

Commit 05eaa05

Browse files
authored
Refactor reconciler.patchResource() to handle both Spec and Status patching (#31)
* Refactored `reconciler.patchResource` to patch both spec and status * Added two separate methods patchResourceMetadataAndSpec , patchResourceStatus for granular patching * Added new unit tests This is a precursor change for server-side-defaults implementation. aws-controllers-k8s/community#812 ``` vijat@u872f1b87e2dc5e:~/go/src/github.com/aws-controllers-k8s/runtime$ make test building mocks for pkg/types ... ok. building mocks for k8s.io/apimachinery/pkg/apis/meta/v1 ... ok. building mocks for k8s.io/apimachinery/runtime ... ok. building mocks for k8s.io/apimachinery/runtime/schema ... ok. building mocks for sigs.k8s.io/controller-runtime/pkg/client ... ok. go test ./... ? github.com/aws-controllers-k8s/runtime/apis/core/v1alpha1 [no test files] ? github.com/aws-controllers-k8s/runtime/mocks/apimachinery/pkg/apis/meta/v1 [no test files] ? github.com/aws-controllers-k8s/runtime/mocks/apimachinery/pkg/runtime [no test files] ? github.com/aws-controllers-k8s/runtime/mocks/apimachinery/pkg/runtime/schema [no test files] ? github.com/aws-controllers-k8s/runtime/mocks/controller-runtime/pkg/client [no test files] ? github.com/aws-controllers-k8s/runtime/mocks/pkg/types [no test files] ok github.com/aws-controllers-k8s/runtime/pkg/compare (cached) ok github.com/aws-controllers-k8s/runtime/pkg/condition (cached) ? github.com/aws-controllers-k8s/runtime/pkg/config [no test files] ? github.com/aws-controllers-k8s/runtime/pkg/errors [no test files] ? github.com/aws-controllers-k8s/runtime/pkg/metrics [no test files] ok github.com/aws-controllers-k8s/runtime/pkg/requeue (cached) ok github.com/aws-controllers-k8s/runtime/pkg/runtime 0.020s ok github.com/aws-controllers-k8s/runtime/pkg/runtime/cache (cached) ? github.com/aws-controllers-k8s/runtime/pkg/runtime/log [no test files] ? github.com/aws-controllers-k8s/runtime/pkg/types [no test files] ok github.com/aws-controllers-k8s/runtime/pkg/util (cached) ? github.com/aws-controllers-k8s/runtime/pkg/webhook [no test files] ``` ``` 2021-07-15T22:23:28.022Z DEBUG ackrt > r.Sync {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generation": 1, � � 2021-07-15T22:23:28.022Z DEBUG ackrt >> rm.ReadOne {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generation � � 2021-07-15T22:23:28.022Z DEBUG ackrt >>> rm.sdkFind {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generatio � � 2021-07-15T22:23:28.427Z DEBUG ackrt <<< rm.sdkFind {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generatio � � 2021-07-15T22:23:28.427Z DEBUG ackrt << rm.ReadOne {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generation � � 2021-07-15T22:23:28.427Z DEBUG ackrt >> r.setResourceManaged {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", " � � 2021-07-15T22:23:28.427Z DEBUG ackrt >>> kc.Patch (metadata + spec) {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo � � 2021-07-15T22:23:28.430Z DEBUG ackrt <<< kc.Patch (metadata + spec) {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo � � 2021-07-15T22:23:28.430Z DEBUG ackrt marked resource as managed {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417" � � 2021-07-15T22:23:28.430Z DEBUG ackrt << r.setResourceManaged {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", " � � 2021-07-15T22:23:28.430Z DEBUG ackrt >> rm.Create {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generation" � � 2021-07-15T22:23:28.430Z DEBUG ackrt >>> rm.sdkCreate {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generat � � 2021-07-15T22:23:29.167Z DEBUG ackrt <<< rm.sdkCreate {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generat � � 2021-07-15T22:23:29.167Z DEBUG ackrt << rm.Create {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generation" � � 2021-07-15T22:23:29.167Z INFO ackrt created new resource {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "gene � � 2021-07-15T22:23:29.167Z DEBUG ackrt >> r.patchResourceMetadataAndSpec {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pz � � 2021-07-15T22:23:29.167Z DEBUG ackrt No difference found between metadata & spec for desired and latest object. {"kind": "Bucket", "namespace � � 2021-07-15T22:23:29.167Z DEBUG ackrt << r.patchResourceMetadataAndSpec {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pz � � 2021-07-15T22:23:29.167Z DEBUG ackrt >> r.patchResourceStatus {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", � � 2021-07-15T22:23:29.167Z DEBUG ackrt >>> kc.Patch (status) {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "ge � � 2021-07-15T22:23:29.170Z DEBUG ackrt <<< kc.Patch (status) {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "ge � � 2021-07-15T22:23:29.170Z DEBUG ackrt patched resource status {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", " � � 2021-07-15T22:23:29.170Z DEBUG ackrt << r.patchResourceStatus {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", � � 2021-07-15T22:23:29.170Z DEBUG ackrt < r.Sync {"kind": "Bucket", "namespace": "default", "name": "s3-bucket-ku7fb4pzamo417", "generation": 1, ```
1 parent 5f0499c commit 05eaa05

File tree

12 files changed

+1087
-33
lines changed

12 files changed

+1087
-33
lines changed

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ GOPATH ?= "$(HOME)/go"
44
GO111MODULE=on
55
K8S_APIMACHINERY_VERSION = $(shell go list -m -f '{{ .Version }}' k8s.io/apimachinery)
66
K8S_APIMACHINERY_DIR = "$(GOPATH)/pkg/mod/k8s.io/apimachinery@$(K8S_APIMACHINERY_VERSION)"
7-
7+
CONTROLLER_RUNTIME_VERSION = $(shell go list -m -f '{{ .Version }}' sigs.k8s.io/controller-runtime)
8+
CONTROLLER_RUNTIME_DIR = "$(GOPATH)/pkg/mod/sigs.k8s.io/controller-runtime@$(CONTROLLER_RUNTIME_VERSION)"
89
.PHONY: all test clean-mocks mocks
910

1011
all: test
@@ -31,6 +32,9 @@ mocks: install-mockery ## Build mocks
3132
@echo -n "building mocks for k8s.io/apimachinery/runtime/schema ... "
3233
@bin/mockery --quiet --name=ObjectKind --case=underscore --output=mocks/apimachinery/pkg/runtime/schema --dir="$(K8S_APIMACHINERY_DIR)/pkg/runtime/schema"
3334
@echo "ok."
35+
@echo -n "building mocks for sigs.k8s.io/controller-runtime/pkg/client ... "
36+
@bin/mockery --quiet --name="(Client|Status)" --case=underscore --output=mocks/controller-runtime/pkg/client --dir="$(CONTROLLER_RUNTIME_DIR)/pkg/client"
37+
@echo "ok."
3438

3539
help: ## Show this help.
3640
@grep -F -h "##" $(MAKEFILE_LIST) | grep -F -v grep | sed -e 's/\\$$//' \

mocks/controller-runtime/pkg/client/client.go

Lines changed: 176 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/controller-runtime/pkg/client/status_client.go

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/controller-runtime/pkg/client/status_writer.go

Lines changed: 60 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/compare/map.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,16 @@ func MapStringStringPEqual(a, b map[string]*string) bool {
2525
}
2626
return true
2727
}
28+
29+
// MapStringStringEqual returns true if the supplied maps are equal
30+
func MapStringStringEqual(a, b map[string]string) bool {
31+
if len(a) != len(b) {
32+
return false
33+
}
34+
for aKey, aVal := range a {
35+
if bVal, ok := b[aKey]; !ok || bVal != aVal {
36+
return false
37+
}
38+
}
39+
return true
40+
}

pkg/compare/map_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,41 @@ func TestMapStringStringPEqual(t *testing.T) {
5555
require.True(compare.MapStringStringPEqual(ab, ba))
5656
require.True(compare.MapStringStringPEqual(ab, abc))
5757
}
58+
59+
func TestMapStringStringEqual(t *testing.T) {
60+
require := require.New(t)
61+
62+
aStr := "a"
63+
bStr := "b"
64+
65+
empty := map[string]string{}
66+
a := map[string]string{
67+
"a": aStr,
68+
}
69+
ac := map[string]string{
70+
"a": aStr,
71+
}
72+
b := map[string]string{
73+
"b": bStr,
74+
}
75+
ab := map[string]string{
76+
"a": aStr, "b": bStr,
77+
}
78+
abc := map[string]string{
79+
"a": aStr, "b": bStr,
80+
}
81+
ba := map[string]string{
82+
"b": bStr, "a": aStr,
83+
}
84+
85+
require.False(compare.MapStringStringEqual(a, empty))
86+
require.False(compare.MapStringStringEqual(empty, a))
87+
require.False(compare.MapStringStringEqual(a, nil))
88+
require.False(compare.MapStringStringEqual(nil, a))
89+
require.True(compare.MapStringStringEqual(nil, nil))
90+
require.False(compare.MapStringStringEqual(a, b))
91+
require.False(compare.MapStringStringEqual(b, a))
92+
require.True(compare.MapStringStringEqual(a, ac))
93+
require.True(compare.MapStringStringEqual(ab, ba))
94+
require.True(compare.MapStringStringEqual(ab, abc))
95+
}

pkg/compare/meta.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"). You may
4+
// not use this file except in compliance with the License. A copy of the
5+
// License is located at
6+
//
7+
// http://aws.amazon.com/apache2.0/
8+
//
9+
// or in the "license" file accompanying this file. This file is distributed
10+
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
// express or implied. See the License for the specific language governing
12+
// permissions and limitations under the License.
13+
14+
package compare
15+
16+
import (
17+
"encoding/json"
18+
19+
k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20+
)
21+
22+
// MetaV1ObjectEqual returns true if the supplied k8s.io/apimachinery/pkg/apis/meta/v1.Object
23+
// have equal values.
24+
func MetaV1ObjectEqual(a, b k8smetav1.Object) (bool, error) {
25+
// If both parameters are nil, return true
26+
if IsNil(a) && IsNil(b) {
27+
return true, nil
28+
}
29+
30+
// If only one parameter is nil, return false
31+
if HasNilDifference(a, b) {
32+
return false, nil
33+
}
34+
35+
// Marshall both objects and compare for equality
36+
aBytes, err := json.Marshal(a)
37+
if err != nil {
38+
return false, err
39+
}
40+
41+
bBytes, err := json.Marshal(b)
42+
if err != nil {
43+
return false, err
44+
}
45+
46+
return string(aBytes) == string(bBytes), nil
47+
}

0 commit comments

Comments
 (0)