github.com/kubewharf/katalyst-core@v0.5.3/pkg/client/control/node.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package control 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 24 core "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/types" 27 "k8s.io/apimachinery/pkg/util/strategicpatch" 28 "k8s.io/client-go/kubernetes" 29 30 "github.com/kubewharf/katalyst-core/pkg/util/general" 31 ) 32 33 // NodeUpdater is used to update Node 34 type NodeUpdater interface { 35 PatchNode(ctx context.Context, oldNode, newNode *core.Node) error 36 PatchNodeStatus(ctx context.Context, oldNode, newNode *core.Node) error 37 UpdateNode(ctx context.Context, node *core.Node, opts metav1.UpdateOptions) (*core.Node, error) 38 } 39 40 type DummyNodeUpdater struct{} 41 42 func (d *DummyNodeUpdater) UpdateNode(_ context.Context, _ *core.Node, _ metav1.UpdateOptions) (*core.Node, error) { 43 return nil, nil 44 } 45 46 func (d *DummyNodeUpdater) PatchNode(_ context.Context, _, _ *core.Node) error { 47 return nil 48 } 49 50 func (d *DummyNodeUpdater) PatchNodeStatus(_ context.Context, _, _ *core.Node) error { 51 return nil 52 } 53 54 type RealNodeUpdater struct { 55 client kubernetes.Interface 56 } 57 58 func NewRealNodeUpdater(client kubernetes.Interface) *RealNodeUpdater { 59 return &RealNodeUpdater{ 60 client: client, 61 } 62 } 63 64 func (r *RealNodeUpdater) UpdateNode(ctx context.Context, node *core.Node, opts metav1.UpdateOptions) (*core.Node, error) { 65 if node == nil { 66 return nil, fmt.Errorf("can't update a nil node") 67 } 68 69 return r.client.CoreV1().Nodes().Update(ctx, node, opts) 70 } 71 72 func (r *RealNodeUpdater) PatchNode(ctx context.Context, oldNode, newNode *core.Node) error { 73 if oldNode == nil || newNode == nil { 74 return fmt.Errorf("can't update a nil node") 75 } 76 77 oldData, err := json.Marshal(oldNode) 78 if err != nil { 79 return err 80 } 81 82 newData, err := json.Marshal(newNode) 83 if err != nil { 84 return err 85 } 86 87 patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, &core.Node{}) 88 if err != nil { 89 return fmt.Errorf("failed to create merge patch for node%q: %v", oldNode.Name, err) 90 } 91 if general.JsonPathEmpty(patchBytes) { 92 return nil 93 } 94 95 _, err = r.client.CoreV1().Nodes().Patch(ctx, oldNode.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}) 96 return err 97 } 98 99 func (r *RealNodeUpdater) PatchNodeStatus(ctx context.Context, oldNode, newNode *core.Node) error { 100 if oldNode == nil || newNode == nil { 101 return fmt.Errorf("can't update a nil node") 102 } 103 104 oldData, err := json.Marshal(oldNode) 105 if err != nil { 106 return err 107 } 108 109 newData, err := json.Marshal(newNode) 110 if err != nil { 111 return err 112 } 113 114 patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, &core.Node{}) 115 if err != nil { 116 return fmt.Errorf("failed to create merge patch for node%q: %v", oldNode.Name, err) 117 } 118 if general.JsonPathEmpty(patchBytes) { 119 return nil 120 } 121 122 _, err = r.client.CoreV1().Nodes().Patch(ctx, oldNode.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status") 123 return err 124 }