From e34741364998f4e6ff52fd733e37883ddf6cbae9 Mon Sep 17 00:00:00 2001 From: Manuel de Brito Fontes Date: Wed, 24 May 2017 01:55:13 -0400 Subject: [PATCH] Replace use of endpoint as locks with configmap --- core/pkg/ingress/status/election.go | 4 +- .../resourcelock/configmaplock.go | 109 ++++++++++++++++++ .../resourcelock/endpointslock.go | 103 ----------------- 3 files changed, 111 insertions(+), 105 deletions(-) create mode 100644 core/pkg/ingress/status/leaderelection/resourcelock/configmaplock.go delete mode 100644 core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go diff --git a/core/pkg/ingress/status/election.go b/core/pkg/ingress/status/election.go index 17fc0dd0f..cf52699eb 100644 --- a/core/pkg/ingress/status/election.go +++ b/core/pkg/ingress/status/election.go @@ -101,8 +101,8 @@ func NewElection(electionID, Host: hostname, }) - lock := resourcelock.EndpointsLock{ - EndpointsMeta: meta_v1.ObjectMeta{Namespace: namespace, Name: electionID}, + lock := resourcelock.ConfigMapLock{ + ConfigMapMeta: meta_v1.ObjectMeta{Namespace: namespace, Name: electionID}, Client: c, LockConfig: resourcelock.ResourceLockConfig{ Identity: id, diff --git a/core/pkg/ingress/status/leaderelection/resourcelock/configmaplock.go b/core/pkg/ingress/status/leaderelection/resourcelock/configmaplock.go new file mode 100644 index 000000000..b4e0c398d --- /dev/null +++ b/core/pkg/ingress/status/leaderelection/resourcelock/configmaplock.go @@ -0,0 +1,109 @@ +/* +Copyright 2017 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resourcelock + +import ( + "encoding/json" + "errors" + "fmt" + + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/pkg/api/v1" +) + +// TODO: This is almost a exact replica of Endpoints lock. +// going forwards as we self host more and more components +// and use ConfigMaps as the means to pass that configuration +// data we will likely move to deprecate the Endpoints lock. + +type ConfigMapLock struct { + // ConfigMapMeta should contain a Name and a Namespace of an + // ConfigMapMeta object that the Leadercmlector will attempt to lead. + ConfigMapMeta meta_v1.ObjectMeta + Client kubernetes.Interface + LockConfig ResourceLockConfig + cm *v1.ConfigMap +} + +// Get returns the cmlection record from a ConfigMap Annotation +func (cml *ConfigMapLock) Get() (*LeaderElectionRecord, error) { + var record LeaderElectionRecord + var err error + cml.cm, err = cml.Client.Core().ConfigMaps(cml.ConfigMapMeta.Namespace).Get(cml.ConfigMapMeta.Name, meta_v1.GetOptions{}) + if err != nil { + return nil, err + } + if cml.cm.Annotations == nil { + cml.cm.Annotations = make(map[string]string) + } + if recordBytes, found := cml.cm.Annotations[LeaderElectionRecordAnnotationKey]; found { + if err := json.Unmarshal([]byte(recordBytes), &record); err != nil { + return nil, err + } + } + return &record, nil +} + +// Create attempts to create a LeadercmlectionRecord annotation +func (cml *ConfigMapLock) Create(ler LeaderElectionRecord) error { + recordBytes, err := json.Marshal(ler) + if err != nil { + return err + } + cml.cm, err = cml.Client.Core().ConfigMaps(cml.ConfigMapMeta.Namespace).Create(&v1.ConfigMap{ + ObjectMeta: meta_v1.ObjectMeta{ + Name: cml.ConfigMapMeta.Name, + Namespace: cml.ConfigMapMeta.Namespace, + Annotations: map[string]string{ + LeaderElectionRecordAnnotationKey: string(recordBytes), + }, + }, + }) + return err +} + +// Update will update and existing annotation on a given resource. +func (cml *ConfigMapLock) Update(ler LeaderElectionRecord) error { + if cml.cm == nil { + return errors.New("endpoint not initialized, call get or create first") + } + recordBytes, err := json.Marshal(ler) + if err != nil { + return err + } + cml.cm.Annotations[LeaderElectionRecordAnnotationKey] = string(recordBytes) + cml.cm, err = cml.Client.Core().ConfigMaps(cml.ConfigMapMeta.Namespace).Update(cml.cm) + return err +} + +// RecordEvent in leader cmlection while adding meta-data +func (cml *ConfigMapLock) RecordEvent(s string) { + events := fmt.Sprintf("%v %v", cml.LockConfig.Identity, s) + cml.LockConfig.EventRecorder.Eventf(&v1.ConfigMap{ObjectMeta: cml.cm.ObjectMeta}, v1.EventTypeNormal, "LeaderElection", events) +} + +// Describe is used to convert details on current resource lock +// into a string +func (cml *ConfigMapLock) Describe() string { + return fmt.Sprintf("%v/%v", cml.ConfigMapMeta.Namespace, cml.ConfigMapMeta.Name) +} + +// returns the Identity of the lock +func (cml *ConfigMapLock) Identity() string { + return cml.LockConfig.Identity +} diff --git a/core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go b/core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go deleted file mode 100644 index 26d5782b6..000000000 --- a/core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourcelock - -import ( - "encoding/json" - "errors" - "fmt" - - meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/client-go/pkg/api/v1" -) - -type EndpointsLock struct { - // EndpointsMeta should contain a Name and a Namespace of an - // Endpoints object that the LeaderElector will attempt to lead. - EndpointsMeta meta_v1.ObjectMeta - Client clientset.Interface - LockConfig ResourceLockConfig - e *v1.Endpoints -} - -func (el *EndpointsLock) Get() (*LeaderElectionRecord, error) { - var record LeaderElectionRecord - var err error - el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Get(el.EndpointsMeta.Name, meta_v1.GetOptions{}) - if err != nil { - return nil, err - } - if el.e.Annotations == nil { - el.e.Annotations = make(map[string]string) - } - if recordBytes, found := el.e.Annotations[LeaderElectionRecordAnnotationKey]; found { - if err := json.Unmarshal([]byte(recordBytes), &record); err != nil { - return nil, err - } - } - return &record, nil -} - -// Create attempts to create a LeaderElectionRecord annotation -func (el *EndpointsLock) Create(ler LeaderElectionRecord) error { - recordBytes, err := json.Marshal(ler) - if err != nil { - return err - } - el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Create(&v1.Endpoints{ - ObjectMeta: meta_v1.ObjectMeta{ - Name: el.EndpointsMeta.Name, - Namespace: el.EndpointsMeta.Namespace, - Annotations: map[string]string{ - LeaderElectionRecordAnnotationKey: string(recordBytes), - }, - }, - }) - return err -} - -// Update will update and existing annotation on a given resource. -func (el *EndpointsLock) Update(ler LeaderElectionRecord) error { - if el.e == nil { - return errors.New("endpoint not initialized, call get or create first") - } - recordBytes, err := json.Marshal(ler) - if err != nil { - return err - } - el.e.Annotations[LeaderElectionRecordAnnotationKey] = string(recordBytes) - el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Update(el.e) - return err -} - -// RecordEvent in leader election while adding meta-data -func (el *EndpointsLock) RecordEvent(s string) { - events := fmt.Sprintf("%v %v", el.LockConfig.Identity, s) - el.LockConfig.EventRecorder.Eventf(&v1.Endpoints{ObjectMeta: el.e.ObjectMeta}, v1.EventTypeNormal, "LeaderElection", events) -} - -// Describe is used to convert details on current resource lock -// into a string -func (el *EndpointsLock) Describe() string { - return fmt.Sprintf("%v/%v", el.EndpointsMeta.Namespace, el.EndpointsMeta.Name) -} - -// returns the Identity of the lock -func (el *EndpointsLock) Identity() string { - return el.LockConfig.Identity -}