Update nginx and generic controller
This commit is contained in:
parent
c7c2a564a9
commit
e0561ddeb9
62 changed files with 1043 additions and 510 deletions
|
@ -32,7 +32,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"strings"
|
||||
|
||||
|
@ -71,7 +71,7 @@ func newNGINXController() ingress.Controller {
|
|||
}
|
||||
n := &NGINXController{
|
||||
binary: ngx,
|
||||
configmap: &api.ConfigMap{},
|
||||
configmap: &api_v1.ConfigMap{},
|
||||
}
|
||||
|
||||
var onChange func()
|
||||
|
@ -108,7 +108,7 @@ Error loading new template : %v
|
|||
type NGINXController struct {
|
||||
t *ngx_template.Template
|
||||
|
||||
configmap *api.ConfigMap
|
||||
configmap *api_v1.ConfigMap
|
||||
|
||||
storeLister ingress.StoreLister
|
||||
|
||||
|
@ -308,7 +308,7 @@ Error: %v
|
|||
}
|
||||
|
||||
// SetConfig sets the configured configmap
|
||||
func (n *NGINXController) SetConfig(cmap *api.ConfigMap) {
|
||||
func (n *NGINXController) SetConfig(cmap *api_v1.ConfigMap) {
|
||||
n.configmap = cmap
|
||||
}
|
||||
|
||||
|
@ -383,7 +383,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er
|
|||
}
|
||||
|
||||
if exists {
|
||||
setHeaders = cmap.(*api.ConfigMap).Data
|
||||
setHeaders = cmap.(*api_v1.ConfigMap).Data
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er
|
|||
}
|
||||
|
||||
if exists {
|
||||
secret := s.(*api.Secret)
|
||||
secret := s.(*api_v1.Secret)
|
||||
nsSecName := strings.Replace(secretName, "/", "-", -1)
|
||||
|
||||
dh, ok := secret.Data["dhparam.pem"]
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"strings"
|
||||
text_template "text/template"
|
||||
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
|
|
34
core/pkg/cache/main.go
vendored
34
core/pkg/cache/main.go
vendored
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 cache
|
||||
|
||||
import "k8s.io/kubernetes/pkg/client/cache"
|
||||
|
||||
// StoreToIngressLister makes a Store that lists Ingress.
|
||||
type StoreToIngressLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// StoreToSecretsLister makes a Store that lists Secrets.
|
||||
type StoreToSecretsLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// StoreToConfigmapLister makes a Store that lists Configmap.
|
||||
type StoreToConfigmapLister struct {
|
||||
cache.Store
|
||||
}
|
92
core/pkg/cache/main_test.go
vendored
92
core/pkg/cache/main_test.go
vendored
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
Copyright 2015 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 cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
|
||||
func TestStoreToIngressLister(t *testing.T) {
|
||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
||||
ids := sets.NewString("foo", "bar", "baz")
|
||||
for id := range ids {
|
||||
store.Add(&extensions.Ingress{ObjectMeta: api.ObjectMeta{Name: id}})
|
||||
}
|
||||
sml := StoreToIngressLister{store}
|
||||
|
||||
gotIngress := sml.List()
|
||||
got := make([]string, len(gotIngress))
|
||||
for ix := range gotIngress {
|
||||
ing, ok := gotIngress[ix].(*extensions.Ingress)
|
||||
if !ok {
|
||||
t.Errorf("expected an Ingress type")
|
||||
}
|
||||
got[ix] = ing.Name
|
||||
}
|
||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
||||
t.Errorf("expected %v, got %v", ids, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToSecretsLister(t *testing.T) {
|
||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
||||
ids := sets.NewString("foo", "bar", "baz")
|
||||
for id := range ids {
|
||||
store.Add(&api.Secret{ObjectMeta: api.ObjectMeta{Name: id}})
|
||||
}
|
||||
sml := StoreToSecretsLister{store}
|
||||
|
||||
gotIngress := sml.List()
|
||||
got := make([]string, len(gotIngress))
|
||||
for ix := range gotIngress {
|
||||
s, ok := gotIngress[ix].(*api.Secret)
|
||||
if !ok {
|
||||
t.Errorf("expected a Secret type")
|
||||
}
|
||||
got[ix] = s.Name
|
||||
}
|
||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
||||
t.Errorf("expected %v, got %v", ids, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreToConfigmapLister(t *testing.T) {
|
||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
||||
ids := sets.NewString("foo", "bar", "baz")
|
||||
for id := range ids {
|
||||
store.Add(&api.ConfigMap{ObjectMeta: api.ObjectMeta{Name: id}})
|
||||
}
|
||||
sml := StoreToConfigmapLister{store}
|
||||
|
||||
gotIngress := sml.List()
|
||||
got := make([]string, len(gotIngress))
|
||||
for ix := range gotIngress {
|
||||
m, ok := gotIngress[ix].(*api.ConfigMap)
|
||||
if !ok {
|
||||
t.Errorf("expected an Ingress type")
|
||||
}
|
||||
got[ix] = m.Name
|
||||
}
|
||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
||||
t.Errorf("expected %v, got %v", ids, got)
|
||||
}
|
||||
}
|
|
@ -24,8 +24,8 @@ import (
|
|||
"regexp"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"
|
||||
|
|
|
@ -24,9 +24,11 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
|
@ -36,7 +38,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
@ -73,7 +75,7 @@ func (m mockSecret) GetSecret(name string) (*api.Secret, error) {
|
|||
}
|
||||
|
||||
return &api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
Name: "demo-secret",
|
||||
},
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"strings"
|
||||
"regexp"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"
|
||||
|
|
|
@ -21,9 +21,11 @@ import (
|
|||
"testing"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
|
@ -33,7 +35,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ package authtls
|
|||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"
|
||||
|
|
|
@ -19,9 +19,10 @@ package authtls
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
|
@ -31,7 +32,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ package class
|
|||
|
||||
import (
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
"k8s.io/ingress/core/pkg/ingress/errors"
|
||||
|
|
|
@ -19,8 +19,9 @@ package class
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func TestIsValidClass(t *testing.T) {
|
||||
|
@ -40,7 +41,7 @@ func TestIsValidClass(t *testing.T) {
|
|||
}
|
||||
|
||||
ing := &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package cors
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
|
|
@ -19,8 +19,9 @@ package cors
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -45,7 +46,7 @@ func TestParse(t *testing.T) {
|
|||
}
|
||||
|
||||
ing := &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package healthcheck
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
|
|
|
@ -19,9 +19,10 @@ package healthcheck
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
)
|
||||
|
@ -33,7 +34,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -21,7 +21,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/util/net/sets"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
|
|
|
@ -20,9 +20,10 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
"k8s.io/ingress/core/pkg/ingress/errors"
|
||||
|
@ -35,7 +36,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ package parser
|
|||
import (
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/errors"
|
||||
)
|
||||
|
|
|
@ -19,13 +19,14 @@ package parser
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package portinredirect
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
|
|
|
@ -19,9 +19,10 @@ package portinredirect
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"fmt"
|
||||
|
||||
|
@ -35,7 +36,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
|
|
|
@ -19,9 +19,10 @@ package proxy
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
)
|
||||
|
@ -33,7 +34,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@ package ratelimit
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
|
|
@ -19,9 +19,11 @@ package ratelimit
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
|
@ -31,7 +33,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package rewrite
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
|
|
|
@ -19,9 +19,10 @@ package rewrite
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
)
|
||||
|
@ -37,7 +38,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package secureupstream
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
|
|
@ -19,9 +19,11 @@ package secureupstream
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
|
@ -31,7 +33,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -21,9 +21,9 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -54,7 +54,7 @@ func (npm namedPortMapping) getPortMappings() map[string]string {
|
|||
}
|
||||
|
||||
// GetPortMapping returns the number of the named port or an error if is not valid
|
||||
func GetPortMapping(name string, s *api.Service) (int32, error) {
|
||||
func GetPortMapping(name string, s *api_v1.Service) (int32, error) {
|
||||
if s == nil {
|
||||
return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name)
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@ package service
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"testing"
|
||||
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
)
|
||||
|
||||
func fakeService(npa bool, ps bool, expectedP string) *api.Service {
|
||||
|
@ -41,11 +42,11 @@ func fakeService(npa bool, ps bool, expectedP string) *api.Service {
|
|||
|
||||
// fake service
|
||||
return &api.Service{
|
||||
TypeMeta: unversioned.TypeMeta{
|
||||
TypeMeta: meta_v1.TypeMeta{
|
||||
Kind: "ingress",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Annotations: map[string]string{
|
||||
fakeNpa: string(fakePs),
|
||||
},
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
|
|
@ -19,9 +19,10 @@ package sessionaffinity
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
|
@ -31,7 +32,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package snippet
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
)
|
||||
|
|
|
@ -19,8 +19,9 @@ package snippet
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
|
@ -40,7 +41,7 @@ func TestParse(t *testing.T) {
|
|||
}
|
||||
|
||||
ing := &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package sslpassthrough
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
ing_errors "k8s.io/ingress/core/pkg/ingress/errors"
|
||||
|
|
|
@ -19,14 +19,16 @@ package sslpassthrough
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
|
||||
func buildIngress() *extensions.Ingress {
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
|
|
@ -21,8 +21,8 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/authreq"
|
||||
|
|
|
@ -19,9 +19,10 @@ package controller
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
|
@ -75,7 +76,7 @@ func buildIngress() *extensions.Ingress {
|
|||
}
|
||||
|
||||
return &extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
|
@ -251,7 +252,7 @@ func TestCertificateAuthSecret(t *testing.T) {
|
|||
resolver := mockCfg{}
|
||||
resolver.MockSecrets = map[string]*api.Secret{
|
||||
"default/foo_secret": {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_secret_name",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -24,9 +24,9 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/parser"
|
||||
|
|
|
@ -29,17 +29,17 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"github.com/kylelemons/godebug/pretty"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/util/flowcontrol"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
unversionedcore "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
def_api "k8s.io/client-go/pkg/api"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
|
||||
cache_store "k8s.io/ingress/core/pkg/cache"
|
||||
"k8s.io/ingress/core/pkg/ingress"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/class"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/healthcheck"
|
||||
|
@ -48,6 +48,7 @@ import (
|
|||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
"k8s.io/ingress/core/pkg/ingress/resolver"
|
||||
"k8s.io/ingress/core/pkg/ingress/status"
|
||||
"k8s.io/ingress/core/pkg/ingress/store"
|
||||
"k8s.io/ingress/core/pkg/k8s"
|
||||
ssl "k8s.io/ingress/core/pkg/net/ssl"
|
||||
local_strings "k8s.io/ingress/core/pkg/strings"
|
||||
|
@ -70,19 +71,19 @@ var (
|
|||
type GenericController struct {
|
||||
cfg *Configuration
|
||||
|
||||
ingController *cache.Controller
|
||||
endpController *cache.Controller
|
||||
svcController *cache.Controller
|
||||
nodeController *cache.Controller
|
||||
secrController *cache.Controller
|
||||
mapController *cache.Controller
|
||||
ingController cache.Controller
|
||||
endpController cache.Controller
|
||||
svcController cache.Controller
|
||||
nodeController cache.Controller
|
||||
secrController cache.Controller
|
||||
mapController cache.Controller
|
||||
|
||||
ingLister cache_store.StoreToIngressLister
|
||||
svcLister cache.StoreToServiceLister
|
||||
nodeLister cache.StoreToNodeLister
|
||||
endpLister cache.StoreToEndpointsLister
|
||||
secrLister cache_store.StoreToSecretsLister
|
||||
mapLister cache_store.StoreToConfigmapLister
|
||||
ingLister store.IngressLister
|
||||
svcLister store.ServiceLister
|
||||
nodeLister store.NodeLister
|
||||
endpLister store.EndpointLister
|
||||
secrLister store.SecretLister
|
||||
mapLister store.ConfigMapLister
|
||||
|
||||
annotations annotationExtractor
|
||||
|
||||
|
@ -149,7 +150,7 @@ func newIngressController(config *Configuration) *GenericController {
|
|||
stopLock: &sync.Mutex{},
|
||||
stopCh: make(chan struct{}),
|
||||
syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.1, 1),
|
||||
recorder: eventBroadcaster.NewRecorder(api.EventSource{
|
||||
recorder: eventBroadcaster.NewRecorder(def_api.Scheme, api.EventSource{
|
||||
Component: "ingress-controller",
|
||||
}),
|
||||
sslCertTracker: newSSLCertTracker(),
|
||||
|
@ -306,12 +307,9 @@ func newIngressController(config *Configuration) *GenericController {
|
|||
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", api.NamespaceAll, fields.Everything()),
|
||||
&api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler)
|
||||
|
||||
ic.svcLister.Indexer, ic.svcController = cache.NewIndexerInformer(
|
||||
ic.svcLister.Store, ic.svcController = cache.NewInformer(
|
||||
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "services", ic.cfg.Namespace, fields.Everything()),
|
||||
&api.Service{},
|
||||
ic.cfg.ResyncPeriod,
|
||||
cache.ResourceEventHandlerFuncs{},
|
||||
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
|
||||
&api.Service{}, ic.cfg.ResyncPeriod, cache.ResourceEventHandlerFuncs{})
|
||||
|
||||
ic.nodeLister.Store, ic.nodeController = cache.NewInformer(
|
||||
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "nodes", api.NamespaceAll, fields.Everything()),
|
||||
|
@ -498,7 +496,7 @@ func (ic *GenericController) getStreamServices(configmapName string, proto api.P
|
|||
continue
|
||||
}
|
||||
|
||||
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(nsName)
|
||||
svcObj, svcExists, err := ic.svcLister.Store.GetByKey(nsName)
|
||||
if err != nil {
|
||||
glog.Warningf("error getting service %v: %v", nsName, err)
|
||||
continue
|
||||
|
@ -562,7 +560,7 @@ func (ic *GenericController) getDefaultUpstream() *ingress.Backend {
|
|||
Name: defUpstreamName,
|
||||
}
|
||||
svcKey := ic.cfg.DefaultService
|
||||
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey)
|
||||
svcObj, svcExists, err := ic.svcLister.Store.GetByKey(svcKey)
|
||||
if err != nil {
|
||||
glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err)
|
||||
upstream.Endpoints = append(upstream.Endpoints, newDefaultServer())
|
||||
|
@ -809,7 +807,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing
|
|||
// to a service.
|
||||
func (ic *GenericController) serviceEndpoints(svcKey, backendPort string,
|
||||
hz *healthcheck.Upstream) ([]ingress.Endpoint, error) {
|
||||
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey)
|
||||
svcObj, svcExists, err := ic.svcLister.Store.GetByKey(svcKey)
|
||||
|
||||
var upstreams []ingress.Endpoint
|
||||
if err != nil {
|
||||
|
|
|
@ -14,11 +14,12 @@ import (
|
|||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api"
|
||||
"k8s.io/kubernetes/pkg/healthz"
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clientcmd_api "k8s.io/client-go/tools/clientcmd/api"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress"
|
||||
"k8s.io/ingress/core/pkg/k8s"
|
||||
|
@ -208,19 +209,35 @@ const (
|
|||
defaultBurst = 1e6
|
||||
)
|
||||
|
||||
// buildConfigFromFlags builds REST config based on master URL and kubeconfig path.
|
||||
// If both of them are empty then in cluster config is used.
|
||||
func buildConfigFromFlags(masterURL, kubeconfigPath string) (*rest.Config, error) {
|
||||
if kubeconfigPath == "" && masterURL == "" {
|
||||
kubeconfig, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return kubeconfig, nil
|
||||
}
|
||||
|
||||
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
|
||||
&clientcmd.ConfigOverrides{
|
||||
ClusterInfo: clientcmd_api.Cluster{
|
||||
Server: masterURL,
|
||||
},
|
||||
}).ClientConfig()
|
||||
}
|
||||
|
||||
// createApiserverClient creates new Kubernetes Apiserver client. When kubeconfig or apiserverHost param is empty
|
||||
// the function assumes that it is running inside a Kubernetes cluster and attempts to
|
||||
// discover the Apiserver. Otherwise, it connects to the Apiserver specified.
|
||||
//
|
||||
// apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001.
|
||||
// kubeConfig location of kubeconfig file
|
||||
func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Clientset, error) {
|
||||
|
||||
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeConfig},
|
||||
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: apiserverHost}})
|
||||
|
||||
cfg, err := clientConfig.ClientConfig()
|
||||
func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes.Clientset, error) {
|
||||
cfg, err := buildConfigFromFlags(apiserverHost, kubeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -231,7 +248,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Cli
|
|||
|
||||
glog.Infof("Creating API server client for %s", cfg.Host)
|
||||
|
||||
client, err := client.NewForConfig(cfg)
|
||||
client, err := kubernetes.NewForConfig(cfg)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -24,9 +24,10 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
podutil "k8s.io/kubernetes/pkg/api/pod"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/service"
|
||||
)
|
||||
|
@ -35,11 +36,11 @@ import (
|
|||
// named port. If the annotation in the service does not exist or is not equals
|
||||
// to the port mapping obtained from the pod the service must be updated to reflect
|
||||
// the current state
|
||||
func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
|
||||
func (ic *GenericController) checkSvcForUpdate(svc *api_v1.Service) error {
|
||||
// get the pods associated with the service
|
||||
// TODO: switch this to a watch
|
||||
pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(api.ListOptions{
|
||||
LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(),
|
||||
pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(meta_v1.ListOptions{
|
||||
LabelSelector: labels.Set(svc.Spec.Selector).AsSelector().String(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
@ -60,7 +61,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
|
|||
|
||||
_, err := strconv.Atoi(servicePort.TargetPort.StrVal)
|
||||
if err != nil {
|
||||
portNum, err := podutil.FindPort(pod, servicePort)
|
||||
portNum, err := findPort(pod, servicePort)
|
||||
if err != nil {
|
||||
glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err)
|
||||
continue
|
||||
|
@ -82,7 +83,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
|
|||
if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) {
|
||||
data, _ := json.Marshal(namedPorts)
|
||||
|
||||
newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name)
|
||||
newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err)
|
||||
}
|
||||
|
@ -103,3 +104,26 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FindPort locates the container port for the given pod and portName. If the
|
||||
// targetPort is a number, use that. If the targetPort is a string, look that
|
||||
// string up in all named ports in all containers in the target pod. If no
|
||||
// match is found, fail.
|
||||
func findPort(pod *api_v1.Pod, svcPort *api_v1.ServicePort) (int, error) {
|
||||
portName := svcPort.TargetPort
|
||||
switch portName.Type {
|
||||
case intstr.String:
|
||||
name := portName.StrVal
|
||||
for _, container := range pod.Spec.Containers {
|
||||
for _, port := range container.Ports {
|
||||
if port.Name == name && port.Protocol == svcPort.Protocol {
|
||||
return int(port.ContainerPort), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
case intstr.Int:
|
||||
return portName.IntValue(), nil
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
|
||||
}
|
||||
|
|
|
@ -20,51 +20,55 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/service"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
)
|
||||
|
||||
func buildSimpleClientSet() *testclient.Clientset {
|
||||
return testclient.NewSimpleClientset(
|
||||
&api.PodList{Items: []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
func buildSimpleClientSet() *fake.Clientset {
|
||||
return fake.NewSimpleClientset(
|
||||
&api_v1.PodList{
|
||||
Items: []api_v1.Pod{
|
||||
{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
NodeName: "foo_node_1",
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Ports: []api.ContainerPort{
|
||||
{
|
||||
Name: "foo1_named_port_c1",
|
||||
Protocol: api.ProtocolTCP,
|
||||
ContainerPort: 80,
|
||||
Spec: api_v1.PodSpec{
|
||||
NodeName: "foo_node_1",
|
||||
Containers: []api_v1.Container{
|
||||
{
|
||||
Ports: []api_v1.ContainerPort{
|
||||
{
|
||||
Name: "foo1_named_port_c1",
|
||||
Protocol: api_v1.ProtocolTCP,
|
||||
ContainerPort: 80,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: api.NamespaceSystem,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: api.NamespaceSystem,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
&api.ServiceList{Items: []api.Service{
|
||||
},
|
||||
&api_v1.ServiceList{Items: []api_v1.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
Name: "named_port_test_service",
|
||||
},
|
||||
|
@ -81,14 +85,13 @@ func buildGenericController() *GenericController {
|
|||
}
|
||||
}
|
||||
|
||||
func buildService() *api.Service {
|
||||
return &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
func buildService() *api_v1.Service {
|
||||
return &api_v1.Service{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Namespace: api.NamespaceSystem,
|
||||
Name: "named_port_test_service",
|
||||
},
|
||||
|
||||
Spec: api.ServiceSpec{
|
||||
Spec: api_v1.ServiceSpec{
|
||||
ClusterIP: "10.10.10.10",
|
||||
},
|
||||
}
|
||||
|
@ -98,17 +101,17 @@ func TestCheckSvcForUpdate(t *testing.T) {
|
|||
foos := []struct {
|
||||
n string
|
||||
ns string
|
||||
sps []api.ServicePort
|
||||
sps []api_v1.ServicePort
|
||||
sl map[string]string
|
||||
er string
|
||||
}{
|
||||
{
|
||||
"pods_have_not_been_found_in_this_namespace",
|
||||
api.NamespaceSystem,
|
||||
[]api.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
[]api_v1.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
},
|
||||
map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
|
@ -118,10 +121,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
|
|||
{
|
||||
"ports_have_not_been_found_in_this_pod",
|
||||
api.NamespaceDefault,
|
||||
[]api.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
[]api_v1.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
},
|
||||
map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
|
@ -132,10 +135,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
|
|||
{
|
||||
"ports_fixed",
|
||||
api.NamespaceDefault,
|
||||
[]api.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(80)},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
[]api_v1.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(80)},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
},
|
||||
map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
|
@ -145,10 +148,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
|
|||
{
|
||||
"nil_selector",
|
||||
api.NamespaceDefault,
|
||||
[]api.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
[]api_v1.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
},
|
||||
nil,
|
||||
"{\"foo1_named_port_c1\":\"80\"}",
|
||||
|
@ -156,10 +159,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
|
|||
{
|
||||
"normal_update",
|
||||
api.NamespaceDefault,
|
||||
[]api.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
[]api_v1.ServicePort{
|
||||
{Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
|
||||
{Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
|
||||
{Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
|
||||
},
|
||||
map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
|
@ -181,7 +184,7 @@ func TestCheckSvcForUpdate(t *testing.T) {
|
|||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service")
|
||||
rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service", meta_v1.GetOptions{})
|
||||
rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation]
|
||||
if !reflect.DeepEqual(rr, foo.er) {
|
||||
t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n)
|
||||
|
|
|
@ -17,9 +17,8 @@ limitations under the License.
|
|||
package controller
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
|
||||
|
|
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
package resolver
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
)
|
||||
|
|
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||
package ingress
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// BackendByNameServers sorts upstreams by name
|
||||
|
@ -69,7 +69,7 @@ func (c LocationByPath) Less(i, j int) bool {
|
|||
|
||||
// SSLCert describes a SSL certificate to be used in a server
|
||||
type SSLCert struct {
|
||||
api.ObjectMeta `json:"metadata,omitempty"`
|
||||
meta_v1.ObjectMeta `json:"metadata,omitempty"`
|
||||
// CAFileName contains the path to the file with the root certificate
|
||||
CAFileName string `json:"caFileName"`
|
||||
// PemFileName contains the path to the file with the certificate and key concatenated
|
||||
|
@ -82,4 +82,6 @@ type SSLCert struct {
|
|||
}
|
||||
|
||||
// GetObjectKind implements the ObjectKind interface as a noop
|
||||
func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
|
||||
func (s SSLCert) GetObjectKind() schema.ObjectKind {
|
||||
return schema.EmptyObjectKind
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ package ingress
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func buildBackendByNameServers() BackendByNameServers {
|
||||
|
@ -365,7 +365,7 @@ func TestLocationByPathLess(t *testing.T) {
|
|||
|
||||
func TestGetObjectKindForSSLCert(t *testing.T) {
|
||||
fk := &SSLCert{
|
||||
ObjectMeta: api.ObjectMeta{},
|
||||
ObjectMeta: meta_v1.ObjectMeta{},
|
||||
CAFileName: "ca_file",
|
||||
PemFileName: "pemfile",
|
||||
PemSHA: "pem_sha",
|
||||
|
|
|
@ -23,16 +23,19 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/leaderelection"
|
||||
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
|
||||
"k8s.io/kubernetes/pkg/client/record"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
client "k8s.io/client-go/kubernetes"
|
||||
def_api "k8s.io/client-go/pkg/api"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/status/leaderelection"
|
||||
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
|
||||
)
|
||||
|
||||
func getCurrentLeader(electionID, namespace string, c client.Interface) (string, *api.Endpoints, error) {
|
||||
endpoints, err := c.Core().Endpoints(namespace).Get(electionID)
|
||||
endpoints, err := c.Core().Endpoints(namespace).Get(electionID, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@ -56,11 +59,11 @@ func NewElection(electionID,
|
|||
callback func(leader string),
|
||||
c client.Interface) (*leaderelection.LeaderElector, error) {
|
||||
|
||||
_, err := c.Core().Endpoints(namespace).Get(electionID)
|
||||
_, err := c.Core().Endpoints(namespace).Get(electionID, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
_, err = c.Core().Endpoints(namespace).Create(&api.Endpoints{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: electionID,
|
||||
},
|
||||
})
|
||||
|
@ -93,13 +96,13 @@ func NewElection(electionID,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
recorder := broadcaster.NewRecorder(api.EventSource{
|
||||
recorder := broadcaster.NewRecorder(def_api.Scheme, api.EventSource{
|
||||
Component: "ingress-leader-elector",
|
||||
Host: hostname,
|
||||
})
|
||||
|
||||
lock := resourcelock.EndpointsLock{
|
||||
EndpointsMeta: api.ObjectMeta{Namespace: namespace, Name: electionID},
|
||||
EndpointsMeta: meta_v1.ObjectMeta{Namespace: namespace, Name: electionID},
|
||||
Client: c,
|
||||
LockConfig: resourcelock.ResourceLockConfig{
|
||||
Identity: id,
|
||||
|
|
|
@ -21,23 +21,25 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
tc "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
|
||||
)
|
||||
|
||||
func TestGetCurrentLeaderLeaderExist(t *testing.T) {
|
||||
fkER := resourcelock.LeaderElectionRecord{
|
||||
HolderIdentity: "currentLeader",
|
||||
LeaseDurationSeconds: 30,
|
||||
AcquireTime: unversioned.Now(),
|
||||
RenewTime: unversioned.Now(),
|
||||
AcquireTime: meta_v1.NewTime(time.Now()),
|
||||
RenewTime: meta_v1.NewTime(time.Now()),
|
||||
LeaderTransitions: 3,
|
||||
}
|
||||
leaderInfo, _ := json.Marshal(fkER)
|
||||
fkEndpoints := api.Endpoints{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
fkEndpoints := api_v1.Endpoints{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "ingress-controller-test",
|
||||
Namespace: api.NamespaceSystem,
|
||||
Annotations: map[string]string{
|
||||
|
@ -45,7 +47,7 @@ func TestGetCurrentLeaderLeaderExist(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}})
|
||||
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
|
||||
identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
|
||||
if err != nil {
|
||||
t.Fatalf("expected identitiy and endpoints but returned error %s", err)
|
||||
|
@ -61,14 +63,14 @@ func TestGetCurrentLeaderLeaderExist(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
|
||||
fkEndpoints := api.Endpoints{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
fkEndpoints := api_v1.Endpoints{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "ingress-controller-test",
|
||||
Namespace: api.NamespaceSystem,
|
||||
Annotations: map[string]string{},
|
||||
},
|
||||
}
|
||||
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}})
|
||||
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
|
||||
identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpeted error: %v", err)
|
||||
|
@ -84,8 +86,8 @@ func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetCurrentLeaderAnnotationError(t *testing.T) {
|
||||
fkEndpoints := api.Endpoints{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
fkEndpoints := api_v1.Endpoints{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "ingress-controller-test",
|
||||
Namespace: api.NamespaceSystem,
|
||||
Annotations: map[string]string{
|
||||
|
@ -93,7 +95,7 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}})
|
||||
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
|
||||
_, _, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
|
||||
if err == nil {
|
||||
t.Errorf("expected error")
|
||||
|
@ -101,15 +103,15 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewElection(t *testing.T) {
|
||||
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{
|
||||
fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "ingress-controller-test",
|
||||
Namespace: api.NamespaceSystem,
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "ingress-controller-test-020",
|
||||
Namespace: api.NamespaceSystem,
|
||||
},
|
||||
|
|
333
core/pkg/ingress/status/leaderelection/leaderelection.go
Normal file
333
core/pkg/ingress/status/leaderelection/leaderelection.go
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
Copyright 2015 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 leaderelection implements leader election of a set of endpoints.
|
||||
// It uses an annotation in the endpoints object to store the record of the
|
||||
// election state.
|
||||
//
|
||||
// This implementation does not guarantee that only one client is acting as a
|
||||
// leader (a.k.a. fencing). A client observes timestamps captured locally to
|
||||
// infer the state of the leader election. Thus the implementation is tolerant
|
||||
// to arbitrary clock skew, but is not tolerant to arbitrary clock skew rate.
|
||||
//
|
||||
// However the level of tolerance to skew rate can be configured by setting
|
||||
// RenewDeadline and LeaseDuration appropriately. The tolerance expressed as a
|
||||
// maximum tolerated ratio of time passed on the fastest node to time passed on
|
||||
// the slowest node can be approximately achieved with a configuration that sets
|
||||
// the same ratio of LeaseDuration to RenewDeadline. For example if a user wanted
|
||||
// to tolerate some nodes progressing forward in time twice as fast as other nodes,
|
||||
// the user could set LeaseDuration to 60 seconds and RenewDeadline to 30 seconds.
|
||||
//
|
||||
// While not required, some method of clock synchronization between nodes in the
|
||||
// cluster is highly recommended. It's important to keep in mind when configuring
|
||||
// this client that the tolerance to skew rate varies inversely to master
|
||||
// availability.
|
||||
//
|
||||
// Larger clusters often have a more lenient SLA for API latency. This should be
|
||||
// taken into account when configuring the client. The rate of leader transitions
|
||||
// should be monitored and RetryPeriod and LeaseDuration should be increased
|
||||
// until the rate is stable and acceptably low. It's important to keep in mind
|
||||
// when configuring this client that the tolerance to API latency varies inversely
|
||||
// to master availability.
|
||||
//
|
||||
// DISCLAIMER: this is an alpha API. This library will likely change significantly
|
||||
// or even be removed entirely in subsequent releases. Depend on this API at
|
||||
// your own risk.
|
||||
package leaderelection
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
rl "k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
JitterFactor = 1.2
|
||||
DefaultLeaseDuration = 15 * time.Second
|
||||
DefaultRenewDeadline = 10 * time.Second
|
||||
DefaultRetryPeriod = 2 * time.Second
|
||||
)
|
||||
|
||||
// LeaderElectionConfiguration defines the configuration of leader election
|
||||
// clients for components that can run with leader election enabled.
|
||||
type LeaderElectionConfiguration struct {
|
||||
// leaderElect enables a leader election client to gain leadership
|
||||
// before executing the main loop. Enable this when running replicated
|
||||
// components for high availability.
|
||||
LeaderElect bool
|
||||
// leaseDuration is the duration that non-leader candidates will wait
|
||||
// after observing a leadership renewal until attempting to acquire
|
||||
// leadership of a led but unrenewed leader slot. This is effectively the
|
||||
// maximum duration that a leader can be stopped before it is replaced
|
||||
// by another candidate. This is only applicable if leader election is
|
||||
// enabled.
|
||||
LeaseDuration metav1.Duration
|
||||
// renewDeadline is the interval between attempts by the acting master to
|
||||
// renew a leadership slot before it stops leading. This must be less
|
||||
// than or equal to the lease duration. This is only applicable if leader
|
||||
// election is enabled.
|
||||
RenewDeadline metav1.Duration
|
||||
// retryPeriod is the duration the clients should wait between attempting
|
||||
// acquisition and renewal of a leadership. This is only applicable if
|
||||
// leader election is enabled.
|
||||
RetryPeriod metav1.Duration
|
||||
}
|
||||
|
||||
// NewLeadereElector creates a LeaderElector from a LeaderElecitionConfig
|
||||
func NewLeaderElector(lec LeaderElectionConfig) (*LeaderElector, error) {
|
||||
if lec.LeaseDuration <= lec.RenewDeadline {
|
||||
return nil, fmt.Errorf("leaseDuration must be greater than renewDeadline")
|
||||
}
|
||||
if lec.RenewDeadline <= time.Duration(JitterFactor*float64(lec.RetryPeriod)) {
|
||||
return nil, fmt.Errorf("renewDeadline must be greater than retryPeriod*JitterFactor")
|
||||
}
|
||||
if lec.Lock == nil {
|
||||
return nil, fmt.Errorf("Lock must not be nil.")
|
||||
}
|
||||
return &LeaderElector{
|
||||
config: lec,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type LeaderElectionConfig struct {
|
||||
// Lock is the resource that will be used for locking
|
||||
Lock rl.Interface
|
||||
|
||||
// LeaseDuration is the duration that non-leader candidates will
|
||||
// wait to force acquire leadership. This is measured against time of
|
||||
// last observed ack.
|
||||
LeaseDuration time.Duration
|
||||
// RenewDeadline is the duration that the acting master will retry
|
||||
// refreshing leadership before giving up.
|
||||
RenewDeadline time.Duration
|
||||
// RetryPeriod is the duration the LeaderElector clients should wait
|
||||
// between tries of actions.
|
||||
RetryPeriod time.Duration
|
||||
|
||||
// Callbacks are callbacks that are triggered during certain lifecycle
|
||||
// events of the LeaderElector
|
||||
Callbacks LeaderCallbacks
|
||||
}
|
||||
|
||||
// LeaderCallbacks are callbacks that are triggered during certain
|
||||
// lifecycle events of the LeaderElector. These are invoked asynchronously.
|
||||
//
|
||||
// possible future callbacks:
|
||||
// * OnChallenge()
|
||||
type LeaderCallbacks struct {
|
||||
// OnStartedLeading is called when a LeaderElector client starts leading
|
||||
OnStartedLeading func(stop <-chan struct{})
|
||||
// OnStoppedLeading is called when a LeaderElector client stops leading
|
||||
OnStoppedLeading func()
|
||||
// OnNewLeader is called when the client observes a leader that is
|
||||
// not the previously observed leader. This includes the first observed
|
||||
// leader when the client starts.
|
||||
OnNewLeader func(identity string)
|
||||
}
|
||||
|
||||
// LeaderElector is a leader election client.
|
||||
//
|
||||
// possible future methods:
|
||||
// * (le *LeaderElector) IsLeader()
|
||||
// * (le *LeaderElector) GetLeader()
|
||||
type LeaderElector struct {
|
||||
config LeaderElectionConfig
|
||||
// internal bookkeeping
|
||||
observedRecord rl.LeaderElectionRecord
|
||||
observedTime time.Time
|
||||
// used to implement OnNewLeader(), may lag slightly from the
|
||||
// value observedRecord.HolderIdentity if the transition has
|
||||
// not yet been reported.
|
||||
reportedLeader string
|
||||
}
|
||||
|
||||
// Run starts the leader election loop
|
||||
func (le *LeaderElector) Run() {
|
||||
defer func() {
|
||||
runtime.HandleCrash()
|
||||
le.config.Callbacks.OnStoppedLeading()
|
||||
}()
|
||||
le.acquire()
|
||||
stop := make(chan struct{})
|
||||
go le.config.Callbacks.OnStartedLeading(stop)
|
||||
le.renew()
|
||||
close(stop)
|
||||
}
|
||||
|
||||
// RunOrDie starts a client with the provided config or panics if the config
|
||||
// fails to validate.
|
||||
func RunOrDie(lec LeaderElectionConfig) {
|
||||
le, err := NewLeaderElector(lec)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
le.Run()
|
||||
}
|
||||
|
||||
// GetLeader returns the identity of the last observed leader or returns the empty string if
|
||||
// no leader has yet been observed.
|
||||
func (le *LeaderElector) GetLeader() string {
|
||||
return le.observedRecord.HolderIdentity
|
||||
}
|
||||
|
||||
// IsLeader returns true if the last observed leader was this client else returns false.
|
||||
func (le *LeaderElector) IsLeader() bool {
|
||||
return le.observedRecord.HolderIdentity == le.config.Lock.Identity()
|
||||
}
|
||||
|
||||
// acquire loops calling tryAcquireOrRenew and returns immediately when tryAcquireOrRenew succeeds.
|
||||
func (le *LeaderElector) acquire() {
|
||||
stop := make(chan struct{})
|
||||
glog.Infof("attempting to acquire leader lease...")
|
||||
wait.JitterUntil(func() {
|
||||
succeeded := le.tryAcquireOrRenew()
|
||||
le.maybeReportTransition()
|
||||
desc := le.config.Lock.Describe()
|
||||
if !succeeded {
|
||||
glog.V(4).Infof("failed to acquire lease %v", desc)
|
||||
return
|
||||
}
|
||||
le.config.Lock.RecordEvent("became leader")
|
||||
glog.Infof("successfully acquired lease %v", desc)
|
||||
close(stop)
|
||||
}, le.config.RetryPeriod, JitterFactor, true, stop)
|
||||
}
|
||||
|
||||
// renew loops calling tryAcquireOrRenew and returns immediately when tryAcquireOrRenew fails.
|
||||
func (le *LeaderElector) renew() {
|
||||
stop := make(chan struct{})
|
||||
wait.Until(func() {
|
||||
err := wait.Poll(le.config.RetryPeriod, le.config.RenewDeadline, func() (bool, error) {
|
||||
return le.tryAcquireOrRenew(), nil
|
||||
})
|
||||
le.maybeReportTransition()
|
||||
desc := le.config.Lock.Describe()
|
||||
if err == nil {
|
||||
glog.V(4).Infof("succesfully renewed lease %v", desc)
|
||||
return
|
||||
}
|
||||
le.config.Lock.RecordEvent("stopped leading")
|
||||
glog.Infof("failed to renew lease %v", desc)
|
||||
close(stop)
|
||||
}, 0, stop)
|
||||
}
|
||||
|
||||
// tryAcquireOrRenew tries to acquire a leader lease if it is not already acquired,
|
||||
// else it tries to renew the lease if it has already been acquired. Returns true
|
||||
// on success else returns false.
|
||||
func (le *LeaderElector) tryAcquireOrRenew() bool {
|
||||
now := metav1.Now()
|
||||
leaderElectionRecord := rl.LeaderElectionRecord{
|
||||
HolderIdentity: le.config.Lock.Identity(),
|
||||
LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second),
|
||||
RenewTime: now,
|
||||
AcquireTime: now,
|
||||
}
|
||||
|
||||
// 1. obtain or create the ElectionRecord
|
||||
oldLeaderElectionRecord, err := le.config.Lock.Get()
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
glog.Errorf("error retrieving resource lock %v: %v", le.config.Lock.Describe(), err)
|
||||
return false
|
||||
}
|
||||
if err = le.config.Lock.Create(leaderElectionRecord); err != nil {
|
||||
glog.Errorf("error initially creating leader election record: %v", err)
|
||||
return false
|
||||
}
|
||||
le.observedRecord = leaderElectionRecord
|
||||
le.observedTime = time.Now()
|
||||
return true
|
||||
}
|
||||
|
||||
// 2. Record obtained, check the Identity & Time
|
||||
if !reflect.DeepEqual(le.observedRecord, *oldLeaderElectionRecord) {
|
||||
le.observedRecord = *oldLeaderElectionRecord
|
||||
le.observedTime = time.Now()
|
||||
}
|
||||
if le.observedTime.Add(le.config.LeaseDuration).After(now.Time) &&
|
||||
oldLeaderElectionRecord.HolderIdentity != le.config.Lock.Identity() {
|
||||
glog.V(4).Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity)
|
||||
return false
|
||||
}
|
||||
|
||||
// 3. We're going to try to update. The leaderElectionRecord is set to it's default
|
||||
// here. Let's correct it before updating.
|
||||
if oldLeaderElectionRecord.HolderIdentity == le.config.Lock.Identity() {
|
||||
leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime
|
||||
leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions
|
||||
} else {
|
||||
leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1
|
||||
}
|
||||
|
||||
// update the lock itself
|
||||
if err = le.config.Lock.Update(leaderElectionRecord); err != nil {
|
||||
glog.Errorf("Failed to update lock: %v", err)
|
||||
return false
|
||||
}
|
||||
le.observedRecord = leaderElectionRecord
|
||||
le.observedTime = time.Now()
|
||||
return true
|
||||
}
|
||||
|
||||
func (l *LeaderElector) maybeReportTransition() {
|
||||
if l.observedRecord.HolderIdentity == l.reportedLeader {
|
||||
return
|
||||
}
|
||||
l.reportedLeader = l.observedRecord.HolderIdentity
|
||||
if l.config.Callbacks.OnNewLeader != nil {
|
||||
go l.config.Callbacks.OnNewLeader(l.reportedLeader)
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultLeaderElectionConfiguration() LeaderElectionConfiguration {
|
||||
return LeaderElectionConfiguration{
|
||||
LeaderElect: false,
|
||||
LeaseDuration: metav1.Duration{Duration: DefaultLeaseDuration},
|
||||
RenewDeadline: metav1.Duration{Duration: DefaultRenewDeadline},
|
||||
RetryPeriod: metav1.Duration{Duration: DefaultRetryPeriod},
|
||||
}
|
||||
}
|
||||
|
||||
// BindFlags binds the common LeaderElectionCLIConfig flags to a flagset
|
||||
func BindFlags(l *LeaderElectionConfiguration, fs *pflag.FlagSet) {
|
||||
fs.BoolVar(&l.LeaderElect, "leader-elect", l.LeaderElect, ""+
|
||||
"Start a leader election client and gain leadership before "+
|
||||
"executing the main loop. Enable this when running replicated "+
|
||||
"components for high availability.")
|
||||
fs.DurationVar(&l.LeaseDuration.Duration, "leader-elect-lease-duration", l.LeaseDuration.Duration, ""+
|
||||
"The duration that non-leader candidates will wait after observing a leadership "+
|
||||
"renewal until attempting to acquire leadership of a led but unrenewed leader "+
|
||||
"slot. This is effectively the maximum duration that a leader can be stopped "+
|
||||
"before it is replaced by another candidate. This is only applicable if leader "+
|
||||
"election is enabled.")
|
||||
fs.DurationVar(&l.RenewDeadline.Duration, "leader-elect-renew-deadline", l.RenewDeadline.Duration, ""+
|
||||
"The interval between attempts by the acting master to renew a leadership slot "+
|
||||
"before it stops leading. This must be less than or equal to the lease duration. "+
|
||||
"This is only applicable if leader election is enabled.")
|
||||
fs.DurationVar(&l.RetryPeriod.Duration, "leader-elect-retry-period", l.RetryPeriod.Duration, ""+
|
||||
"The duration the clients should wait between attempting acquisition and renewal "+
|
||||
"of a leadership. This is only applicable if leader election is enabled.")
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
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
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
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 (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
)
|
||||
|
||||
const (
|
||||
LeaderElectionRecordAnnotationKey = "control-plane.alpha.kubernetes.io/leader"
|
||||
)
|
||||
|
||||
// LeaderElectionRecord is the record that is stored in the leader election annotation.
|
||||
// This information should be used for observational purposes only and could be replaced
|
||||
// with a random string (e.g. UUID) with only slight modification of this code.
|
||||
// TODO(mikedanese): this should potentially be versioned
|
||||
type LeaderElectionRecord struct {
|
||||
HolderIdentity string `json:"holderIdentity"`
|
||||
LeaseDurationSeconds int `json:"leaseDurationSeconds"`
|
||||
AcquireTime metav1.Time `json:"acquireTime"`
|
||||
RenewTime metav1.Time `json:"renewTime"`
|
||||
LeaderTransitions int `json:"leaderTransitions"`
|
||||
}
|
||||
|
||||
// ResourceLockConfig common data that exists across different
|
||||
// resource locks
|
||||
type ResourceLockConfig struct {
|
||||
Identity string
|
||||
EventRecorder record.EventRecorder
|
||||
}
|
||||
|
||||
// Interface offers a common interface for locking on arbitrary
|
||||
// resources used in leader election. The Interface is used
|
||||
// to hide the details on specific implementations in order to allow
|
||||
// them to change over time. This interface is strictly for use
|
||||
// by the leaderelection code.
|
||||
type Interface interface {
|
||||
// Get returns the LeaderElectionRecord
|
||||
Get() (*LeaderElectionRecord, error)
|
||||
|
||||
// Create attempts to create a LeaderElectionRecord
|
||||
Create(ler LeaderElectionRecord) error
|
||||
|
||||
// Update will update and existing LeaderElectionRecord
|
||||
Update(ler LeaderElectionRecord) error
|
||||
|
||||
// RecordEvent is used to record events
|
||||
RecordEvent(string)
|
||||
|
||||
// Identity will return the locks Identity
|
||||
Identity() string
|
||||
|
||||
// Describe is used to convert details on current resource lock
|
||||
// into a string
|
||||
Describe() string
|
||||
}
|
|
@ -24,15 +24,16 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
"k8s.io/kubernetes/pkg/client/leaderelection"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
|
||||
cache_store "k8s.io/ingress/core/pkg/cache"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/class"
|
||||
"k8s.io/ingress/core/pkg/ingress/status/leaderelection"
|
||||
"k8s.io/ingress/core/pkg/ingress/store"
|
||||
"k8s.io/ingress/core/pkg/k8s"
|
||||
"k8s.io/ingress/core/pkg/strings"
|
||||
"k8s.io/ingress/core/pkg/task"
|
||||
|
@ -52,7 +53,7 @@ type Sync interface {
|
|||
type Config struct {
|
||||
Client clientset.Interface
|
||||
PublishService string
|
||||
IngressLister cache_store.StoreToIngressLister
|
||||
IngressLister store.IngressLister
|
||||
ElectionID string
|
||||
|
||||
DefaultIngressClass string
|
||||
|
@ -111,7 +112,7 @@ func (s statusSync) Shutdown() {
|
|||
}
|
||||
|
||||
glog.Infof("removing address from ingress status (%v)", addrs)
|
||||
s.updateStatus([]api.LoadBalancerIngress{})
|
||||
s.updateStatus([]api_v1.LoadBalancerIngress{})
|
||||
}
|
||||
|
||||
func (s *statusSync) run() {
|
||||
|
@ -196,7 +197,7 @@ func NewStatusSyncer(config Config) Sync {
|
|||
func (s *statusSync) runningAddresess() ([]string, error) {
|
||||
if s.PublishService != "" {
|
||||
ns, name, _ := k8s.ParseNameNS(s.PublishService)
|
||||
svc, err := s.Client.Core().Services(ns).Get(name)
|
||||
svc, err := s.Client.Core().Services(ns).Get(name, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -214,8 +215,8 @@ func (s *statusSync) runningAddresess() ([]string, error) {
|
|||
}
|
||||
|
||||
// get information about all the pods running the ingress controller
|
||||
pods, err := s.Client.Core().Pods(s.pod.Namespace).List(api.ListOptions{
|
||||
LabelSelector: labels.SelectorFromSet(s.pod.Labels),
|
||||
pods, err := s.Client.Core().Pods(s.pod.Namespace).List(meta_v1.ListOptions{
|
||||
LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -232,13 +233,13 @@ func (s *statusSync) runningAddresess() ([]string, error) {
|
|||
}
|
||||
|
||||
// sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress
|
||||
func sliceToStatus(endpoints []string) []api.LoadBalancerIngress {
|
||||
lbi := []api.LoadBalancerIngress{}
|
||||
func sliceToStatus(endpoints []string) []api_v1.LoadBalancerIngress {
|
||||
lbi := []api_v1.LoadBalancerIngress{}
|
||||
for _, ep := range endpoints {
|
||||
if net.ParseIP(ep) == nil {
|
||||
lbi = append(lbi, api.LoadBalancerIngress{Hostname: ep})
|
||||
lbi = append(lbi, api_v1.LoadBalancerIngress{Hostname: ep})
|
||||
} else {
|
||||
lbi = append(lbi, api.LoadBalancerIngress{IP: ep})
|
||||
lbi = append(lbi, api_v1.LoadBalancerIngress{IP: ep})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,7 +247,7 @@ func sliceToStatus(endpoints []string) []api.LoadBalancerIngress {
|
|||
return lbi
|
||||
}
|
||||
|
||||
func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
|
||||
func (s *statusSync) updateStatus(newIPs []api_v1.LoadBalancerIngress) {
|
||||
ings := s.IngressLister.List()
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(ings))
|
||||
|
@ -261,7 +262,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
|
|||
go func(wg *sync.WaitGroup, ing *extensions.Ingress) {
|
||||
defer wg.Done()
|
||||
ingClient := s.Client.Extensions().Ingresses(ing.Namespace)
|
||||
currIng, err := ingClient.Get(ing.Name)
|
||||
currIng, err := ingClient.Get(ing.Name, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err)
|
||||
return
|
||||
|
@ -286,7 +287,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
|
|||
wg.Wait()
|
||||
}
|
||||
|
||||
func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
|
||||
func ingressSliceEqual(lhs, rhs []api_v1.LoadBalancerIngress) bool {
|
||||
if len(lhs) != len(rhs) {
|
||||
return false
|
||||
}
|
||||
|
@ -303,7 +304,7 @@ func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
|
|||
}
|
||||
|
||||
// loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP
|
||||
type loadBalancerIngressByIP []api.LoadBalancerIngress
|
||||
type loadBalancerIngressByIP []api_v1.LoadBalancerIngress
|
||||
|
||||
func (c loadBalancerIngressByIP) Len() int { return len(c) }
|
||||
func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
|
|
|
@ -23,19 +23,21 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
testclient "k8s.io/client-go/kubernetes/fake"
|
||||
"k8s.io/client-go/pkg/api"
|
||||
api_v1 "k8s.io/client-go/pkg/api/v1"
|
||||
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
|
||||
cache_store "k8s.io/ingress/core/pkg/cache"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/class"
|
||||
cache_store "k8s.io/ingress/core/pkg/ingress/store"
|
||||
"k8s.io/ingress/core/pkg/k8s"
|
||||
"k8s.io/ingress/core/pkg/task"
|
||||
)
|
||||
|
||||
func buildLoadBalancerIngressByIP() loadBalancerIngressByIP {
|
||||
return []api.LoadBalancerIngress{
|
||||
return []api_v1.LoadBalancerIngress{
|
||||
{
|
||||
IP: "10.0.0.1",
|
||||
Hostname: "foo1",
|
||||
|
@ -57,100 +59,100 @@ func buildLoadBalancerIngressByIP() loadBalancerIngressByIP {
|
|||
|
||||
func buildSimpleClientSet() *testclient.Clientset {
|
||||
return testclient.NewSimpleClientset(
|
||||
&api.PodList{Items: []api.Pod{
|
||||
&api_v1.PodList{Items: []api_v1.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo1",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Spec: api_v1.PodSpec{
|
||||
NodeName: "foo_node_2",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo2",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_no",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo3",
|
||||
Namespace: api.NamespaceSystem,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Spec: api_v1.PodSpec{
|
||||
NodeName: "foo_node_2",
|
||||
},
|
||||
},
|
||||
}},
|
||||
&api.ServiceList{Items: []api.Service{
|
||||
&api_v1.ServiceList{Items: []api_v1.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
},
|
||||
Status: api.ServiceStatus{
|
||||
LoadBalancer: api.LoadBalancerStatus{
|
||||
Status: api_v1.ServiceStatus{
|
||||
LoadBalancer: api_v1.LoadBalancerStatus{
|
||||
Ingress: buildLoadBalancerIngressByIP(),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_non_exist",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
},
|
||||
},
|
||||
}},
|
||||
&api.NodeList{Items: []api.Node{
|
||||
&api_v1.NodeList{Items: []api_v1.Node{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_node_1",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
Addresses: []api.NodeAddress{
|
||||
Status: api_v1.NodeStatus{
|
||||
Addresses: []api_v1.NodeAddress{
|
||||
{
|
||||
Type: api.NodeLegacyHostIP,
|
||||
Type: api_v1.NodeLegacyHostIP,
|
||||
Address: "10.0.0.1",
|
||||
}, {
|
||||
Type: api.NodeExternalIP,
|
||||
Type: api_v1.NodeExternalIP,
|
||||
Address: "10.0.0.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_node_2",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
Addresses: []api.NodeAddress{
|
||||
Status: api_v1.NodeStatus{
|
||||
Addresses: []api_v1.NodeAddress{
|
||||
{
|
||||
Type: api.NodeLegacyHostIP,
|
||||
Type: api_v1.NodeLegacyHostIP,
|
||||
Address: "11.0.0.1",
|
||||
},
|
||||
{
|
||||
Type: api.NodeExternalIP,
|
||||
Type: api_v1.NodeExternalIP,
|
||||
Address: "11.0.0.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
&api.EndpointsList{Items: []api.Endpoints{
|
||||
&api_v1.EndpointsList{Items: []api_v1.Endpoints{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "ingress-controller-leader",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
SelfLink: "/api/v1/namespaces/default/endpoints/ingress-controller-leader",
|
||||
},
|
||||
}}},
|
||||
|
@ -165,13 +167,13 @@ func fakeSynFn(interface{}) error {
|
|||
func buildExtensionsIngresses() []extensions.Ingress {
|
||||
return []extensions.Ingress{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_ingress_1",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
},
|
||||
Status: extensions.IngressStatus{
|
||||
LoadBalancer: api.LoadBalancerStatus{
|
||||
Ingress: []api.LoadBalancerIngress{
|
||||
LoadBalancer: api_v1.LoadBalancerStatus{
|
||||
Ingress: []api_v1.LoadBalancerIngress{
|
||||
{
|
||||
IP: "10.0.0.1",
|
||||
Hostname: "foo1",
|
||||
|
@ -181,7 +183,7 @@ func buildExtensionsIngresses() []extensions.Ingress {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_ingress_different_class",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Annotations: map[string]string{
|
||||
|
@ -189,8 +191,8 @@ func buildExtensionsIngresses() []extensions.Ingress {
|
|||
},
|
||||
},
|
||||
Status: extensions.IngressStatus{
|
||||
LoadBalancer: api.LoadBalancerStatus{
|
||||
Ingress: []api.LoadBalancerIngress{
|
||||
LoadBalancer: api_v1.LoadBalancerStatus{
|
||||
Ingress: []api_v1.LoadBalancerIngress{
|
||||
{
|
||||
IP: "0.0.0.0",
|
||||
Hostname: "foo.bar.com",
|
||||
|
@ -200,45 +202,45 @@ func buildExtensionsIngresses() []extensions.Ingress {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_ingress_2",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
},
|
||||
Status: extensions.IngressStatus{
|
||||
LoadBalancer: api.LoadBalancerStatus{
|
||||
Ingress: []api.LoadBalancerIngress{},
|
||||
LoadBalancer: api_v1.LoadBalancerStatus{
|
||||
Ingress: []api_v1.LoadBalancerIngress{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func buildIngressListener() cache_store.StoreToIngressLister {
|
||||
func buildIngressListener() cache_store.IngressLister {
|
||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
||||
store.Add(&extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_ingress_non_01",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
}})
|
||||
store.Add(&extensions.Ingress{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "foo_ingress_1",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
},
|
||||
Status: extensions.IngressStatus{
|
||||
LoadBalancer: api.LoadBalancerStatus{
|
||||
LoadBalancer: api_v1.LoadBalancerStatus{
|
||||
Ingress: buildLoadBalancerIngressByIP(),
|
||||
},
|
||||
},
|
||||
})
|
||||
return cache_store.StoreToIngressLister{Store: store}
|
||||
return cache_store.IngressLister{Store: store}
|
||||
}
|
||||
|
||||
func buildStatusSync() statusSync {
|
||||
return statusSync{
|
||||
pod: &k8s.PodInfo{
|
||||
Name: "foo_base_pod",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Namespace: api_v1.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
"lable_sig": "foo_pod",
|
||||
},
|
||||
|
@ -247,7 +249,7 @@ func buildStatusSync() statusSync {
|
|||
syncQueue: task.NewTaskQueue(fakeSynFn),
|
||||
Config: Config{
|
||||
Client: buildSimpleClientSet(),
|
||||
PublishService: api.NamespaceDefault + "/" + "foo",
|
||||
PublishService: api_v1.NamespaceDefault + "/" + "foo",
|
||||
IngressLister: buildIngressListener(),
|
||||
},
|
||||
}
|
||||
|
@ -256,7 +258,7 @@ func buildStatusSync() statusSync {
|
|||
func TestStatusActions(t *testing.T) {
|
||||
// make sure election can be created
|
||||
os.Setenv("POD_NAME", "foo1")
|
||||
os.Setenv("POD_NAMESPACE", api.NamespaceDefault)
|
||||
os.Setenv("POD_NAMESPACE", api_v1.NamespaceDefault)
|
||||
c := Config{
|
||||
Client: buildSimpleClientSet(),
|
||||
PublishService: "",
|
||||
|
@ -273,7 +275,7 @@ func TestStatusActions(t *testing.T) {
|
|||
fk := fkSync.(statusSync)
|
||||
|
||||
ns := make(chan struct{})
|
||||
// start it and wait for the election and sync actions
|
||||
// start it and wait for the election and syn actions
|
||||
go fk.Run(ns)
|
||||
// wait for the election
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
@ -281,10 +283,10 @@ func TestStatusActions(t *testing.T) {
|
|||
fk.sync("just-test")
|
||||
// PublishService is empty, so the running address is: ["11.0.0.2"]
|
||||
// after updated, the ingress's ip should only be "11.0.0.2"
|
||||
newIPs := []api.LoadBalancerIngress{{
|
||||
newIPs := []api_v1.LoadBalancerIngress{{
|
||||
IP: "11.0.0.2",
|
||||
}}
|
||||
fooIngress1, err1 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1")
|
||||
fooIngress1, err1 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
|
||||
if err1 != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
@ -296,8 +298,8 @@ func TestStatusActions(t *testing.T) {
|
|||
// execute shutdown
|
||||
fk.Shutdown()
|
||||
// ingress should be empty
|
||||
newIPs2 := []api.LoadBalancerIngress{}
|
||||
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1")
|
||||
newIPs2 := []api_v1.LoadBalancerIngress{}
|
||||
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
|
||||
if err2 != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
@ -306,7 +308,7 @@ func TestStatusActions(t *testing.T) {
|
|||
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2)
|
||||
}
|
||||
|
||||
oic, err := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_different_class")
|
||||
oic, err := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_different_class", meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
@ -374,7 +376,7 @@ func TestUpdateStatus(t *testing.T) {
|
|||
sort.Sort(loadBalancerIngressByIP(newIPs))
|
||||
fk.updateStatus(newIPs)
|
||||
|
||||
fooIngress1, err1 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1")
|
||||
fooIngress1, err1 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
|
||||
if err1 != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
|
@ -383,13 +385,13 @@ func TestUpdateStatus(t *testing.T) {
|
|||
t.Fatalf("returned %v but expected %v", fooIngress1CurIPs, newIPs)
|
||||
}
|
||||
|
||||
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_2")
|
||||
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_2", meta_v1.GetOptions{})
|
||||
if err2 != nil {
|
||||
t.Fatalf("unexpected error")
|
||||
}
|
||||
fooIngress2CurIPs := fooIngress2.Status.LoadBalancer.Ingress
|
||||
if !ingressSliceEqual(fooIngress2CurIPs, []api.LoadBalancerIngress{}) {
|
||||
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api.LoadBalancerIngress{})
|
||||
if !ingressSliceEqual(fooIngress2CurIPs, []api_v1.LoadBalancerIngress{}) {
|
||||
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api_v1.LoadBalancerIngress{})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,7 +405,7 @@ func TestSliceToStatus(t *testing.T) {
|
|||
r := sliceToStatus(fkEndpoints)
|
||||
|
||||
if r == nil {
|
||||
t.Fatalf("returned nil but expected a valid []api.LoadBalancerIngress")
|
||||
t.Fatalf("returned nil but expected a valid []api_v1.LoadBalancerIngress")
|
||||
}
|
||||
rl := len(r)
|
||||
if rl != 3 {
|
||||
|
@ -411,21 +413,21 @@ func TestSliceToStatus(t *testing.T) {
|
|||
}
|
||||
re1 := r[0]
|
||||
if re1.Hostname != "opensource-k8s-ingress" {
|
||||
t.Fatalf("returned %v but expected %v", re1, api.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"})
|
||||
t.Fatalf("returned %v but expected %v", re1, api_v1.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"})
|
||||
}
|
||||
re2 := r[1]
|
||||
if re2.IP != "10.0.0.1" {
|
||||
t.Fatalf("returned %v but expected %v", re2, api.LoadBalancerIngress{IP: "10.0.0.1"})
|
||||
t.Fatalf("returned %v but expected %v", re2, api_v1.LoadBalancerIngress{IP: "10.0.0.1"})
|
||||
}
|
||||
re3 := r[2]
|
||||
if re3.IP != "2001:db8::68" {
|
||||
t.Fatalf("returned %v but expected %v", re3, api.LoadBalancerIngress{IP: "2001:db8::68"})
|
||||
t.Fatalf("returned %v but expected %v", re3, api_v1.LoadBalancerIngress{IP: "2001:db8::68"})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIngressSliceEqual(t *testing.T) {
|
||||
fk1 := buildLoadBalancerIngressByIP()
|
||||
fk2 := append(buildLoadBalancerIngressByIP(), api.LoadBalancerIngress{
|
||||
fk2 := append(buildLoadBalancerIngressByIP(), api_v1.LoadBalancerIngress{
|
||||
IP: "10.0.0.5",
|
||||
Hostname: "foo5",
|
||||
})
|
||||
|
@ -435,8 +437,8 @@ func TestIngressSliceEqual(t *testing.T) {
|
|||
fk4[2].IP = "11.0.0.3"
|
||||
|
||||
fooTests := []struct {
|
||||
lhs []api.LoadBalancerIngress
|
||||
rhs []api.LoadBalancerIngress
|
||||
lhs []api_v1.LoadBalancerIngress
|
||||
rhs []api_v1.LoadBalancerIngress
|
||||
er bool
|
||||
}{
|
||||
{fk1, fk1, true},
|
||||
|
@ -445,7 +447,7 @@ func TestIngressSliceEqual(t *testing.T) {
|
|||
{fk4, fk1, false},
|
||||
{fk1, nil, false},
|
||||
{nil, nil, true},
|
||||
{[]api.LoadBalancerIngress{}, []api.LoadBalancerIngress{}, true},
|
||||
{[]api_v1.LoadBalancerIngress{}, []api_v1.LoadBalancerIngress{}, true},
|
||||
}
|
||||
|
||||
for _, fooTest := range fooTests {
|
||||
|
@ -461,7 +463,7 @@ func TestLoadBalancerIngressByIPLen(t *testing.T) {
|
|||
ips loadBalancerIngressByIP
|
||||
el int
|
||||
}{
|
||||
{[]api.LoadBalancerIngress{}, 0},
|
||||
{[]api_v1.LoadBalancerIngress{}, 0},
|
||||
{buildLoadBalancerIngressByIP(), 4},
|
||||
{nil, 0},
|
||||
}
|
||||
|
|
71
core/pkg/ingress/store/main.go
Normal file
71
core/pkg/ingress/store/main.go
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
Copyright 2015 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 store
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// IngressLister makes a Store that lists Ingress.
|
||||
type IngressLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// SecretsLister makes a Store that lists Secrets.
|
||||
type SecretsLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// ConfigMapLister makes a Store that lists Configmaps.
|
||||
type ConfigMapLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// ServiceLister makes a Store that lists Services.
|
||||
type ServiceLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// NodeLister makes a Store that lists Nodes.
|
||||
type NodeLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// EndpointLister makes a Store that lists Endpoints.
|
||||
type EndpointLister struct {
|
||||
cache.Store
|
||||
}
|
||||
|
||||
// GetServiceEndpoints returns the endpoints of a service, matched on service name.
|
||||
func (s *EndpointLister) GetServiceEndpoints(svc *api.Service) (ep api.Endpoints, err error) {
|
||||
for _, m := range s.Store.List() {
|
||||
ep = *m.(*api.Endpoints)
|
||||
if svc.Name == ep.Name && svc.Namespace == ep.Namespace {
|
||||
return ep, nil
|
||||
}
|
||||
}
|
||||
err = fmt.Errorf("could not find endpoints for service: %v", svc.Name)
|
||||
return
|
||||
}
|
||||
|
||||
// SecretLister makes a Store that lists Secres.
|
||||
type SecretLister struct {
|
||||
cache.Store
|
||||
}
|
|
@ -19,12 +19,10 @@ package ingress
|
|||
import (
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
"k8s.io/kubernetes/pkg/healthz"
|
||||
"k8s.io/kubernetes/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apiserver/pkg/server/healthz"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
cache_store "k8s.io/ingress/core/pkg/cache"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/authreq"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/authtls"
|
||||
|
@ -33,6 +31,7 @@ import (
|
|||
"k8s.io/ingress/core/pkg/ingress/annotations/ratelimit"
|
||||
"k8s.io/ingress/core/pkg/ingress/annotations/rewrite"
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
"k8s.io/ingress/core/pkg/ingress/store"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -103,12 +102,12 @@ type Controller interface {
|
|||
// StoreLister returns the configured stores for ingresses, services,
|
||||
// endpoints, secrets and configmaps.
|
||||
type StoreLister struct {
|
||||
Ingress cache_store.StoreToIngressLister
|
||||
Service cache.StoreToServiceLister
|
||||
Node cache.StoreToNodeLister
|
||||
Endpoint cache.StoreToEndpointsLister
|
||||
Secret cache_store.StoreToSecretsLister
|
||||
ConfigMap cache_store.StoreToConfigmapLister
|
||||
Ingress store.IngressLister
|
||||
Service store.ServiceLister
|
||||
Node store.NodeLister
|
||||
Endpoint store.EndpointLister
|
||||
Secret store.SecretLister
|
||||
ConfigMap store.ConfigMapLister
|
||||
}
|
||||
|
||||
// BackendInfo returns information about the backend.
|
||||
|
|
|
@ -21,8 +21,9 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
)
|
||||
|
||||
// IsValidService checks if exists a service with the specified name
|
||||
|
@ -31,7 +32,7 @@ func IsValidService(kubeClient clientset.Interface, name string) (*api.Service,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kubeClient.Core().Services(ns).Get(name)
|
||||
return kubeClient.Core().Services(ns).Get(name, meta_v1.GetOptions{})
|
||||
}
|
||||
|
||||
// isValidConfigMap check if exists a configmap with the specified name
|
||||
|
@ -43,7 +44,7 @@ func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.Con
|
|||
return nil, err
|
||||
}
|
||||
|
||||
configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name)
|
||||
configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name, meta_v1.GetOptions{})
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("configmap not found: %v", err)
|
||||
|
@ -55,7 +56,7 @@ func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.Con
|
|||
|
||||
// isValidNamespace chck if exists a namespace with the specified name
|
||||
func IsValidNamespace(kubeClient clientset.Interface, name string) (*api.Namespace, error) {
|
||||
return kubeClient.Core().Namespaces().Get(name)
|
||||
return kubeClient.Core().Namespaces().Get(name, meta_v1.GetOptions{})
|
||||
}
|
||||
|
||||
// IsValidSecret checks if exists a secret with the specified name
|
||||
|
@ -64,7 +65,7 @@ func IsValidSecret(kubeClient clientset.Interface, name string) (*api.Secret, er
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return kubeClient.Core().Secrets(ns).Get(name)
|
||||
return kubeClient.Core().Secrets(ns).Get(name, meta_v1.GetOptions{})
|
||||
}
|
||||
|
||||
// ParseNameNS parses a string searching a namespace and name
|
||||
|
@ -80,7 +81,7 @@ func ParseNameNS(input string) (string, string, error) {
|
|||
// GetNodeIP returns the IP address of a node in the cluster
|
||||
func GetNodeIP(kubeClient clientset.Interface, name string) string {
|
||||
var externalIP string
|
||||
node, err := kubeClient.Core().Nodes().Get(name)
|
||||
node, err := kubeClient.Core().Nodes().Get(name, meta_v1.GetOptions{})
|
||||
if err != nil {
|
||||
return externalIP
|
||||
}
|
||||
|
@ -120,7 +121,7 @@ func GetPodDetails(kubeClient clientset.Interface) (*PodInfo, error) {
|
|||
return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable")
|
||||
}
|
||||
|
||||
pod, _ := kubeClient.Core().Pods(podNs).Get(podName)
|
||||
pod, _ := kubeClient.Core().Pods(podNs).Get(podName, meta_v1.GetOptions{})
|
||||
if pod == nil {
|
||||
return nil, fmt.Errorf("unable to get POD information")
|
||||
}
|
||||
|
|
|
@ -17,11 +17,12 @@ limitations under the License.
|
|||
package k8s
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
|
||||
"os"
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
testclient "k8s.io/client-go/kubernetes/fake"
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
)
|
||||
|
||||
func TestParseNameNS(t *testing.T) {
|
||||
|
@ -57,7 +58,7 @@ func TestParseNameNS(t *testing.T) {
|
|||
|
||||
func TestIsValidService(t *testing.T) {
|
||||
fk := testclient.NewSimpleClientset(&api.Service{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
Name: "demo",
|
||||
},
|
||||
|
@ -88,7 +89,7 @@ func TestIsValidService(t *testing.T) {
|
|||
func TestIsValidNamespace(t *testing.T) {
|
||||
|
||||
fk := testclient.NewSimpleClientset(&api.Namespace{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "default",
|
||||
},
|
||||
})
|
||||
|
@ -112,7 +113,7 @@ func TestIsValidNamespace(t *testing.T) {
|
|||
func TestIsValidConfigMap(t *testing.T) {
|
||||
|
||||
fk := testclient.NewSimpleClientset(&api.ConfigMap{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
Name: "demo",
|
||||
},
|
||||
|
@ -145,7 +146,7 @@ func TestIsValidConfigMap(t *testing.T) {
|
|||
|
||||
func TestIsValidSecret(t *testing.T) {
|
||||
fk := testclient.NewSimpleClientset(&api.Secret{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
Name: "demo",
|
||||
},
|
||||
|
@ -184,7 +185,7 @@ func TestGetNodeIP(t *testing.T) {
|
|||
|
||||
// node not exist
|
||||
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
@ -199,7 +200,7 @@ func TestGetNodeIP(t *testing.T) {
|
|||
|
||||
// node exist
|
||||
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
@ -215,7 +216,7 @@ func TestGetNodeIP(t *testing.T) {
|
|||
// search the correct node
|
||||
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo1",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
@ -228,7 +229,7 @@ func TestGetNodeIP(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo2",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
@ -244,7 +245,7 @@ func TestGetNodeIP(t *testing.T) {
|
|||
|
||||
// get NodeExternalIP
|
||||
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
@ -262,7 +263,7 @@ func TestGetNodeIP(t *testing.T) {
|
|||
|
||||
// get NodeLegacyHostIP
|
||||
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
@ -307,7 +308,7 @@ func TestGetPodDetails(t *testing.T) {
|
|||
// success to get PodInfo
|
||||
fkClient := testclient.NewSimpleClientset(
|
||||
&api.PodList{Items: []api.Pod{{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "testpod",
|
||||
Namespace: api.NamespaceDefault,
|
||||
Labels: map[string]string{
|
||||
|
@ -317,7 +318,7 @@ func TestGetPodDetails(t *testing.T) {
|
|||
},
|
||||
}}},
|
||||
&api.NodeList{Items: []api.Node{{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
Name: "demo",
|
||||
},
|
||||
Status: api.NodeStatus{
|
||||
|
|
|
@ -22,9 +22,9 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
"k8s.io/kubernetes/pkg/util/wait"
|
||||
"k8s.io/kubernetes/pkg/util/workqueue"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -8,11 +8,12 @@ import (
|
|||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
api "k8s.io/client-go/pkg/api/v1"
|
||||
|
||||
nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config"
|
||||
"k8s.io/ingress/core/pkg/ingress"
|
||||
"k8s.io/ingress/core/pkg/ingress/controller"
|
||||
"k8s.io/ingress/core/pkg/ingress/defaults"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -89,3 +90,7 @@ func (n DummyController) OverrideFlags(*pflag.FlagSet) {
|
|||
func (n DummyController) SetListers(lister ingress.StoreLister) {
|
||||
|
||||
}
|
||||
|
||||
func (n DummyController) DefaultIngressClass() string {
|
||||
return "dummy"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue