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/golang/glog"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api" api_v1 "k8s.io/client-go/pkg/api/v1"
"strings" "strings"
@ -71,7 +71,7 @@ func newNGINXController() ingress.Controller {
} }
n := &NGINXController{ n := &NGINXController{
binary: ngx, binary: ngx,
configmap: &api.ConfigMap{}, configmap: &api_v1.ConfigMap{},
} }
var onChange func() var onChange func()
@ -108,7 +108,7 @@ Error loading new template : %v
type NGINXController struct { type NGINXController struct {
t *ngx_template.Template t *ngx_template.Template
configmap *api.ConfigMap configmap *api_v1.ConfigMap
storeLister ingress.StoreLister storeLister ingress.StoreLister
@ -308,7 +308,7 @@ Error: %v
} }
// SetConfig sets the configured configmap // SetConfig sets the configured configmap
func (n *NGINXController) SetConfig(cmap *api.ConfigMap) { func (n *NGINXController) SetConfig(cmap *api_v1.ConfigMap) {
n.configmap = cmap n.configmap = cmap
} }
@ -383,7 +383,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er
} }
if exists { 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 { if exists {
secret := s.(*api.Secret) secret := s.(*api_v1.Secret)
nsSecName := strings.Replace(secretName, "/", "-", -1) nsSecName := strings.Replace(secretName, "/", "-", -1)
dh, ok := secret.Data["dhparam.pem"] dh, ok := secret.Data["dhparam.pem"]

View file

@ -26,7 +26,7 @@ import (
"strings" "strings"
text_template "text/template" text_template "text/template"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"github.com/golang/glog" "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" "regexp"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api" api "k8s.io/client-go/pkg/api/v1"
"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/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -24,9 +24,11 @@ import (
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/util/intstr" "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 { func buildIngress() *extensions.Ingress {
@ -36,7 +38,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },
@ -73,7 +75,7 @@ func (m mockSecret) GetSecret(name string) (*api.Secret, error) {
} }
return &api.Secret{ return &api.Secret{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Name: "demo-secret", Name: "demo-secret",
}, },

View file

@ -21,7 +21,7 @@ import (
"strings" "strings"
"regexp" "regexp"
"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/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -21,9 +21,11 @@ import (
"testing" "testing"
"reflect" "reflect"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
@ -33,7 +35,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -18,7 +18,7 @@ package authtls
import ( import (
"github.com/pkg/errors" "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" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,9 +19,10 @@ package authtls
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/intstr" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
@ -31,7 +32,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -18,7 +18,7 @@ package class
import ( import (
"github.com/golang/glog" "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/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/errors" "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,8 +19,9 @@ package class
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
) )
func TestIsValidClass(t *testing.T) { func TestIsValidClass(t *testing.T) {
@ -40,7 +41,7 @@ func TestIsValidClass(t *testing.T) {
} }
ing := &extensions.Ingress{ ing := &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package cors package cors
import ( 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/annotations/parser"
) )

View file

@ -19,8 +19,9 @@ package cors
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
) )
const ( const (
@ -45,7 +46,7 @@ func TestParse(t *testing.T) {
} }
ing := &extensions.Ingress{ ing := &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package healthcheck package healthcheck
import ( 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/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,9 +19,10 @@ package healthcheck
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/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/defaults"
) )
@ -33,7 +34,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -21,7 +21,8 @@ import (
"strings" "strings"
"github.com/pkg/errors" "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/kubernetes/pkg/util/net/sets"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"

View file

@ -20,9 +20,10 @@ import (
"reflect" "reflect"
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/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/defaults"
"k8s.io/ingress/core/pkg/ingress/errors" "k8s.io/ingress/core/pkg/ingress/errors"
@ -35,7 +36,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -19,7 +19,7 @@ package parser
import ( import (
"strconv" "strconv"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/errors" "k8s.io/ingress/core/pkg/ingress/errors"
) )

View file

@ -19,13 +19,14 @@ package parser
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package portinredirect package portinredirect
import ( 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/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,9 +19,10 @@ package portinredirect
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/intstr" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"fmt" "fmt"
@ -35,7 +36,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package proxy package proxy
import ( 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/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,9 +19,10 @@ package proxy
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/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/defaults"
) )
@ -33,7 +34,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -19,7 +19,7 @@ package ratelimit
import ( import (
"fmt" "fmt"
"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/annotations/parser"
) )

View file

@ -19,9 +19,11 @@ package ratelimit
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
@ -31,7 +33,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package rewrite package rewrite
import ( 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/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

@ -19,9 +19,10 @@ package rewrite
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/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/defaults"
) )
@ -37,7 +38,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package secureupstream package secureupstream
import ( 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/annotations/parser"
) )

View file

@ -19,9 +19,11 @@ package secureupstream
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
@ -31,7 +33,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -21,9 +21,9 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"k8s.io/kubernetes/pkg/api"
"github.com/golang/glog" "github.com/golang/glog"
api_v1 "k8s.io/client-go/pkg/api/v1"
) )
const ( 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 // 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 { if s == nil {
return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name) return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name)
} }

View file

@ -18,9 +18,10 @@ package service
import ( import (
"encoding/json" "encoding/json"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"testing" "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 { 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 // fake service
return &api.Service{ return &api.Service{
TypeMeta: unversioned.TypeMeta{ TypeMeta: meta_v1.TypeMeta{
Kind: "ingress", Kind: "ingress",
APIVersion: "v1", APIVersion: "v1",
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Annotations: map[string]string{ Annotations: map[string]string{
fakeNpa: string(fakePs), fakeNpa: string(fakePs),
}, },

View file

@ -21,7 +21,7 @@ import (
"github.com/golang/glog" "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/annotations/parser"
) )

View file

@ -19,9 +19,10 @@ package sessionaffinity
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/intstr" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
@ -31,7 +32,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package snippet package snippet
import ( 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/annotations/parser"
) )

View file

@ -19,8 +19,9 @@ package snippet
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
) )
func TestParse(t *testing.T) { func TestParse(t *testing.T) {
@ -40,7 +41,7 @@ func TestParse(t *testing.T) {
} }
ing := &extensions.Ingress{ ing := &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -17,7 +17,7 @@ limitations under the License.
package sslpassthrough package sslpassthrough
import ( 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/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

@ -19,14 +19,16 @@ package sslpassthrough
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/apimachinery/pkg/util/intstr"
) )
func buildIngress() *extensions.Ingress { func buildIngress() *extensions.Ingress {
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },

View file

@ -21,8 +21,8 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq" "k8s.io/ingress/core/pkg/ingress/annotations/authreq"

View file

@ -19,9 +19,10 @@ package controller
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/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/defaults"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"
@ -75,7 +76,7 @@ func buildIngress() *extensions.Ingress {
} }
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
}, },
@ -251,7 +252,7 @@ func TestCertificateAuthSecret(t *testing.T) {
resolver := mockCfg{} resolver := mockCfg{}
resolver.MockSecrets = map[string]*api.Secret{ resolver.MockSecrets = map[string]*api.Secret{
"default/foo_secret": { "default/foo_secret": {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_secret_name", Name: "foo_secret_name",
}, },
}, },

View file

@ -24,9 +24,9 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/client-go/tools/cache"
"k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"

View file

@ -29,17 +29,17 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"github.com/kylelemons/godebug/pretty" "github.com/kylelemons/godebug/pretty"
"k8s.io/kubernetes/pkg/api" "k8s.io/apimachinery/pkg/fields"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/client/cache" clientset "k8s.io/client-go/kubernetes"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" unversionedcore "k8s.io/client-go/kubernetes/typed/core/v1"
unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" def_api "k8s.io/client-go/pkg/api"
"k8s.io/kubernetes/pkg/client/record" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/fields" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/util/flowcontrol" "k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/util/intstr" "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"
"k8s.io/ingress/core/pkg/ingress/annotations/class" "k8s.io/ingress/core/pkg/ingress/annotations/class"
"k8s.io/ingress/core/pkg/ingress/annotations/healthcheck" "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/defaults"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"
"k8s.io/ingress/core/pkg/ingress/status" "k8s.io/ingress/core/pkg/ingress/status"
"k8s.io/ingress/core/pkg/ingress/store"
"k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/k8s"
ssl "k8s.io/ingress/core/pkg/net/ssl" ssl "k8s.io/ingress/core/pkg/net/ssl"
local_strings "k8s.io/ingress/core/pkg/strings" local_strings "k8s.io/ingress/core/pkg/strings"
@ -70,19 +71,19 @@ var (
type GenericController struct { type GenericController struct {
cfg *Configuration cfg *Configuration
ingController *cache.Controller ingController cache.Controller
endpController *cache.Controller endpController cache.Controller
svcController *cache.Controller svcController cache.Controller
nodeController *cache.Controller nodeController cache.Controller
secrController *cache.Controller secrController cache.Controller
mapController *cache.Controller mapController cache.Controller
ingLister cache_store.StoreToIngressLister ingLister store.IngressLister
svcLister cache.StoreToServiceLister svcLister store.ServiceLister
nodeLister cache.StoreToNodeLister nodeLister store.NodeLister
endpLister cache.StoreToEndpointsLister endpLister store.EndpointLister
secrLister cache_store.StoreToSecretsLister secrLister store.SecretLister
mapLister cache_store.StoreToConfigmapLister mapLister store.ConfigMapLister
annotations annotationExtractor annotations annotationExtractor
@ -149,7 +150,7 @@ func newIngressController(config *Configuration) *GenericController {
stopLock: &sync.Mutex{}, stopLock: &sync.Mutex{},
stopCh: make(chan struct{}), stopCh: make(chan struct{}),
syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.1, 1), syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.1, 1),
recorder: eventBroadcaster.NewRecorder(api.EventSource{ recorder: eventBroadcaster.NewRecorder(def_api.Scheme, api.EventSource{
Component: "ingress-controller", Component: "ingress-controller",
}), }),
sslCertTracker: newSSLCertTracker(), sslCertTracker: newSSLCertTracker(),
@ -306,12 +307,9 @@ func newIngressController(config *Configuration) *GenericController {
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", api.NamespaceAll, fields.Everything()), cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", api.NamespaceAll, fields.Everything()),
&api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler) &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()), cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "services", ic.cfg.Namespace, fields.Everything()),
&api.Service{}, &api.Service{}, ic.cfg.ResyncPeriod, cache.ResourceEventHandlerFuncs{})
ic.cfg.ResyncPeriod,
cache.ResourceEventHandlerFuncs{},
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
ic.nodeLister.Store, ic.nodeController = cache.NewInformer( ic.nodeLister.Store, ic.nodeController = cache.NewInformer(
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "nodes", api.NamespaceAll, fields.Everything()), 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 continue
} }
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(nsName) svcObj, svcExists, err := ic.svcLister.Store.GetByKey(nsName)
if err != nil { if err != nil {
glog.Warningf("error getting service %v: %v", nsName, err) glog.Warningf("error getting service %v: %v", nsName, err)
continue continue
@ -562,7 +560,7 @@ func (ic *GenericController) getDefaultUpstream() *ingress.Backend {
Name: defUpstreamName, Name: defUpstreamName,
} }
svcKey := ic.cfg.DefaultService svcKey := ic.cfg.DefaultService
svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) svcObj, svcExists, err := ic.svcLister.Store.GetByKey(svcKey)
if err != nil { if err != nil {
glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err) glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err)
upstream.Endpoints = append(upstream.Endpoints, newDefaultServer()) upstream.Endpoints = append(upstream.Endpoints, newDefaultServer())
@ -809,7 +807,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing
// to a service. // to a service.
func (ic *GenericController) serviceEndpoints(svcKey, backendPort string, func (ic *GenericController) serviceEndpoints(svcKey, backendPort string,
hz *healthcheck.Upstream) ([]ingress.Endpoint, error) { 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 var upstreams []ingress.Endpoint
if err != nil { if err != nil {

View file

@ -14,11 +14,12 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api" "k8s.io/apiserver/pkg/server/healthz"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" api "k8s.io/client-go/pkg/api/v1"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/healthz" "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/ingress"
"k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/k8s"
@ -208,19 +209,35 @@ const (
defaultBurst = 1e6 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 // 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 // the function assumes that it is running inside a Kubernetes cluster and attempts to
// discover the Apiserver. Otherwise, it connects to the Apiserver specified. // 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. // apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001.
// kubeConfig location of kubeconfig file // kubeConfig location of kubeconfig file
func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Clientset, error) { func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes.Clientset, error) {
cfg, err := buildConfigFromFlags(apiserverHost, kubeConfig)
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeConfig},
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: apiserverHost}})
cfg, err := clientConfig.ClientConfig()
if err != nil { if err != nil {
return nil, err 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) glog.Infof("Creating API server client for %s", cfg.Host)
client, err := client.NewForConfig(cfg) client, err := kubernetes.NewForConfig(cfg)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -24,9 +24,10 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
podutil "k8s.io/kubernetes/pkg/api/pod" "k8s.io/apimachinery/pkg/labels"
"k8s.io/kubernetes/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" "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 // 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 // to the port mapping obtained from the pod the service must be updated to reflect
// the current state // 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 // get the pods associated with the service
// TODO: switch this to a watch // TODO: switch this to a watch
pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(api.ListOptions{ pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(meta_v1.ListOptions{
LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(), LabelSelector: labels.Set(svc.Spec.Selector).AsSelector().String(),
}) })
if err != nil { if err != nil {
@ -60,7 +61,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
_, err := strconv.Atoi(servicePort.TargetPort.StrVal) _, err := strconv.Atoi(servicePort.TargetPort.StrVal)
if err != nil { if err != nil {
portNum, err := podutil.FindPort(pod, servicePort) portNum, err := findPort(pod, servicePort)
if err != nil { if err != nil {
glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err) glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err)
continue continue
@ -82,7 +83,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) { if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) {
data, _ := json.Marshal(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 { if err != nil {
return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err) 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 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,51 +20,55 @@ import (
"reflect" "reflect"
"testing" "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/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 { func buildSimpleClientSet() *fake.Clientset {
return testclient.NewSimpleClientset( return fake.NewSimpleClientset(
&api.PodList{Items: []api.Pod{ &api_v1.PodList{
{ Items: []api_v1.Pod{
ObjectMeta: api.ObjectMeta{ {
Name: "foo1", ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Name: "foo1",
Labels: map[string]string{ Namespace: api.NamespaceDefault,
"lable_sig": "foo_pod", Labels: map[string]string{
"lable_sig": "foo_pod",
},
}, },
}, Spec: api_v1.PodSpec{
Spec: api.PodSpec{ NodeName: "foo_node_1",
NodeName: "foo_node_1", Containers: []api_v1.Container{
Containers: []api.Container{ {
{ Ports: []api_v1.ContainerPort{
Ports: []api.ContainerPort{ {
{ Name: "foo1_named_port_c1",
Name: "foo1_named_port_c1", Protocol: api_v1.ProtocolTCP,
Protocol: api.ProtocolTCP, ContainerPort: 80,
ContainerPort: 80, },
}, },
}, },
}, },
}, },
}, },
}, {
{ ObjectMeta: meta_v1.ObjectMeta{
ObjectMeta: api.ObjectMeta{ Name: "foo1",
Name: "foo1", Namespace: api.NamespaceSystem,
Namespace: api.NamespaceSystem, Labels: map[string]string{
Labels: map[string]string{ "lable_sig": "foo_pod",
"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, Namespace: api.NamespaceDefault,
Name: "named_port_test_service", Name: "named_port_test_service",
}, },
@ -81,14 +85,13 @@ func buildGenericController() *GenericController {
} }
} }
func buildService() *api.Service { func buildService() *api_v1.Service {
return &api.Service{ return &api_v1.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Name: "named_port_test_service", Name: "named_port_test_service",
}, },
Spec: api_v1.ServiceSpec{
Spec: api.ServiceSpec{
ClusterIP: "10.10.10.10", ClusterIP: "10.10.10.10",
}, },
} }
@ -98,17 +101,17 @@ func TestCheckSvcForUpdate(t *testing.T) {
foos := []struct { foos := []struct {
n string n string
ns string ns string
sps []api.ServicePort sps []api_v1.ServicePort
sl map[string]string sl map[string]string
er string er string
}{ }{
{ {
"pods_have_not_been_found_in_this_namespace", "pods_have_not_been_found_in_this_namespace",
api.NamespaceSystem, api.NamespaceSystem,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, {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.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -118,10 +121,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"ports_have_not_been_found_in_this_pod", "ports_have_not_been_found_in_this_pod",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")}, {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.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -132,10 +135,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"ports_fixed", "ports_fixed",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(80)}, {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(80)},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -145,10 +148,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"nil_selector", "nil_selector",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, {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.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
nil, nil,
"{\"foo1_named_port_c1\":\"80\"}", "{\"foo1_named_port_c1\":\"80\"}",
@ -156,10 +159,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"normal_update", "normal_update",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, {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.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -181,7 +184,7 @@ func TestCheckSvcForUpdate(t *testing.T) {
t.Fatalf("unexpected error: %v", err) 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] rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation]
if !reflect.DeepEqual(rr, foo.er) { if !reflect.DeepEqual(rr, foo.er) {
t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n) 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 package controller
import ( import (
"testing"
"reflect" "reflect"
"testing"
"k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/auth"

View file

@ -17,7 +17,7 @@ limitations under the License.
package resolver package resolver
import ( import (
"k8s.io/kubernetes/pkg/api" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/defaults"
) )

View file

@ -17,8 +17,8 @@ limitations under the License.
package ingress package ingress
import ( import (
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/apimachinery/pkg/runtime/schema"
) )
// BackendByNameServers sorts upstreams by name // 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 // SSLCert describes a SSL certificate to be used in a server
type SSLCert struct { 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 contains the path to the file with the root certificate
CAFileName string `json:"caFileName"` CAFileName string `json:"caFileName"`
// PemFileName contains the path to the file with the certificate and key concatenated // 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 // 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 ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func buildBackendByNameServers() BackendByNameServers { func buildBackendByNameServers() BackendByNameServers {
@ -365,7 +365,7 @@ func TestLocationByPathLess(t *testing.T) {
func TestGetObjectKindForSSLCert(t *testing.T) { func TestGetObjectKindForSSLCert(t *testing.T) {
fk := &SSLCert{ fk := &SSLCert{
ObjectMeta: api.ObjectMeta{}, ObjectMeta: meta_v1.ObjectMeta{},
CAFileName: "ca_file", CAFileName: "ca_file",
PemFileName: "pemfile", PemFileName: "pemfile",
PemSHA: "pem_sha", PemSHA: "pem_sha",

View file

@ -23,16 +23,19 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/errors" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" client "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/client/leaderelection" def_api "k8s.io/client-go/pkg/api"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/client/record" "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) { 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 { if err != nil {
return "", nil, err return "", nil, err
} }
@ -56,11 +59,11 @@ func NewElection(electionID,
callback func(leader string), callback func(leader string),
c client.Interface) (*leaderelection.LeaderElector, error) { 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 err != nil {
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
_, err = c.Core().Endpoints(namespace).Create(&api.Endpoints{ _, err = c.Core().Endpoints(namespace).Create(&api.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: electionID, Name: electionID,
}, },
}) })
@ -93,13 +96,13 @@ func NewElection(electionID,
if err != nil { if err != nil {
return nil, err return nil, err
} }
recorder := broadcaster.NewRecorder(api.EventSource{ recorder := broadcaster.NewRecorder(def_api.Scheme, api.EventSource{
Component: "ingress-leader-elector", Component: "ingress-leader-elector",
Host: hostname, Host: hostname,
}) })
lock := resourcelock.EndpointsLock{ lock := resourcelock.EndpointsLock{
EndpointsMeta: api.ObjectMeta{Namespace: namespace, Name: electionID}, EndpointsMeta: meta_v1.ObjectMeta{Namespace: namespace, Name: electionID},
Client: c, Client: c,
LockConfig: resourcelock.ResourceLockConfig{ LockConfig: resourcelock.ResourceLockConfig{
Identity: id, Identity: id,

View file

@ -21,23 +21,25 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/client-go/kubernetes/fake"
tc "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/client-go/pkg/api"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
) )
func TestGetCurrentLeaderLeaderExist(t *testing.T) { func TestGetCurrentLeaderLeaderExist(t *testing.T) {
fkER := resourcelock.LeaderElectionRecord{ fkER := resourcelock.LeaderElectionRecord{
HolderIdentity: "currentLeader", HolderIdentity: "currentLeader",
LeaseDurationSeconds: 30, LeaseDurationSeconds: 30,
AcquireTime: unversioned.Now(), AcquireTime: meta_v1.NewTime(time.Now()),
RenewTime: unversioned.Now(), RenewTime: meta_v1.NewTime(time.Now()),
LeaderTransitions: 3, LeaderTransitions: 3,
} }
leaderInfo, _ := json.Marshal(fkER) leaderInfo, _ := json.Marshal(fkER)
fkEndpoints := api.Endpoints{ fkEndpoints := api_v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Annotations: map[string]string{ 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) identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err != nil { if err != nil {
t.Fatalf("expected identitiy and endpoints but returned error %s", err) 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) { func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
fkEndpoints := api.Endpoints{ fkEndpoints := api_v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Annotations: map[string]string{}, 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) identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err != nil { if err != nil {
t.Fatalf("unexpeted error: %v", err) t.Fatalf("unexpeted error: %v", err)
@ -84,8 +86,8 @@ func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
} }
func TestGetCurrentLeaderAnnotationError(t *testing.T) { func TestGetCurrentLeaderAnnotationError(t *testing.T) {
fkEndpoints := api.Endpoints{ fkEndpoints := api_v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Annotations: map[string]string{ 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) _, _, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err == nil { if err == nil {
t.Errorf("expected error") t.Errorf("expected error")
@ -101,15 +103,15 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) {
} }
func TestNewElection(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", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test-020", Name: "ingress-controller-test-020",
Namespace: api.NamespaceSystem, 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" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/labels"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/client/leaderelection" clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/labels" api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/wait" 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/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/k8s"
"k8s.io/ingress/core/pkg/strings" "k8s.io/ingress/core/pkg/strings"
"k8s.io/ingress/core/pkg/task" "k8s.io/ingress/core/pkg/task"
@ -52,7 +53,7 @@ type Sync interface {
type Config struct { type Config struct {
Client clientset.Interface Client clientset.Interface
PublishService string PublishService string
IngressLister cache_store.StoreToIngressLister IngressLister store.IngressLister
ElectionID string ElectionID string
DefaultIngressClass string DefaultIngressClass string
@ -111,7 +112,7 @@ func (s statusSync) Shutdown() {
} }
glog.Infof("removing address from ingress status (%v)", addrs) glog.Infof("removing address from ingress status (%v)", addrs)
s.updateStatus([]api.LoadBalancerIngress{}) s.updateStatus([]api_v1.LoadBalancerIngress{})
} }
func (s *statusSync) run() { func (s *statusSync) run() {
@ -196,7 +197,7 @@ func NewStatusSyncer(config Config) Sync {
func (s *statusSync) runningAddresess() ([]string, error) { func (s *statusSync) runningAddresess() ([]string, error) {
if s.PublishService != "" { if s.PublishService != "" {
ns, name, _ := k8s.ParseNameNS(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 { if err != nil {
return nil, err return nil, err
} }
@ -214,8 +215,8 @@ func (s *statusSync) runningAddresess() ([]string, error) {
} }
// get information about all the pods running the ingress controller // get information about all the pods running the ingress controller
pods, err := s.Client.Core().Pods(s.pod.Namespace).List(api.ListOptions{ pods, err := s.Client.Core().Pods(s.pod.Namespace).List(meta_v1.ListOptions{
LabelSelector: labels.SelectorFromSet(s.pod.Labels), LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(),
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -232,13 +233,13 @@ func (s *statusSync) runningAddresess() ([]string, error) {
} }
// sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress // sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress
func sliceToStatus(endpoints []string) []api.LoadBalancerIngress { func sliceToStatus(endpoints []string) []api_v1.LoadBalancerIngress {
lbi := []api.LoadBalancerIngress{} lbi := []api_v1.LoadBalancerIngress{}
for _, ep := range endpoints { for _, ep := range endpoints {
if net.ParseIP(ep) == nil { if net.ParseIP(ep) == nil {
lbi = append(lbi, api.LoadBalancerIngress{Hostname: ep}) lbi = append(lbi, api_v1.LoadBalancerIngress{Hostname: ep})
} else { } 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 return lbi
} }
func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) { func (s *statusSync) updateStatus(newIPs []api_v1.LoadBalancerIngress) {
ings := s.IngressLister.List() ings := s.IngressLister.List()
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(len(ings)) wg.Add(len(ings))
@ -261,7 +262,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
go func(wg *sync.WaitGroup, ing *extensions.Ingress) { go func(wg *sync.WaitGroup, ing *extensions.Ingress) {
defer wg.Done() defer wg.Done()
ingClient := s.Client.Extensions().Ingresses(ing.Namespace) 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 { if err != nil {
glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err) glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err)
return return
@ -286,7 +287,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
wg.Wait() wg.Wait()
} }
func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { func ingressSliceEqual(lhs, rhs []api_v1.LoadBalancerIngress) bool {
if len(lhs) != len(rhs) { if len(lhs) != len(rhs) {
return false return false
} }
@ -303,7 +304,7 @@ func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
} }
// loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP // 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) Len() int { return len(c) }
func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] }

View file

@ -23,19 +23,21 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" testclient "k8s.io/client-go/kubernetes/fake"
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/client-go/pkg/api"
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" 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" "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/k8s"
"k8s.io/ingress/core/pkg/task" "k8s.io/ingress/core/pkg/task"
) )
func buildLoadBalancerIngressByIP() loadBalancerIngressByIP { func buildLoadBalancerIngressByIP() loadBalancerIngressByIP {
return []api.LoadBalancerIngress{ return []api_v1.LoadBalancerIngress{
{ {
IP: "10.0.0.1", IP: "10.0.0.1",
Hostname: "foo1", Hostname: "foo1",
@ -57,100 +59,100 @@ func buildLoadBalancerIngressByIP() loadBalancerIngressByIP {
func buildSimpleClientSet() *testclient.Clientset { func buildSimpleClientSet() *testclient.Clientset {
return testclient.NewSimpleClientset( return testclient.NewSimpleClientset(
&api.PodList{Items: []api.Pod{ &api_v1.PodList{Items: []api_v1.Pod{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo1", Name: "foo1",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
}, },
}, },
Spec: api.PodSpec{ Spec: api_v1.PodSpec{
NodeName: "foo_node_2", NodeName: "foo_node_2",
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo2", Name: "foo2",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_no", "lable_sig": "foo_no",
}, },
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo3", Name: "foo3",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
}, },
}, },
Spec: api.PodSpec{ Spec: api_v1.PodSpec{
NodeName: "foo_node_2", 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", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: api.ServiceStatus{ Status: api_v1.ServiceStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: buildLoadBalancerIngressByIP(), Ingress: buildLoadBalancerIngressByIP(),
}, },
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_non_exist", 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", Name: "foo_node_1",
}, },
Status: api.NodeStatus{ Status: api_v1.NodeStatus{
Addresses: []api.NodeAddress{ Addresses: []api_v1.NodeAddress{
{ {
Type: api.NodeLegacyHostIP, Type: api_v1.NodeLegacyHostIP,
Address: "10.0.0.1", Address: "10.0.0.1",
}, { }, {
Type: api.NodeExternalIP, Type: api_v1.NodeExternalIP,
Address: "10.0.0.2", Address: "10.0.0.2",
}, },
}, },
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_node_2", Name: "foo_node_2",
}, },
Status: api.NodeStatus{ Status: api_v1.NodeStatus{
Addresses: []api.NodeAddress{ Addresses: []api_v1.NodeAddress{
{ {
Type: api.NodeLegacyHostIP, Type: api_v1.NodeLegacyHostIP,
Address: "11.0.0.1", Address: "11.0.0.1",
}, },
{ {
Type: api.NodeExternalIP, Type: api_v1.NodeExternalIP,
Address: "11.0.0.2", 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", Name: "ingress-controller-leader",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
SelfLink: "/api/v1/namespaces/default/endpoints/ingress-controller-leader", SelfLink: "/api/v1/namespaces/default/endpoints/ingress-controller-leader",
}, },
}}}, }}},
@ -165,13 +167,13 @@ func fakeSynFn(interface{}) error {
func buildExtensionsIngresses() []extensions.Ingress { func buildExtensionsIngresses() []extensions.Ingress {
return []extensions.Ingress{ return []extensions.Ingress{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_1", Name: "foo_ingress_1",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{ Ingress: []api_v1.LoadBalancerIngress{
{ {
IP: "10.0.0.1", IP: "10.0.0.1",
Hostname: "foo1", Hostname: "foo1",
@ -181,7 +183,7 @@ func buildExtensionsIngresses() []extensions.Ingress {
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_different_class", Name: "foo_ingress_different_class",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Annotations: map[string]string{ Annotations: map[string]string{
@ -189,8 +191,8 @@ func buildExtensionsIngresses() []extensions.Ingress {
}, },
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{ Ingress: []api_v1.LoadBalancerIngress{
{ {
IP: "0.0.0.0", IP: "0.0.0.0",
Hostname: "foo.bar.com", Hostname: "foo.bar.com",
@ -200,45 +202,45 @@ func buildExtensionsIngresses() []extensions.Ingress {
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_2", Name: "foo_ingress_2",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{}, Ingress: []api_v1.LoadBalancerIngress{},
}, },
}, },
}, },
} }
} }
func buildIngressListener() cache_store.StoreToIngressLister { func buildIngressListener() cache_store.IngressLister {
store := cache.NewStore(cache.MetaNamespaceKeyFunc) store := cache.NewStore(cache.MetaNamespaceKeyFunc)
store.Add(&extensions.Ingress{ store.Add(&extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_non_01", Name: "foo_ingress_non_01",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}}) }})
store.Add(&extensions.Ingress{ store.Add(&extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_1", Name: "foo_ingress_1",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: buildLoadBalancerIngressByIP(), Ingress: buildLoadBalancerIngressByIP(),
}, },
}, },
}) })
return cache_store.StoreToIngressLister{Store: store} return cache_store.IngressLister{Store: store}
} }
func buildStatusSync() statusSync { func buildStatusSync() statusSync {
return statusSync{ return statusSync{
pod: &k8s.PodInfo{ pod: &k8s.PodInfo{
Name: "foo_base_pod", Name: "foo_base_pod",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
}, },
@ -247,7 +249,7 @@ func buildStatusSync() statusSync {
syncQueue: task.NewTaskQueue(fakeSynFn), syncQueue: task.NewTaskQueue(fakeSynFn),
Config: Config{ Config: Config{
Client: buildSimpleClientSet(), Client: buildSimpleClientSet(),
PublishService: api.NamespaceDefault + "/" + "foo", PublishService: api_v1.NamespaceDefault + "/" + "foo",
IngressLister: buildIngressListener(), IngressLister: buildIngressListener(),
}, },
} }
@ -256,7 +258,7 @@ func buildStatusSync() statusSync {
func TestStatusActions(t *testing.T) { func TestStatusActions(t *testing.T) {
// make sure election can be created // make sure election can be created
os.Setenv("POD_NAME", "foo1") os.Setenv("POD_NAME", "foo1")
os.Setenv("POD_NAMESPACE", api.NamespaceDefault) os.Setenv("POD_NAMESPACE", api_v1.NamespaceDefault)
c := Config{ c := Config{
Client: buildSimpleClientSet(), Client: buildSimpleClientSet(),
PublishService: "", PublishService: "",
@ -273,7 +275,7 @@ func TestStatusActions(t *testing.T) {
fk := fkSync.(statusSync) fk := fkSync.(statusSync)
ns := make(chan struct{}) 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) go fk.Run(ns)
// wait for the election // wait for the election
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
@ -281,10 +283,10 @@ func TestStatusActions(t *testing.T) {
fk.sync("just-test") fk.sync("just-test")
// PublishService is empty, so the running address is: ["11.0.0.2"] // 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" // 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", 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 { if err1 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -296,8 +298,8 @@ func TestStatusActions(t *testing.T) {
// execute shutdown // execute shutdown
fk.Shutdown() fk.Shutdown()
// ingress should be empty // ingress should be empty
newIPs2 := []api.LoadBalancerIngress{} newIPs2 := []api_v1.LoadBalancerIngress{}
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
if err2 != nil { if err2 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -306,7 +308,7 @@ func TestStatusActions(t *testing.T) {
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2) 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 { if err != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -374,7 +376,7 @@ func TestUpdateStatus(t *testing.T) {
sort.Sort(loadBalancerIngressByIP(newIPs)) sort.Sort(loadBalancerIngressByIP(newIPs))
fk.updateStatus(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 { if err1 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -383,13 +385,13 @@ func TestUpdateStatus(t *testing.T) {
t.Fatalf("returned %v but expected %v", fooIngress1CurIPs, newIPs) 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 { if err2 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
fooIngress2CurIPs := fooIngress2.Status.LoadBalancer.Ingress fooIngress2CurIPs := fooIngress2.Status.LoadBalancer.Ingress
if !ingressSliceEqual(fooIngress2CurIPs, []api.LoadBalancerIngress{}) { if !ingressSliceEqual(fooIngress2CurIPs, []api_v1.LoadBalancerIngress{}) {
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api.LoadBalancerIngress{}) t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api_v1.LoadBalancerIngress{})
} }
} }
@ -403,7 +405,7 @@ func TestSliceToStatus(t *testing.T) {
r := sliceToStatus(fkEndpoints) r := sliceToStatus(fkEndpoints)
if r == nil { 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) rl := len(r)
if rl != 3 { if rl != 3 {
@ -411,21 +413,21 @@ func TestSliceToStatus(t *testing.T) {
} }
re1 := r[0] re1 := r[0]
if re1.Hostname != "opensource-k8s-ingress" { 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] re2 := r[1]
if re2.IP != "10.0.0.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] re3 := r[2]
if re3.IP != "2001:db8::68" { 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) { func TestIngressSliceEqual(t *testing.T) {
fk1 := buildLoadBalancerIngressByIP() fk1 := buildLoadBalancerIngressByIP()
fk2 := append(buildLoadBalancerIngressByIP(), api.LoadBalancerIngress{ fk2 := append(buildLoadBalancerIngressByIP(), api_v1.LoadBalancerIngress{
IP: "10.0.0.5", IP: "10.0.0.5",
Hostname: "foo5", Hostname: "foo5",
}) })
@ -435,8 +437,8 @@ func TestIngressSliceEqual(t *testing.T) {
fk4[2].IP = "11.0.0.3" fk4[2].IP = "11.0.0.3"
fooTests := []struct { fooTests := []struct {
lhs []api.LoadBalancerIngress lhs []api_v1.LoadBalancerIngress
rhs []api.LoadBalancerIngress rhs []api_v1.LoadBalancerIngress
er bool er bool
}{ }{
{fk1, fk1, true}, {fk1, fk1, true},
@ -445,7 +447,7 @@ func TestIngressSliceEqual(t *testing.T) {
{fk4, fk1, false}, {fk4, fk1, false},
{fk1, nil, false}, {fk1, nil, false},
{nil, nil, true}, {nil, nil, true},
{[]api.LoadBalancerIngress{}, []api.LoadBalancerIngress{}, true}, {[]api_v1.LoadBalancerIngress{}, []api_v1.LoadBalancerIngress{}, true},
} }
for _, fooTest := range fooTests { for _, fooTest := range fooTests {
@ -461,7 +463,7 @@ func TestLoadBalancerIngressByIPLen(t *testing.T) {
ips loadBalancerIngressByIP ips loadBalancerIngressByIP
el int el int
}{ }{
{[]api.LoadBalancerIngress{}, 0}, {[]api_v1.LoadBalancerIngress{}, 0},
{buildLoadBalancerIngressByIP(), 4}, {buildLoadBalancerIngressByIP(), 4},
{nil, 0}, {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 ( import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/apiserver/pkg/server/healthz"
"k8s.io/kubernetes/pkg/healthz" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr"
cache_store "k8s.io/ingress/core/pkg/cache"
"k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq" "k8s.io/ingress/core/pkg/ingress/annotations/authreq"
"k8s.io/ingress/core/pkg/ingress/annotations/authtls" "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/ratelimit"
"k8s.io/ingress/core/pkg/ingress/annotations/rewrite" "k8s.io/ingress/core/pkg/ingress/annotations/rewrite"
"k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/ingress/store"
) )
var ( var (
@ -103,12 +102,12 @@ type Controller interface {
// StoreLister returns the configured stores for ingresses, services, // StoreLister returns the configured stores for ingresses, services,
// endpoints, secrets and configmaps. // endpoints, secrets and configmaps.
type StoreLister struct { type StoreLister struct {
Ingress cache_store.StoreToIngressLister Ingress store.IngressLister
Service cache.StoreToServiceLister Service store.ServiceLister
Node cache.StoreToNodeLister Node store.NodeLister
Endpoint cache.StoreToEndpointsLister Endpoint store.EndpointLister
Secret cache_store.StoreToSecretsLister Secret store.SecretLister
ConfigMap cache_store.StoreToConfigmapLister ConfigMap store.ConfigMapLister
} }
// BackendInfo returns information about the backend. // BackendInfo returns information about the backend.

View file

@ -21,8 +21,9 @@ import (
"os" "os"
"strings" "strings"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
) )
// IsValidService checks if exists a service with the specified name // 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 { if err != nil {
return nil, err 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 // 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 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 { if err != nil {
return nil, fmt.Errorf("configmap not found: %v", err) 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 // isValidNamespace chck if exists a namespace with the specified name
func IsValidNamespace(kubeClient clientset.Interface, name string) (*api.Namespace, error) { 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 // 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 { if err != nil {
return nil, err 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 // 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 // GetNodeIP returns the IP address of a node in the cluster
func GetNodeIP(kubeClient clientset.Interface, name string) string { func GetNodeIP(kubeClient clientset.Interface, name string) string {
var externalIP string var externalIP string
node, err := kubeClient.Core().Nodes().Get(name) node, err := kubeClient.Core().Nodes().Get(name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return externalIP 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") 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 { if pod == nil {
return nil, fmt.Errorf("unable to get POD information") return nil, fmt.Errorf("unable to get POD information")
} }

View file

@ -17,11 +17,12 @@ limitations under the License.
package k8s package k8s
import ( import (
"os"
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" testclient "k8s.io/client-go/kubernetes/fake"
"os" api "k8s.io/client-go/pkg/api/v1"
) )
func TestParseNameNS(t *testing.T) { func TestParseNameNS(t *testing.T) {
@ -57,7 +58,7 @@ func TestParseNameNS(t *testing.T) {
func TestIsValidService(t *testing.T) { func TestIsValidService(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.Service{ fk := testclient.NewSimpleClientset(&api.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Name: "demo", Name: "demo",
}, },
@ -88,7 +89,7 @@ func TestIsValidService(t *testing.T) {
func TestIsValidNamespace(t *testing.T) { func TestIsValidNamespace(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.Namespace{ fk := testclient.NewSimpleClientset(&api.Namespace{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "default", Name: "default",
}, },
}) })
@ -112,7 +113,7 @@ func TestIsValidNamespace(t *testing.T) {
func TestIsValidConfigMap(t *testing.T) { func TestIsValidConfigMap(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.ConfigMap{ fk := testclient.NewSimpleClientset(&api.ConfigMap{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Name: "demo", Name: "demo",
}, },
@ -145,7 +146,7 @@ func TestIsValidConfigMap(t *testing.T) {
func TestIsValidSecret(t *testing.T) { func TestIsValidSecret(t *testing.T) {
fk := testclient.NewSimpleClientset(&api.Secret{ fk := testclient.NewSimpleClientset(&api.Secret{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Name: "demo", Name: "demo",
}, },
@ -184,7 +185,7 @@ func TestGetNodeIP(t *testing.T) {
// node not exist // node not exist
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo", Name: "demo",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{
@ -199,7 +200,7 @@ func TestGetNodeIP(t *testing.T) {
// node exist // node exist
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo", Name: "demo",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{
@ -215,7 +216,7 @@ func TestGetNodeIP(t *testing.T) {
// search the correct node // search the correct node
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{ {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo1", Name: "demo1",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{
@ -228,7 +229,7 @@ func TestGetNodeIP(t *testing.T) {
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo2", Name: "demo2",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{
@ -244,7 +245,7 @@ func TestGetNodeIP(t *testing.T) {
// get NodeExternalIP // get NodeExternalIP
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo", Name: "demo",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{
@ -262,7 +263,7 @@ func TestGetNodeIP(t *testing.T) {
// get NodeLegacyHostIP // get NodeLegacyHostIP
{testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo", Name: "demo",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{
@ -307,7 +308,7 @@ func TestGetPodDetails(t *testing.T) {
// success to get PodInfo // success to get PodInfo
fkClient := testclient.NewSimpleClientset( fkClient := testclient.NewSimpleClientset(
&api.PodList{Items: []api.Pod{{ &api.PodList{Items: []api.Pod{{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "testpod", Name: "testpod",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
@ -317,7 +318,7 @@ func TestGetPodDetails(t *testing.T) {
}, },
}}}, }}},
&api.NodeList{Items: []api.Node{{ &api.NodeList{Items: []api.Node{{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "demo", Name: "demo",
}, },
Status: api.NodeStatus{ Status: api.NodeStatus{

View file

@ -22,9 +22,9 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/pkg/util/workqueue" "k8s.io/client-go/util/workqueue"
) )
var ( var (

View file

@ -8,11 +8,12 @@ import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
api "k8s.io/client-go/pkg/api/v1"
nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config" nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config"
"k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/controller" "k8s.io/ingress/core/pkg/ingress/controller"
"k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/kubernetes/pkg/api"
) )
func main() { func main() {
@ -89,3 +90,7 @@ func (n DummyController) OverrideFlags(*pflag.FlagSet) {
func (n DummyController) SetListers(lister ingress.StoreLister) { func (n DummyController) SetListers(lister ingress.StoreLister) {
} }
func (n DummyController) DefaultIngressClass() string {
return "dummy"
}