Skip to content

[helm-operator] Fix reconciliation of resources with jsonpatch #2777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
- The command `operator-sdk generate k8s` no longer requires users to explicitly set GOROOT in their environment. Now, GOROOT is detected using `go env GOROOT` and set automatically. ([#2754](https://github.com/operator-framework/operator-sdk/pull/2754))
- `operator-sdk generate csv` and `operator-sdk test local` now parse multi-manifest files correctly. ([#2758](https://github.com/operator-framework/operator-sdk/pull/2758))
- Fixed CRD validation generation issue with `status.Conditions`. ([#2739](https://github.com/operator-framework/operator-sdk/pull/2739))
- Fix issue faced in the reconciliation when arrays are used in the config YAML files for Helm based-operators. ([#2777](https://github.com/operator-framework/operator-sdk/pull/2777))

## v0.16.0

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ require (
github.com/jmoiron/sqlx v1.2.0 // indirect
github.com/markbates/inflect v1.0.4
github.com/martinlindhe/base36 v1.0.0
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a
github.com/mattn/go-isatty v0.0.12
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.1.2
Expand All @@ -40,6 +39,7 @@ require (
github.com/ziutek/mymysql v1.5.4 // indirect
go.uber.org/zap v1.14.1
golang.org/x/tools v0.0.0-20200327195553-82bb89366a1e
gomodules.xyz/jsonpatch/v3 v3.0.1
gopkg.in/gorp.v1 v1.7.2 // indirect
gopkg.in/yaml.v2 v2.2.8
helm.sh/helm/v3 v3.1.2
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,6 @@ github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzfe
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/martinlindhe/base36 v1.0.0 h1:eYsumTah144C0A8P1T/AVSUk5ZoLnhfYFM3OGQxB52A=
github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a h1:+J2gw7Bw77w/fbK7wnNJJDKmw1IbWft2Ul5BzrG1Qm8=
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
Expand Down Expand Up @@ -1206,6 +1204,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v3 v3.0.1 h1:Te7hKxV52TKCbNYq3t84tzKav3xhThdvSsSp/W89IyI=
gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto=
gomodules.xyz/orderedmap v0.1.0 h1:fM/+TGh/O1KkqGR5xjTKg6bU8OKBkg7p0Y+x/J9m8Os=
gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
Expand Down
5 changes: 3 additions & 2 deletions pkg/helm/release/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"strings"

"gomodules.xyz/jsonpatch/v3"
"helm.sh/helm/v3/pkg/action"
cpb "helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/kube"
Expand All @@ -35,7 +36,6 @@ import (
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/rest"

"github.com/mattbaird/jsonpatch"
"github.com/operator-framework/operator-sdk/pkg/helm/internal/types"
)

Expand Down Expand Up @@ -275,9 +275,10 @@ func generatePatch(existing, expected runtime.Object) ([]byte, error) {
// fields added by Kubernetes or by the user after the existing release
// resource has been applied. The goal for this patch is to make sure that
// the fields managed by the Helm chart are applied.
// All "add" operations without a value (null) can be ignored
patchOps := make([]jsonpatch.JsonPatchOperation, 0)
for _, op := range ops {
if op.Operation != "remove" {
if op.Operation != "remove" && !(op.Operation == "add" && op.Value == nil) {
Copy link
Contributor

@camilamacedo86 camilamacedo86 Apr 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 now it shows ok

patchOps = append(patchOps, op)
}
}
Expand Down
140 changes: 140 additions & 0 deletions pkg/helm/release/manager_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
// Copyright 2018 The Operator-SDK Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package release

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

func newTestDeployment(containers []interface{}) *unstructured.Unstructured {
return &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": "Deployment",
"apiVersion": "apps/v1",
"metadata": map[string]interface{}{
"name": "test",
"namespace": "ns",
},
"spec": map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"containers": containers,
},
},
},
},
}
}

func TestManagerGeneratePatch(t *testing.T) {

tests := []struct {
o1 *unstructured.Unstructured
o2 *unstructured.Unstructured
patch []map[string]interface{}
}{
{
o1: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
},
map[string]interface{}{
"name": "test2",
},
}),
o2: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
},
}),
patch: []map[string]interface{}{},
},
{
o1: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
},
}),
o2: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
},
map[string]interface{}{
"name": "test2",
},
}),
patch: []map[string]interface{}{
{
"op": "add",
"path": "/spec/template/spec/containers/1",
"value": map[string]interface{}{
"name": string("test2"),
},
},
},
},
{
o1: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
},
}),
o2: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
"test": nil,
},
}),
patch: []map[string]interface{}{},
},
{
o1: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test1",
},
}),
o2: newTestDeployment([]interface{}{
map[string]interface{}{
"name": "test2",
},
}),
patch: []map[string]interface{}{
{
"op": "replace",
"path": "/spec/template/spec/containers/0/name",
"value": "test2",
},
},
},
}

for _, test := range tests {
diff, err := generatePatch(test.o1, test.o2)
assert.NoError(t, err)

if len(test.patch) == 0 {
assert.Equal(t, 0, len(test.patch))
} else {
x := []map[string]interface{}{}
err = json.Unmarshal(diff, &x)
assert.NoError(t, err)
assert.Equal(t, test.patch, x)
}
}
}
3 changes: 2 additions & 1 deletion test/test-framework/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,6 @@ github.com/markbates/inflect v1.0.4 h1:5fh1gzTFhfae06u3hzHYO9xe3l3v3nW5Pwt3naLTP
github.com/markbates/inflect v1.0.4/go.mod h1:1fR9+pO2KHEO9ZRtto13gDwwZaAKstQzferVeWqbgNs=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/martinlindhe/base36 v1.0.0/go.mod h1:+AtEs8xrBpCeYgSLoY/aJ6Wf37jtBuR0s35750M27+8=
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
Expand Down Expand Up @@ -1086,6 +1085,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IV
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v3 v3.0.1/go.mod h1:CBhndykehEwTOlEfnsfJwvkFQbSN8YZFr9M+cIHAJto=
gomodules.xyz/orderedmap v0.1.0/go.mod h1:g9/TPUCm1t2gwD3j3zfV8uylyYhVdCNSi+xCEIu7yTU=
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
Expand Down