Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Argo Cd
Commits
9c0daebf
Unverified
Commit
9c0daebf
authored
6 years ago
by
Jesse Suen
Browse files
Options
Download
Email Patches
Plain Diff
Fix diff falsely reporting OutOfSync due to namespace/annotation defaulting
parent
f2a0ca56
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
util/diff/diff.go
+17
-0
util/diff/diff.go
util/diff/diff_test.go
+79
-6
util/diff/diff_test.go
with
96 additions
and
6 deletions
+96
-6
util/diff/diff.go
+
17
-
0
View file @
9c0daebf
...
...
@@ -56,6 +56,7 @@ func TwoWayDiff(config, live *unstructured.Unstructured) *DiffResult {
// ThreeWayDiff performs a diff with the understanding of how to incorporate the
// last-applied-configuration annotation in the diff.
func
ThreeWayDiff
(
orig
,
config
,
live
*
unstructured
.
Unstructured
)
*
DiffResult
{
orig
=
removeNamespaceAnnotation
(
orig
)
// remove extra fields in the live, that were not in the original object
liveObj
:=
RemoveMapFields
(
orig
.
Object
,
live
.
Object
)
// now we have a pruned live object
...
...
@@ -84,6 +85,22 @@ func ThreeWayDiff(orig, config, live *unstructured.Unstructured) *DiffResult {
return
&
dr
}
func
removeNamespaceAnnotation
(
orig
*
unstructured
.
Unstructured
)
*
unstructured
.
Unstructured
{
orig
=
orig
.
DeepCopy
()
// remove the namespace an annotation from the
if
metadataIf
,
ok
:=
orig
.
Object
[
"metadata"
];
ok
{
metadata
:=
metadataIf
.
(
map
[
string
]
interface
{})
delete
(
metadata
,
"namespace"
)
if
annotationsIf
,
ok
:=
metadata
[
"annotations"
];
ok
{
annotation
:=
annotationsIf
.
(
map
[
string
]
interface
{})
if
len
(
annotation
)
==
0
{
delete
(
metadata
,
"annotations"
)
}
}
}
return
orig
}
func
threeWayMergePatch
(
orig
,
config
,
live
*
unstructured
.
Unstructured
)
([]
byte
,
error
)
{
origBytes
,
err
:=
json
.
Marshal
(
orig
.
Object
)
if
err
!=
nil
{
...
...
This diff is collapsed.
Click to expand it.
util/diff/diff_test.go
+
79
-
6
View file @
9c0daebf
...
...
@@ -15,12 +15,23 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
var
(
formatOpts
=
formatter
.
AsciiFormatterConfig
{
Coloring
:
terminal
.
IsTerminal
(
int
(
os
.
Stdout
.
Fd
())),
}
)
func
TestDiff
(
t
*
testing
.
T
)
{
leftDep
:=
test
.
DemoDeployment
()
leftUn
:=
kube
.
MustToUnstructured
(
leftDep
)
diffRes
:=
Diff
(
leftUn
,
leftUn
)
assert
.
False
(
t
,
diffRes
.
Diff
.
Modified
())
ascii
,
err
:=
diffRes
.
ASCIIFormat
(
leftUn
,
formatOpts
)
assert
.
Nil
(
t
,
err
)
if
ascii
!=
""
{
log
.
Println
(
ascii
)
}
}
func
TestDiffWithNils
(
t
*
testing
.
T
)
{
...
...
@@ -86,6 +97,7 @@ func TestDiffArrayModification(t *testing.T) {
func
TestThreeWayDiff
(
t
*
testing
.
T
)
{
// 1. get config and live to be the same. Both have a foo annotation.
configDep
:=
test
.
DemoDeployment
()
configDep
.
ObjectMeta
.
Namespace
=
""
configDep
.
Annotations
=
map
[
string
]
string
{
"foo"
:
"bar"
,
}
...
...
@@ -93,11 +105,15 @@ func TestThreeWayDiff(t *testing.T) {
// 2. add a extra field to the live. this simulates kubernetes adding default values in the
// object. We should not consider defaulted values as a difference
liveDep
.
Annotations
[
"some-default-val"
]
=
"default"
liveDep
.
SetNamespace
(
"default"
)
configUn
:=
kube
.
MustToUnstructured
(
configDep
)
liveUn
:=
kube
.
MustToUnstructured
(
liveDep
)
res
:=
Diff
(
configUn
,
liveUn
)
assert
.
False
(
t
,
res
.
Modified
)
if
!
assert
.
False
(
t
,
res
.
Modified
)
{
ascii
,
err
:=
res
.
ASCIIFormat
(
configUn
,
formatOpts
)
assert
.
Nil
(
t
,
err
)
log
.
Println
(
ascii
)
}
// 3. Add a last-applied-configuration annotation in the live. There should still not be any
// difference
...
...
@@ -107,7 +123,11 @@ func TestThreeWayDiff(t *testing.T) {
configUn
=
kube
.
MustToUnstructured
(
configDep
)
liveUn
=
kube
.
MustToUnstructured
(
liveDep
)
res
=
Diff
(
configUn
,
liveUn
)
assert
.
False
(
t
,
res
.
Modified
)
if
!
assert
.
False
(
t
,
res
.
Modified
)
{
ascii
,
err
:=
res
.
ASCIIFormat
(
configUn
,
formatOpts
)
assert
.
Nil
(
t
,
err
)
log
.
Println
(
ascii
)
}
// 4. Remove the foo annotation from config and perform the diff again. We should detect a
// difference since three-way diff detects the removal of a managed field
...
...
@@ -125,9 +145,6 @@ func TestThreeWayDiff(t *testing.T) {
configUn
=
kube
.
MustToUnstructured
(
configDep
)
liveUn
=
kube
.
MustToUnstructured
(
liveDep
)
res
=
Diff
(
configUn
,
liveUn
)
formatOpts
:=
formatter
.
AsciiFormatterConfig
{
Coloring
:
terminal
.
IsTerminal
(
int
(
os
.
Stdout
.
Fd
())),
}
ascii
,
err
:=
res
.
ASCIIFormat
(
configUn
,
formatOpts
)
assert
.
Nil
(
t
,
err
)
if
ascii
!=
""
{
...
...
@@ -135,3 +152,59 @@ func TestThreeWayDiff(t *testing.T) {
}
assert
.
False
(
t
,
res
.
Modified
)
}
var
demoConfig
=
`
{
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": {
"labels": {
"applications.argoproj.io/app-name": "argocd-demo"
},
"name": "application-controller"
}
}
`
var
demoLive
=
`
{
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": {
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"annotations\":{},\"labels\":{\"applications.argoproj.io/app-name\":\"argocd-demo\"},\"name\":\"application-controller\",\"namespace\":\"argocd-demo\"}}\n"
},
"creationTimestamp": "2018-04-16T22:08:57Z",
"labels": {
"applications.argoproj.io/app-name": "argocd-demo"
},
"name": "application-controller",
"namespace": "argocd-demo",
"resourceVersion": "7584502",
"selfLink": "/api/v1/namespaces/argocd-demo/serviceaccounts/application-controller",
"uid": "c22bb2b4-41c2-11e8-978a-028445d52ec8"
},
"secrets": [
{
"name": "application-controller-token-kfxct"
}
]
}
`
// Tests a real world example
func
TestDiffActualExample
(
t
*
testing
.
T
)
{
var
configUn
,
liveUn
unstructured
.
Unstructured
err
:=
json
.
Unmarshal
([]
byte
(
demoConfig
),
&
configUn
.
Object
)
assert
.
Nil
(
t
,
err
)
err
=
json
.
Unmarshal
([]
byte
(
demoLive
),
&
liveUn
.
Object
)
assert
.
Nil
(
t
,
err
)
dr
:=
Diff
(
&
configUn
,
&
liveUn
)
assert
.
False
(
t
,
dr
.
Modified
)
ascii
,
err
:=
dr
.
ASCIIFormat
(
&
configUn
,
formatOpts
)
assert
.
Nil
(
t
,
err
)
if
ascii
!=
""
{
log
.
Println
(
ascii
)
}
}
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment