Skip to content

Commit bbe717e

Browse files
committed
Add support for v1.Node
1 parent 28f87ca commit bbe717e

File tree

5 files changed

+119
-1
lines changed

5 files changed

+119
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Here at Banzai Cloud we love and write lots of Kubernetes [operators](https://gi
2626
- ServiceAccount
2727
- PodDisruptionBudget
2828
- Unstructured
29+
- Node
2930

3031
### How to use it
3132

integration_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,26 @@ func TestIntegration(t *testing.T) {
481481
Version: "v1",
482482
Resource: "serviceaccounts",
483483
}),
484+
NewTestMatch("node match",
485+
&v1.Node{
486+
ObjectMeta: standardObjectMeta(),
487+
Spec: v1.NodeSpec{
488+
PodCIDR: "10.0.0.0/24",
489+
},
490+
// ignore due to already removed field
491+
}).withIgnoreVersions([]string{"v1.10"}),
492+
NewTestDiff("node diff for podcidr",
493+
&v1.Node{
494+
ObjectMeta: standardObjectMeta(),
495+
Spec: v1.NodeSpec{
496+
PodCIDR: "10.0.0.0/24",
497+
},
498+
}).
499+
withLocalChange(func(i interface{}) {
500+
n := i.(*v1.Node)
501+
n.Spec.PodCIDR = "10.0.0.1/24"
502+
// ignore due to already removed field
503+
}).withIgnoreVersions([]string{"v1.10"}),
484504
}
485505
for _, test := range tests {
486506
serverVersion := os.Getenv("K8S_VERSION")
@@ -502,7 +522,11 @@ func TestIntegration(t *testing.T) {
502522
}
503523
err := testMatchOnObject(test)
504524
if err != nil {
505-
t.Errorf("Test '%s' failed: %s %s", test.name, err, emperror.Context(err))
525+
if *failonerror {
526+
t.Fatalf("Test '%s' failed: %s %s", test.name, err, emperror.Context(err))
527+
} else {
528+
t.Errorf("Test '%s' failed: %s %s", test.name, err, emperror.Context(err))
529+
}
506530
}
507531
}
508532
}

main_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var (
4848
kubeconfig = flag.String("kubeconfig", filepath.Join(homedir.HomeDir(), ".kube/config"), "kubernetes config to use for tests")
4949
kubecontext = flag.String("kubecontext", "", "kubernetes context to use in tests")
5050
keepnamespace = flag.Bool("keepnamespace", false, "keep the kubernetes namespace that was used for the tests")
51+
failonerror = flag.Bool("failonerror", false, "fail on error to be able to debug invalid state")
5152
testContext = &IntegrationTestContext{}
5253
)
5354

@@ -368,6 +369,17 @@ func testMatchOnObject(testItem *TestItem) error {
368369
log.Printf("Failed to remove object %s", existing.GetName())
369370
}
370371
}()
372+
case *v1.Node:
373+
existing, err = testContext.Client.CoreV1().Nodes().Create(newObject.(*v1.Node))
374+
if err != nil {
375+
return emperror.WrapWith(err, "failed to create object", "object", newObject)
376+
}
377+
defer func() {
378+
err = testContext.Client.CoreV1().Nodes().Delete(existing.GetName(), deleteOptions)
379+
if err != nil {
380+
log.Printf("Failed to remove object %s", existing.GetName())
381+
}
382+
}()
371383
}
372384

373385
if testItem.remoteChange != nil {

node.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright © 2019 Banzai Cloud
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package objectmatch
16+
17+
import (
18+
"encoding/json"
19+
20+
"github.com/goph/emperror"
21+
v1 "k8s.io/api/core/v1"
22+
kubernetescorev1 "k8s.io/kubernetes/pkg/apis/core/v1"
23+
)
24+
25+
type nodeMatcher struct {
26+
objectMatcher ObjectMatcher
27+
}
28+
29+
func NewNodeMatcher(objectMatcher ObjectMatcher) *nodeMatcher {
30+
return &nodeMatcher{
31+
objectMatcher: objectMatcher,
32+
}
33+
}
34+
35+
func (m nodeMatcher) Match(oldOrig, newOrig *v1.Node) (bool, error) {
36+
37+
old := oldOrig.DeepCopy()
38+
new := newOrig.DeepCopy()
39+
40+
kubernetescorev1.SetObjectDefaults_Node(new)
41+
42+
type Node struct {
43+
ObjectMeta
44+
Spec v1.NodeSpec
45+
}
46+
47+
oldData, err := json.Marshal(Node{
48+
ObjectMeta: m.objectMatcher.GetObjectMeta(old.ObjectMeta),
49+
Spec: old.Spec,
50+
})
51+
if err != nil {
52+
return false, emperror.WrapWith(err, "could not marshal old object", "name", old.Name)
53+
}
54+
55+
newObject := Node{
56+
ObjectMeta: m.objectMatcher.GetObjectMeta(new.ObjectMeta),
57+
Spec: new.Spec,
58+
}
59+
60+
newData, err := json.Marshal(newObject)
61+
if err != nil {
62+
return false, emperror.WrapWith(err, "could not marshal new object", "name", new.Name)
63+
}
64+
65+
matched, err := m.objectMatcher.MatchJSON(oldData, newData, newObject)
66+
if err != nil {
67+
return false, emperror.WrapWith(err, "could not match objects", "name", new.Name)
68+
}
69+
70+
return matched, nil
71+
}

objectmatch.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,16 @@ func (om *objectMatcher) Match(old, new interface{}) (bool, error) {
218218
return false, errors.WithStack(err)
219219
}
220220
return ok, nil
221+
case *corev1.Node:
222+
oldObject := old.(*corev1.Node)
223+
newObject := new.(*corev1.Node)
224+
225+
m := NewNodeMatcher(om)
226+
ok, err := m.Match(oldObject, newObject)
227+
if err != nil {
228+
return false, errors.WithStack(err)
229+
}
230+
return ok, nil
221231
}
222232
}
223233

0 commit comments

Comments
 (0)