diff --git a/controllers/nginx/pkg/cmd/controller/nginx.go b/controllers/nginx/pkg/cmd/controller/nginx.go index f8685deee..91d1f48e3 100644 --- a/controllers/nginx/pkg/cmd/controller/nginx.go +++ b/controllers/nginx/pkg/cmd/controller/nginx.go @@ -32,7 +32,7 @@ import ( "github.com/golang/glog" "github.com/spf13/pflag" - "k8s.io/kubernetes/pkg/api" + api_v1 "k8s.io/client-go/pkg/api/v1" "strings" @@ -71,7 +71,7 @@ func newNGINXController() ingress.Controller { } n := &NGINXController{ binary: ngx, - configmap: &api.ConfigMap{}, + configmap: &api_v1.ConfigMap{}, } var onChange func() @@ -108,7 +108,7 @@ Error loading new template : %v type NGINXController struct { t *ngx_template.Template - configmap *api.ConfigMap + configmap *api_v1.ConfigMap storeLister ingress.StoreLister @@ -308,7 +308,7 @@ Error: %v } // SetConfig sets the configured configmap -func (n *NGINXController) SetConfig(cmap *api.ConfigMap) { +func (n *NGINXController) SetConfig(cmap *api_v1.ConfigMap) { n.configmap = cmap } @@ -383,7 +383,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er } if exists { - setHeaders = cmap.(*api.ConfigMap).Data + setHeaders = cmap.(*api_v1.ConfigMap).Data } } @@ -396,7 +396,7 @@ func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) ([]byte, er } if exists { - secret := s.(*api.Secret) + secret := s.(*api_v1.Secret) nsSecName := strings.Replace(secretName, "/", "-", -1) dh, ok := secret.Data["dhparam.pem"] diff --git a/controllers/nginx/pkg/template/template.go b/controllers/nginx/pkg/template/template.go index 70fecb211..14ae2025b 100644 --- a/controllers/nginx/pkg/template/template.go +++ b/controllers/nginx/pkg/template/template.go @@ -26,7 +26,7 @@ import ( "strings" text_template "text/template" - "k8s.io/kubernetes/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/sets" "github.com/golang/glog" diff --git a/core/pkg/cache/main.go b/core/pkg/cache/main.go deleted file mode 100644 index 04257a0ba..000000000 --- a/core/pkg/cache/main.go +++ /dev/null @@ -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 -} diff --git a/core/pkg/cache/main_test.go b/core/pkg/cache/main_test.go deleted file mode 100644 index 72dc7617e..000000000 --- a/core/pkg/cache/main_test.go +++ /dev/null @@ -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) - } -} diff --git a/core/pkg/ingress/annotations/auth/main.go b/core/pkg/ingress/annotations/auth/main.go index fe2167f03..33abf407c 100644 --- a/core/pkg/ingress/annotations/auth/main.go +++ b/core/pkg/ingress/annotations/auth/main.go @@ -24,8 +24,8 @@ import ( "regexp" "github.com/pkg/errors" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ing_errors "k8s.io/ingress/core/pkg/ingress/errors" diff --git a/core/pkg/ingress/annotations/auth/main_test.go b/core/pkg/ingress/annotations/auth/main_test.go index 6d4027313..aec7549b3 100644 --- a/core/pkg/ingress/annotations/auth/main_test.go +++ b/core/pkg/ingress/annotations/auth/main_test.go @@ -24,9 +24,11 @@ import ( "time" "github.com/pkg/errors" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) func buildIngress() *extensions.Ingress { @@ -36,7 +38,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, @@ -73,7 +75,7 @@ func (m mockSecret) GetSecret(name string) (*api.Secret, error) { } return &api.Secret{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "demo-secret", }, diff --git a/core/pkg/ingress/annotations/authreq/main.go b/core/pkg/ingress/annotations/authreq/main.go index e26a94185..529791f0e 100644 --- a/core/pkg/ingress/annotations/authreq/main.go +++ b/core/pkg/ingress/annotations/authreq/main.go @@ -21,7 +21,7 @@ import ( "strings" "regexp" - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ing_errors "k8s.io/ingress/core/pkg/ingress/errors" diff --git a/core/pkg/ingress/annotations/authreq/main_test.go b/core/pkg/ingress/annotations/authreq/main_test.go index 319c75853..aa1a18d23 100644 --- a/core/pkg/ingress/annotations/authreq/main_test.go +++ b/core/pkg/ingress/annotations/authreq/main_test.go @@ -21,9 +21,11 @@ import ( "testing" "reflect" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + + "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *extensions.Ingress { @@ -33,7 +35,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/authtls/main.go b/core/pkg/ingress/annotations/authtls/main.go index c4172e51c..2de8b22c0 100644 --- a/core/pkg/ingress/annotations/authtls/main.go +++ b/core/pkg/ingress/annotations/authtls/main.go @@ -18,7 +18,7 @@ package authtls import ( "github.com/pkg/errors" - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ing_errors "k8s.io/ingress/core/pkg/ingress/errors" diff --git a/core/pkg/ingress/annotations/authtls/main_test.go b/core/pkg/ingress/annotations/authtls/main_test.go index b1f4886f6..50057503b 100644 --- a/core/pkg/ingress/annotations/authtls/main_test.go +++ b/core/pkg/ingress/annotations/authtls/main_test.go @@ -19,9 +19,10 @@ package authtls import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) func buildIngress() *extensions.Ingress { @@ -31,7 +32,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/class/main.go b/core/pkg/ingress/annotations/class/main.go index d9e862938..1c1066e16 100644 --- a/core/pkg/ingress/annotations/class/main.go +++ b/core/pkg/ingress/annotations/class/main.go @@ -18,7 +18,7 @@ package class import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/errors" diff --git a/core/pkg/ingress/annotations/class/main_test.go b/core/pkg/ingress/annotations/class/main_test.go index bf204052f..f48525078 100644 --- a/core/pkg/ingress/annotations/class/main_test.go +++ b/core/pkg/ingress/annotations/class/main_test.go @@ -19,8 +19,9 @@ package class import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) func TestIsValidClass(t *testing.T) { @@ -40,7 +41,7 @@ func TestIsValidClass(t *testing.T) { } ing := &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/cors/main.go b/core/pkg/ingress/annotations/cors/main.go index 71195863f..c460f8215 100644 --- a/core/pkg/ingress/annotations/cors/main.go +++ b/core/pkg/ingress/annotations/cors/main.go @@ -17,7 +17,7 @@ limitations under the License. package cors import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) diff --git a/core/pkg/ingress/annotations/cors/main_test.go b/core/pkg/ingress/annotations/cors/main_test.go index 61521f301..480356ca8 100644 --- a/core/pkg/ingress/annotations/cors/main_test.go +++ b/core/pkg/ingress/annotations/cors/main_test.go @@ -19,8 +19,9 @@ package cors import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) const ( @@ -45,7 +46,7 @@ func TestParse(t *testing.T) { } ing := &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/healthcheck/main.go b/core/pkg/ingress/annotations/healthcheck/main.go index 493195154..973e911dc 100644 --- a/core/pkg/ingress/annotations/healthcheck/main.go +++ b/core/pkg/ingress/annotations/healthcheck/main.go @@ -17,7 +17,7 @@ limitations under the License. package healthcheck import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/resolver" diff --git a/core/pkg/ingress/annotations/healthcheck/main_test.go b/core/pkg/ingress/annotations/healthcheck/main_test.go index 21166cbe0..09215b17b 100644 --- a/core/pkg/ingress/annotations/healthcheck/main_test.go +++ b/core/pkg/ingress/annotations/healthcheck/main_test.go @@ -19,9 +19,10 @@ package healthcheck import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/defaults" ) @@ -33,7 +34,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/ipwhitelist/main.go b/core/pkg/ingress/annotations/ipwhitelist/main.go index d42f0fad3..3c043967b 100644 --- a/core/pkg/ingress/annotations/ipwhitelist/main.go +++ b/core/pkg/ingress/annotations/ipwhitelist/main.go @@ -21,7 +21,8 @@ import ( "strings" "github.com/pkg/errors" - "k8s.io/kubernetes/pkg/apis/extensions" + + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/util/net/sets" "k8s.io/ingress/core/pkg/ingress/annotations/parser" diff --git a/core/pkg/ingress/annotations/ipwhitelist/main_test.go b/core/pkg/ingress/annotations/ipwhitelist/main_test.go index 190a36f89..ba2c946a1 100644 --- a/core/pkg/ingress/annotations/ipwhitelist/main_test.go +++ b/core/pkg/ingress/annotations/ipwhitelist/main_test.go @@ -20,9 +20,10 @@ import ( "reflect" "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/errors" @@ -35,7 +36,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/parser/main.go b/core/pkg/ingress/annotations/parser/main.go index bff6f2210..a35c80a38 100644 --- a/core/pkg/ingress/annotations/parser/main.go +++ b/core/pkg/ingress/annotations/parser/main.go @@ -19,7 +19,7 @@ package parser import ( "strconv" - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/errors" ) diff --git a/core/pkg/ingress/annotations/parser/main_test.go b/core/pkg/ingress/annotations/parser/main_test.go index 099e76556..8dd2db1b5 100644 --- a/core/pkg/ingress/annotations/parser/main_test.go +++ b/core/pkg/ingress/annotations/parser/main_test.go @@ -19,13 +19,14 @@ package parser import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) func buildIngress() *extensions.Ingress { return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/portinredirect/main.go b/core/pkg/ingress/annotations/portinredirect/main.go index 1b16e8dcd..2f264f32d 100644 --- a/core/pkg/ingress/annotations/portinredirect/main.go +++ b/core/pkg/ingress/annotations/portinredirect/main.go @@ -17,7 +17,7 @@ limitations under the License. package portinredirect import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/resolver" diff --git a/core/pkg/ingress/annotations/portinredirect/main_test.go b/core/pkg/ingress/annotations/portinredirect/main_test.go index cb6403fd1..46fe8ad92 100644 --- a/core/pkg/ingress/annotations/portinredirect/main_test.go +++ b/core/pkg/ingress/annotations/portinredirect/main_test.go @@ -19,9 +19,10 @@ package portinredirect import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "fmt" @@ -35,7 +36,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/proxy/main.go b/core/pkg/ingress/annotations/proxy/main.go index ab7d2e07a..e097edd24 100644 --- a/core/pkg/ingress/annotations/proxy/main.go +++ b/core/pkg/ingress/annotations/proxy/main.go @@ -17,7 +17,7 @@ limitations under the License. package proxy import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/resolver" diff --git a/core/pkg/ingress/annotations/proxy/main_test.go b/core/pkg/ingress/annotations/proxy/main_test.go index 8671c42a4..11e85dc30 100644 --- a/core/pkg/ingress/annotations/proxy/main_test.go +++ b/core/pkg/ingress/annotations/proxy/main_test.go @@ -19,9 +19,10 @@ package proxy import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/defaults" ) @@ -33,7 +34,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/ratelimit/main.go b/core/pkg/ingress/annotations/ratelimit/main.go index 31850a90b..06a0160b7 100644 --- a/core/pkg/ingress/annotations/ratelimit/main.go +++ b/core/pkg/ingress/annotations/ratelimit/main.go @@ -19,7 +19,7 @@ package ratelimit import ( "fmt" - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) diff --git a/core/pkg/ingress/annotations/ratelimit/main_test.go b/core/pkg/ingress/annotations/ratelimit/main_test.go index 46ad25d54..4718851de 100644 --- a/core/pkg/ingress/annotations/ratelimit/main_test.go +++ b/core/pkg/ingress/annotations/ratelimit/main_test.go @@ -19,9 +19,11 @@ package ratelimit import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + + "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *extensions.Ingress { @@ -31,7 +33,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/rewrite/main.go b/core/pkg/ingress/annotations/rewrite/main.go index e522a275a..771fc80a7 100644 --- a/core/pkg/ingress/annotations/rewrite/main.go +++ b/core/pkg/ingress/annotations/rewrite/main.go @@ -17,7 +17,7 @@ limitations under the License. package rewrite import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/resolver" diff --git a/core/pkg/ingress/annotations/rewrite/main_test.go b/core/pkg/ingress/annotations/rewrite/main_test.go index 2a3252184..38f224d9d 100644 --- a/core/pkg/ingress/annotations/rewrite/main_test.go +++ b/core/pkg/ingress/annotations/rewrite/main_test.go @@ -19,9 +19,10 @@ package rewrite import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/defaults" ) @@ -37,7 +38,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/secureupstream/main.go b/core/pkg/ingress/annotations/secureupstream/main.go index 732b577cd..331b44b96 100644 --- a/core/pkg/ingress/annotations/secureupstream/main.go +++ b/core/pkg/ingress/annotations/secureupstream/main.go @@ -17,7 +17,7 @@ limitations under the License. package secureupstream import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) diff --git a/core/pkg/ingress/annotations/secureupstream/main_test.go b/core/pkg/ingress/annotations/secureupstream/main_test.go index a841e28c7..388cc8ddc 100644 --- a/core/pkg/ingress/annotations/secureupstream/main_test.go +++ b/core/pkg/ingress/annotations/secureupstream/main_test.go @@ -19,9 +19,11 @@ package secureupstream import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + + "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *extensions.Ingress { @@ -31,7 +33,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/service/service.go b/core/pkg/ingress/annotations/service/service.go index 0615645c8..b268e63ed 100644 --- a/core/pkg/ingress/annotations/service/service.go +++ b/core/pkg/ingress/annotations/service/service.go @@ -21,9 +21,9 @@ import ( "fmt" "strconv" - "k8s.io/kubernetes/pkg/api" - "github.com/golang/glog" + + api_v1 "k8s.io/client-go/pkg/api/v1" ) const ( @@ -54,7 +54,7 @@ func (npm namedPortMapping) getPortMappings() map[string]string { } // GetPortMapping returns the number of the named port or an error if is not valid -func GetPortMapping(name string, s *api.Service) (int32, error) { +func GetPortMapping(name string, s *api_v1.Service) (int32, error) { if s == nil { return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name) } diff --git a/core/pkg/ingress/annotations/service/service_test.go b/core/pkg/ingress/annotations/service/service_test.go index abfa0f907..2eaf016aa 100644 --- a/core/pkg/ingress/annotations/service/service_test.go +++ b/core/pkg/ingress/annotations/service/service_test.go @@ -18,9 +18,10 @@ package service import ( "encoding/json" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/unversioned" "testing" + + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" ) func fakeService(npa bool, ps bool, expectedP string) *api.Service { @@ -41,11 +42,11 @@ func fakeService(npa bool, ps bool, expectedP string) *api.Service { // fake service return &api.Service{ - TypeMeta: unversioned.TypeMeta{ + TypeMeta: meta_v1.TypeMeta{ Kind: "ingress", APIVersion: "v1", }, - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Annotations: map[string]string{ fakeNpa: string(fakePs), }, diff --git a/core/pkg/ingress/annotations/sessionaffinity/main.go b/core/pkg/ingress/annotations/sessionaffinity/main.go index d506e844e..d6760f156 100644 --- a/core/pkg/ingress/annotations/sessionaffinity/main.go +++ b/core/pkg/ingress/annotations/sessionaffinity/main.go @@ -21,7 +21,7 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) diff --git a/core/pkg/ingress/annotations/sessionaffinity/main_test.go b/core/pkg/ingress/annotations/sessionaffinity/main_test.go index 3a3a17200..4a44389b1 100644 --- a/core/pkg/ingress/annotations/sessionaffinity/main_test.go +++ b/core/pkg/ingress/annotations/sessionaffinity/main_test.go @@ -19,9 +19,10 @@ package sessionaffinity import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) func buildIngress() *extensions.Ingress { @@ -31,7 +32,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/snippet/main.go b/core/pkg/ingress/annotations/snippet/main.go index d88cfbc32..8a6970d1b 100644 --- a/core/pkg/ingress/annotations/snippet/main.go +++ b/core/pkg/ingress/annotations/snippet/main.go @@ -17,7 +17,7 @@ limitations under the License. package snippet import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ) diff --git a/core/pkg/ingress/annotations/snippet/main_test.go b/core/pkg/ingress/annotations/snippet/main_test.go index 269996a95..450a21487 100644 --- a/core/pkg/ingress/annotations/snippet/main_test.go +++ b/core/pkg/ingress/annotations/snippet/main_test.go @@ -19,8 +19,9 @@ package snippet import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" ) func TestParse(t *testing.T) { @@ -40,7 +41,7 @@ func TestParse(t *testing.T) { } ing := &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/annotations/sslpassthrough/main.go b/core/pkg/ingress/annotations/sslpassthrough/main.go index 99fcd0ab3..e6895c068 100644 --- a/core/pkg/ingress/annotations/sslpassthrough/main.go +++ b/core/pkg/ingress/annotations/sslpassthrough/main.go @@ -17,7 +17,7 @@ limitations under the License. package sslpassthrough import ( - "k8s.io/kubernetes/pkg/apis/extensions" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/parser" ing_errors "k8s.io/ingress/core/pkg/ingress/errors" diff --git a/core/pkg/ingress/annotations/sslpassthrough/main_test.go b/core/pkg/ingress/annotations/sslpassthrough/main_test.go index 3f1f6286b..fc4c990e5 100644 --- a/core/pkg/ingress/annotations/sslpassthrough/main_test.go +++ b/core/pkg/ingress/annotations/sslpassthrough/main_test.go @@ -19,14 +19,16 @@ package sslpassthrough import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + + "k8s.io/apimachinery/pkg/util/intstr" ) func buildIngress() *extensions.Ingress { return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, diff --git a/core/pkg/ingress/controller/annotations.go b/core/pkg/ingress/controller/annotations.go index b0ab4218b..75b7df684 100644 --- a/core/pkg/ingress/controller/annotations.go +++ b/core/pkg/ingress/controller/annotations.go @@ -21,8 +21,8 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/authreq" diff --git a/core/pkg/ingress/controller/annotations_test.go b/core/pkg/ingress/controller/annotations_test.go index 0b0aa5d91..7b612a7c6 100644 --- a/core/pkg/ingress/controller/annotations_test.go +++ b/core/pkg/ingress/controller/annotations_test.go @@ -19,9 +19,10 @@ package controller import ( "testing" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/util/intstr" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" "k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/resolver" @@ -75,7 +76,7 @@ func buildIngress() *extensions.Ingress { } return &extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", Namespace: api.NamespaceDefault, }, @@ -251,7 +252,7 @@ func TestCertificateAuthSecret(t *testing.T) { resolver := mockCfg{} resolver.MockSecrets = map[string]*api.Secret{ "default/foo_secret": { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_secret_name", }, }, diff --git a/core/pkg/ingress/controller/backend_ssl.go b/core/pkg/ingress/controller/backend_ssl.go index 74d1da3d0..419b05744 100644 --- a/core/pkg/ingress/controller/backend_ssl.go +++ b/core/pkg/ingress/controller/backend_ssl.go @@ -24,9 +24,9 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/cache" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + "k8s.io/client-go/tools/cache" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/annotations/parser" diff --git a/core/pkg/ingress/controller/controller.go b/core/pkg/ingress/controller/controller.go index 82bedae32..a97fe6cfc 100644 --- a/core/pkg/ingress/controller/controller.go +++ b/core/pkg/ingress/controller/controller.go @@ -29,17 +29,17 @@ import ( "github.com/golang/glog" "github.com/kylelemons/godebug/pretty" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/cache" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - unversionedcore "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" - "k8s.io/kubernetes/pkg/client/record" - "k8s.io/kubernetes/pkg/fields" - "k8s.io/kubernetes/pkg/util/flowcontrol" - "k8s.io/kubernetes/pkg/util/intstr" + "k8s.io/apimachinery/pkg/fields" + "k8s.io/apimachinery/pkg/util/intstr" + clientset "k8s.io/client-go/kubernetes" + unversionedcore "k8s.io/client-go/kubernetes/typed/core/v1" + def_api "k8s.io/client-go/pkg/api" + api "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/record" + "k8s.io/client-go/util/flowcontrol" - cache_store "k8s.io/ingress/core/pkg/cache" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/annotations/class" "k8s.io/ingress/core/pkg/ingress/annotations/healthcheck" @@ -48,6 +48,7 @@ import ( "k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/status" + "k8s.io/ingress/core/pkg/ingress/store" "k8s.io/ingress/core/pkg/k8s" ssl "k8s.io/ingress/core/pkg/net/ssl" local_strings "k8s.io/ingress/core/pkg/strings" @@ -70,19 +71,19 @@ var ( type GenericController struct { cfg *Configuration - ingController *cache.Controller - endpController *cache.Controller - svcController *cache.Controller - nodeController *cache.Controller - secrController *cache.Controller - mapController *cache.Controller + ingController cache.Controller + endpController cache.Controller + svcController cache.Controller + nodeController cache.Controller + secrController cache.Controller + mapController cache.Controller - ingLister cache_store.StoreToIngressLister - svcLister cache.StoreToServiceLister - nodeLister cache.StoreToNodeLister - endpLister cache.StoreToEndpointsLister - secrLister cache_store.StoreToSecretsLister - mapLister cache_store.StoreToConfigmapLister + ingLister store.IngressLister + svcLister store.ServiceLister + nodeLister store.NodeLister + endpLister store.EndpointLister + secrLister store.SecretLister + mapLister store.ConfigMapLister annotations annotationExtractor @@ -149,7 +150,7 @@ func newIngressController(config *Configuration) *GenericController { stopLock: &sync.Mutex{}, stopCh: make(chan struct{}), syncRateLimiter: flowcontrol.NewTokenBucketRateLimiter(0.1, 1), - recorder: eventBroadcaster.NewRecorder(api.EventSource{ + recorder: eventBroadcaster.NewRecorder(def_api.Scheme, api.EventSource{ Component: "ingress-controller", }), sslCertTracker: newSSLCertTracker(), @@ -306,12 +307,9 @@ func newIngressController(config *Configuration) *GenericController { cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", api.NamespaceAll, fields.Everything()), &api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler) - ic.svcLister.Indexer, ic.svcController = cache.NewIndexerInformer( + ic.svcLister.Store, ic.svcController = cache.NewInformer( cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "services", ic.cfg.Namespace, fields.Everything()), - &api.Service{}, - ic.cfg.ResyncPeriod, - cache.ResourceEventHandlerFuncs{}, - cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}) + &api.Service{}, ic.cfg.ResyncPeriod, cache.ResourceEventHandlerFuncs{}) ic.nodeLister.Store, ic.nodeController = cache.NewInformer( cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "nodes", api.NamespaceAll, fields.Everything()), @@ -498,7 +496,7 @@ func (ic *GenericController) getStreamServices(configmapName string, proto api.P continue } - svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(nsName) + svcObj, svcExists, err := ic.svcLister.Store.GetByKey(nsName) if err != nil { glog.Warningf("error getting service %v: %v", nsName, err) continue @@ -562,7 +560,7 @@ func (ic *GenericController) getDefaultUpstream() *ingress.Backend { Name: defUpstreamName, } svcKey := ic.cfg.DefaultService - svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) + svcObj, svcExists, err := ic.svcLister.Store.GetByKey(svcKey) if err != nil { glog.Warningf("unexpected error searching the default backend %v: %v", ic.cfg.DefaultService, err) upstream.Endpoints = append(upstream.Endpoints, newDefaultServer()) @@ -809,7 +807,7 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing // to a service. func (ic *GenericController) serviceEndpoints(svcKey, backendPort string, hz *healthcheck.Upstream) ([]ingress.Endpoint, error) { - svcObj, svcExists, err := ic.svcLister.Indexer.GetByKey(svcKey) + svcObj, svcExists, err := ic.svcLister.Store.GetByKey(svcKey) var upstreams []ingress.Endpoint if err != nil { diff --git a/core/pkg/ingress/controller/launch.go b/core/pkg/ingress/controller/launch.go index d532c0653..145ee5937 100644 --- a/core/pkg/ingress/controller/launch.go +++ b/core/pkg/ingress/controller/launch.go @@ -14,11 +14,12 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/spf13/pflag" - "k8s.io/kubernetes/pkg/api" - client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" - clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" - "k8s.io/kubernetes/pkg/healthz" + "k8s.io/apiserver/pkg/server/healthz" + "k8s.io/client-go/kubernetes" + api "k8s.io/client-go/pkg/api/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + clientcmd_api "k8s.io/client-go/tools/clientcmd/api" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/k8s" @@ -208,19 +209,35 @@ const ( defaultBurst = 1e6 ) +// buildConfigFromFlags builds REST config based on master URL and kubeconfig path. +// If both of them are empty then in cluster config is used. +func buildConfigFromFlags(masterURL, kubeconfigPath string) (*rest.Config, error) { + if kubeconfigPath == "" && masterURL == "" { + kubeconfig, err := rest.InClusterConfig() + if err != nil { + return nil, err + } + + return kubeconfig, nil + } + + return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath}, + &clientcmd.ConfigOverrides{ + ClusterInfo: clientcmd_api.Cluster{ + Server: masterURL, + }, + }).ClientConfig() +} + // createApiserverClient creates new Kubernetes Apiserver client. When kubeconfig or apiserverHost param is empty // the function assumes that it is running inside a Kubernetes cluster and attempts to // discover the Apiserver. Otherwise, it connects to the Apiserver specified. // // apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001. // kubeConfig location of kubeconfig file -func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Clientset, error) { - - clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - &clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeConfig}, - &clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: apiserverHost}}) - - cfg, err := clientConfig.ClientConfig() +func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes.Clientset, error) { + cfg, err := buildConfigFromFlags(apiserverHost, kubeConfig) if err != nil { return nil, err } @@ -231,7 +248,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Cli glog.Infof("Creating API server client for %s", cfg.Host) - client, err := client.NewForConfig(cfg) + client, err := kubernetes.NewForConfig(cfg) if err != nil { return nil, err diff --git a/core/pkg/ingress/controller/named_port.go b/core/pkg/ingress/controller/named_port.go index da28df135..a3a555151 100644 --- a/core/pkg/ingress/controller/named_port.go +++ b/core/pkg/ingress/controller/named_port.go @@ -24,9 +24,10 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - podutil "k8s.io/kubernetes/pkg/api/pod" - "k8s.io/kubernetes/pkg/labels" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/intstr" + api_v1 "k8s.io/client-go/pkg/api/v1" "k8s.io/ingress/core/pkg/ingress/annotations/service" ) @@ -35,11 +36,11 @@ import ( // named port. If the annotation in the service does not exist or is not equals // to the port mapping obtained from the pod the service must be updated to reflect // the current state -func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error { +func (ic *GenericController) checkSvcForUpdate(svc *api_v1.Service) error { // get the pods associated with the service // TODO: switch this to a watch - pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(api.ListOptions{ - LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(), + pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(meta_v1.ListOptions{ + LabelSelector: labels.Set(svc.Spec.Selector).AsSelector().String(), }) if err != nil { @@ -60,7 +61,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error { _, err := strconv.Atoi(servicePort.TargetPort.StrVal) if err != nil { - portNum, err := podutil.FindPort(pod, servicePort) + portNum, err := findPort(pod, servicePort) if err != nil { glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err) continue @@ -82,7 +83,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error { if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) { data, _ := json.Marshal(namedPorts) - newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name) + newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name, meta_v1.GetOptions{}) if err != nil { return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err) } @@ -103,3 +104,26 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error { return nil } + +// FindPort locates the container port for the given pod and portName. If the +// targetPort is a number, use that. If the targetPort is a string, look that +// string up in all named ports in all containers in the target pod. If no +// match is found, fail. +func findPort(pod *api_v1.Pod, svcPort *api_v1.ServicePort) (int, error) { + portName := svcPort.TargetPort + switch portName.Type { + case intstr.String: + name := portName.StrVal + for _, container := range pod.Spec.Containers { + for _, port := range container.Ports { + if port.Name == name && port.Protocol == svcPort.Protocol { + return int(port.ContainerPort), nil + } + } + } + case intstr.Int: + return portName.IntValue(), nil + } + + return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID) +} diff --git a/core/pkg/ingress/controller/named_port_test.go b/core/pkg/ingress/controller/named_port_test.go index c92ad9806..0f87a4e0c 100644 --- a/core/pkg/ingress/controller/named_port_test.go +++ b/core/pkg/ingress/controller/named_port_test.go @@ -20,51 +20,55 @@ import ( "reflect" "testing" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/pkg/api" + api_v1 "k8s.io/client-go/pkg/api/v1" "k8s.io/ingress/core/pkg/ingress/annotations/service" - "k8s.io/kubernetes/pkg/api" - testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" - "k8s.io/kubernetes/pkg/util/intstr" ) -func buildSimpleClientSet() *testclient.Clientset { - return testclient.NewSimpleClientset( - &api.PodList{Items: []api.Pod{ - { - ObjectMeta: api.ObjectMeta{ - Name: "foo1", - Namespace: api.NamespaceDefault, - Labels: map[string]string{ - "lable_sig": "foo_pod", +func buildSimpleClientSet() *fake.Clientset { + return fake.NewSimpleClientset( + &api_v1.PodList{ + Items: []api_v1.Pod{ + { + ObjectMeta: meta_v1.ObjectMeta{ + Name: "foo1", + Namespace: api.NamespaceDefault, + Labels: map[string]string{ + "lable_sig": "foo_pod", + }, }, - }, - Spec: api.PodSpec{ - NodeName: "foo_node_1", - Containers: []api.Container{ - { - Ports: []api.ContainerPort{ - { - Name: "foo1_named_port_c1", - Protocol: api.ProtocolTCP, - ContainerPort: 80, + Spec: api_v1.PodSpec{ + NodeName: "foo_node_1", + Containers: []api_v1.Container{ + { + Ports: []api_v1.ContainerPort{ + { + Name: "foo1_named_port_c1", + Protocol: api_v1.ProtocolTCP, + ContainerPort: 80, + }, }, }, }, }, }, - }, - { - ObjectMeta: api.ObjectMeta{ - Name: "foo1", - Namespace: api.NamespaceSystem, - Labels: map[string]string{ - "lable_sig": "foo_pod", + { + ObjectMeta: meta_v1.ObjectMeta{ + Name: "foo1", + Namespace: api.NamespaceSystem, + Labels: map[string]string{ + "lable_sig": "foo_pod", + }, }, }, }, - }}, - &api.ServiceList{Items: []api.Service{ + }, + &api_v1.ServiceList{Items: []api_v1.Service{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "named_port_test_service", }, @@ -81,14 +85,13 @@ func buildGenericController() *GenericController { } } -func buildService() *api.Service { - return &api.Service{ - ObjectMeta: api.ObjectMeta{ +func buildService() *api_v1.Service { + return &api_v1.Service{ + ObjectMeta: meta_v1.ObjectMeta{ Namespace: api.NamespaceSystem, Name: "named_port_test_service", }, - - Spec: api.ServiceSpec{ + Spec: api_v1.ServiceSpec{ ClusterIP: "10.10.10.10", }, } @@ -98,17 +101,17 @@ func TestCheckSvcForUpdate(t *testing.T) { foos := []struct { n string ns string - sps []api.ServicePort + sps []api_v1.ServicePort sl map[string]string er string }{ { "pods_have_not_been_found_in_this_namespace", api.NamespaceSystem, - []api.ServicePort{ - {Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, - {Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, - {Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, + []api_v1.ServicePort{ + {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, + {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)}, + {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")}, }, map[string]string{ "lable_sig": "foo_pod", @@ -118,10 +121,10 @@ func TestCheckSvcForUpdate(t *testing.T) { { "ports_have_not_been_found_in_this_pod", api.NamespaceDefault, - []api.ServicePort{ - {Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")}, - {Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, - {Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, + []api_v1.ServicePort{ + {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")}, + {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)}, + {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")}, }, map[string]string{ "lable_sig": "foo_pod", @@ -132,10 +135,10 @@ func TestCheckSvcForUpdate(t *testing.T) { { "ports_fixed", api.NamespaceDefault, - []api.ServicePort{ - {Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(80)}, - {Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, - {Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, + []api_v1.ServicePort{ + {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(80)}, + {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)}, + {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")}, }, map[string]string{ "lable_sig": "foo_pod", @@ -145,10 +148,10 @@ func TestCheckSvcForUpdate(t *testing.T) { { "nil_selector", api.NamespaceDefault, - []api.ServicePort{ - {Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, - {Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, - {Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, + []api_v1.ServicePort{ + {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, + {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)}, + {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")}, }, nil, "{\"foo1_named_port_c1\":\"80\"}", @@ -156,10 +159,10 @@ func TestCheckSvcForUpdate(t *testing.T) { { "normal_update", api.NamespaceDefault, - []api.ServicePort{ - {Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, - {Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, - {Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, + []api_v1.ServicePort{ + {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, + {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)}, + {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")}, }, map[string]string{ "lable_sig": "foo_pod", @@ -181,7 +184,7 @@ func TestCheckSvcForUpdate(t *testing.T) { t.Fatalf("unexpected error: %v", err) } - rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service") + rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service", meta_v1.GetOptions{}) rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation] if !reflect.DeepEqual(rr, foo.er) { t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n) diff --git a/core/pkg/ingress/controller/util_test.go b/core/pkg/ingress/controller/util_test.go index b4da882d2..2aa6d5a20 100644 --- a/core/pkg/ingress/controller/util_test.go +++ b/core/pkg/ingress/controller/util_test.go @@ -17,9 +17,8 @@ limitations under the License. package controller import ( - "testing" - "reflect" + "testing" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/annotations/auth" diff --git a/core/pkg/ingress/resolver/main.go b/core/pkg/ingress/resolver/main.go index a11b35f58..0a701fb31 100644 --- a/core/pkg/ingress/resolver/main.go +++ b/core/pkg/ingress/resolver/main.go @@ -17,7 +17,7 @@ limitations under the License. package resolver import ( - "k8s.io/kubernetes/pkg/api" + api "k8s.io/client-go/pkg/api/v1" "k8s.io/ingress/core/pkg/ingress/defaults" ) diff --git a/core/pkg/ingress/sort_ingress.go b/core/pkg/ingress/sort_ingress.go index cc5f2d76d..549846844 100644 --- a/core/pkg/ingress/sort_ingress.go +++ b/core/pkg/ingress/sort_ingress.go @@ -17,8 +17,8 @@ limitations under the License. package ingress import ( - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/unversioned" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" ) // BackendByNameServers sorts upstreams by name @@ -69,7 +69,7 @@ func (c LocationByPath) Less(i, j int) bool { // SSLCert describes a SSL certificate to be used in a server type SSLCert struct { - api.ObjectMeta `json:"metadata,omitempty"` + meta_v1.ObjectMeta `json:"metadata,omitempty"` // CAFileName contains the path to the file with the root certificate CAFileName string `json:"caFileName"` // PemFileName contains the path to the file with the certificate and key concatenated @@ -82,4 +82,6 @@ type SSLCert struct { } // GetObjectKind implements the ObjectKind interface as a noop -func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind } +func (s SSLCert) GetObjectKind() schema.ObjectKind { + return schema.EmptyObjectKind +} diff --git a/core/pkg/ingress/sort_ingress_test.go b/core/pkg/ingress/sort_ingress_test.go index 52ceb7029..8c6010a98 100644 --- a/core/pkg/ingress/sort_ingress_test.go +++ b/core/pkg/ingress/sort_ingress_test.go @@ -19,7 +19,7 @@ package ingress import ( "testing" - "k8s.io/kubernetes/pkg/api" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func buildBackendByNameServers() BackendByNameServers { @@ -365,7 +365,7 @@ func TestLocationByPathLess(t *testing.T) { func TestGetObjectKindForSSLCert(t *testing.T) { fk := &SSLCert{ - ObjectMeta: api.ObjectMeta{}, + ObjectMeta: meta_v1.ObjectMeta{}, CAFileName: "ca_file", PemFileName: "pemfile", PemSHA: "pem_sha", diff --git a/core/pkg/ingress/status/election.go b/core/pkg/ingress/status/election.go index 0710f1d82..17fc0dd0f 100644 --- a/core/pkg/ingress/status/election.go +++ b/core/pkg/ingress/status/election.go @@ -23,16 +23,19 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/errors" - client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/leaderelection" - "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" - "k8s.io/kubernetes/pkg/client/record" + "k8s.io/apimachinery/pkg/api/errors" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + client "k8s.io/client-go/kubernetes" + def_api "k8s.io/client-go/pkg/api" + api "k8s.io/client-go/pkg/api/v1" + "k8s.io/client-go/tools/record" + + "k8s.io/ingress/core/pkg/ingress/status/leaderelection" + "k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock" ) func getCurrentLeader(electionID, namespace string, c client.Interface) (string, *api.Endpoints, error) { - endpoints, err := c.Core().Endpoints(namespace).Get(electionID) + endpoints, err := c.Core().Endpoints(namespace).Get(electionID, meta_v1.GetOptions{}) if err != nil { return "", nil, err } @@ -56,11 +59,11 @@ func NewElection(electionID, callback func(leader string), c client.Interface) (*leaderelection.LeaderElector, error) { - _, err := c.Core().Endpoints(namespace).Get(electionID) + _, err := c.Core().Endpoints(namespace).Get(electionID, meta_v1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { _, err = c.Core().Endpoints(namespace).Create(&api.Endpoints{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: electionID, }, }) @@ -93,13 +96,13 @@ func NewElection(electionID, if err != nil { return nil, err } - recorder := broadcaster.NewRecorder(api.EventSource{ + recorder := broadcaster.NewRecorder(def_api.Scheme, api.EventSource{ Component: "ingress-leader-elector", Host: hostname, }) lock := resourcelock.EndpointsLock{ - EndpointsMeta: api.ObjectMeta{Namespace: namespace, Name: electionID}, + EndpointsMeta: meta_v1.ObjectMeta{Namespace: namespace, Name: electionID}, Client: c, LockConfig: resourcelock.ResourceLockConfig{ Identity: id, diff --git a/core/pkg/ingress/status/election_test.go b/core/pkg/ingress/status/election_test.go index 4726aa8af..3e6504d00 100644 --- a/core/pkg/ingress/status/election_test.go +++ b/core/pkg/ingress/status/election_test.go @@ -21,23 +21,25 @@ import ( "testing" "time" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/api/unversioned" - tc "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" - "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/pkg/api" + api_v1 "k8s.io/client-go/pkg/api/v1" + + "k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock" ) func TestGetCurrentLeaderLeaderExist(t *testing.T) { fkER := resourcelock.LeaderElectionRecord{ HolderIdentity: "currentLeader", LeaseDurationSeconds: 30, - AcquireTime: unversioned.Now(), - RenewTime: unversioned.Now(), + AcquireTime: meta_v1.NewTime(time.Now()), + RenewTime: meta_v1.NewTime(time.Now()), LeaderTransitions: 3, } leaderInfo, _ := json.Marshal(fkER) - fkEndpoints := api.Endpoints{ - ObjectMeta: api.ObjectMeta{ + fkEndpoints := api_v1.Endpoints{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "ingress-controller-test", Namespace: api.NamespaceSystem, Annotations: map[string]string{ @@ -45,7 +47,7 @@ func TestGetCurrentLeaderLeaderExist(t *testing.T) { }, }, } - fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}}) + fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}}) identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk) if err != nil { t.Fatalf("expected identitiy and endpoints but returned error %s", err) @@ -61,14 +63,14 @@ func TestGetCurrentLeaderLeaderExist(t *testing.T) { } func TestGetCurrentLeaderLeaderNotExist(t *testing.T) { - fkEndpoints := api.Endpoints{ - ObjectMeta: api.ObjectMeta{ + fkEndpoints := api_v1.Endpoints{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "ingress-controller-test", Namespace: api.NamespaceSystem, Annotations: map[string]string{}, }, } - fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}}) + fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}}) identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk) if err != nil { t.Fatalf("unexpeted error: %v", err) @@ -84,8 +86,8 @@ func TestGetCurrentLeaderLeaderNotExist(t *testing.T) { } func TestGetCurrentLeaderAnnotationError(t *testing.T) { - fkEndpoints := api.Endpoints{ - ObjectMeta: api.ObjectMeta{ + fkEndpoints := api_v1.Endpoints{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "ingress-controller-test", Namespace: api.NamespaceSystem, Annotations: map[string]string{ @@ -93,7 +95,7 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) { }, }, } - fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}}) + fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}}) _, _, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk) if err == nil { t.Errorf("expected error") @@ -101,15 +103,15 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) { } func TestNewElection(t *testing.T) { - fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{ + fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "ingress-controller-test", Namespace: api.NamespaceSystem, }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "ingress-controller-test-020", Namespace: api.NamespaceSystem, }, diff --git a/core/pkg/ingress/status/leaderelection/leaderelection.go b/core/pkg/ingress/status/leaderelection/leaderelection.go new file mode 100644 index 000000000..c7f2c2b7d --- /dev/null +++ b/core/pkg/ingress/status/leaderelection/leaderelection.go @@ -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.") +} diff --git a/core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go b/core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go new file mode 100644 index 000000000..26d5782b6 --- /dev/null +++ b/core/pkg/ingress/status/leaderelection/resourcelock/endpointslock.go @@ -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 +} diff --git a/core/pkg/ingress/status/leaderelection/resourcelock/interface.go b/core/pkg/ingress/status/leaderelection/resourcelock/interface.go new file mode 100644 index 000000000..7b3775b9b --- /dev/null +++ b/core/pkg/ingress/status/leaderelection/resourcelock/interface.go @@ -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 +} diff --git a/core/pkg/ingress/status/status.go b/core/pkg/ingress/status/status.go index 88627a82b..05af3329e 100644 --- a/core/pkg/ingress/status/status.go +++ b/core/pkg/ingress/status/status.go @@ -24,15 +24,16 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" - "k8s.io/kubernetes/pkg/client/leaderelection" - "k8s.io/kubernetes/pkg/labels" - "k8s.io/kubernetes/pkg/util/wait" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/wait" + clientset "k8s.io/client-go/kubernetes" + api_v1 "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" - cache_store "k8s.io/ingress/core/pkg/cache" "k8s.io/ingress/core/pkg/ingress/annotations/class" + "k8s.io/ingress/core/pkg/ingress/status/leaderelection" + "k8s.io/ingress/core/pkg/ingress/store" "k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/strings" "k8s.io/ingress/core/pkg/task" @@ -52,7 +53,7 @@ type Sync interface { type Config struct { Client clientset.Interface PublishService string - IngressLister cache_store.StoreToIngressLister + IngressLister store.IngressLister ElectionID string DefaultIngressClass string @@ -111,7 +112,7 @@ func (s statusSync) Shutdown() { } glog.Infof("removing address from ingress status (%v)", addrs) - s.updateStatus([]api.LoadBalancerIngress{}) + s.updateStatus([]api_v1.LoadBalancerIngress{}) } func (s *statusSync) run() { @@ -196,7 +197,7 @@ func NewStatusSyncer(config Config) Sync { func (s *statusSync) runningAddresess() ([]string, error) { if s.PublishService != "" { ns, name, _ := k8s.ParseNameNS(s.PublishService) - svc, err := s.Client.Core().Services(ns).Get(name) + svc, err := s.Client.Core().Services(ns).Get(name, meta_v1.GetOptions{}) if err != nil { return nil, err } @@ -214,8 +215,8 @@ func (s *statusSync) runningAddresess() ([]string, error) { } // get information about all the pods running the ingress controller - pods, err := s.Client.Core().Pods(s.pod.Namespace).List(api.ListOptions{ - LabelSelector: labels.SelectorFromSet(s.pod.Labels), + pods, err := s.Client.Core().Pods(s.pod.Namespace).List(meta_v1.ListOptions{ + LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(), }) if err != nil { return nil, err @@ -232,13 +233,13 @@ func (s *statusSync) runningAddresess() ([]string, error) { } // sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress -func sliceToStatus(endpoints []string) []api.LoadBalancerIngress { - lbi := []api.LoadBalancerIngress{} +func sliceToStatus(endpoints []string) []api_v1.LoadBalancerIngress { + lbi := []api_v1.LoadBalancerIngress{} for _, ep := range endpoints { if net.ParseIP(ep) == nil { - lbi = append(lbi, api.LoadBalancerIngress{Hostname: ep}) + lbi = append(lbi, api_v1.LoadBalancerIngress{Hostname: ep}) } else { - lbi = append(lbi, api.LoadBalancerIngress{IP: ep}) + lbi = append(lbi, api_v1.LoadBalancerIngress{IP: ep}) } } @@ -246,7 +247,7 @@ func sliceToStatus(endpoints []string) []api.LoadBalancerIngress { return lbi } -func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) { +func (s *statusSync) updateStatus(newIPs []api_v1.LoadBalancerIngress) { ings := s.IngressLister.List() var wg sync.WaitGroup wg.Add(len(ings)) @@ -261,7 +262,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) { go func(wg *sync.WaitGroup, ing *extensions.Ingress) { defer wg.Done() ingClient := s.Client.Extensions().Ingresses(ing.Namespace) - currIng, err := ingClient.Get(ing.Name) + currIng, err := ingClient.Get(ing.Name, meta_v1.GetOptions{}) if err != nil { glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err) return @@ -286,7 +287,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) { wg.Wait() } -func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { +func ingressSliceEqual(lhs, rhs []api_v1.LoadBalancerIngress) bool { if len(lhs) != len(rhs) { return false } @@ -303,7 +304,7 @@ func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { } // loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP -type loadBalancerIngressByIP []api.LoadBalancerIngress +type loadBalancerIngressByIP []api_v1.LoadBalancerIngress func (c loadBalancerIngressByIP) Len() int { return len(c) } func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] } diff --git a/core/pkg/ingress/status/status_test.go b/core/pkg/ingress/status/status_test.go index bbaef43dd..e5b3f26f6 100644 --- a/core/pkg/ingress/status/status_test.go +++ b/core/pkg/ingress/status/status_test.go @@ -23,19 +23,21 @@ import ( "testing" "time" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/apis/extensions" - "k8s.io/kubernetes/pkg/client/cache" - testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + testclient "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/pkg/api" + api_v1 "k8s.io/client-go/pkg/api/v1" + extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1" + "k8s.io/client-go/tools/cache" - cache_store "k8s.io/ingress/core/pkg/cache" "k8s.io/ingress/core/pkg/ingress/annotations/class" + cache_store "k8s.io/ingress/core/pkg/ingress/store" "k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/task" ) func buildLoadBalancerIngressByIP() loadBalancerIngressByIP { - return []api.LoadBalancerIngress{ + return []api_v1.LoadBalancerIngress{ { IP: "10.0.0.1", Hostname: "foo1", @@ -57,100 +59,100 @@ func buildLoadBalancerIngressByIP() loadBalancerIngressByIP { func buildSimpleClientSet() *testclient.Clientset { return testclient.NewSimpleClientset( - &api.PodList{Items: []api.Pod{ + &api_v1.PodList{Items: []api_v1.Pod{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo1", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, Labels: map[string]string{ "lable_sig": "foo_pod", }, }, - Spec: api.PodSpec{ + Spec: api_v1.PodSpec{ NodeName: "foo_node_2", }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo2", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, Labels: map[string]string{ "lable_sig": "foo_no", }, }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo3", Namespace: api.NamespaceSystem, Labels: map[string]string{ "lable_sig": "foo_pod", }, }, - Spec: api.PodSpec{ + Spec: api_v1.PodSpec{ NodeName: "foo_node_2", }, }, }}, - &api.ServiceList{Items: []api.Service{ + &api_v1.ServiceList{Items: []api_v1.Service{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, }, - Status: api.ServiceStatus{ - LoadBalancer: api.LoadBalancerStatus{ + Status: api_v1.ServiceStatus{ + LoadBalancer: api_v1.LoadBalancerStatus{ Ingress: buildLoadBalancerIngressByIP(), }, }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_non_exist", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, }, }, }}, - &api.NodeList{Items: []api.Node{ + &api_v1.NodeList{Items: []api_v1.Node{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_node_1", }, - Status: api.NodeStatus{ - Addresses: []api.NodeAddress{ + Status: api_v1.NodeStatus{ + Addresses: []api_v1.NodeAddress{ { - Type: api.NodeLegacyHostIP, + Type: api_v1.NodeLegacyHostIP, Address: "10.0.0.1", }, { - Type: api.NodeExternalIP, + Type: api_v1.NodeExternalIP, Address: "10.0.0.2", }, }, }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_node_2", }, - Status: api.NodeStatus{ - Addresses: []api.NodeAddress{ + Status: api_v1.NodeStatus{ + Addresses: []api_v1.NodeAddress{ { - Type: api.NodeLegacyHostIP, + Type: api_v1.NodeLegacyHostIP, Address: "11.0.0.1", }, { - Type: api.NodeExternalIP, + Type: api_v1.NodeExternalIP, Address: "11.0.0.2", }, }, }, }, }}, - &api.EndpointsList{Items: []api.Endpoints{ + &api_v1.EndpointsList{Items: []api_v1.Endpoints{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "ingress-controller-leader", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, SelfLink: "/api/v1/namespaces/default/endpoints/ingress-controller-leader", }, }}}, @@ -165,13 +167,13 @@ func fakeSynFn(interface{}) error { func buildExtensionsIngresses() []extensions.Ingress { return []extensions.Ingress{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_ingress_1", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, }, Status: extensions.IngressStatus{ - LoadBalancer: api.LoadBalancerStatus{ - Ingress: []api.LoadBalancerIngress{ + LoadBalancer: api_v1.LoadBalancerStatus{ + Ingress: []api_v1.LoadBalancerIngress{ { IP: "10.0.0.1", Hostname: "foo1", @@ -181,7 +183,7 @@ func buildExtensionsIngresses() []extensions.Ingress { }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_ingress_different_class", Namespace: api.NamespaceDefault, Annotations: map[string]string{ @@ -189,8 +191,8 @@ func buildExtensionsIngresses() []extensions.Ingress { }, }, Status: extensions.IngressStatus{ - LoadBalancer: api.LoadBalancerStatus{ - Ingress: []api.LoadBalancerIngress{ + LoadBalancer: api_v1.LoadBalancerStatus{ + Ingress: []api_v1.LoadBalancerIngress{ { IP: "0.0.0.0", Hostname: "foo.bar.com", @@ -200,45 +202,45 @@ func buildExtensionsIngresses() []extensions.Ingress { }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_ingress_2", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, }, Status: extensions.IngressStatus{ - LoadBalancer: api.LoadBalancerStatus{ - Ingress: []api.LoadBalancerIngress{}, + LoadBalancer: api_v1.LoadBalancerStatus{ + Ingress: []api_v1.LoadBalancerIngress{}, }, }, }, } } -func buildIngressListener() cache_store.StoreToIngressLister { +func buildIngressListener() cache_store.IngressLister { store := cache.NewStore(cache.MetaNamespaceKeyFunc) store.Add(&extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_ingress_non_01", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, }}) store.Add(&extensions.Ingress{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "foo_ingress_1", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, }, Status: extensions.IngressStatus{ - LoadBalancer: api.LoadBalancerStatus{ + LoadBalancer: api_v1.LoadBalancerStatus{ Ingress: buildLoadBalancerIngressByIP(), }, }, }) - return cache_store.StoreToIngressLister{Store: store} + return cache_store.IngressLister{Store: store} } func buildStatusSync() statusSync { return statusSync{ pod: &k8s.PodInfo{ Name: "foo_base_pod", - Namespace: api.NamespaceDefault, + Namespace: api_v1.NamespaceDefault, Labels: map[string]string{ "lable_sig": "foo_pod", }, @@ -247,7 +249,7 @@ func buildStatusSync() statusSync { syncQueue: task.NewTaskQueue(fakeSynFn), Config: Config{ Client: buildSimpleClientSet(), - PublishService: api.NamespaceDefault + "/" + "foo", + PublishService: api_v1.NamespaceDefault + "/" + "foo", IngressLister: buildIngressListener(), }, } @@ -256,7 +258,7 @@ func buildStatusSync() statusSync { func TestStatusActions(t *testing.T) { // make sure election can be created os.Setenv("POD_NAME", "foo1") - os.Setenv("POD_NAMESPACE", api.NamespaceDefault) + os.Setenv("POD_NAMESPACE", api_v1.NamespaceDefault) c := Config{ Client: buildSimpleClientSet(), PublishService: "", @@ -273,7 +275,7 @@ func TestStatusActions(t *testing.T) { fk := fkSync.(statusSync) ns := make(chan struct{}) - // start it and wait for the election and sync actions + // start it and wait for the election and syn actions go fk.Run(ns) // wait for the election time.Sleep(100 * time.Millisecond) @@ -281,10 +283,10 @@ func TestStatusActions(t *testing.T) { fk.sync("just-test") // PublishService is empty, so the running address is: ["11.0.0.2"] // after updated, the ingress's ip should only be "11.0.0.2" - newIPs := []api.LoadBalancerIngress{{ + newIPs := []api_v1.LoadBalancerIngress{{ IP: "11.0.0.2", }} - fooIngress1, err1 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") + fooIngress1, err1 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{}) if err1 != nil { t.Fatalf("unexpected error") } @@ -296,8 +298,8 @@ func TestStatusActions(t *testing.T) { // execute shutdown fk.Shutdown() // ingress should be empty - newIPs2 := []api.LoadBalancerIngress{} - fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") + newIPs2 := []api_v1.LoadBalancerIngress{} + fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{}) if err2 != nil { t.Fatalf("unexpected error") } @@ -306,7 +308,7 @@ func TestStatusActions(t *testing.T) { t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2) } - oic, err := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_different_class") + oic, err := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_different_class", meta_v1.GetOptions{}) if err != nil { t.Fatalf("unexpected error") } @@ -374,7 +376,7 @@ func TestUpdateStatus(t *testing.T) { sort.Sort(loadBalancerIngressByIP(newIPs)) fk.updateStatus(newIPs) - fooIngress1, err1 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") + fooIngress1, err1 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{}) if err1 != nil { t.Fatalf("unexpected error") } @@ -383,13 +385,13 @@ func TestUpdateStatus(t *testing.T) { t.Fatalf("returned %v but expected %v", fooIngress1CurIPs, newIPs) } - fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_2") + fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_2", meta_v1.GetOptions{}) if err2 != nil { t.Fatalf("unexpected error") } fooIngress2CurIPs := fooIngress2.Status.LoadBalancer.Ingress - if !ingressSliceEqual(fooIngress2CurIPs, []api.LoadBalancerIngress{}) { - t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api.LoadBalancerIngress{}) + if !ingressSliceEqual(fooIngress2CurIPs, []api_v1.LoadBalancerIngress{}) { + t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api_v1.LoadBalancerIngress{}) } } @@ -403,7 +405,7 @@ func TestSliceToStatus(t *testing.T) { r := sliceToStatus(fkEndpoints) if r == nil { - t.Fatalf("returned nil but expected a valid []api.LoadBalancerIngress") + t.Fatalf("returned nil but expected a valid []api_v1.LoadBalancerIngress") } rl := len(r) if rl != 3 { @@ -411,21 +413,21 @@ func TestSliceToStatus(t *testing.T) { } re1 := r[0] if re1.Hostname != "opensource-k8s-ingress" { - t.Fatalf("returned %v but expected %v", re1, api.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"}) + t.Fatalf("returned %v but expected %v", re1, api_v1.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"}) } re2 := r[1] if re2.IP != "10.0.0.1" { - t.Fatalf("returned %v but expected %v", re2, api.LoadBalancerIngress{IP: "10.0.0.1"}) + t.Fatalf("returned %v but expected %v", re2, api_v1.LoadBalancerIngress{IP: "10.0.0.1"}) } re3 := r[2] if re3.IP != "2001:db8::68" { - t.Fatalf("returned %v but expected %v", re3, api.LoadBalancerIngress{IP: "2001:db8::68"}) + t.Fatalf("returned %v but expected %v", re3, api_v1.LoadBalancerIngress{IP: "2001:db8::68"}) } } func TestIngressSliceEqual(t *testing.T) { fk1 := buildLoadBalancerIngressByIP() - fk2 := append(buildLoadBalancerIngressByIP(), api.LoadBalancerIngress{ + fk2 := append(buildLoadBalancerIngressByIP(), api_v1.LoadBalancerIngress{ IP: "10.0.0.5", Hostname: "foo5", }) @@ -435,8 +437,8 @@ func TestIngressSliceEqual(t *testing.T) { fk4[2].IP = "11.0.0.3" fooTests := []struct { - lhs []api.LoadBalancerIngress - rhs []api.LoadBalancerIngress + lhs []api_v1.LoadBalancerIngress + rhs []api_v1.LoadBalancerIngress er bool }{ {fk1, fk1, true}, @@ -445,7 +447,7 @@ func TestIngressSliceEqual(t *testing.T) { {fk4, fk1, false}, {fk1, nil, false}, {nil, nil, true}, - {[]api.LoadBalancerIngress{}, []api.LoadBalancerIngress{}, true}, + {[]api_v1.LoadBalancerIngress{}, []api_v1.LoadBalancerIngress{}, true}, } for _, fooTest := range fooTests { @@ -461,7 +463,7 @@ func TestLoadBalancerIngressByIPLen(t *testing.T) { ips loadBalancerIngressByIP el int }{ - {[]api.LoadBalancerIngress{}, 0}, + {[]api_v1.LoadBalancerIngress{}, 0}, {buildLoadBalancerIngressByIP(), 4}, {nil, 0}, } diff --git a/core/pkg/ingress/store/main.go b/core/pkg/ingress/store/main.go new file mode 100644 index 000000000..4fb6f7929 --- /dev/null +++ b/core/pkg/ingress/store/main.go @@ -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 +} diff --git a/core/pkg/ingress/types.go b/core/pkg/ingress/types.go index 8121abe4d..e787d82b5 100644 --- a/core/pkg/ingress/types.go +++ b/core/pkg/ingress/types.go @@ -19,12 +19,10 @@ package ingress import ( "github.com/spf13/pflag" - "k8s.io/kubernetes/pkg/api" - "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/healthz" - "k8s.io/kubernetes/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apiserver/pkg/server/healthz" + api "k8s.io/client-go/pkg/api/v1" - cache_store "k8s.io/ingress/core/pkg/cache" "k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/authreq" "k8s.io/ingress/core/pkg/ingress/annotations/authtls" @@ -33,6 +31,7 @@ import ( "k8s.io/ingress/core/pkg/ingress/annotations/ratelimit" "k8s.io/ingress/core/pkg/ingress/annotations/rewrite" "k8s.io/ingress/core/pkg/ingress/defaults" + "k8s.io/ingress/core/pkg/ingress/store" ) var ( @@ -103,12 +102,12 @@ type Controller interface { // StoreLister returns the configured stores for ingresses, services, // endpoints, secrets and configmaps. type StoreLister struct { - Ingress cache_store.StoreToIngressLister - Service cache.StoreToServiceLister - Node cache.StoreToNodeLister - Endpoint cache.StoreToEndpointsLister - Secret cache_store.StoreToSecretsLister - ConfigMap cache_store.StoreToConfigmapLister + Ingress store.IngressLister + Service store.ServiceLister + Node store.NodeLister + Endpoint store.EndpointLister + Secret store.SecretLister + ConfigMap store.ConfigMapLister } // BackendInfo returns information about the backend. diff --git a/core/pkg/k8s/main.go b/core/pkg/k8s/main.go index af0b5df73..8a317cfdc 100644 --- a/core/pkg/k8s/main.go +++ b/core/pkg/k8s/main.go @@ -21,8 +21,9 @@ import ( "os" "strings" - "k8s.io/kubernetes/pkg/api" - clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + clientset "k8s.io/client-go/kubernetes" + api "k8s.io/client-go/pkg/api/v1" ) // IsValidService checks if exists a service with the specified name @@ -31,7 +32,7 @@ func IsValidService(kubeClient clientset.Interface, name string) (*api.Service, if err != nil { return nil, err } - return kubeClient.Core().Services(ns).Get(name) + return kubeClient.Core().Services(ns).Get(name, meta_v1.GetOptions{}) } // isValidConfigMap check if exists a configmap with the specified name @@ -43,7 +44,7 @@ func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.Con return nil, err } - configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name) + configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name, meta_v1.GetOptions{}) if err != nil { return nil, fmt.Errorf("configmap not found: %v", err) @@ -55,7 +56,7 @@ func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.Con // isValidNamespace chck if exists a namespace with the specified name func IsValidNamespace(kubeClient clientset.Interface, name string) (*api.Namespace, error) { - return kubeClient.Core().Namespaces().Get(name) + return kubeClient.Core().Namespaces().Get(name, meta_v1.GetOptions{}) } // IsValidSecret checks if exists a secret with the specified name @@ -64,7 +65,7 @@ func IsValidSecret(kubeClient clientset.Interface, name string) (*api.Secret, er if err != nil { return nil, err } - return kubeClient.Core().Secrets(ns).Get(name) + return kubeClient.Core().Secrets(ns).Get(name, meta_v1.GetOptions{}) } // ParseNameNS parses a string searching a namespace and name @@ -80,7 +81,7 @@ func ParseNameNS(input string) (string, string, error) { // GetNodeIP returns the IP address of a node in the cluster func GetNodeIP(kubeClient clientset.Interface, name string) string { var externalIP string - node, err := kubeClient.Core().Nodes().Get(name) + node, err := kubeClient.Core().Nodes().Get(name, meta_v1.GetOptions{}) if err != nil { return externalIP } @@ -120,7 +121,7 @@ func GetPodDetails(kubeClient clientset.Interface) (*PodInfo, error) { return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable") } - pod, _ := kubeClient.Core().Pods(podNs).Get(podName) + pod, _ := kubeClient.Core().Pods(podNs).Get(podName, meta_v1.GetOptions{}) if pod == nil { return nil, fmt.Errorf("unable to get POD information") } diff --git a/core/pkg/k8s/main_test.go b/core/pkg/k8s/main_test.go index 58f640dec..962db0759 100644 --- a/core/pkg/k8s/main_test.go +++ b/core/pkg/k8s/main_test.go @@ -17,11 +17,12 @@ limitations under the License. package k8s import ( + "os" "testing" - "k8s.io/kubernetes/pkg/api" - testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" - "os" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + testclient "k8s.io/client-go/kubernetes/fake" + api "k8s.io/client-go/pkg/api/v1" ) func TestParseNameNS(t *testing.T) { @@ -57,7 +58,7 @@ func TestParseNameNS(t *testing.T) { func TestIsValidService(t *testing.T) { fk := testclient.NewSimpleClientset(&api.Service{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "demo", }, @@ -88,7 +89,7 @@ func TestIsValidService(t *testing.T) { func TestIsValidNamespace(t *testing.T) { fk := testclient.NewSimpleClientset(&api.Namespace{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "default", }, }) @@ -112,7 +113,7 @@ func TestIsValidNamespace(t *testing.T) { func TestIsValidConfigMap(t *testing.T) { fk := testclient.NewSimpleClientset(&api.ConfigMap{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "demo", }, @@ -145,7 +146,7 @@ func TestIsValidConfigMap(t *testing.T) { func TestIsValidSecret(t *testing.T) { fk := testclient.NewSimpleClientset(&api.Secret{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Namespace: api.NamespaceDefault, Name: "demo", }, @@ -184,7 +185,7 @@ func TestGetNodeIP(t *testing.T) { // node not exist {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo", }, Status: api.NodeStatus{ @@ -199,7 +200,7 @@ func TestGetNodeIP(t *testing.T) { // node exist {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo", }, Status: api.NodeStatus{ @@ -215,7 +216,7 @@ func TestGetNodeIP(t *testing.T) { // search the correct node {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{ { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo1", }, Status: api.NodeStatus{ @@ -228,7 +229,7 @@ func TestGetNodeIP(t *testing.T) { }, }, { - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo2", }, Status: api.NodeStatus{ @@ -244,7 +245,7 @@ func TestGetNodeIP(t *testing.T) { // get NodeExternalIP {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo", }, Status: api.NodeStatus{ @@ -262,7 +263,7 @@ func TestGetNodeIP(t *testing.T) { // get NodeLegacyHostIP {testclient.NewSimpleClientset(&api.NodeList{Items: []api.Node{{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo", }, Status: api.NodeStatus{ @@ -307,7 +308,7 @@ func TestGetPodDetails(t *testing.T) { // success to get PodInfo fkClient := testclient.NewSimpleClientset( &api.PodList{Items: []api.Pod{{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "testpod", Namespace: api.NamespaceDefault, Labels: map[string]string{ @@ -317,7 +318,7 @@ func TestGetPodDetails(t *testing.T) { }, }}}, &api.NodeList{Items: []api.Node{{ - ObjectMeta: api.ObjectMeta{ + ObjectMeta: meta_v1.ObjectMeta{ Name: "demo", }, Status: api.NodeStatus{ diff --git a/core/pkg/task/queue.go b/core/pkg/task/queue.go index d29f3c2c9..a6786a622 100644 --- a/core/pkg/task/queue.go +++ b/core/pkg/task/queue.go @@ -22,9 +22,9 @@ import ( "github.com/golang/glog" - "k8s.io/kubernetes/pkg/client/cache" - "k8s.io/kubernetes/pkg/util/wait" - "k8s.io/kubernetes/pkg/util/workqueue" + "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" ) var ( diff --git a/examples/custom-controller/server.go b/examples/custom-controller/server.go index 5c6eea4b7..a0554fceb 100644 --- a/examples/custom-controller/server.go +++ b/examples/custom-controller/server.go @@ -8,11 +8,12 @@ import ( "github.com/spf13/pflag" + api "k8s.io/client-go/pkg/api/v1" + nginxconfig "k8s.io/ingress/controllers/nginx/pkg/config" "k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress/controller" "k8s.io/ingress/core/pkg/ingress/defaults" - "k8s.io/kubernetes/pkg/api" ) func main() { @@ -89,3 +90,7 @@ func (n DummyController) OverrideFlags(*pflag.FlagSet) { func (n DummyController) SetListers(lister ingress.StoreLister) { } + +func (n DummyController) DefaultIngressClass() string { + return "dummy" +}