istio
127 строк · 4.0 Кб
1/*
2Copyright 2017 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package k8sresourcelock
18
19import (
20"context"
21"encoding/json"
22"errors"
23"fmt"
24
25v1 "k8s.io/api/core/v1"
26metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
28)
29
30// TODO: This is almost a exact replica of Endpoints lock.
31// going forwards as we self host more and more components
32// and use ConfigMaps as the means to pass that configuration
33// data we will likely move to deprecate the Endpoints lock.
34
35type ConfigMapLock struct {
36// ConfigMapMeta should contain a Name and a Namespace of a
37// ConfigMapMeta object that the LeaderElector will attempt to lead.
38ConfigMapMeta metav1.ObjectMeta
39Client corev1client.ConfigMapsGetter
40LockConfig ResourceLockConfig
41cm *v1.ConfigMap
42}
43
44// Get returns the election record from a ConfigMap Annotation
45func (cml *ConfigMapLock) Get(ctx context.Context) (*LeaderElectionRecord, []byte, error) {
46var record LeaderElectionRecord
47var err error
48cml.cm, err = cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Get(ctx, cml.ConfigMapMeta.Name, metav1.GetOptions{})
49if err != nil {
50return nil, nil, err
51}
52if cml.cm.Annotations == nil {
53cml.cm.Annotations = make(map[string]string)
54}
55recordStr, found := cml.cm.Annotations[LeaderElectionRecordAnnotationKey]
56recordBytes := []byte(recordStr)
57if found {
58if err := json.Unmarshal(recordBytes, &record); err != nil {
59return nil, nil, err
60}
61}
62return &record, recordBytes, nil
63}
64
65// Create attempts to create a LeaderElectionRecord annotation
66func (cml *ConfigMapLock) Create(ctx context.Context, ler LeaderElectionRecord) error {
67recordBytes, err := json.Marshal(ler)
68if err != nil {
69return err
70}
71cml.cm, err = cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Create(ctx, &v1.ConfigMap{
72ObjectMeta: metav1.ObjectMeta{
73Name: cml.ConfigMapMeta.Name,
74Namespace: cml.ConfigMapMeta.Namespace,
75Annotations: map[string]string{
76LeaderElectionRecordAnnotationKey: string(recordBytes),
77},
78},
79}, metav1.CreateOptions{})
80return err
81}
82
83// Update will update an existing annotation on a given resource.
84func (cml *ConfigMapLock) Update(ctx context.Context, ler LeaderElectionRecord) error {
85if cml.cm == nil {
86return errors.New("configmap not initialized, call get or create first")
87}
88recordBytes, err := json.Marshal(ler)
89if err != nil {
90return err
91}
92if cml.cm.Annotations == nil {
93cml.cm.Annotations = make(map[string]string)
94}
95cml.cm.Annotations[LeaderElectionRecordAnnotationKey] = string(recordBytes)
96cm, err := cml.Client.ConfigMaps(cml.ConfigMapMeta.Namespace).Update(ctx, cml.cm, metav1.UpdateOptions{})
97if err != nil {
98return err
99}
100cml.cm = cm
101return nil
102}
103
104// RecordEvent in leader election while adding meta-data
105func (cml *ConfigMapLock) RecordEvent(s string) {
106if cml.LockConfig.EventRecorder == nil {
107return
108}
109events := fmt.Sprintf("%v %v", cml.LockConfig.Identity, s)
110cml.LockConfig.EventRecorder.Eventf(&v1.ConfigMap{ObjectMeta: cml.cm.ObjectMeta}, v1.EventTypeNormal, "LeaderElection", events)
111}
112
113// Describe is used to convert details on current resource lock
114// into a string
115func (cml *ConfigMapLock) Describe() string {
116return fmt.Sprintf("%v/%v", cml.ConfigMapMeta.Namespace, cml.ConfigMapMeta.Name)
117}
118
119// Identity returns the Identity of the lock
120func (cml *ConfigMapLock) Identity() string {
121return cml.LockConfig.Identity
122}
123
124// Identity returns the Identity of the lock
125func (cml *ConfigMapLock) Key() string {
126return cml.LockConfig.Key
127}
128