Update nginx and generic controller

This commit is contained in:
Manuel de Brito Fontes 2017-04-01 11:39:42 -03:00
parent c7c2a564a9
commit e0561ddeb9
62 changed files with 1043 additions and 510 deletions

View file

@ -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"]

View file

@ -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"

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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"

View file

@ -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",
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"
)

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"
)

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"
)

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"
)

View file

@ -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,
},

View file

@ -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)
}

View file

@ -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),
},

View file

@ -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"
)

View file

@ -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,
},

View file

@ -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"
)

View file

@ -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,
},

View file

@ -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"

View file

@ -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,
},

View file

@ -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"

View file

@ -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",
},
},

View file

@ -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"

View file

@ -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 {

View file

@ -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

View file

@ -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)
}

View file

@ -20,31 +20,34 @@ 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{
func buildSimpleClientSet() *fake.Clientset {
return fake.NewSimpleClientset(
&api_v1.PodList{
Items: []api_v1.Pod{
{
ObjectMeta: api.ObjectMeta{
ObjectMeta: meta_v1.ObjectMeta{
Name: "foo1",
Namespace: api.NamespaceDefault,
Labels: map[string]string{
"lable_sig": "foo_pod",
},
},
Spec: api.PodSpec{
Spec: api_v1.PodSpec{
NodeName: "foo_node_1",
Containers: []api.Container{
Containers: []api_v1.Container{
{
Ports: []api.ContainerPort{
Ports: []api_v1.ContainerPort{
{
Name: "foo1_named_port_c1",
Protocol: api.ProtocolTCP,
Protocol: api_v1.ProtocolTCP,
ContainerPort: 80,
},
},
@ -53,7 +56,7 @@ func buildSimpleClientSet() *testclient.Clientset {
},
},
{
ObjectMeta: api.ObjectMeta{
ObjectMeta: meta_v1.ObjectMeta{
Name: "foo1",
Namespace: api.NamespaceSystem,
Labels: map[string]string{
@ -61,10 +64,11 @@ func buildSimpleClientSet() *testclient.Clientset {
},
},
},
}},
&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)

View file

@ -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"

View file

@ -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"
)

View file

@ -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
}

View file

@ -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",

View file

@ -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,

View file

@ -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,
},

View 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.")
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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] }

View file

@ -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},
}

View 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
}

View file

@ -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.

View file

@ -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")
}

View file

@ -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{

View file

@ -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 (

View file

@ -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"
}