github.phpd.cn/cilium/cilium@v1.6.12/pkg/k8s/annotate.go (about) 1 // Copyright 2016-2019 Authors of Cilium 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 k8s 16 17 import ( 18 "context" 19 "encoding/json" 20 "fmt" 21 "net" 22 23 "github.com/cilium/cilium/pkg/annotation" 24 "github.com/cilium/cilium/pkg/cidr" 25 "github.com/cilium/cilium/pkg/controller" 26 clientset "github.com/cilium/cilium/pkg/k8s/client/clientset/versioned" 27 "github.com/cilium/cilium/pkg/logging/logfields" 28 29 "github.com/sirupsen/logrus" 30 "k8s.io/apimachinery/pkg/types" 31 "k8s.io/client-go/kubernetes" 32 ) 33 34 // K8sClient is a wrapper around kubernetes.Interface. 35 type K8sClient struct { 36 // kubernetes.Interface is the object through which interactions with 37 // Kubernetes are performed. 38 kubernetes.Interface 39 } 40 41 // K8sCiliumClient is a wrapper around clientset.Interface. 42 type K8sCiliumClient struct { 43 clientset.Interface 44 } 45 46 func updateNodeAnnotation(c kubernetes.Interface, nodeName string, v4CIDR, v6CIDR *cidr.CIDR, v4HealthIP, v6HealthIP, v4CiliumHostIP, v6CiliumHostIP net.IP) error { 47 annotations := map[string]string{} 48 49 if v4CIDR != nil { 50 annotations[annotation.V4CIDRName] = v4CIDR.String() 51 } 52 if v6CIDR != nil { 53 annotations[annotation.V6CIDRName] = v6CIDR.String() 54 } 55 56 if v4HealthIP != nil { 57 annotations[annotation.V4HealthName] = v4HealthIP.String() 58 } 59 if v6HealthIP != nil { 60 annotations[annotation.V6HealthName] = v6HealthIP.String() 61 } 62 63 if v4CiliumHostIP != nil { 64 annotations[annotation.CiliumHostIP] = v4CiliumHostIP.String() 65 } 66 67 if v6CiliumHostIP != nil { 68 annotations[annotation.CiliumHostIPv6] = v6CiliumHostIP.String() 69 } 70 71 if len(annotations) == 0 { 72 return nil 73 } 74 75 raw, err := json.Marshal(annotations) 76 if err != nil { 77 return err 78 } 79 patch := []byte(fmt.Sprintf(`{"metadata":{"annotations":%s}}`, raw)) 80 81 _, err = c.CoreV1().Nodes().Patch(nodeName, types.StrategicMergePatchType, patch) 82 83 return err 84 } 85 86 // AnnotateNode writes v4 and v6 CIDRs and health IPs in the given k8s node name. 87 // In case of failure while updating the node, this function while spawn a go 88 // routine to retry the node update indefinitely. 89 func (k8sCli K8sClient) AnnotateNode(nodeName string, v4CIDR, v6CIDR *cidr.CIDR, v4HealthIP, v6HealthIP, v4CiliumHostIP, v6CiliumHostIP net.IP) error { 90 scopedLog := log.WithFields(logrus.Fields{ 91 logfields.NodeName: nodeName, 92 logfields.V4Prefix: v4CIDR, 93 logfields.V6Prefix: v6CIDR, 94 logfields.V4HealthIP: v4HealthIP, 95 logfields.V6HealthIP: v6HealthIP, 96 logfields.V4CiliumHostIP: v4CiliumHostIP, 97 logfields.V6CiliumHostIP: v6CiliumHostIP, 98 }) 99 scopedLog.Debug("Updating node annotations with node CIDRs") 100 101 controller.NewManager().UpdateController("update-k8s-node-annotations", 102 controller.ControllerParams{ 103 DoFunc: func(_ context.Context) error { 104 err := updateNodeAnnotation(k8sCli, nodeName, v4CIDR, v6CIDR, v4HealthIP, v6HealthIP, v4CiliumHostIP, v6CiliumHostIP) 105 if err != nil { 106 scopedLog.WithFields(logrus.Fields{}).WithError(err).Warn("Unable to patch node resource with annotation") 107 } 108 return err 109 }, 110 }) 111 112 return nil 113 }