Merge pull request #539 from aledbf/migrate-client-go

Migrate to client-go
This commit is contained in:
Nick Sardo 2017-04-05 13:50:22 -07:00 committed by GitHub
commit 12a0373d2e
2054 changed files with 414791 additions and 223145 deletions

1834
Godeps/Godeps.json generated

File diff suppressed because it is too large Load diff

View file

@ -23,10 +23,11 @@ import (
"strings" "strings"
"time" "time"
"k8s.io/kubernetes/pkg/util/sets"
"github.com/golang/glog" "github.com/golang/glog"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/healthchecks" "k8s.io/ingress/controllers/gce/healthchecks"
"k8s.io/ingress/controllers/gce/instances" "k8s.io/ingress/controllers/gce/instances"
"k8s.io/ingress/controllers/gce/storage" "k8s.io/ingress/controllers/gce/storage"

View file

@ -21,13 +21,13 @@ import (
"testing" "testing"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/healthchecks" "k8s.io/ingress/controllers/gce/healthchecks"
"k8s.io/ingress/controllers/gce/instances" "k8s.io/ingress/controllers/gce/instances"
"k8s.io/ingress/controllers/gce/storage" "k8s.io/ingress/controllers/gce/storage"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/util/sets"
"google.golang.org/api/googleapi"
) )
const defaultZone = "zone-a" const defaultZone = "zone-a"

View file

@ -20,8 +20,9 @@ import (
"fmt" "fmt"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/client-go/tools/cache"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/client/cache"
) )
// NewFakeBackendServices creates a new fake backend services manager. // NewFakeBackendServices creates a new fake backend services manager.

View file

@ -22,16 +22,17 @@ import (
"os" "os"
"time" "time"
"github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider"
gce "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
"k8s.io/ingress/controllers/gce/backends" "k8s.io/ingress/controllers/gce/backends"
"k8s.io/ingress/controllers/gce/firewalls" "k8s.io/ingress/controllers/gce/firewalls"
"k8s.io/ingress/controllers/gce/healthchecks" "k8s.io/ingress/controllers/gce/healthchecks"
"k8s.io/ingress/controllers/gce/instances" "k8s.io/ingress/controllers/gce/instances"
"k8s.io/ingress/controllers/gce/loadbalancers" "k8s.io/ingress/controllers/gce/loadbalancers"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/cloudprovider"
gce "k8s.io/kubernetes/pkg/cloudprovider/providers/gce"
"github.com/golang/glog"
) )
const ( const (

View file

@ -23,20 +23,21 @@ import (
"sync" "sync"
"time" "time"
"github.com/golang/glog"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/client-go/kubernetes"
unversionedcore "k8s.io/client-go/kubernetes/typed/core/v1"
listers "k8s.io/client-go/listers/core/v1"
base_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/ingress/controllers/gce/loadbalancers" "k8s.io/ingress/controllers/gce/loadbalancers"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/cache"
client "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/runtime"
"k8s.io/kubernetes/pkg/watch"
"github.com/golang/glog"
) )
var ( var (
@ -57,16 +58,16 @@ var (
// LoadBalancerController watches the kubernetes api and adds/removes services // LoadBalancerController watches the kubernetes api and adds/removes services
// from the loadbalancer, via loadBalancerConfig. // from the loadbalancer, via loadBalancerConfig.
type LoadBalancerController struct { type LoadBalancerController struct {
client client.Interface client kubernetes.Interface
ingController *cache.Controller ingController cache.Controller
nodeController *cache.Controller nodeController cache.Controller
svcController *cache.Controller svcController cache.Controller
podController *cache.Controller podController cache.Controller
ingLister StoreToIngressLister ingLister StoreToIngressLister
nodeLister cache.StoreToNodeLister nodeLister StoreToNodeLister
svcLister cache.StoreToServiceLister svcLister StoreToServiceLister
// Health checks are the readiness probes of containers on pods. // Health checks are the readiness probes of containers on pods.
podLister cache.StoreToPodLister podLister StoreToPodLister
// TODO: Watch secrets // TODO: Watch secrets
CloudClusterManager *ClusterManager CloudClusterManager *ClusterManager
recorder record.EventRecorder recorder record.EventRecorder
@ -91,7 +92,7 @@ type LoadBalancerController struct {
// - clusterManager: A ClusterManager capable of creating all cloud resources // - clusterManager: A ClusterManager capable of creating all cloud resources
// required for L7 loadbalancing. // required for L7 loadbalancing.
// - resyncPeriod: Watchers relist from the Kubernetes API server this often. // - resyncPeriod: Watchers relist from the Kubernetes API server this often.
func NewLoadBalancerController(kubeClient client.Interface, clusterManager *ClusterManager, resyncPeriod time.Duration, namespace string) (*LoadBalancerController, error) { func NewLoadBalancerController(kubeClient kubernetes.Interface, clusterManager *ClusterManager, resyncPeriod time.Duration, namespace string) (*LoadBalancerController, error) {
eventBroadcaster := record.NewBroadcaster() eventBroadcaster := record.NewBroadcaster()
eventBroadcaster.StartLogging(glog.Infof) eventBroadcaster.StartLogging(glog.Infof)
eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{ eventBroadcaster.StartRecordingToSink(&unversionedcore.EventSinkImpl{
@ -101,7 +102,7 @@ func NewLoadBalancerController(kubeClient client.Interface, clusterManager *Clus
client: kubeClient, client: kubeClient,
CloudClusterManager: clusterManager, CloudClusterManager: clusterManager,
stopCh: make(chan struct{}), stopCh: make(chan struct{}),
recorder: eventBroadcaster.NewRecorder( recorder: eventBroadcaster.NewRecorder(base_api.Scheme,
api.EventSource{Component: "loadbalancer-controller"}), api.EventSource{Component: "loadbalancer-controller"}),
} }
lbc.nodeQueue = NewTaskQueue(lbc.syncNodes) lbc.nodeQueue = NewTaskQueue(lbc.syncNodes)
@ -140,10 +141,7 @@ func NewLoadBalancerController(kubeClient client.Interface, clusterManager *Clus
}, },
} }
lbc.ingLister.Store, lbc.ingController = cache.NewInformer( lbc.ingLister.Store, lbc.ingController = cache.NewInformer(
&cache.ListWatch{ cache.NewListWatchFromClient(lbc.client.Extensions().RESTClient(), "ingresses", namespace, fields.Everything()),
ListFunc: ingressListFunc(lbc.client, namespace),
WatchFunc: ingressWatchFunc(lbc.client, namespace),
},
&extensions.Ingress{}, resyncPeriod, pathHandlers) &extensions.Ingress{}, resyncPeriod, pathHandlers)
// Service watch handlers // Service watch handlers
@ -173,30 +171,14 @@ func NewLoadBalancerController(kubeClient client.Interface, clusterManager *Clus
cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
) )
nodeHandlers := cache.ResourceEventHandlerFuncs{
AddFunc: lbc.nodeQueue.enqueue,
DeleteFunc: lbc.nodeQueue.enqueue,
// Nodes are updated every 10s and we don't care, so no update handler.
}
// Node watch handlers // Node watch handlers
lbc.nodeLister.Store, lbc.nodeController = cache.NewInformer( lbc.nodeLister.Indexer, lbc.nodeController = cache.NewIndexerInformer(
&cache.ListWatch{ cache.NewListWatchFromClient(lbc.client.Core().RESTClient(), "nodes", api.NamespaceAll, fields.Everything()),
ListFunc: func(opts api.ListOptions) (runtime.Object, error) { &api.Node{},
return lbc.client.Core().RESTClient().Get(). resyncPeriod,
Resource("nodes"). cache.ResourceEventHandlerFuncs{},
FieldsSelectorParam(fields.Everything()). cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
Do(). )
Get()
},
WatchFunc: func(options api.ListOptions) (watch.Interface, error) {
return lbc.client.Core().RESTClient().Get().
Prefix("watch").
Resource("nodes").
FieldsSelectorParam(fields.Everything()).
Param("resourceVersion", options.ResourceVersion).Watch()
},
},
&api.Node{}, 0, nodeHandlers)
lbc.tr = &GCETranslator{&lbc} lbc.tr = &GCETranslator{&lbc}
lbc.tlsLoader = &apiServerTLSLoader{client: lbc.client} lbc.tlsLoader = &apiServerTLSLoader{client: lbc.client}
@ -205,18 +187,6 @@ func NewLoadBalancerController(kubeClient client.Interface, clusterManager *Clus
return &lbc, nil return &lbc, nil
} }
func ingressListFunc(c client.Interface, ns string) func(api.ListOptions) (runtime.Object, error) {
return func(opts api.ListOptions) (runtime.Object, error) {
return c.Extensions().Ingresses(ns).List(opts)
}
}
func ingressWatchFunc(c client.Interface, ns string) func(options api.ListOptions) (watch.Interface, error) {
return func(options api.ListOptions) (watch.Interface, error) {
return c.Extensions().Ingresses(ns).Watch(options)
}
}
// enqueueIngressForService enqueues all the Ingress' for a Service. // enqueueIngressForService enqueues all the Ingress' for a Service.
func (lbc *LoadBalancerController) enqueueIngressForService(obj interface{}) { func (lbc *LoadBalancerController) enqueueIngressForService(obj interface{}) {
svc := obj.(*api.Service) svc := obj.(*api.Service)
@ -377,7 +347,7 @@ func (lbc *LoadBalancerController) updateIngressStatus(l7 *loadbalancers.L7, ing
// Update IP through update/status endpoint // Update IP through update/status endpoint
ip := l7.GetIP() ip := l7.GetIP()
currIng, err := ingClient.Get(ing.Name) currIng, err := ingClient.Get(ing.Name, metav1.GetOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -401,7 +371,7 @@ func (lbc *LoadBalancerController) updateIngressStatus(l7 *loadbalancers.L7, ing
} }
} }
// Update annotations through /update endpoint // Update annotations through /update endpoint
currIng, err = ingClient.Get(ing.Name) currIng, err = ingClient.Get(ing.Name, metav1.GetOptions{})
if err != nil { if err != nil {
return err return err
} }
@ -464,7 +434,7 @@ func (lbc *LoadBalancerController) syncNodes(key string) error {
return nil return nil
} }
func getNodeReadyPredicate() cache.NodeConditionPredicate { func getNodeReadyPredicate() listers.NodeConditionPredicate {
return func(node *api.Node) bool { return func(node *api.Node) bool {
for ix := range node.Status.Conditions { for ix := range node.Status.Conditions {
condition := &node.Status.Conditions[ix] condition := &node.Status.Conditions[ix]
@ -479,7 +449,7 @@ func getNodeReadyPredicate() cache.NodeConditionPredicate {
// getReadyNodeNames returns names of schedulable, ready nodes from the node lister. // getReadyNodeNames returns names of schedulable, ready nodes from the node lister.
func (lbc *LoadBalancerController) getReadyNodeNames() ([]string, error) { func (lbc *LoadBalancerController) getReadyNodeNames() ([]string, error) {
nodeNames := []string{} nodeNames := []string{}
nodes, err := lbc.nodeLister.NodeCondition(getNodeReadyPredicate()).List() nodes, err := listers.NewNodeLister(lbc.nodeLister.Indexer).ListWithPredicate(getNodeReadyPredicate())
if err != nil { if err != nil {
return nodeNames, err return nodeNames, err
} }

View file

@ -24,18 +24,18 @@ import (
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/uuid"
"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/ingress/controllers/gce/firewalls" "k8s.io/ingress/controllers/gce/firewalls"
"k8s.io/ingress/controllers/gce/loadbalancers" "k8s.io/ingress/controllers/gce/loadbalancers"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/uuid"
) )
const testClusterName = "testcluster" const testClusterName = "testcluster"
@ -51,9 +51,9 @@ func defaultBackendName(clusterName string) string {
} }
// newLoadBalancerController create a loadbalancer controller. // newLoadBalancerController create a loadbalancer controller.
func newLoadBalancerController(t *testing.T, cm *fakeClusterManager, masterURL string) *LoadBalancerController { func newLoadBalancerController(t *testing.T, cm *fakeClusterManager) *LoadBalancerController {
client := client.NewForConfigOrDie(&restclient.Config{Host: masterURL, ContentConfig: restclient.ContentConfig{GroupVersion: testapi.Default.GroupVersion()}}) kubeClient := fake.NewSimpleClientset()
lb, err := NewLoadBalancerController(client, cm.ClusterManager, 1*time.Second, api.NamespaceAll) lb, err := NewLoadBalancerController(kubeClient, cm.ClusterManager, 1*time.Second, api_v1.NamespaceAll)
if err != nil { if err != nil {
t.Fatalf("%v", err) t.Fatalf("%v", err)
} }
@ -95,7 +95,7 @@ func toIngressRules(hostRules map[string]utils.FakeIngressRuleValueMap) []extens
// newIngress returns a new Ingress with the given path map. // newIngress returns a new Ingress with the given path map.
func newIngress(hostRules map[string]utils.FakeIngressRuleValueMap) *extensions.Ingress { func newIngress(hostRules map[string]utils.FakeIngressRuleValueMap) *extensions.Ingress {
return &extensions.Ingress{ return &extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: fmt.Sprintf("%v", uuid.NewUUID()), Name: fmt.Sprintf("%v", uuid.NewUUID()),
Namespace: api.NamespaceNone, Namespace: api.NamespaceNone,
}, },
@ -107,8 +107,8 @@ func newIngress(hostRules map[string]utils.FakeIngressRuleValueMap) *extensions.
Rules: toIngressRules(hostRules), Rules: toIngressRules(hostRules),
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{ Ingress: []api_v1.LoadBalancerIngress{
{IP: testIPManager.ip()}, {IP: testIPManager.ip()},
}, },
}, },
@ -178,21 +178,21 @@ func addIngress(lbc *LoadBalancerController, ing *extensions.Ingress, pm *nodePo
} }
for _, rule := range ing.Spec.Rules { for _, rule := range ing.Spec.Rules {
for _, path := range rule.HTTP.Paths { for _, path := range rule.HTTP.Paths {
svc := &api.Service{ svc := &api_v1.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: path.Backend.ServiceName, Name: path.Backend.ServiceName,
Namespace: ing.Namespace, Namespace: ing.Namespace,
}, },
} }
var svcPort api.ServicePort var svcPort api_v1.ServicePort
switch path.Backend.ServicePort.Type { switch path.Backend.ServicePort.Type {
case intstr.Int: case intstr.Int:
svcPort = api.ServicePort{Port: path.Backend.ServicePort.IntVal} svcPort = api_v1.ServicePort{Port: path.Backend.ServicePort.IntVal}
default: default:
svcPort = api.ServicePort{Name: path.Backend.ServicePort.StrVal} svcPort = api_v1.ServicePort{Name: path.Backend.ServicePort.StrVal}
} }
svcPort.NodePort = int32(pm.getNodePort(path.Backend.ServiceName)) svcPort.NodePort = int32(pm.getNodePort(path.Backend.ServiceName))
svc.Spec.Ports = []api.ServicePort{svcPort} svc.Spec.Ports = []api_v1.ServicePort{svcPort}
lbc.svcLister.Indexer.Add(svc) lbc.svcLister.Indexer.Add(svc)
} }
} }
@ -201,7 +201,7 @@ func addIngress(lbc *LoadBalancerController, ing *extensions.Ingress, pm *nodePo
func TestLbCreateDelete(t *testing.T) { func TestLbCreateDelete(t *testing.T) {
testFirewallName := "quux" testFirewallName := "quux"
cm := NewFakeClusterManager(DefaultClusterUID, testFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, testFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
inputMap1 := map[string]utils.FakeIngressRuleValueMap{ inputMap1 := map[string]utils.FakeIngressRuleValueMap{
"foo.example.com": { "foo.example.com": {
"/foo1": "foo1svc", "/foo1": "foo1svc",
@ -293,7 +293,7 @@ func TestLbCreateDelete(t *testing.T) {
func TestLbFaultyUpdate(t *testing.T) { func TestLbFaultyUpdate(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
inputMap := map[string]utils.FakeIngressRuleValueMap{ inputMap := map[string]utils.FakeIngressRuleValueMap{
"foo.example.com": { "foo.example.com": {
"/foo1": "foo1svc", "/foo1": "foo1svc",
@ -330,7 +330,7 @@ func TestLbFaultyUpdate(t *testing.T) {
func TestLbDefaulting(t *testing.T) { func TestLbDefaulting(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
// Make sure the controller plugs in the default values accepted by GCE. // Make sure the controller plugs in the default values accepted by GCE.
ing := newIngress(map[string]utils.FakeIngressRuleValueMap{"": {"": "foo1svc"}}) ing := newIngress(map[string]utils.FakeIngressRuleValueMap{"": {"": "foo1svc"}})
pm := newPortManager(1, 65536) pm := newPortManager(1, 65536)
@ -348,7 +348,7 @@ func TestLbDefaulting(t *testing.T) {
func TestLbNoService(t *testing.T) { func TestLbNoService(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
inputMap := map[string]utils.FakeIngressRuleValueMap{ inputMap := map[string]utils.FakeIngressRuleValueMap{
"foo.example.com": { "foo.example.com": {
"/foo1": "foo1svc", "/foo1": "foo1svc",
@ -373,8 +373,8 @@ func TestLbNoService(t *testing.T) {
// Creates the service, next sync should have complete url map. // Creates the service, next sync should have complete url map.
pm := newPortManager(1, 65536) pm := newPortManager(1, 65536)
addIngress(lbc, ing, pm) addIngress(lbc, ing, pm)
lbc.enqueueIngressForService(&api.Service{ lbc.enqueueIngressForService(&api_v1.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo1svc", Name: "foo1svc",
Namespace: ing.Namespace, Namespace: ing.Namespace,
}, },
@ -392,7 +392,7 @@ func TestLbNoService(t *testing.T) {
func TestLbChangeStaticIP(t *testing.T) { func TestLbChangeStaticIP(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
inputMap := map[string]utils.FakeIngressRuleValueMap{ inputMap := map[string]utils.FakeIngressRuleValueMap{
"foo.example.com": { "foo.example.com": {
"/foo1": "foo1svc", "/foo1": "foo1svc",

View file

@ -17,10 +17,10 @@ limitations under the License.
package controller package controller
import ( import (
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/sets"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/backends" "k8s.io/ingress/controllers/gce/backends"
"k8s.io/ingress/controllers/gce/firewalls" "k8s.io/ingress/controllers/gce/firewalls"
"k8s.io/ingress/controllers/gce/healthchecks" "k8s.io/ingress/controllers/gce/healthchecks"

View file

@ -19,13 +19,14 @@ package controller
import ( import (
"fmt" "fmt"
"k8s.io/ingress/controllers/gce/loadbalancers"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"github.com/golang/glog" "github.com/golang/glog"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/controllers/gce/loadbalancers"
) )
// secretLoaders returns a type containing all the secrets of an Ingress. // secretLoaders returns a type containing all the secrets of an Ingress.
@ -44,7 +45,7 @@ func (n *noOPValidator) validate(certs *loadbalancers.TLSCerts) error {
// apiServerTLSLoader loads TLS certs from the apiserver. // apiServerTLSLoader loads TLS certs from the apiserver.
type apiServerTLSLoader struct { type apiServerTLSLoader struct {
noOPValidator noOPValidator
client client.Interface client kubernetes.Interface
} }
func (t *apiServerTLSLoader) load(ing *extensions.Ingress) (*loadbalancers.TLSCerts, error) { func (t *apiServerTLSLoader) load(ing *extensions.Ingress) (*loadbalancers.TLSCerts, error) {
@ -59,7 +60,7 @@ func (t *apiServerTLSLoader) load(ing *extensions.Ingress) (*loadbalancers.TLSCe
secretName := ing.Spec.TLS[0].SecretName secretName := ing.Spec.TLS[0].SecretName
// TODO: Replace this for a secret watcher. // TODO: Replace this for a secret watcher.
glog.V(3).Infof("Retrieving secret for ing %v with name %v", ing.Name, secretName) glog.V(3).Infof("Retrieving secret for ing %v with name %v", ing.Name, secretName)
secret, err := t.client.Core().Secrets(ing.Namespace).Get(secretName) secret, err := t.client.Core().Secrets(ing.Namespace).Get(secretName, meta_v1.GetOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -21,10 +21,10 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/sets" api_v1 "k8s.io/client-go/pkg/api/v1"
) )
// Pods created in loops start from this time, for routines that // Pods created in loops start from this time, for routines that
@ -33,7 +33,7 @@ var firstPodCreationTime = time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC)
func TestZoneListing(t *testing.T) { func TestZoneListing(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
zoneToNode := map[string][]string{ zoneToNode := map[string][]string{
"zone-1": {"n1"}, "zone-1": {"n1"},
"zone-2": {"n2"}, "zone-2": {"n2"},
@ -58,7 +58,7 @@ func TestZoneListing(t *testing.T) {
func TestInstancesAddedToZones(t *testing.T) { func TestInstancesAddedToZones(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
zoneToNode := map[string][]string{ zoneToNode := map[string][]string{
"zone-1": {"n1", "n2"}, "zone-1": {"n1", "n2"},
"zone-2": {"n3"}, "zone-2": {"n3"},
@ -93,12 +93,12 @@ func TestInstancesAddedToZones(t *testing.T) {
func TestProbeGetter(t *testing.T) { func TestProbeGetter(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
nodePortToHealthCheck := map[int64]string{ nodePortToHealthCheck := map[int64]string{
3001: "/healthz", 3001: "/healthz",
3002: "/foo", 3002: "/foo",
} }
addPods(lbc, nodePortToHealthCheck, api.NamespaceDefault) addPods(lbc, nodePortToHealthCheck, api_v1.NamespaceDefault)
for p, exp := range nodePortToHealthCheck { for p, exp := range nodePortToHealthCheck {
got, err := lbc.tr.HealthCheck(p) got, err := lbc.tr.HealthCheck(p)
if err != nil { if err != nil {
@ -111,13 +111,13 @@ func TestProbeGetter(t *testing.T) {
func TestProbeGetterNamedPort(t *testing.T) { func TestProbeGetterNamedPort(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
nodePortToHealthCheck := map[int64]string{ nodePortToHealthCheck := map[int64]string{
3001: "/healthz", 3001: "/healthz",
} }
addPods(lbc, nodePortToHealthCheck, api.NamespaceDefault) addPods(lbc, nodePortToHealthCheck, api_v1.NamespaceDefault)
for _, p := range lbc.podLister.Indexer.List() { for _, p := range lbc.podLister.Indexer.List() {
pod := p.(*api.Pod) pod := p.(*api_v1.Pod)
pod.Spec.Containers[0].Ports[0].Name = "test" pod.Spec.Containers[0].Ports[0].Name = "test"
pod.Spec.Containers[0].ReadinessProbe.Handler.HTTPGet.Port = intstr.IntOrString{Type: intstr.String, StrVal: "test"} pod.Spec.Containers[0].ReadinessProbe.Handler.HTTPGet.Port = intstr.IntOrString{Type: intstr.String, StrVal: "test"}
} }
@ -134,26 +134,26 @@ func TestProbeGetterNamedPort(t *testing.T) {
func TestProbeGetterCrossNamespace(t *testing.T) { func TestProbeGetterCrossNamespace(t *testing.T) {
cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName) cm := NewFakeClusterManager(DefaultClusterUID, DefaultFirewallName)
lbc := newLoadBalancerController(t, cm, "") lbc := newLoadBalancerController(t, cm)
firstPod := &api.Pod{ firstPod := &api_v1.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
// labels match those added by "addPods", but ns and health check // labels match those added by "addPods", but ns and health check
// path is different. If this pod was created in the same ns, it // path is different. If this pod was created in the same ns, it
// would become the health check. // would become the health check.
Labels: map[string]string{"app-3001": "test"}, Labels: map[string]string{"app-3001": "test"},
Name: fmt.Sprintf("test-pod-new-ns"), Name: fmt.Sprintf("test-pod-new-ns"),
Namespace: "new-ns", Namespace: "new-ns",
CreationTimestamp: unversioned.NewTime(firstPodCreationTime.Add(-time.Duration(time.Hour))), CreationTimestamp: meta_v1.NewTime(firstPodCreationTime.Add(-time.Duration(time.Hour))),
}, },
Spec: api.PodSpec{ Spec: api_v1.PodSpec{
Containers: []api.Container{ Containers: []api_v1.Container{
{ {
Ports: []api.ContainerPort{{ContainerPort: 80}}, Ports: []api_v1.ContainerPort{{ContainerPort: 80}},
ReadinessProbe: &api.Probe{ ReadinessProbe: &api_v1.Probe{
Handler: api.Handler{ Handler: api_v1.Handler{
HTTPGet: &api.HTTPGetAction{ HTTPGet: &api_v1.HTTPGetAction{
Scheme: api.URISchemeHTTP, Scheme: api_v1.URISchemeHTTP,
Path: "/badpath", Path: "/badpath",
Port: intstr.IntOrString{ Port: intstr.IntOrString{
Type: intstr.Int, Type: intstr.Int,
@ -170,7 +170,7 @@ func TestProbeGetterCrossNamespace(t *testing.T) {
nodePortToHealthCheck := map[int64]string{ nodePortToHealthCheck := map[int64]string{
3001: "/healthz", 3001: "/healthz",
} }
addPods(lbc, nodePortToHealthCheck, api.NamespaceDefault) addPods(lbc, nodePortToHealthCheck, api_v1.NamespaceDefault)
for p, exp := range nodePortToHealthCheck { for p, exp := range nodePortToHealthCheck {
got, err := lbc.tr.HealthCheck(p) got, err := lbc.tr.HealthCheck(p)
@ -186,10 +186,10 @@ func addPods(lbc *LoadBalancerController, nodePortToHealthCheck map[int64]string
delay := time.Minute delay := time.Minute
for np, u := range nodePortToHealthCheck { for np, u := range nodePortToHealthCheck {
l := map[string]string{fmt.Sprintf("app-%d", np): "test"} l := map[string]string{fmt.Sprintf("app-%d", np): "test"}
svc := &api.Service{ svc := &api_v1.Service{
Spec: api.ServiceSpec{ Spec: api_v1.ServiceSpec{
Selector: l, Selector: l,
Ports: []api.ServicePort{ Ports: []api_v1.ServicePort{
{ {
NodePort: int32(np), NodePort: int32(np),
TargetPort: intstr.IntOrString{ TargetPort: intstr.IntOrString{
@ -204,21 +204,21 @@ func addPods(lbc *LoadBalancerController, nodePortToHealthCheck map[int64]string
svc.Namespace = ns svc.Namespace = ns
lbc.svcLister.Indexer.Add(svc) lbc.svcLister.Indexer.Add(svc)
pod := &api.Pod{ pod := &api_v1.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Labels: l, Labels: l,
Name: fmt.Sprintf("%d", np), Name: fmt.Sprintf("%d", np),
Namespace: ns, Namespace: ns,
CreationTimestamp: unversioned.NewTime(firstPodCreationTime.Add(delay)), CreationTimestamp: meta_v1.NewTime(firstPodCreationTime.Add(delay)),
}, },
Spec: api.PodSpec{ Spec: api_v1.PodSpec{
Containers: []api.Container{ Containers: []api_v1.Container{
{ {
Ports: []api.ContainerPort{{Name: "test", ContainerPort: 80}}, Ports: []api_v1.ContainerPort{{Name: "test", ContainerPort: 80}},
ReadinessProbe: &api.Probe{ ReadinessProbe: &api_v1.Probe{
Handler: api.Handler{ Handler: api_v1.Handler{
HTTPGet: &api.HTTPGetAction{ HTTPGet: &api_v1.HTTPGetAction{
Scheme: api.URISchemeHTTP, Scheme: api_v1.URISchemeHTTP,
Path: u, Path: u,
Port: intstr.IntOrString{ Port: intstr.IntOrString{
Type: intstr.Int, Type: intstr.Int,
@ -239,20 +239,20 @@ func addPods(lbc *LoadBalancerController, nodePortToHealthCheck map[int64]string
func addNodes(lbc *LoadBalancerController, zoneToNode map[string][]string) { func addNodes(lbc *LoadBalancerController, zoneToNode map[string][]string) {
for zone, nodes := range zoneToNode { for zone, nodes := range zoneToNode {
for _, node := range nodes { for _, node := range nodes {
n := &api.Node{ n := &api_v1.Node{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: node, Name: node,
Labels: map[string]string{ Labels: map[string]string{
zoneKey: zone, zoneKey: zone,
}, },
}, },
Status: api.NodeStatus{ Status: api_v1.NodeStatus{
Conditions: []api.NodeCondition{ Conditions: []api_v1.NodeCondition{
{Type: api.NodeReady, Status: api.ConditionTrue}, {Type: api_v1.NodeReady, Status: api_v1.ConditionTrue},
}, },
}, },
} }
lbc.nodeLister.Store.Add(n) lbc.nodeLister.Indexer.Add(n)
} }
} }
lbc.CloudClusterManager.instancePool.Init(lbc.tr) lbc.CloudClusterManager.instancePool.Init(lbc.tr)

View file

@ -22,19 +22,23 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/api/meta"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
listers "k8s.io/client-go/listers/core/v1"
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/util/workqueue"
"k8s.io/ingress/controllers/gce/loadbalancers" "k8s.io/ingress/controllers/gce/loadbalancers"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util/intstr"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/util/workqueue"
"github.com/golang/glog"
) )
const ( const (
@ -202,6 +206,41 @@ type StoreToIngressLister struct {
cache.Store cache.Store
} }
// StoreToNodeLister makes a Store that lists Node.
type StoreToNodeLister struct {
cache.Indexer
}
// StoreToServiceLister makes a Store that lists Service.
type StoreToServiceLister struct {
cache.Indexer
}
// StoreToPodLister makes a Store that lists Pods.
type StoreToPodLister struct {
cache.Indexer
}
func (s *StoreToPodLister) List(selector labels.Selector) (ret []*api.Pod, err error) {
err = ListAll(s.Indexer, selector, func(m interface{}) {
ret = append(ret, m.(*api.Pod))
})
return ret, err
}
func ListAll(store cache.Store, selector labels.Selector, appendFn cache.AppendFunc) error {
for _, m := range store.List() {
metadata, err := meta.Accessor(m)
if err != nil {
return err
}
if selector.Matches(labels.Set(metadata.GetLabels())) {
appendFn(m)
}
}
return nil
}
// List lists all Ingress' in the store. // List lists all Ingress' in the store.
func (s *StoreToIngressLister) List() (ing extensions.IngressList, err error) { func (s *StoreToIngressLister) List() (ing extensions.IngressList, err error) {
for _, m := range s.Store.List() { for _, m := range s.Store.List() {
@ -336,7 +375,7 @@ func (t *GCETranslator) toGCEBackend(be *extensions.IngressBackend, ns string) (
func (t *GCETranslator) getServiceNodePort(be extensions.IngressBackend, namespace string) (int, error) { func (t *GCETranslator) getServiceNodePort(be extensions.IngressBackend, namespace string) (int, error) {
obj, exists, err := t.svcLister.Indexer.Get( obj, exists, err := t.svcLister.Indexer.Get(
&api.Service{ &api.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: be.ServiceName, Name: be.ServiceName,
Namespace: namespace, Namespace: namespace,
}, },
@ -411,7 +450,7 @@ func getZone(n *api.Node) string {
// GetZoneForNode returns the zone for a given node by looking up its zone label. // GetZoneForNode returns the zone for a given node by looking up its zone label.
func (t *GCETranslator) GetZoneForNode(name string) (string, error) { func (t *GCETranslator) GetZoneForNode(name string) (string, error) {
nodes, err := t.nodeLister.NodeCondition(getNodeReadyPredicate()).List() nodes, err := listers.NewNodeLister(t.nodeLister.Indexer).ListWithPredicate(getNodeReadyPredicate())
if err != nil { if err != nil {
return "", err return "", err
} }
@ -428,7 +467,7 @@ func (t *GCETranslator) GetZoneForNode(name string) (string, error) {
// ListZones returns a list of zones this Kubernetes cluster spans. // ListZones returns a list of zones this Kubernetes cluster spans.
func (t *GCETranslator) ListZones() ([]string, error) { func (t *GCETranslator) ListZones() ([]string, error) {
zones := sets.String{} zones := sets.String{}
readyNodes, err := t.nodeLister.NodeCondition(getNodeReadyPredicate()).List() readyNodes, err := listers.NewNodeLister(t.nodeLister.Indexer).ListWithPredicate(getNodeReadyPredicate())
if err != nil { if err != nil {
return zones.List(), err return zones.List(), err
} }
@ -502,14 +541,12 @@ func isSimpleHTTPProbe(probe *api.Probe) bool {
// the request path, callers are responsible for swapping this out for the // the request path, callers are responsible for swapping this out for the
// appropriate default. // appropriate default.
func (t *GCETranslator) HealthCheck(port int64) (*compute.HttpHealthCheck, error) { func (t *GCETranslator) HealthCheck(port int64) (*compute.HttpHealthCheck, error) {
sl, err := t.svcLister.List(labels.Everything()) sl := t.svcLister.List()
if err != nil {
return nil, err
}
var ingresses []extensions.Ingress var ingresses []extensions.Ingress
var healthCheck *compute.HttpHealthCheck var healthCheck *compute.HttpHealthCheck
// Find the label and target port of the one service with the given nodePort // Find the label and target port of the one service with the given nodePort
for _, s := range sl { for _, as := range sl {
s := as.(*api.Service)
for _, p := range s.Spec.Ports { for _, p := range s.Spec.Ports {
// only one Service can match this nodePort, try and look up // only one Service can match this nodePort, try and look up

View file

@ -26,9 +26,11 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"k8s.io/kubernetes/pkg/api" registered "k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/kubernetes/pkg/apimachinery/registered" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
// This installs the legacy v1 API // This installs the legacy v1 API
_ "k8s.io/kubernetes/pkg/api/install" _ "k8s.io/kubernetes/pkg/api/install"
@ -58,14 +60,19 @@ func main() {
} }
tlsCrt := read(*crt) tlsCrt := read(*crt)
tlsKey := read(*key) tlsKey := read(*key)
secret := &api.Secret{ secret := &api_v1.Secret{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: *name, Name: *name,
}, },
Data: map[string][]byte{ Data: map[string][]byte{
api.TLSCertKey: tlsCrt, api_v1.TLSCertKey: tlsCrt,
api.TLSPrivateKeyKey: tlsKey, api_v1.TLSPrivateKeyKey: tlsKey,
}, },
} }
fmt.Printf(runtime.EncodeOrDie(api.Codecs.LegacyCodec(registered.EnabledVersions()...), secret))
arm, err := registered.NewAPIRegistrationManager("")
if err != nil {
log.Fatalf("%v", err)
}
fmt.Printf(runtime.EncodeOrDie(api.Codecs.LegacyCodec(arm.EnabledVersions()...), secret))
} }

View file

@ -20,8 +20,9 @@ import (
"fmt" "fmt"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/ingress/controllers/gce/utils"
netset "k8s.io/kubernetes/pkg/util/net/sets" netset "k8s.io/kubernetes/pkg/util/net/sets"
"k8s.io/ingress/controllers/gce/utils"
) )
type fakeFirewallRules struct { type fakeFirewallRules struct {

View file

@ -17,13 +17,15 @@ limitations under the License.
package firewalls package firewalls
import ( import (
"github.com/golang/glog"
"strconv" "strconv"
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/apimachinery/pkg/util/sets"
netset "k8s.io/kubernetes/pkg/util/net/sets" netset "k8s.io/kubernetes/pkg/util/net/sets"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/ingress/controllers/gce/utils"
) )
// Src ranges from which the GCE L7 performs health checks. // Src ranges from which the GCE L7 performs health checks.

View file

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
) )

View file

@ -17,11 +17,12 @@ limitations under the License.
package healthchecks package healthchecks
import ( import (
compute "google.golang.org/api/compute/v1" "net/http"
"github.com/golang/glog" "github.com/golang/glog"
compute "google.golang.org/api/compute/v1"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"net/http"
) )
// HealthChecks manages health checks. // HealthChecks manages health checks.

View file

@ -20,8 +20,9 @@ import (
"fmt" "fmt"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/util/sets"
) )
// NewFakeInstanceGroups creates a new FakeInstanceGroups. // NewFakeInstanceGroups creates a new FakeInstanceGroups.

View file

@ -21,12 +21,13 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/storage" "k8s.io/ingress/controllers/gce/storage"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/util/sets"
"github.com/golang/glog"
) )
const ( const (

View file

@ -19,7 +19,7 @@ package instances
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
) )
const defaultZone = "default-zone" const defaultZone = "default-zone"

View file

@ -21,8 +21,9 @@ import (
"testing" "testing"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/util/sets"
) )
var testIPManager = testIP{} var testIPManager = testIP{}

View file

@ -25,13 +25,14 @@ import (
"reflect" "reflect"
"strings" "strings"
"github.com/golang/glog"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/backends" "k8s.io/ingress/controllers/gce/backends"
"k8s.io/ingress/controllers/gce/storage" "k8s.io/ingress/controllers/gce/storage"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/util/sets"
"github.com/golang/glog"
) )
const ( const (

View file

@ -21,11 +21,12 @@ import (
"testing" "testing"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/ingress/controllers/gce/backends" "k8s.io/ingress/controllers/gce/backends"
"k8s.io/ingress/controllers/gce/healthchecks" "k8s.io/ingress/controllers/gce/healthchecks"
"k8s.io/ingress/controllers/gce/instances" "k8s.io/ingress/controllers/gce/instances"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/util/sets"
) )
const ( const (

View file

@ -26,20 +26,24 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus/promhttp"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/ingress/controllers/gce/controller" "k8s.io/ingress/controllers/gce/controller"
"k8s.io/ingress/controllers/gce/loadbalancers" "k8s.io/ingress/controllers/gce/loadbalancers"
"k8s.io/ingress/controllers/gce/storage" "k8s.io/ingress/controllers/gce/storage"
"k8s.io/ingress/controllers/gce/utils" "k8s.io/ingress/controllers/gce/utils"
"k8s.io/kubernetes/pkg/api"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/restclient"
kubectl_util "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/util/wait"
"github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus/promhttp"
) )
// Entrypoint of GLBC. Example invocation: // Entrypoint of GLBC. Example invocation:
@ -50,9 +54,9 @@ import (
// $ glbc --proxy="http://localhost:proxyport" // $ glbc --proxy="http://localhost:proxyport"
const ( const (
// lbApiPort is the port on which the loadbalancer controller serves a // lbAPIPort is the port on which the loadbalancer controller serves a
// minimal api (/healthz, /delete-all-and-quit etc). // minimal api (/healthz, /delete-all-and-quit etc).
lbApiPort = 8081 lbAPIPort = 8081
// A delimiter used for clarity in naming GCE resources. // A delimiter used for clarity in naming GCE resources.
clusterNameDelimiter = "--" clusterNameDelimiter = "--"
@ -84,6 +88,12 @@ var (
`Optional, if this controller is running in a kubernetes cluster, use the `Optional, if this controller is running in a kubernetes cluster, use the
pod secrets for creating a Kubernetes client.`) pod secrets for creating a Kubernetes client.`)
apiServerHost = flags.String("apiserver-host", "", "The address of the Kubernetes Apiserver "+
"to connect to in the format of protocol://address:port, e.g., "+
"http://localhost:8080. If not specified, the assumption is that the binary runs inside a "+
"Kubernetes cluster and local discovery is attempted.")
kubeConfigFile = flags.String("kubeconfig", "", "Path to kubeconfig file with authorization and master location information.")
// TODO: Consolidate this flag and running-in-cluster. People already use // TODO: Consolidate this flag and running-in-cluster. People already use
// the first one to mean "running in dev", unfortunately. // the first one to mean "running in dev", unfortunately.
useRealCloud = flags.Bool("use-real-cloud", false, useRealCloud = flags.Bool("use-real-cloud", false,
@ -119,7 +129,7 @@ var (
`Path to a file containing the gce config. If left unspecified this `Path to a file containing the gce config. If left unspecified this
controller only works with default zones.`) controller only works with default zones.`)
healthzPort = flags.Int("healthz-port", lbApiPort, healthzPort = flags.Int("healthz-port", lbAPIPort,
`Port to run healthz server. Must match the health check port in yaml.`) `Port to run healthz server. Must match the health check port in yaml.`)
) )
@ -171,7 +181,6 @@ func main() {
// We only really need a binary switch from light, v(2) logging to // We only really need a binary switch from light, v(2) logging to
// heavier debug style V(4) logging, which we use --verbose for. // heavier debug style V(4) logging, which we use --verbose for.
flags.Parse(os.Args) flags.Parse(os.Args)
clientConfig := kubectl_util.DefaultClientConfig(flags)
// Set glog verbosity levels, unconditionally set --alsologtostderr. // Set glog verbosity levels, unconditionally set --alsologtostderr.
go_flag.Lookup("logtostderr").Value.Set("true") go_flag.Lookup("logtostderr").Value.Set("true")
@ -183,20 +192,30 @@ func main() {
glog.Fatalf("Please specify --default-backend") glog.Fatalf("Please specify --default-backend")
} }
var config *restclient.Config var config *rest.Config
// Create kubeclient // Create kubeclient
if *inCluster { if *inCluster {
if config, err = restclient.InClusterConfig(); err != nil { if config, err = rest.InClusterConfig(); err != nil {
glog.Fatalf("error creating client configuration: %v", err) glog.Fatalf("error creating client configuration: %v", err)
} }
} else { } else {
config, err = clientConfig.ClientConfig() if *apiServerHost == "" {
glog.Fatalf("please specify the api server address using the flag --apiserver-host")
}
config, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: *kubeConfigFile},
&clientcmd.ConfigOverrides{
ClusterInfo: clientcmdapi.Cluster{
Server: *apiServerHost,
},
}).ClientConfig()
if err != nil { if err != nil {
glog.Fatalf("error creating client configuration: %v", err) glog.Fatalf("error creating client configuration: %v", err)
} }
} }
kubeClient, err := client.NewForConfig(config) kubeClient, err := kubernetes.NewForConfig(config)
if err != nil { if err != nil {
glog.Fatalf("Failed to create client: %v.", err) glog.Fatalf("Failed to create client: %v.", err)
} }
@ -247,7 +266,7 @@ func main() {
} }
} }
func newNamer(kubeClient client.Interface, clusterName string, fwName string) (*utils.Namer, error) { func newNamer(kubeClient kubernetes.Interface, clusterName string, fwName string) (*utils.Namer, error) {
name, err := getClusterUID(kubeClient, clusterName) name, err := getClusterUID(kubeClient, clusterName)
if err != nil { if err != nil {
return nil, err return nil, err
@ -329,7 +348,7 @@ func useDefaultOrLookupVault(cfgVault *storage.ConfigMapVault, cm_key, default_n
// backwards compatibility, the firewall name will default to the cluster UID. // backwards compatibility, the firewall name will default to the cluster UID.
// Use getFlagOrLookupVault to obtain a stored or overridden value for the firewall name. // Use getFlagOrLookupVault to obtain a stored or overridden value for the firewall name.
// else, use the cluster UID as a backup (this retains backwards compatibility). // else, use the cluster UID as a backup (this retains backwards compatibility).
func getFirewallName(kubeClient client.Interface, name, cluster_uid string) (string, error) { func getFirewallName(kubeClient kubernetes.Interface, name, cluster_uid string) (string, error) {
cfgVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName) cfgVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName)
if fw_name, err := useDefaultOrLookupVault(cfgVault, storage.ProviderDataKey, name); err != nil { if fw_name, err := useDefaultOrLookupVault(cfgVault, storage.ProviderDataKey, name); err != nil {
return "", err return "", err
@ -347,7 +366,7 @@ func getFirewallName(kubeClient client.Interface, name, cluster_uid string) (str
// else, check if there are any working Ingresses // else, check if there are any working Ingresses
// - remember that "" is the cluster uid // - remember that "" is the cluster uid
// else, allocate a new uid // else, allocate a new uid
func getClusterUID(kubeClient client.Interface, name string) (string, error) { func getClusterUID(kubeClient kubernetes.Interface, name string) (string, error) {
cfgVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName) cfgVault := storage.NewConfigMapVault(kubeClient, api.NamespaceSystem, uidConfigMapName)
if name, err := useDefaultOrLookupVault(cfgVault, storage.UidDataKey, name); err != nil { if name, err := useDefaultOrLookupVault(cfgVault, storage.UidDataKey, name); err != nil {
return "", err return "", err
@ -356,7 +375,9 @@ func getClusterUID(kubeClient client.Interface, name string) (string, error) {
} }
// Check if the cluster has an Ingress with ip // Check if the cluster has an Ingress with ip
ings, err := kubeClient.Extensions().Ingresses(api.NamespaceAll).List(api.ListOptions{LabelSelector: labels.Everything()}) ings, err := kubeClient.Extensions().Ingresses(api.NamespaceAll).List(meta_v1.ListOptions{
LabelSelector: labels.Everything().String(),
})
if err != nil { if err != nil {
return "", err return "", err
} }
@ -387,11 +408,11 @@ func getClusterUID(kubeClient client.Interface, name string) (string, error) {
} }
// getNodePort waits for the Service, and returns it's first node port. // getNodePort waits for the Service, and returns it's first node port.
func getNodePort(client client.Interface, ns, name string) (nodePort int64, err error) { func getNodePort(client kubernetes.Interface, ns, name string) (nodePort int64, err error) {
var svc *api.Service var svc *api_v1.Service
glog.V(3).Infof("Waiting for %v/%v", ns, name) glog.V(3).Infof("Waiting for %v/%v", ns, name)
wait.Poll(1*time.Second, 5*time.Minute, func() (bool, error) { wait.Poll(1*time.Second, 5*time.Minute, func() (bool, error) {
svc, err = client.Core().Services(ns).Get(name) svc, err = client.Core().Services(ns).Get(name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return false, nil return false, nil
} }

View file

@ -22,10 +22,12 @@ import (
"sync" "sync"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/kubernetes/pkg/client/cache" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/cache"
) )
const ( const (
@ -72,7 +74,7 @@ func (c *ConfigMapVault) Put(key, val string) error {
c.storeLock.Lock() c.storeLock.Lock()
defer c.storeLock.Unlock() defer c.storeLock.Unlock()
apiObj := &api.ConfigMap{ apiObj := &api.ConfigMap{
ObjectMeta: api.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: c.name, Name: c.name,
Namespace: c.namespace, Namespace: c.namespace,
}, },
@ -121,7 +123,7 @@ func (c *ConfigMapVault) Delete() error {
// NewConfigMapVault creates a config map client. // NewConfigMapVault creates a config map client.
// This client is essentially meant to abstract out the details of // This client is essentially meant to abstract out the details of
// configmaps and the API, and just store/retrieve a single value, the cluster uid. // configmaps and the API, and just store/retrieve a single value, the cluster uid.
func NewConfigMapVault(c client.Interface, uidNs, uidConfigMapName string) *ConfigMapVault { func NewConfigMapVault(c kubernetes.Interface, uidNs, uidConfigMapName string) *ConfigMapVault {
return &ConfigMapVault{ return &ConfigMapVault{
ConfigMapStore: NewConfigMapStore(c), ConfigMapStore: NewConfigMapStore(c),
namespace: uidNs, namespace: uidNs,
@ -148,7 +150,7 @@ type ConfigMapStore interface {
// through cache. // through cache.
type APIServerConfigMapStore struct { type APIServerConfigMapStore struct {
ConfigMapStore ConfigMapStore
client client.Interface client kubernetes.Interface
} }
// Add adds the given config map to the apiserver's store. // Add adds the given config map to the apiserver's store.
@ -168,7 +170,7 @@ func (a *APIServerConfigMapStore) Update(obj interface{}) error {
// Delete deletes the existing config map object. // Delete deletes the existing config map object.
func (a *APIServerConfigMapStore) Delete(obj interface{}) error { func (a *APIServerConfigMapStore) Delete(obj interface{}) error {
cfg := obj.(*api.ConfigMap) cfg := obj.(*api.ConfigMap)
return a.client.Core().ConfigMaps(cfg.Namespace).Delete(cfg.Name, &api.DeleteOptions{}) return a.client.Core().ConfigMaps(cfg.Namespace).Delete(cfg.Name, &metav1.DeleteOptions{})
} }
// GetByKey returns the config map for a given key. // GetByKey returns the config map for a given key.
@ -179,7 +181,7 @@ func (a *APIServerConfigMapStore) GetByKey(key string) (item interface{}, exists
return nil, false, fmt.Errorf("failed to get key %v, unexpecte format, expecting ns/name", key) return nil, false, fmt.Errorf("failed to get key %v, unexpecte format, expecting ns/name", key)
} }
ns, name := nsName[0], nsName[1] ns, name := nsName[0], nsName[1]
cfg, err := a.client.Core().ConfigMaps(ns).Get(name) cfg, err := a.client.Core().ConfigMaps(ns).Get(name, metav1.GetOptions{})
if err != nil { if err != nil {
// Translate not found errors to found=false, err=nil // Translate not found errors to found=false, err=nil
if errors.IsNotFound(err) { if errors.IsNotFound(err) {
@ -192,6 +194,6 @@ func (a *APIServerConfigMapStore) GetByKey(key string) (item interface{}, exists
// NewConfigMapStore returns a config map store capable of persisting updates // NewConfigMapStore returns a config map store capable of persisting updates
// to apiserver. // to apiserver.
func NewConfigMapStore(c client.Interface) ConfigMapStore { func NewConfigMapStore(c kubernetes.Interface) ConfigMapStore {
return &APIServerConfigMapStore{ConfigMapStore: cache.NewStore(cache.MetaNamespaceKeyFunc), client: c} return &APIServerConfigMapStore{ConfigMapStore: cache.NewStore(cache.MetaNamespaceKeyFunc), client: c}
} }

View file

@ -19,7 +19,7 @@ package storage
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/client-go/pkg/api"
) )
func TestConfigMapUID(t *testing.T) { func TestConfigMapUID(t *testing.T) {

View file

@ -21,8 +21,9 @@ import (
"time" "time"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/tools/cache"
) )
// Snapshotter is an interface capable of providing a consistent snapshot of // Snapshotter is an interface capable of providing a consistent snapshot of

View file

@ -18,6 +18,7 @@ package utils
import ( import (
"fmt" "fmt"
"regexp"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -25,7 +26,6 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
compute "google.golang.org/api/compute/v1" compute "google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi" "google.golang.org/api/googleapi"
"regexp"
) )
const ( const (

View file

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

View file

@ -26,7 +26,7 @@ import (
"strings" "strings"
text_template "text/template" text_template "text/template"
"k8s.io/kubernetes/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"github.com/golang/glog" "github.com/golang/glog"

View file

@ -1,92 +0,0 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cache
import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/util/sets"
)
func TestStoreToIngressLister(t *testing.T) {
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
ids := sets.NewString("foo", "bar", "baz")
for id := range ids {
store.Add(&extensions.Ingress{ObjectMeta: api.ObjectMeta{Name: id}})
}
sml := StoreToIngressLister{store}
gotIngress := sml.List()
got := make([]string, len(gotIngress))
for ix := range gotIngress {
ing, ok := gotIngress[ix].(*extensions.Ingress)
if !ok {
t.Errorf("expected an Ingress type")
}
got[ix] = ing.Name
}
if !ids.HasAll(got...) || len(got) != len(ids) {
t.Errorf("expected %v, got %v", ids, got)
}
}
func TestStoreToSecretsLister(t *testing.T) {
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
ids := sets.NewString("foo", "bar", "baz")
for id := range ids {
store.Add(&api.Secret{ObjectMeta: api.ObjectMeta{Name: id}})
}
sml := StoreToSecretsLister{store}
gotIngress := sml.List()
got := make([]string, len(gotIngress))
for ix := range gotIngress {
s, ok := gotIngress[ix].(*api.Secret)
if !ok {
t.Errorf("expected a Secret type")
}
got[ix] = s.Name
}
if !ids.HasAll(got...) || len(got) != len(ids) {
t.Errorf("expected %v, got %v", ids, got)
}
}
func TestStoreToConfigmapLister(t *testing.T) {
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
ids := sets.NewString("foo", "bar", "baz")
for id := range ids {
store.Add(&api.ConfigMap{ObjectMeta: api.ObjectMeta{Name: id}})
}
sml := StoreToConfigmapLister{store}
gotIngress := sml.List()
got := make([]string, len(gotIngress))
for ix := range gotIngress {
m, ok := gotIngress[ix].(*api.ConfigMap)
if !ok {
t.Errorf("expected an Ingress type")
}
got[ix] = m.Name
}
if !ids.HasAll(got...) || len(got) != len(ids) {
t.Errorf("expected %v, got %v", ids, got)
}
}

View file

@ -24,8 +24,8 @@ import (
"regexp" "regexp"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/api" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

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

View file

@ -21,7 +21,7 @@ import (
"regexp" "regexp"
"strings" "strings"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

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

View file

@ -18,7 +18,7 @@ package authtls
import ( import (
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

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

View file

@ -18,7 +18,7 @@ package class
import ( import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/errors" "k8s.io/ingress/core/pkg/ingress/errors"

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package cors package cors
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
) )

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package healthcheck package healthcheck
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

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

View file

@ -21,7 +21,8 @@ import (
"strings" "strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/kubernetes/pkg/apis/extensions"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/util/net/sets" "k8s.io/kubernetes/pkg/util/net/sets"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"

View file

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

View file

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

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package portinredirect package portinredirect
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package proxy package proxy
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

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

View file

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

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package rewrite package rewrite
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
"k8s.io/ingress/core/pkg/ingress/resolver" "k8s.io/ingress/core/pkg/ingress/resolver"

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package secureupstream package secureupstream
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
) )

View file

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

View file

@ -21,9 +21,9 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"k8s.io/kubernetes/pkg/api"
"github.com/golang/glog" "github.com/golang/glog"
api_v1 "k8s.io/client-go/pkg/api/v1"
) )
const ( const (
@ -54,7 +54,7 @@ func (npm namedPortMapping) getPortMappings() map[string]string {
} }
// GetPortMapping returns the number of the named port or an error if is not valid // GetPortMapping returns the number of the named port or an error if is not valid
func GetPortMapping(name string, s *api.Service) (int32, error) { func GetPortMapping(name string, s *api_v1.Service) (int32, error) {
if s == nil { if s == nil {
return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name) return -1, fmt.Errorf("impossible to extract por mapping from %v (missing service)", name)
} }

View file

@ -18,9 +18,10 @@ package service
import ( import (
"encoding/json" "encoding/json"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"testing" "testing"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
api "k8s.io/client-go/pkg/api/v1"
) )
func fakeService(npa bool, ps bool, expectedP string) *api.Service { func fakeService(npa bool, ps bool, expectedP string) *api.Service {
@ -41,11 +42,11 @@ func fakeService(npa bool, ps bool, expectedP string) *api.Service {
// fake service // fake service
return &api.Service{ return &api.Service{
TypeMeta: unversioned.TypeMeta{ TypeMeta: meta_v1.TypeMeta{
Kind: "ingress", Kind: "ingress",
APIVersion: "v1", APIVersion: "v1",
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Annotations: map[string]string{ Annotations: map[string]string{
fakeNpa: string(fakePs), fakeNpa: string(fakePs),
}, },

View file

@ -21,7 +21,7 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
) )

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package snippet package snippet
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
) )

View file

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

View file

@ -17,7 +17,7 @@ limitations under the License.
package sslpassthrough package sslpassthrough
import ( import (
"k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/ingress/core/pkg/ingress/annotations/parser" "k8s.io/ingress/core/pkg/ingress/annotations/parser"
ing_errors "k8s.io/ingress/core/pkg/ingress/errors" ing_errors "k8s.io/ingress/core/pkg/ingress/errors"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -14,11 +14,12 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp" "github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api" "k8s.io/apiserver/pkg/server/healthz"
client "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd" api "k8s.io/client-go/pkg/api/v1"
clientcmdapi "k8s.io/kubernetes/pkg/client/unversioned/clientcmd/api" "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/healthz" "k8s.io/client-go/tools/clientcmd"
clientcmd_api "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/k8s"
@ -208,19 +209,35 @@ const (
defaultBurst = 1e6 defaultBurst = 1e6
) )
// buildConfigFromFlags builds REST config based on master URL and kubeconfig path.
// If both of them are empty then in cluster config is used.
func buildConfigFromFlags(masterURL, kubeconfigPath string) (*rest.Config, error) {
if kubeconfigPath == "" && masterURL == "" {
kubeconfig, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
return kubeconfig, nil
}
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfigPath},
&clientcmd.ConfigOverrides{
ClusterInfo: clientcmd_api.Cluster{
Server: masterURL,
},
}).ClientConfig()
}
// createApiserverClient creates new Kubernetes Apiserver client. When kubeconfig or apiserverHost param is empty // createApiserverClient creates new Kubernetes Apiserver client. When kubeconfig or apiserverHost param is empty
// the function assumes that it is running inside a Kubernetes cluster and attempts to // the function assumes that it is running inside a Kubernetes cluster and attempts to
// discover the Apiserver. Otherwise, it connects to the Apiserver specified. // discover the Apiserver. Otherwise, it connects to the Apiserver specified.
// //
// apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001. // apiserverHost param is in the format of protocol://address:port/pathPrefix, e.g.http://localhost:8001.
// kubeConfig location of kubeconfig file // kubeConfig location of kubeconfig file
func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Clientset, error) { func createApiserverClient(apiserverHost string, kubeConfig string) (*kubernetes.Clientset, error) {
cfg, err := buildConfigFromFlags(apiserverHost, kubeConfig)
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeConfig},
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: apiserverHost}})
cfg, err := clientConfig.ClientConfig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -231,7 +248,7 @@ func createApiserverClient(apiserverHost string, kubeConfig string) (*client.Cli
glog.Infof("Creating API server client for %s", cfg.Host) glog.Infof("Creating API server client for %s", cfg.Host)
client, err := client.NewForConfig(cfg) client, err := kubernetes.NewForConfig(cfg)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -24,9 +24,10 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
podutil "k8s.io/kubernetes/pkg/api/pod" "k8s.io/apimachinery/pkg/labels"
"k8s.io/kubernetes/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/annotations/service" "k8s.io/ingress/core/pkg/ingress/annotations/service"
) )
@ -35,11 +36,11 @@ import (
// named port. If the annotation in the service does not exist or is not equals // named port. If the annotation in the service does not exist or is not equals
// to the port mapping obtained from the pod the service must be updated to reflect // to the port mapping obtained from the pod the service must be updated to reflect
// the current state // the current state
func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error { func (ic *GenericController) checkSvcForUpdate(svc *api_v1.Service) error {
// get the pods associated with the service // get the pods associated with the service
// TODO: switch this to a watch // TODO: switch this to a watch
pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(api.ListOptions{ pods, err := ic.cfg.Client.Core().Pods(svc.Namespace).List(meta_v1.ListOptions{
LabelSelector: labels.Set(svc.Spec.Selector).AsSelector(), LabelSelector: labels.Set(svc.Spec.Selector).AsSelector().String(),
}) })
if err != nil { if err != nil {
@ -60,7 +61,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
_, err := strconv.Atoi(servicePort.TargetPort.StrVal) _, err := strconv.Atoi(servicePort.TargetPort.StrVal)
if err != nil { if err != nil {
portNum, err := podutil.FindPort(pod, servicePort) portNum, err := findPort(pod, servicePort)
if err != nil { if err != nil {
glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err) glog.V(4).Infof("failed to find port for service %s/%s: %v", portNum, svc.Namespace, svc.Name, err)
continue continue
@ -82,7 +83,7 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) { if len(namedPorts) > 0 && !reflect.DeepEqual(curNamedPort, namedPorts) {
data, _ := json.Marshal(namedPorts) data, _ := json.Marshal(namedPorts)
newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name) newSvc, err := ic.cfg.Client.Core().Services(svc.Namespace).Get(svc.Name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err) return fmt.Errorf("error getting service %v/%v: %v", svc.Namespace, svc.Name, err)
} }
@ -103,3 +104,26 @@ func (ic *GenericController) checkSvcForUpdate(svc *api.Service) error {
return nil return nil
} }
// FindPort locates the container port for the given pod and portName. If the
// targetPort is a number, use that. If the targetPort is a string, look that
// string up in all named ports in all containers in the target pod. If no
// match is found, fail.
func findPort(pod *api_v1.Pod, svcPort *api_v1.ServicePort) (int, error) {
portName := svcPort.TargetPort
switch portName.Type {
case intstr.String:
name := portName.StrVal
for _, container := range pod.Spec.Containers {
for _, port := range container.Ports {
if port.Name == name && port.Protocol == svcPort.Protocol {
return int(port.ContainerPort), nil
}
}
}
case intstr.Int:
return portName.IntValue(), nil
}
return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID)
}

View file

@ -20,51 +20,55 @@ import (
"reflect" "reflect"
"testing" "testing"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/pkg/api"
api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/annotations/service" "k8s.io/ingress/core/pkg/ingress/annotations/service"
"k8s.io/kubernetes/pkg/api"
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/util/intstr"
) )
func buildSimpleClientSet() *testclient.Clientset { func buildSimpleClientSet() *fake.Clientset {
return testclient.NewSimpleClientset( return fake.NewSimpleClientset(
&api.PodList{Items: []api.Pod{ &api_v1.PodList{
{ Items: []api_v1.Pod{
ObjectMeta: api.ObjectMeta{ {
Name: "foo1", ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Name: "foo1",
Labels: map[string]string{ Namespace: api.NamespaceDefault,
"lable_sig": "foo_pod", Labels: map[string]string{
"lable_sig": "foo_pod",
},
}, },
}, Spec: api_v1.PodSpec{
Spec: api.PodSpec{ NodeName: "foo_node_1",
NodeName: "foo_node_1", Containers: []api_v1.Container{
Containers: []api.Container{ {
{ Ports: []api_v1.ContainerPort{
Ports: []api.ContainerPort{ {
{ Name: "foo1_named_port_c1",
Name: "foo1_named_port_c1", Protocol: api_v1.ProtocolTCP,
Protocol: api.ProtocolTCP, ContainerPort: 80,
ContainerPort: 80, },
}, },
}, },
}, },
}, },
}, },
}, {
{ ObjectMeta: meta_v1.ObjectMeta{
ObjectMeta: api.ObjectMeta{ Name: "foo1",
Name: "foo1", Namespace: api.NamespaceSystem,
Namespace: api.NamespaceSystem, Labels: map[string]string{
Labels: map[string]string{ "lable_sig": "foo_pod",
"lable_sig": "foo_pod", },
}, },
}, },
}, },
}}, },
&api.ServiceList{Items: []api.Service{ &api_v1.ServiceList{Items: []api_v1.Service{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Name: "named_port_test_service", Name: "named_port_test_service",
}, },
@ -81,14 +85,13 @@ func buildGenericController() *GenericController {
} }
} }
func buildService() *api.Service { func buildService() *api_v1.Service {
return &api.Service{ return &api_v1.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Name: "named_port_test_service", Name: "named_port_test_service",
}, },
Spec: api_v1.ServiceSpec{
Spec: api.ServiceSpec{
ClusterIP: "10.10.10.10", ClusterIP: "10.10.10.10",
}, },
} }
@ -98,17 +101,17 @@ func TestCheckSvcForUpdate(t *testing.T) {
foos := []struct { foos := []struct {
n string n string
ns string ns string
sps []api.ServicePort sps []api_v1.ServicePort
sl map[string]string sl map[string]string
er string er string
}{ }{
{ {
"pods_have_not_been_found_in_this_namespace", "pods_have_not_been_found_in_this_namespace",
api.NamespaceSystem, api.NamespaceSystem,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -118,10 +121,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"ports_have_not_been_found_in_this_pod", "ports_have_not_been_found_in_this_pod",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")}, {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_cXX")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -132,10 +135,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"ports_fixed", "ports_fixed",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(80)}, {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(80)},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -145,10 +148,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"nil_selector", "nil_selector",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
nil, nil,
"{\"foo1_named_port_c1\":\"80\"}", "{\"foo1_named_port_c1\":\"80\"}",
@ -156,10 +159,10 @@ func TestCheckSvcForUpdate(t *testing.T) {
{ {
"normal_update", "normal_update",
api.NamespaceDefault, api.NamespaceDefault,
[]api.ServicePort{ []api_v1.ServicePort{
{Name: "foo_port_1", Port: 8080, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")}, {Name: "foo_port_1", Port: 8080, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("foo1_named_port_c1")},
{Name: "foo_port_2", Port: 8181, Protocol: api.ProtocolTCP, TargetPort: intstr.FromInt(81)}, {Name: "foo_port_2", Port: 8181, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromInt(81)},
{Name: "foo_port_3", Port: 8282, Protocol: api.ProtocolTCP, TargetPort: intstr.FromString("")}, {Name: "foo_port_3", Port: 8282, Protocol: api_v1.ProtocolTCP, TargetPort: intstr.FromString("")},
}, },
map[string]string{ map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
@ -181,7 +184,7 @@ func TestCheckSvcForUpdate(t *testing.T) {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service") rs, _ := gc.cfg.Client.Core().Services(api.NamespaceDefault).Get("named_port_test_service", meta_v1.GetOptions{})
rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation] rr := rs.ObjectMeta.Annotations[service.NamedPortAnnotation]
if !reflect.DeepEqual(rr, foo.er) { if !reflect.DeepEqual(rr, foo.er) {
t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n) t.Errorf("Returned %s, but expected %s for %s", rr, foo.er, foo.n)

View file

@ -17,9 +17,8 @@ limitations under the License.
package controller package controller
import ( import (
"testing"
"reflect" "reflect"
"testing"
"k8s.io/ingress/core/pkg/ingress" "k8s.io/ingress/core/pkg/ingress"
"k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/auth"

View file

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

View file

@ -17,8 +17,8 @@ limitations under the License.
package ingress package ingress
import ( import (
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/apimachinery/pkg/runtime/schema"
) )
// BackendByNameServers sorts upstreams by name // BackendByNameServers sorts upstreams by name
@ -69,7 +69,7 @@ func (c LocationByPath) Less(i, j int) bool {
// SSLCert describes a SSL certificate to be used in a server // SSLCert describes a SSL certificate to be used in a server
type SSLCert struct { type SSLCert struct {
api.ObjectMeta `json:"metadata,omitempty"` meta_v1.ObjectMeta `json:"metadata,omitempty"`
// CAFileName contains the path to the file with the root certificate // CAFileName contains the path to the file with the root certificate
CAFileName string `json:"caFileName"` CAFileName string `json:"caFileName"`
// PemFileName contains the path to the file with the certificate and key concatenated // PemFileName contains the path to the file with the certificate and key concatenated
@ -82,4 +82,6 @@ type SSLCert struct {
} }
// GetObjectKind implements the ObjectKind interface as a noop // GetObjectKind implements the ObjectKind interface as a noop
func (s SSLCert) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind } func (s SSLCert) GetObjectKind() schema.ObjectKind {
return schema.EmptyObjectKind
}

View file

@ -19,7 +19,7 @@ package ingress
import ( import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
func buildBackendByNameServers() BackendByNameServers { func buildBackendByNameServers() BackendByNameServers {
@ -365,7 +365,7 @@ func TestLocationByPathLess(t *testing.T) {
func TestGetObjectKindForSSLCert(t *testing.T) { func TestGetObjectKindForSSLCert(t *testing.T) {
fk := &SSLCert{ fk := &SSLCert{
ObjectMeta: api.ObjectMeta{}, ObjectMeta: meta_v1.ObjectMeta{},
CAFileName: "ca_file", CAFileName: "ca_file",
PemFileName: "pemfile", PemFileName: "pemfile",
PemSHA: "pem_sha", PemSHA: "pem_sha",

View file

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

View file

@ -21,23 +21,25 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/client-go/kubernetes/fake"
tc "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/client-go/pkg/api"
"k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
) )
func TestGetCurrentLeaderLeaderExist(t *testing.T) { func TestGetCurrentLeaderLeaderExist(t *testing.T) {
fkER := resourcelock.LeaderElectionRecord{ fkER := resourcelock.LeaderElectionRecord{
HolderIdentity: "currentLeader", HolderIdentity: "currentLeader",
LeaseDurationSeconds: 30, LeaseDurationSeconds: 30,
AcquireTime: unversioned.Now(), AcquireTime: meta_v1.NewTime(time.Now()),
RenewTime: unversioned.Now(), RenewTime: meta_v1.NewTime(time.Now()),
LeaderTransitions: 3, LeaderTransitions: 3,
} }
leaderInfo, _ := json.Marshal(fkER) leaderInfo, _ := json.Marshal(fkER)
fkEndpoints := api.Endpoints{ fkEndpoints := api_v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Annotations: map[string]string{ Annotations: map[string]string{
@ -45,7 +47,7 @@ func TestGetCurrentLeaderLeaderExist(t *testing.T) {
}, },
}, },
} }
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}}) fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk) identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err != nil { if err != nil {
t.Fatalf("expected identitiy and endpoints but returned error %s", err) t.Fatalf("expected identitiy and endpoints but returned error %s", err)
@ -61,14 +63,14 @@ func TestGetCurrentLeaderLeaderExist(t *testing.T) {
} }
func TestGetCurrentLeaderLeaderNotExist(t *testing.T) { func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
fkEndpoints := api.Endpoints{ fkEndpoints := api_v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Annotations: map[string]string{}, Annotations: map[string]string{},
}, },
} }
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}}) fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk) identity, endpoints, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err != nil { if err != nil {
t.Fatalf("unexpeted error: %v", err) t.Fatalf("unexpeted error: %v", err)
@ -84,8 +86,8 @@ func TestGetCurrentLeaderLeaderNotExist(t *testing.T) {
} }
func TestGetCurrentLeaderAnnotationError(t *testing.T) { func TestGetCurrentLeaderAnnotationError(t *testing.T) {
fkEndpoints := api.Endpoints{ fkEndpoints := api_v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Annotations: map[string]string{ Annotations: map[string]string{
@ -93,7 +95,7 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) {
}, },
}, },
} }
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{fkEndpoints}}) fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{fkEndpoints}})
_, _, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk) _, _, err := getCurrentLeader("ingress-controller-test", api.NamespaceSystem, fk)
if err == nil { if err == nil {
t.Errorf("expected error") t.Errorf("expected error")
@ -101,15 +103,15 @@ func TestGetCurrentLeaderAnnotationError(t *testing.T) {
} }
func TestNewElection(t *testing.T) { func TestNewElection(t *testing.T) {
fk := tc.NewSimpleClientset(&api.EndpointsList{Items: []api.Endpoints{ fk := fake.NewSimpleClientset(&api_v1.EndpointsList{Items: []api_v1.Endpoints{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test", Name: "ingress-controller-test",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-test-020", Name: "ingress-controller-test-020",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
}, },

View file

@ -53,12 +53,11 @@ import (
"reflect" "reflect"
"time" "time"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/unversioned" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/componentconfig" "k8s.io/apimachinery/pkg/util/runtime"
rl "k8s.io/kubernetes/pkg/client/leaderelection/resourcelock" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/util/runtime" rl "k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
"k8s.io/kubernetes/pkg/util/wait"
"github.com/golang/glog" "github.com/golang/glog"
"github.com/spf13/pflag" "github.com/spf13/pflag"
@ -71,6 +70,31 @@ const (
DefaultRetryPeriod = 2 * 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 // NewLeadereElector creates a LeaderElector from a LeaderElecitionConfig
func NewLeaderElector(lec LeaderElectionConfig) (*LeaderElector, error) { func NewLeaderElector(lec LeaderElectionConfig) (*LeaderElector, error) {
if lec.LeaseDuration <= lec.RenewDeadline { if lec.LeaseDuration <= lec.RenewDeadline {
@ -176,16 +200,17 @@ func (le *LeaderElector) IsLeader() bool {
// acquire loops calling tryAcquireOrRenew and returns immediately when tryAcquireOrRenew succeeds. // acquire loops calling tryAcquireOrRenew and returns immediately when tryAcquireOrRenew succeeds.
func (le *LeaderElector) acquire() { func (le *LeaderElector) acquire() {
stop := make(chan struct{}) stop := make(chan struct{})
glog.Infof("attempting to acquire leader lease...")
wait.JitterUntil(func() { wait.JitterUntil(func() {
succeeded := le.tryAcquireOrRenew() succeeded := le.tryAcquireOrRenew()
le.maybeReportTransition() le.maybeReportTransition()
desc := le.config.Lock.Describe() desc := le.config.Lock.Describe()
if !succeeded { if !succeeded {
glog.V(4).Infof("failed to renew lease %v", desc) glog.V(4).Infof("failed to acquire lease %v", desc)
return return
} }
le.config.Lock.RecordEvent("became leader") le.config.Lock.RecordEvent("became leader")
glog.Infof("sucessfully acquired lease %v", desc) glog.Infof("successfully acquired lease %v", desc)
close(stop) close(stop)
}, le.config.RetryPeriod, JitterFactor, true, stop) }, le.config.RetryPeriod, JitterFactor, true, stop)
} }
@ -213,7 +238,7 @@ func (le *LeaderElector) renew() {
// else it tries to renew the lease if it has already been acquired. Returns true // else it tries to renew the lease if it has already been acquired. Returns true
// on success else returns false. // on success else returns false.
func (le *LeaderElector) tryAcquireOrRenew() bool { func (le *LeaderElector) tryAcquireOrRenew() bool {
now := unversioned.Now() now := metav1.Now()
leaderElectionRecord := rl.LeaderElectionRecord{ leaderElectionRecord := rl.LeaderElectionRecord{
HolderIdentity: le.config.Lock.Identity(), HolderIdentity: le.config.Lock.Identity(),
LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second), LeaseDurationSeconds: int(le.config.LeaseDuration / time.Second),
@ -244,7 +269,7 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
} }
if le.observedTime.Add(le.config.LeaseDuration).After(now.Time) && if le.observedTime.Add(le.config.LeaseDuration).After(now.Time) &&
oldLeaderElectionRecord.HolderIdentity != le.config.Lock.Identity() { oldLeaderElectionRecord.HolderIdentity != le.config.Lock.Identity() {
glog.Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity) glog.V(4).Infof("lock is held by %v and has not yet expired", oldLeaderElectionRecord.HolderIdentity)
return false return false
} }
@ -252,6 +277,7 @@ func (le *LeaderElector) tryAcquireOrRenew() bool {
// here. Let's correct it before updating. // here. Let's correct it before updating.
if oldLeaderElectionRecord.HolderIdentity == le.config.Lock.Identity() { if oldLeaderElectionRecord.HolderIdentity == le.config.Lock.Identity() {
leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime leaderElectionRecord.AcquireTime = oldLeaderElectionRecord.AcquireTime
leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions
} else { } else {
leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1 leaderElectionRecord.LeaderTransitions = oldLeaderElectionRecord.LeaderTransitions + 1
} }
@ -276,17 +302,17 @@ func (l *LeaderElector) maybeReportTransition() {
} }
} }
func DefaultLeaderElectionConfiguration() componentconfig.LeaderElectionConfiguration { func DefaultLeaderElectionConfiguration() LeaderElectionConfiguration {
return componentconfig.LeaderElectionConfiguration{ return LeaderElectionConfiguration{
LeaderElect: false, LeaderElect: false,
LeaseDuration: unversioned.Duration{Duration: DefaultLeaseDuration}, LeaseDuration: metav1.Duration{Duration: DefaultLeaseDuration},
RenewDeadline: unversioned.Duration{Duration: DefaultRenewDeadline}, RenewDeadline: metav1.Duration{Duration: DefaultRenewDeadline},
RetryPeriod: unversioned.Duration{Duration: DefaultRetryPeriod}, RetryPeriod: metav1.Duration{Duration: DefaultRetryPeriod},
} }
} }
// BindFlags binds the common LeaderElectionCLIConfig flags to a flagset // BindFlags binds the common LeaderElectionCLIConfig flags to a flagset
func BindFlags(l *componentconfig.LeaderElectionConfiguration, fs *pflag.FlagSet) { func BindFlags(l *LeaderElectionConfiguration, fs *pflag.FlagSet) {
fs.BoolVar(&l.LeaderElect, "leader-elect", l.LeaderElect, ""+ fs.BoolVar(&l.LeaderElect, "leader-elect", l.LeaderElect, ""+
"Start a leader election client and gain leadership before "+ "Start a leader election client and gain leadership before "+
"executing the main loop. Enable this when running replicated "+ "executing the main loop. Enable this when running replicated "+

View file

@ -21,23 +21,24 @@ import (
"errors" "errors"
"fmt" "fmt"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api/v1"
) )
type EndpointsLock struct { type EndpointsLock struct {
// EndpointsMeta should contain a Name and a Namespace of an // EndpointsMeta should contain a Name and a Namespace of an
// Endpoints object that the LeaderElector will attempt to lead. // Endpoints object that the LeaderElector will attempt to lead.
EndpointsMeta api.ObjectMeta EndpointsMeta meta_v1.ObjectMeta
Client clientset.Interface Client clientset.Interface
LockConfig ResourceLockConfig LockConfig ResourceLockConfig
e *api.Endpoints e *v1.Endpoints
} }
func (el *EndpointsLock) Get() (*LeaderElectionRecord, error) { func (el *EndpointsLock) Get() (*LeaderElectionRecord, error) {
var record LeaderElectionRecord var record LeaderElectionRecord
var err error var err error
el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Get(el.EndpointsMeta.Name) el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Get(el.EndpointsMeta.Name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -58,8 +59,8 @@ func (el *EndpointsLock) Create(ler LeaderElectionRecord) error {
if err != nil { if err != nil {
return err return err
} }
el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Create(&api.Endpoints{ el.e, err = el.Client.Core().Endpoints(el.EndpointsMeta.Namespace).Create(&v1.Endpoints{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: el.EndpointsMeta.Name, Name: el.EndpointsMeta.Name,
Namespace: el.EndpointsMeta.Namespace, Namespace: el.EndpointsMeta.Namespace,
Annotations: map[string]string{ Annotations: map[string]string{
@ -87,7 +88,7 @@ func (el *EndpointsLock) Update(ler LeaderElectionRecord) error {
// RecordEvent in leader election while adding meta-data // RecordEvent in leader election while adding meta-data
func (el *EndpointsLock) RecordEvent(s string) { func (el *EndpointsLock) RecordEvent(s string) {
events := fmt.Sprintf("%v %v", el.LockConfig.Identity, s) events := fmt.Sprintf("%v %v", el.LockConfig.Identity, s)
el.LockConfig.EventRecorder.Eventf(&api.Endpoints{ObjectMeta: el.e.ObjectMeta}, api.EventTypeNormal, "LeaderElection", events) el.LockConfig.EventRecorder.Eventf(&v1.Endpoints{ObjectMeta: el.e.ObjectMeta}, v1.EventTypeNormal, "LeaderElection", events)
} }
// Describe is used to convert details on current resource lock // Describe is used to convert details on current resource lock

View file

@ -17,8 +17,8 @@ limitations under the License.
package resourcelock package resourcelock
import ( import (
"k8s.io/kubernetes/pkg/api/unversioned" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/client/record" "k8s.io/client-go/tools/record"
) )
const ( const (
@ -30,11 +30,11 @@ const (
// with a random string (e.g. UUID) with only slight modification of this code. // with a random string (e.g. UUID) with only slight modification of this code.
// TODO(mikedanese): this should potentially be versioned // TODO(mikedanese): this should potentially be versioned
type LeaderElectionRecord struct { type LeaderElectionRecord struct {
HolderIdentity string `json:"holderIdentity"` HolderIdentity string `json:"holderIdentity"`
LeaseDurationSeconds int `json:"leaseDurationSeconds"` LeaseDurationSeconds int `json:"leaseDurationSeconds"`
AcquireTime unversioned.Time `json:"acquireTime"` AcquireTime metav1.Time `json:"acquireTime"`
RenewTime unversioned.Time `json:"renewTime"` RenewTime metav1.Time `json:"renewTime"`
LeaderTransitions int `json:"leaderTransitions"` LeaderTransitions int `json:"leaderTransitions"`
} }
// ResourceLockConfig common data that exists across different // ResourceLockConfig common data that exists across different

View file

@ -24,15 +24,16 @@ import (
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/apimachinery/pkg/labels"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/kubernetes/pkg/client/leaderelection" clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/pkg/labels" api_v1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/wait" extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
cache_store "k8s.io/ingress/core/pkg/cache"
"k8s.io/ingress/core/pkg/ingress/annotations/class" "k8s.io/ingress/core/pkg/ingress/annotations/class"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection"
"k8s.io/ingress/core/pkg/ingress/store"
"k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/k8s"
"k8s.io/ingress/core/pkg/strings" "k8s.io/ingress/core/pkg/strings"
"k8s.io/ingress/core/pkg/task" "k8s.io/ingress/core/pkg/task"
@ -52,7 +53,7 @@ type Sync interface {
type Config struct { type Config struct {
Client clientset.Interface Client clientset.Interface
PublishService string PublishService string
IngressLister cache_store.StoreToIngressLister IngressLister store.IngressLister
ElectionID string ElectionID string
DefaultIngressClass string DefaultIngressClass string
@ -111,7 +112,7 @@ func (s statusSync) Shutdown() {
} }
glog.Infof("removing address from ingress status (%v)", addrs) glog.Infof("removing address from ingress status (%v)", addrs)
s.updateStatus([]api.LoadBalancerIngress{}) s.updateStatus([]api_v1.LoadBalancerIngress{})
} }
func (s *statusSync) run() { func (s *statusSync) run() {
@ -196,7 +197,7 @@ func NewStatusSyncer(config Config) Sync {
func (s *statusSync) runningAddresess() ([]string, error) { func (s *statusSync) runningAddresess() ([]string, error) {
if s.PublishService != "" { if s.PublishService != "" {
ns, name, _ := k8s.ParseNameNS(s.PublishService) ns, name, _ := k8s.ParseNameNS(s.PublishService)
svc, err := s.Client.Core().Services(ns).Get(name) svc, err := s.Client.Core().Services(ns).Get(name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -214,8 +215,8 @@ func (s *statusSync) runningAddresess() ([]string, error) {
} }
// get information about all the pods running the ingress controller // get information about all the pods running the ingress controller
pods, err := s.Client.Core().Pods(s.pod.Namespace).List(api.ListOptions{ pods, err := s.Client.Core().Pods(s.pod.Namespace).List(meta_v1.ListOptions{
LabelSelector: labels.SelectorFromSet(s.pod.Labels), LabelSelector: labels.SelectorFromSet(s.pod.Labels).String(),
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -232,13 +233,13 @@ func (s *statusSync) runningAddresess() ([]string, error) {
} }
// sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress // sliceToStatus converts a slice of IP and/or hostnames to LoadBalancerIngress
func sliceToStatus(endpoints []string) []api.LoadBalancerIngress { func sliceToStatus(endpoints []string) []api_v1.LoadBalancerIngress {
lbi := []api.LoadBalancerIngress{} lbi := []api_v1.LoadBalancerIngress{}
for _, ep := range endpoints { for _, ep := range endpoints {
if net.ParseIP(ep) == nil { if net.ParseIP(ep) == nil {
lbi = append(lbi, api.LoadBalancerIngress{Hostname: ep}) lbi = append(lbi, api_v1.LoadBalancerIngress{Hostname: ep})
} else { } else {
lbi = append(lbi, api.LoadBalancerIngress{IP: ep}) lbi = append(lbi, api_v1.LoadBalancerIngress{IP: ep})
} }
} }
@ -246,7 +247,7 @@ func sliceToStatus(endpoints []string) []api.LoadBalancerIngress {
return lbi return lbi
} }
func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) { func (s *statusSync) updateStatus(newIPs []api_v1.LoadBalancerIngress) {
ings := s.IngressLister.List() ings := s.IngressLister.List()
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(len(ings)) wg.Add(len(ings))
@ -261,7 +262,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
go func(wg *sync.WaitGroup, ing *extensions.Ingress) { go func(wg *sync.WaitGroup, ing *extensions.Ingress) {
defer wg.Done() defer wg.Done()
ingClient := s.Client.Extensions().Ingresses(ing.Namespace) ingClient := s.Client.Extensions().Ingresses(ing.Namespace)
currIng, err := ingClient.Get(ing.Name) currIng, err := ingClient.Get(ing.Name, meta_v1.GetOptions{})
if err != nil { if err != nil {
glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err) glog.Errorf("unexpected error searching Ingress %v/%v: %v", ing.Namespace, ing.Name, err)
return return
@ -286,7 +287,7 @@ func (s *statusSync) updateStatus(newIPs []api.LoadBalancerIngress) {
wg.Wait() wg.Wait()
} }
func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool { func ingressSliceEqual(lhs, rhs []api_v1.LoadBalancerIngress) bool {
if len(lhs) != len(rhs) { if len(lhs) != len(rhs) {
return false return false
} }
@ -303,7 +304,7 @@ func ingressSliceEqual(lhs, rhs []api.LoadBalancerIngress) bool {
} }
// loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP // loadBalancerIngressByIP sorts LoadBalancerIngress using the field IP
type loadBalancerIngressByIP []api.LoadBalancerIngress type loadBalancerIngressByIP []api_v1.LoadBalancerIngress
func (c loadBalancerIngressByIP) Len() int { return len(c) } func (c loadBalancerIngressByIP) Len() int { return len(c) }
func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c loadBalancerIngressByIP) Swap(i, j int) { c[i], c[j] = c[j], c[i] }

View file

@ -23,19 +23,21 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apis/extensions" testclient "k8s.io/client-go/kubernetes/fake"
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/client-go/pkg/api"
testclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" api_v1 "k8s.io/client-go/pkg/api/v1"
extensions "k8s.io/client-go/pkg/apis/extensions/v1beta1"
"k8s.io/client-go/tools/cache"
cache_store "k8s.io/ingress/core/pkg/cache"
"k8s.io/ingress/core/pkg/ingress/annotations/class" "k8s.io/ingress/core/pkg/ingress/annotations/class"
cache_store "k8s.io/ingress/core/pkg/ingress/store"
"k8s.io/ingress/core/pkg/k8s" "k8s.io/ingress/core/pkg/k8s"
"k8s.io/ingress/core/pkg/task" "k8s.io/ingress/core/pkg/task"
) )
func buildLoadBalancerIngressByIP() loadBalancerIngressByIP { func buildLoadBalancerIngressByIP() loadBalancerIngressByIP {
return []api.LoadBalancerIngress{ return []api_v1.LoadBalancerIngress{
{ {
IP: "10.0.0.1", IP: "10.0.0.1",
Hostname: "foo1", Hostname: "foo1",
@ -57,100 +59,100 @@ func buildLoadBalancerIngressByIP() loadBalancerIngressByIP {
func buildSimpleClientSet() *testclient.Clientset { func buildSimpleClientSet() *testclient.Clientset {
return testclient.NewSimpleClientset( return testclient.NewSimpleClientset(
&api.PodList{Items: []api.Pod{ &api_v1.PodList{Items: []api_v1.Pod{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo1", Name: "foo1",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
}, },
}, },
Spec: api.PodSpec{ Spec: api_v1.PodSpec{
NodeName: "foo_node_2", NodeName: "foo_node_2",
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo2", Name: "foo2",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_no", "lable_sig": "foo_no",
}, },
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo3", Name: "foo3",
Namespace: api.NamespaceSystem, Namespace: api.NamespaceSystem,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
}, },
}, },
Spec: api.PodSpec{ Spec: api_v1.PodSpec{
NodeName: "foo_node_2", NodeName: "foo_node_2",
}, },
}, },
}}, }},
&api.ServiceList{Items: []api.Service{ &api_v1.ServiceList{Items: []api_v1.Service{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: api.ServiceStatus{ Status: api_v1.ServiceStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: buildLoadBalancerIngressByIP(), Ingress: buildLoadBalancerIngressByIP(),
}, },
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_non_exist", Name: "foo_non_exist",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
}, },
}}, }},
&api.NodeList{Items: []api.Node{ &api_v1.NodeList{Items: []api_v1.Node{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_node_1", Name: "foo_node_1",
}, },
Status: api.NodeStatus{ Status: api_v1.NodeStatus{
Addresses: []api.NodeAddress{ Addresses: []api_v1.NodeAddress{
{ {
Type: api.NodeLegacyHostIP, Type: api_v1.NodeLegacyHostIP,
Address: "10.0.0.1", Address: "10.0.0.1",
}, { }, {
Type: api.NodeExternalIP, Type: api_v1.NodeExternalIP,
Address: "10.0.0.2", Address: "10.0.0.2",
}, },
}, },
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_node_2", Name: "foo_node_2",
}, },
Status: api.NodeStatus{ Status: api_v1.NodeStatus{
Addresses: []api.NodeAddress{ Addresses: []api_v1.NodeAddress{
{ {
Type: api.NodeLegacyHostIP, Type: api_v1.NodeLegacyHostIP,
Address: "11.0.0.1", Address: "11.0.0.1",
}, },
{ {
Type: api.NodeExternalIP, Type: api_v1.NodeExternalIP,
Address: "11.0.0.2", Address: "11.0.0.2",
}, },
}, },
}, },
}, },
}}, }},
&api.EndpointsList{Items: []api.Endpoints{ &api_v1.EndpointsList{Items: []api_v1.Endpoints{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "ingress-controller-leader", Name: "ingress-controller-leader",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
SelfLink: "/api/v1/namespaces/default/endpoints/ingress-controller-leader", SelfLink: "/api/v1/namespaces/default/endpoints/ingress-controller-leader",
}, },
}}}, }}},
@ -165,13 +167,13 @@ func fakeSynFn(interface{}) error {
func buildExtensionsIngresses() []extensions.Ingress { func buildExtensionsIngresses() []extensions.Ingress {
return []extensions.Ingress{ return []extensions.Ingress{
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_1", Name: "foo_ingress_1",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{ Ingress: []api_v1.LoadBalancerIngress{
{ {
IP: "10.0.0.1", IP: "10.0.0.1",
Hostname: "foo1", Hostname: "foo1",
@ -181,7 +183,7 @@ func buildExtensionsIngresses() []extensions.Ingress {
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_different_class", Name: "foo_ingress_different_class",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Annotations: map[string]string{ Annotations: map[string]string{
@ -189,8 +191,8 @@ func buildExtensionsIngresses() []extensions.Ingress {
}, },
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{ Ingress: []api_v1.LoadBalancerIngress{
{ {
IP: "0.0.0.0", IP: "0.0.0.0",
Hostname: "foo.bar.com", Hostname: "foo.bar.com",
@ -200,45 +202,45 @@ func buildExtensionsIngresses() []extensions.Ingress {
}, },
}, },
{ {
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_2", Name: "foo_ingress_2",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: []api.LoadBalancerIngress{}, Ingress: []api_v1.LoadBalancerIngress{},
}, },
}, },
}, },
} }
} }
func buildIngressListener() cache_store.StoreToIngressLister { func buildIngressListener() cache_store.IngressLister {
store := cache.NewStore(cache.MetaNamespaceKeyFunc) store := cache.NewStore(cache.MetaNamespaceKeyFunc)
store.Add(&extensions.Ingress{ store.Add(&extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_non_01", Name: "foo_ingress_non_01",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}}) }})
store.Add(&extensions.Ingress{ store.Add(&extensions.Ingress{
ObjectMeta: api.ObjectMeta{ ObjectMeta: meta_v1.ObjectMeta{
Name: "foo_ingress_1", Name: "foo_ingress_1",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
}, },
Status: extensions.IngressStatus{ Status: extensions.IngressStatus{
LoadBalancer: api.LoadBalancerStatus{ LoadBalancer: api_v1.LoadBalancerStatus{
Ingress: buildLoadBalancerIngressByIP(), Ingress: buildLoadBalancerIngressByIP(),
}, },
}, },
}) })
return cache_store.StoreToIngressLister{Store: store} return cache_store.IngressLister{Store: store}
} }
func buildStatusSync() statusSync { func buildStatusSync() statusSync {
return statusSync{ return statusSync{
pod: &k8s.PodInfo{ pod: &k8s.PodInfo{
Name: "foo_base_pod", Name: "foo_base_pod",
Namespace: api.NamespaceDefault, Namespace: api_v1.NamespaceDefault,
Labels: map[string]string{ Labels: map[string]string{
"lable_sig": "foo_pod", "lable_sig": "foo_pod",
}, },
@ -247,7 +249,7 @@ func buildStatusSync() statusSync {
syncQueue: task.NewTaskQueue(fakeSynFn), syncQueue: task.NewTaskQueue(fakeSynFn),
Config: Config{ Config: Config{
Client: buildSimpleClientSet(), Client: buildSimpleClientSet(),
PublishService: api.NamespaceDefault + "/" + "foo", PublishService: api_v1.NamespaceDefault + "/" + "foo",
IngressLister: buildIngressListener(), IngressLister: buildIngressListener(),
}, },
} }
@ -256,7 +258,7 @@ func buildStatusSync() statusSync {
func TestStatusActions(t *testing.T) { func TestStatusActions(t *testing.T) {
// make sure election can be created // make sure election can be created
os.Setenv("POD_NAME", "foo1") os.Setenv("POD_NAME", "foo1")
os.Setenv("POD_NAMESPACE", api.NamespaceDefault) os.Setenv("POD_NAMESPACE", api_v1.NamespaceDefault)
c := Config{ c := Config{
Client: buildSimpleClientSet(), Client: buildSimpleClientSet(),
PublishService: "", PublishService: "",
@ -273,7 +275,7 @@ func TestStatusActions(t *testing.T) {
fk := fkSync.(statusSync) fk := fkSync.(statusSync)
ns := make(chan struct{}) ns := make(chan struct{})
// start it and wait for the election and sync actions // start it and wait for the election and syn actions
go fk.Run(ns) go fk.Run(ns)
// wait for the election // wait for the election
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
@ -281,10 +283,10 @@ func TestStatusActions(t *testing.T) {
fk.sync("just-test") fk.sync("just-test")
// PublishService is empty, so the running address is: ["11.0.0.2"] // PublishService is empty, so the running address is: ["11.0.0.2"]
// after updated, the ingress's ip should only be "11.0.0.2" // after updated, the ingress's ip should only be "11.0.0.2"
newIPs := []api.LoadBalancerIngress{{ newIPs := []api_v1.LoadBalancerIngress{{
IP: "11.0.0.2", IP: "11.0.0.2",
}} }}
fooIngress1, err1 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") fooIngress1, err1 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
if err1 != nil { if err1 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -296,8 +298,8 @@ func TestStatusActions(t *testing.T) {
// execute shutdown // execute shutdown
fk.Shutdown() fk.Shutdown()
// ingress should be empty // ingress should be empty
newIPs2 := []api.LoadBalancerIngress{} newIPs2 := []api_v1.LoadBalancerIngress{}
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
if err2 != nil { if err2 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -306,7 +308,7 @@ func TestStatusActions(t *testing.T) {
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2) t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, newIPs2)
} }
oic, err := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_different_class") oic, err := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_different_class", meta_v1.GetOptions{})
if err != nil { if err != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -374,7 +376,7 @@ func TestUpdateStatus(t *testing.T) {
sort.Sort(loadBalancerIngressByIP(newIPs)) sort.Sort(loadBalancerIngressByIP(newIPs))
fk.updateStatus(newIPs) fk.updateStatus(newIPs)
fooIngress1, err1 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_1") fooIngress1, err1 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_1", meta_v1.GetOptions{})
if err1 != nil { if err1 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
@ -383,13 +385,13 @@ func TestUpdateStatus(t *testing.T) {
t.Fatalf("returned %v but expected %v", fooIngress1CurIPs, newIPs) t.Fatalf("returned %v but expected %v", fooIngress1CurIPs, newIPs)
} }
fooIngress2, err2 := fk.Client.Extensions().Ingresses(api.NamespaceDefault).Get("foo_ingress_2") fooIngress2, err2 := fk.Client.Extensions().Ingresses(api_v1.NamespaceDefault).Get("foo_ingress_2", meta_v1.GetOptions{})
if err2 != nil { if err2 != nil {
t.Fatalf("unexpected error") t.Fatalf("unexpected error")
} }
fooIngress2CurIPs := fooIngress2.Status.LoadBalancer.Ingress fooIngress2CurIPs := fooIngress2.Status.LoadBalancer.Ingress
if !ingressSliceEqual(fooIngress2CurIPs, []api.LoadBalancerIngress{}) { if !ingressSliceEqual(fooIngress2CurIPs, []api_v1.LoadBalancerIngress{}) {
t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api.LoadBalancerIngress{}) t.Fatalf("returned %v but expected %v", fooIngress2CurIPs, []api_v1.LoadBalancerIngress{})
} }
} }
@ -403,7 +405,7 @@ func TestSliceToStatus(t *testing.T) {
r := sliceToStatus(fkEndpoints) r := sliceToStatus(fkEndpoints)
if r == nil { if r == nil {
t.Fatalf("returned nil but expected a valid []api.LoadBalancerIngress") t.Fatalf("returned nil but expected a valid []api_v1.LoadBalancerIngress")
} }
rl := len(r) rl := len(r)
if rl != 3 { if rl != 3 {
@ -411,21 +413,21 @@ func TestSliceToStatus(t *testing.T) {
} }
re1 := r[0] re1 := r[0]
if re1.Hostname != "opensource-k8s-ingress" { if re1.Hostname != "opensource-k8s-ingress" {
t.Fatalf("returned %v but expected %v", re1, api.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"}) t.Fatalf("returned %v but expected %v", re1, api_v1.LoadBalancerIngress{Hostname: "opensource-k8s-ingress"})
} }
re2 := r[1] re2 := r[1]
if re2.IP != "10.0.0.1" { if re2.IP != "10.0.0.1" {
t.Fatalf("returned %v but expected %v", re2, api.LoadBalancerIngress{IP: "10.0.0.1"}) t.Fatalf("returned %v but expected %v", re2, api_v1.LoadBalancerIngress{IP: "10.0.0.1"})
} }
re3 := r[2] re3 := r[2]
if re3.IP != "2001:db8::68" { if re3.IP != "2001:db8::68" {
t.Fatalf("returned %v but expected %v", re3, api.LoadBalancerIngress{IP: "2001:db8::68"}) t.Fatalf("returned %v but expected %v", re3, api_v1.LoadBalancerIngress{IP: "2001:db8::68"})
} }
} }
func TestIngressSliceEqual(t *testing.T) { func TestIngressSliceEqual(t *testing.T) {
fk1 := buildLoadBalancerIngressByIP() fk1 := buildLoadBalancerIngressByIP()
fk2 := append(buildLoadBalancerIngressByIP(), api.LoadBalancerIngress{ fk2 := append(buildLoadBalancerIngressByIP(), api_v1.LoadBalancerIngress{
IP: "10.0.0.5", IP: "10.0.0.5",
Hostname: "foo5", Hostname: "foo5",
}) })
@ -435,8 +437,8 @@ func TestIngressSliceEqual(t *testing.T) {
fk4[2].IP = "11.0.0.3" fk4[2].IP = "11.0.0.3"
fooTests := []struct { fooTests := []struct {
lhs []api.LoadBalancerIngress lhs []api_v1.LoadBalancerIngress
rhs []api.LoadBalancerIngress rhs []api_v1.LoadBalancerIngress
er bool er bool
}{ }{
{fk1, fk1, true}, {fk1, fk1, true},
@ -445,7 +447,7 @@ func TestIngressSliceEqual(t *testing.T) {
{fk4, fk1, false}, {fk4, fk1, false},
{fk1, nil, false}, {fk1, nil, false},
{nil, nil, true}, {nil, nil, true},
{[]api.LoadBalancerIngress{}, []api.LoadBalancerIngress{}, true}, {[]api_v1.LoadBalancerIngress{}, []api_v1.LoadBalancerIngress{}, true},
} }
for _, fooTest := range fooTests { for _, fooTest := range fooTests {
@ -461,7 +463,7 @@ func TestLoadBalancerIngressByIPLen(t *testing.T) {
ips loadBalancerIngressByIP ips loadBalancerIngressByIP
el int el int
}{ }{
{[]api.LoadBalancerIngress{}, 0}, {[]api_v1.LoadBalancerIngress{}, 0},
{buildLoadBalancerIngressByIP(), 4}, {buildLoadBalancerIngressByIP(), 4},
{nil, 0}, {nil, 0},
} }

View file

@ -0,0 +1,71 @@
/*
Copyright 2015 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package store
import (
"fmt"
api "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/tools/cache"
)
// IngressLister makes a Store that lists Ingress.
type IngressLister struct {
cache.Store
}
// SecretsLister makes a Store that lists Secrets.
type SecretsLister struct {
cache.Store
}
// ConfigMapLister makes a Store that lists Configmaps.
type ConfigMapLister struct {
cache.Store
}
// ServiceLister makes a Store that lists Services.
type ServiceLister struct {
cache.Store
}
// NodeLister makes a Store that lists Nodes.
type NodeLister struct {
cache.Store
}
// EndpointLister makes a Store that lists Endpoints.
type EndpointLister struct {
cache.Store
}
// GetServiceEndpoints returns the endpoints of a service, matched on service name.
func (s *EndpointLister) GetServiceEndpoints(svc *api.Service) (ep api.Endpoints, err error) {
for _, m := range s.Store.List() {
ep = *m.(*api.Endpoints)
if svc.Name == ep.Name && svc.Namespace == ep.Namespace {
return ep, nil
}
}
err = fmt.Errorf("could not find endpoints for service: %v", svc.Name)
return
}
// SecretLister makes a Store that lists Secres.
type SecretLister struct {
cache.Store
}

View file

@ -19,12 +19,10 @@ package ingress
import ( import (
"github.com/spf13/pflag" "github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/api" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/apiserver/pkg/server/healthz"
"k8s.io/kubernetes/pkg/healthz" api "k8s.io/client-go/pkg/api/v1"
"k8s.io/kubernetes/pkg/util/intstr"
cache_store "k8s.io/ingress/core/pkg/cache"
"k8s.io/ingress/core/pkg/ingress/annotations/auth" "k8s.io/ingress/core/pkg/ingress/annotations/auth"
"k8s.io/ingress/core/pkg/ingress/annotations/authreq" "k8s.io/ingress/core/pkg/ingress/annotations/authreq"
"k8s.io/ingress/core/pkg/ingress/annotations/authtls" "k8s.io/ingress/core/pkg/ingress/annotations/authtls"
@ -33,6 +31,7 @@ import (
"k8s.io/ingress/core/pkg/ingress/annotations/ratelimit" "k8s.io/ingress/core/pkg/ingress/annotations/ratelimit"
"k8s.io/ingress/core/pkg/ingress/annotations/rewrite" "k8s.io/ingress/core/pkg/ingress/annotations/rewrite"
"k8s.io/ingress/core/pkg/ingress/defaults" "k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/ingress/store"
) )
var ( var (
@ -103,12 +102,12 @@ type Controller interface {
// StoreLister returns the configured stores for ingresses, services, // StoreLister returns the configured stores for ingresses, services,
// endpoints, secrets and configmaps. // endpoints, secrets and configmaps.
type StoreLister struct { type StoreLister struct {
Ingress cache_store.StoreToIngressLister Ingress store.IngressLister
Service cache.StoreToServiceLister Service store.ServiceLister
Node cache.StoreToNodeLister Node store.NodeLister
Endpoint cache.StoreToEndpointsLister Endpoint store.EndpointLister
Secret cache_store.StoreToSecretsLister Secret store.SecretLister
ConfigMap cache_store.StoreToConfigmapLister ConfigMap store.ConfigMapLister
} }
// BackendInfo returns information about the backend. // BackendInfo returns information about the backend.

View file

@ -21,8 +21,9 @@ import (
"os" "os"
"strings" "strings"
"k8s.io/kubernetes/pkg/api" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/client-go/kubernetes"
api "k8s.io/client-go/pkg/api/v1"
) )
// IsValidService checks if exists a service with the specified name // IsValidService checks if exists a service with the specified name
@ -31,7 +32,7 @@ func IsValidService(kubeClient clientset.Interface, name string) (*api.Service,
if err != nil { if err != nil {
return nil, err return nil, err
} }
return kubeClient.Core().Services(ns).Get(name) return kubeClient.Core().Services(ns).Get(name, meta_v1.GetOptions{})
} }
// IsValidConfigMap check if exists a configmap with the specified name // IsValidConfigMap check if exists a configmap with the specified name
@ -43,7 +44,7 @@ func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.Con
return nil, err return nil, err
} }
configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name) configMap, err := kubeClient.Core().ConfigMaps(ns).Get(name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return nil, fmt.Errorf("configmap not found: %v", err) return nil, fmt.Errorf("configmap not found: %v", err)
@ -55,7 +56,7 @@ func IsValidConfigMap(kubeClient clientset.Interface, fullName string) (*api.Con
// IsValidNamespace chck if exists a namespace with the specified name // IsValidNamespace chck if exists a namespace with the specified name
func IsValidNamespace(kubeClient clientset.Interface, name string) (*api.Namespace, error) { func IsValidNamespace(kubeClient clientset.Interface, name string) (*api.Namespace, error) {
return kubeClient.Core().Namespaces().Get(name) return kubeClient.Core().Namespaces().Get(name, meta_v1.GetOptions{})
} }
// IsValidSecret checks if exists a secret with the specified name // IsValidSecret checks if exists a secret with the specified name
@ -64,7 +65,7 @@ func IsValidSecret(kubeClient clientset.Interface, name string) (*api.Secret, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
return kubeClient.Core().Secrets(ns).Get(name) return kubeClient.Core().Secrets(ns).Get(name, meta_v1.GetOptions{})
} }
// ParseNameNS parses a string searching a namespace and name // ParseNameNS parses a string searching a namespace and name
@ -80,7 +81,7 @@ func ParseNameNS(input string) (string, string, error) {
// GetNodeIP returns the IP address of a node in the cluster // GetNodeIP returns the IP address of a node in the cluster
func GetNodeIP(kubeClient clientset.Interface, name string) string { func GetNodeIP(kubeClient clientset.Interface, name string) string {
var externalIP string var externalIP string
node, err := kubeClient.Core().Nodes().Get(name) node, err := kubeClient.Core().Nodes().Get(name, meta_v1.GetOptions{})
if err != nil { if err != nil {
return externalIP return externalIP
} }
@ -120,7 +121,7 @@ func GetPodDetails(kubeClient clientset.Interface) (*PodInfo, error) {
return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable") return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable")
} }
pod, _ := kubeClient.Core().Pods(podNs).Get(podName) pod, _ := kubeClient.Core().Pods(podNs).Get(podName, meta_v1.GetOptions{})
if pod == nil { if pod == nil {
return nil, fmt.Errorf("unable to get POD information") return nil, fmt.Errorf("unable to get POD information")
} }

View file

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

View file

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

View file

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

15
vendor/cloud.google.com/go/AUTHORS generated vendored Normal file
View file

@ -0,0 +1,15 @@
# This is the official list of cloud authors for copyright purposes.
# This file is distinct from the CONTRIBUTORS files.
# See the latter for an explanation.
# Names should be added to this file as:
# Name or Organization <email address>
# The email address is not required for organizations.
Filippo Valsorda <hi@filippo.io>
Google Inc.
Ingo Oeser <nightlyone@googlemail.com>
Palm Stone Games, Inc.
Paweł Knap <pawelknap88@gmail.com>
Péter Szilágyi <peterke@gmail.com>
Tyler Treat <ttreat31@gmail.com>

34
vendor/cloud.google.com/go/CONTRIBUTORS generated vendored Normal file
View file

@ -0,0 +1,34 @@
# People who have agreed to one of the CLAs and can contribute patches.
# The AUTHORS file lists the copyright holders; this file
# lists people. For example, Google employees are listed here
# but not in AUTHORS, because Google holds the copyright.
#
# https://developers.google.com/open-source/cla/individual
# https://developers.google.com/open-source/cla/corporate
#
# Names should be added to this file as:
# Name <email address>
# Keep the list alphabetically sorted.
Andreas Litt <andreas.litt@gmail.com>
Andrew Gerrand <adg@golang.org>
Brad Fitzpatrick <bradfitz@golang.org>
Burcu Dogan <jbd@google.com>
Dave Day <djd@golang.org>
David Sansome <me@davidsansome.com>
David Symonds <dsymonds@golang.org>
Filippo Valsorda <hi@filippo.io>
Glenn Lewis <gmlewis@google.com>
Ingo Oeser <nightlyone@googlemail.com>
Johan Euphrosine <proppy@google.com>
Jonathan Amsterdam <jba@google.com>
Luna Duclos <luna.duclos@palmstonegames.com>
Michael McGreevy <mcgreevy@golang.org>
Omar Jarjur <ojarjur@google.com>
Paweł Knap <pawelknap88@gmail.com>
Péter Szilágyi <peterke@gmail.com>
Sarah Adams <shadams@google.com>
Toby Burress <kurin@google.com>
Tuo Shan <shantuo@google.com>
Tyler Treat <ttreat31@gmail.com>

View file

@ -1,22 +0,0 @@
The MIT License
Copyright (c) 2014 Benedikt Lang <github at benediktlang.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,142 +0,0 @@
semver for golang [![Build Status](https://drone.io/github.com/blang/semver/status.png)](https://drone.io/github.com/blang/semver/latest) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
======
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
Usage
-----
```bash
$ go get github.com/blang/semver
```
Note: Always vendor your dependencies or fix on a specific version tag.
```go
import github.com/blang/semver
v1, err := semver.Make("1.0.0-beta")
v2, err := semver.Make("2.0.0-beta")
v1.Compare(v2)
```
Also check the [GoDocs](http://godoc.org/github.com/blang/semver).
Why should I use this lib?
-----
- Fully spec compatible
- No reflection
- No regex
- Fully tested (Coverage >99%)
- Readable parsing/validation errors
- Fast (See [Benchmarks](#benchmarks))
- Only Stdlib
- Uses values instead of pointers
- Many features, see below
Features
-----
- Parsing and validation at all levels
- Comparator-like comparisons
- Compare Helper Methods
- InPlace manipulation
- Sortable (implements sort.Interface)
- database/sql compatible (sql.Scanner/Valuer)
- encoding/json compatible (json.Marshaler/Unmarshaler)
Example
-----
Have a look at full examples in [examples/main.go](examples/main.go)
```go
import github.com/blang/semver
v, err := semver.Make("0.0.1-alpha.preview+123.github")
fmt.Printf("Major: %d\n", v.Major)
fmt.Printf("Minor: %d\n", v.Minor)
fmt.Printf("Patch: %d\n", v.Patch)
fmt.Printf("Pre: %s\n", v.Pre)
fmt.Printf("Build: %s\n", v.Build)
// Prerelease versions array
if len(v.Pre) > 0 {
fmt.Println("Prerelease versions:")
for i, pre := range v.Pre {
fmt.Printf("%d: %q\n", i, pre)
}
}
// Build meta data array
if len(v.Build) > 0 {
fmt.Println("Build meta data:")
for i, build := range v.Build {
fmt.Printf("%d: %q\n", i, build)
}
}
v001, err := semver.Make("0.0.1")
// Compare using helpers: v.GT(v2), v.LT, v.GTE, v.LTE
v001.GT(v) == true
v.LT(v001) == true
v.GTE(v) == true
v.LTE(v) == true
// Or use v.Compare(v2) for comparisons (-1, 0, 1):
v001.Compare(v) == 1
v.Compare(v001) == -1
v.Compare(v) == 0
// Manipulate Version in place:
v.Pre[0], err = semver.NewPRVersion("beta")
if err != nil {
fmt.Printf("Error parsing pre release version: %q", err)
}
fmt.Println("\nValidate versions:")
v.Build[0] = "?"
err = v.Validate()
if err != nil {
fmt.Printf("Validation failed: %s\n", err)
}
```
Benchmarks
-----
BenchmarkParseSimple 5000000 328 ns/op 49 B/op 1 allocs/op
BenchmarkParseComplex 1000000 2105 ns/op 263 B/op 7 allocs/op
BenchmarkParseAverage 1000000 1301 ns/op 168 B/op 4 allocs/op
BenchmarkStringSimple 10000000 130 ns/op 5 B/op 1 allocs/op
BenchmarkStringLarger 5000000 280 ns/op 32 B/op 2 allocs/op
BenchmarkStringComplex 3000000 512 ns/op 80 B/op 3 allocs/op
BenchmarkStringAverage 5000000 387 ns/op 47 B/op 2 allocs/op
BenchmarkValidateSimple 500000000 7.92 ns/op 0 B/op 0 allocs/op
BenchmarkValidateComplex 2000000 923 ns/op 0 B/op 0 allocs/op
BenchmarkValidateAverage 5000000 452 ns/op 0 B/op 0 allocs/op
BenchmarkCompareSimple 100000000 11.2 ns/op 0 B/op 0 allocs/op
BenchmarkCompareComplex 50000000 40.9 ns/op 0 B/op 0 allocs/op
BenchmarkCompareAverage 50000000 43.8 ns/op 0 B/op 0 allocs/op
BenchmarkSort 5000000 436 ns/op 259 B/op 2 allocs/op
See benchmark cases at [semver_test.go](semver_test.go)
Motivation
-----
I simply couldn't find any lib supporting the full spec. Others were just wrong or used reflection and regex which i don't like.
Contribution
-----
Feel free to make a pull request. For bigger changes create a issue first to discuss about it.
License
-----
See [LICENSE](LICENSE) file.

View file

@ -1,23 +0,0 @@
package semver
import (
"encoding/json"
)
// MarshalJSON implements the encoding/json.Marshaler interface.
func (v Version) MarshalJSON() ([]byte, error) {
return json.Marshal(v.String())
}
// UnmarshalJSON implements the encoding/json.Unmarshaler interface.
func (v *Version) UnmarshalJSON(data []byte) (err error) {
var versionString string
if err = json.Unmarshal(data, &versionString); err != nil {
return
}
*v, err = Parse(versionString)
return
}

View file

@ -1,395 +0,0 @@
package semver
import (
"errors"
"fmt"
"strconv"
"strings"
)
const (
numbers string = "0123456789"
alphas = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"
alphanum = alphas + numbers
)
// SpecVersion is the latest fully supported spec version of semver
var SpecVersion = Version{
Major: 2,
Minor: 0,
Patch: 0,
}
// Version represents a semver compatible version
type Version struct {
Major uint64
Minor uint64
Patch uint64
Pre []PRVersion
Build []string //No Precendence
}
// Version to string
func (v Version) String() string {
b := make([]byte, 0, 5)
b = strconv.AppendUint(b, v.Major, 10)
b = append(b, '.')
b = strconv.AppendUint(b, v.Minor, 10)
b = append(b, '.')
b = strconv.AppendUint(b, v.Patch, 10)
if len(v.Pre) > 0 {
b = append(b, '-')
b = append(b, v.Pre[0].String()...)
for _, pre := range v.Pre[1:] {
b = append(b, '.')
b = append(b, pre.String()...)
}
}
if len(v.Build) > 0 {
b = append(b, '+')
b = append(b, v.Build[0]...)
for _, build := range v.Build[1:] {
b = append(b, '.')
b = append(b, build...)
}
}
return string(b)
}
// Equals checks if v is equal to o.
func (v Version) Equals(o Version) bool {
return (v.Compare(o) == 0)
}
// EQ checks if v is equal to o.
func (v Version) EQ(o Version) bool {
return (v.Compare(o) == 0)
}
// NE checks if v is not equal to o.
func (v Version) NE(o Version) bool {
return (v.Compare(o) != 0)
}
// GT checks if v is greater than o.
func (v Version) GT(o Version) bool {
return (v.Compare(o) == 1)
}
// GTE checks if v is greater than or equal to o.
func (v Version) GTE(o Version) bool {
return (v.Compare(o) >= 0)
}
// GE checks if v is greater than or equal to o.
func (v Version) GE(o Version) bool {
return (v.Compare(o) >= 0)
}
// LT checks if v is less than o.
func (v Version) LT(o Version) bool {
return (v.Compare(o) == -1)
}
// LTE checks if v is less than or equal to o.
func (v Version) LTE(o Version) bool {
return (v.Compare(o) <= 0)
}
// LE checks if v is less than or equal to o.
func (v Version) LE(o Version) bool {
return (v.Compare(o) <= 0)
}
// Compare compares Versions v to o:
// -1 == v is less than o
// 0 == v is equal to o
// 1 == v is greater than o
func (v Version) Compare(o Version) int {
if v.Major != o.Major {
if v.Major > o.Major {
return 1
}
return -1
}
if v.Minor != o.Minor {
if v.Minor > o.Minor {
return 1
}
return -1
}
if v.Patch != o.Patch {
if v.Patch > o.Patch {
return 1
}
return -1
}
// Quick comparison if a version has no prerelease versions
if len(v.Pre) == 0 && len(o.Pre) == 0 {
return 0
} else if len(v.Pre) == 0 && len(o.Pre) > 0 {
return 1
} else if len(v.Pre) > 0 && len(o.Pre) == 0 {
return -1
}
i := 0
for ; i < len(v.Pre) && i < len(o.Pre); i++ {
if comp := v.Pre[i].Compare(o.Pre[i]); comp == 0 {
continue
} else if comp == 1 {
return 1
} else {
return -1
}
}
// If all pr versions are the equal but one has further prversion, this one greater
if i == len(v.Pre) && i == len(o.Pre) {
return 0
} else if i == len(v.Pre) && i < len(o.Pre) {
return -1
} else {
return 1
}
}
// Validate validates v and returns error in case
func (v Version) Validate() error {
// Major, Minor, Patch already validated using uint64
for _, pre := range v.Pre {
if !pre.IsNum { //Numeric prerelease versions already uint64
if len(pre.VersionStr) == 0 {
return fmt.Errorf("Prerelease can not be empty %q", pre.VersionStr)
}
if !containsOnly(pre.VersionStr, alphanum) {
return fmt.Errorf("Invalid character(s) found in prerelease %q", pre.VersionStr)
}
}
}
for _, build := range v.Build {
if len(build) == 0 {
return fmt.Errorf("Build meta data can not be empty %q", build)
}
if !containsOnly(build, alphanum) {
return fmt.Errorf("Invalid character(s) found in build meta data %q", build)
}
}
return nil
}
// New is an alias for Parse and returns a pointer, parses version string and returns a validated Version or error
func New(s string) (vp *Version, err error) {
v, err := Parse(s)
vp = &v
return
}
// Make is an alias for Parse, parses version string and returns a validated Version or error
func Make(s string) (Version, error) {
return Parse(s)
}
// Parse parses version string and returns a validated Version or error
func Parse(s string) (Version, error) {
if len(s) == 0 {
return Version{}, errors.New("Version string empty")
}
// Split into major.minor.(patch+pr+meta)
parts := strings.SplitN(s, ".", 3)
if len(parts) != 3 {
return Version{}, errors.New("No Major.Minor.Patch elements found")
}
// Major
if !containsOnly(parts[0], numbers) {
return Version{}, fmt.Errorf("Invalid character(s) found in major number %q", parts[0])
}
if hasLeadingZeroes(parts[0]) {
return Version{}, fmt.Errorf("Major number must not contain leading zeroes %q", parts[0])
}
major, err := strconv.ParseUint(parts[0], 10, 64)
if err != nil {
return Version{}, err
}
// Minor
if !containsOnly(parts[1], numbers) {
return Version{}, fmt.Errorf("Invalid character(s) found in minor number %q", parts[1])
}
if hasLeadingZeroes(parts[1]) {
return Version{}, fmt.Errorf("Minor number must not contain leading zeroes %q", parts[1])
}
minor, err := strconv.ParseUint(parts[1], 10, 64)
if err != nil {
return Version{}, err
}
v := Version{}
v.Major = major
v.Minor = minor
var build, prerelease []string
patchStr := parts[2]
if buildIndex := strings.IndexRune(patchStr, '+'); buildIndex != -1 {
build = strings.Split(patchStr[buildIndex+1:], ".")
patchStr = patchStr[:buildIndex]
}
if preIndex := strings.IndexRune(patchStr, '-'); preIndex != -1 {
prerelease = strings.Split(patchStr[preIndex+1:], ".")
patchStr = patchStr[:preIndex]
}
if !containsOnly(patchStr, numbers) {
return Version{}, fmt.Errorf("Invalid character(s) found in patch number %q", patchStr)
}
if hasLeadingZeroes(patchStr) {
return Version{}, fmt.Errorf("Patch number must not contain leading zeroes %q", patchStr)
}
patch, err := strconv.ParseUint(patchStr, 10, 64)
if err != nil {
return Version{}, err
}
v.Patch = patch
// Prerelease
for _, prstr := range prerelease {
parsedPR, err := NewPRVersion(prstr)
if err != nil {
return Version{}, err
}
v.Pre = append(v.Pre, parsedPR)
}
// Build meta data
for _, str := range build {
if len(str) == 0 {
return Version{}, errors.New("Build meta data is empty")
}
if !containsOnly(str, alphanum) {
return Version{}, fmt.Errorf("Invalid character(s) found in build meta data %q", str)
}
v.Build = append(v.Build, str)
}
return v, nil
}
// MustParse is like Parse but panics if the version cannot be parsed.
func MustParse(s string) Version {
v, err := Parse(s)
if err != nil {
panic(`semver: Parse(` + s + `): ` + err.Error())
}
return v
}
// PRVersion represents a PreRelease Version
type PRVersion struct {
VersionStr string
VersionNum uint64
IsNum bool
}
// NewPRVersion creates a new valid prerelease version
func NewPRVersion(s string) (PRVersion, error) {
if len(s) == 0 {
return PRVersion{}, errors.New("Prerelease is empty")
}
v := PRVersion{}
if containsOnly(s, numbers) {
if hasLeadingZeroes(s) {
return PRVersion{}, fmt.Errorf("Numeric PreRelease version must not contain leading zeroes %q", s)
}
num, err := strconv.ParseUint(s, 10, 64)
// Might never be hit, but just in case
if err != nil {
return PRVersion{}, err
}
v.VersionNum = num
v.IsNum = true
} else if containsOnly(s, alphanum) {
v.VersionStr = s
v.IsNum = false
} else {
return PRVersion{}, fmt.Errorf("Invalid character(s) found in prerelease %q", s)
}
return v, nil
}
// IsNumeric checks if prerelease-version is numeric
func (v PRVersion) IsNumeric() bool {
return v.IsNum
}
// Compare compares two PreRelease Versions v and o:
// -1 == v is less than o
// 0 == v is equal to o
// 1 == v is greater than o
func (v PRVersion) Compare(o PRVersion) int {
if v.IsNum && !o.IsNum {
return -1
} else if !v.IsNum && o.IsNum {
return 1
} else if v.IsNum && o.IsNum {
if v.VersionNum == o.VersionNum {
return 0
} else if v.VersionNum > o.VersionNum {
return 1
} else {
return -1
}
} else { // both are Alphas
if v.VersionStr == o.VersionStr {
return 0
} else if v.VersionStr > o.VersionStr {
return 1
} else {
return -1
}
}
}
// PreRelease version to string
func (v PRVersion) String() string {
if v.IsNum {
return strconv.FormatUint(v.VersionNum, 10)
}
return v.VersionStr
}
func containsOnly(s string, set string) bool {
return strings.IndexFunc(s, func(r rune) bool {
return !strings.ContainsRune(set, r)
}) == -1
}
func hasLeadingZeroes(s string) bool {
return len(s) > 1 && s[0] == '0'
}
// NewBuildVersion creates a new valid build version
func NewBuildVersion(s string) (string, error) {
if len(s) == 0 {
return "", errors.New("Buildversion is empty")
}
if !containsOnly(s, alphanum) {
return "", fmt.Errorf("Invalid character(s) found in build meta data %q", s)
}
return s, nil
}

View file

@ -1,28 +0,0 @@
package semver
import (
"sort"
)
// Versions represents multiple versions.
type Versions []Version
// Len returns length of version collection
func (s Versions) Len() int {
return len(s)
}
// Swap swaps two versions inside the collection by its indices
func (s Versions) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
// Less checks if version at index i is less than version at index j
func (s Versions) Less(i, j int) bool {
return s[i].LT(s[j])
}
// Sort sorts a slice of versions
func Sort(versions []Version) {
sort.Sort(Versions(versions))
}

View file

@ -1,30 +0,0 @@
package semver
import (
"database/sql/driver"
"fmt"
)
// Scan implements the database/sql.Scanner interface.
func (v *Version) Scan(src interface{}) (err error) {
var str string
switch src := src.(type) {
case string:
str = src
case []byte:
str = string(src)
default:
return fmt.Errorf("Version.Scan: cannot convert %T to string.", src)
}
if t, err := Parse(str); err == nil {
*v = t
}
return
}
// Value implements the database/sql/driver.Valuer interface.
func (v Version) Value() (driver.Value, error) {
return v.String(), nil
}

View file

@ -1,5 +0,0 @@
CoreOS Project
Copyright 2014 CoreOS, Inc
This product includes software developed at CoreOS, Inc.
(http://www.coreos.com/).

View file

@ -1,7 +0,0 @@
package http
import "net/http"
type Client interface {
Do(*http.Request) (*http.Response, error)
}

View file

@ -1,156 +0,0 @@
package http
import (
"encoding/base64"
"encoding/json"
"errors"
"log"
"net/http"
"net/url"
"path"
"strconv"
"strings"
"time"
)
func WriteError(w http.ResponseWriter, code int, msg string) {
e := struct {
Error string `json:"error"`
}{
Error: msg,
}
b, err := json.Marshal(e)
if err != nil {
log.Printf("go-oidc: failed to marshal %#v: %v", e, err)
code = http.StatusInternalServerError
b = []byte(`{"error":"server_error"}`)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
w.Write(b)
}
// BasicAuth parses a username and password from the request's
// Authorization header. This was pulled from golang master:
// https://codereview.appspot.com/76540043
func BasicAuth(r *http.Request) (username, password string, ok bool) {
auth := r.Header.Get("Authorization")
if auth == "" {
return
}
if !strings.HasPrefix(auth, "Basic ") {
return
}
c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
if err != nil {
return
}
cs := string(c)
s := strings.IndexByte(cs, ':')
if s < 0 {
return
}
return cs[:s], cs[s+1:], true
}
func cacheControlMaxAge(hdr string) (time.Duration, bool, error) {
for _, field := range strings.Split(hdr, ",") {
parts := strings.SplitN(strings.TrimSpace(field), "=", 2)
k := strings.ToLower(strings.TrimSpace(parts[0]))
if k != "max-age" {
continue
}
if len(parts) == 1 {
return 0, false, errors.New("max-age has no value")
}
v := strings.TrimSpace(parts[1])
if v == "" {
return 0, false, errors.New("max-age has empty value")
}
age, err := strconv.Atoi(v)
if err != nil {
return 0, false, err
}
if age <= 0 {
return 0, false, nil
}
return time.Duration(age) * time.Second, true, nil
}
return 0, false, nil
}
func expires(date, expires string) (time.Duration, bool, error) {
if date == "" || expires == "" {
return 0, false, nil
}
te, err := time.Parse(time.RFC1123, expires)
if err != nil {
return 0, false, err
}
td, err := time.Parse(time.RFC1123, date)
if err != nil {
return 0, false, err
}
ttl := te.Sub(td)
// headers indicate data already expired, caller should not
// have to care about this case
if ttl <= 0 {
return 0, false, nil
}
return ttl, true, nil
}
func Cacheable(hdr http.Header) (time.Duration, bool, error) {
ttl, ok, err := cacheControlMaxAge(hdr.Get("Cache-Control"))
if err != nil || ok {
return ttl, ok, err
}
return expires(hdr.Get("Date"), hdr.Get("Expires"))
}
// MergeQuery appends additional query values to an existing URL.
func MergeQuery(u url.URL, q url.Values) url.URL {
uv := u.Query()
for k, vs := range q {
for _, v := range vs {
uv.Add(k, v)
}
}
u.RawQuery = uv.Encode()
return u
}
// NewResourceLocation appends a resource id to the end of the requested URL path.
func NewResourceLocation(reqURL *url.URL, id string) string {
var u url.URL
u = *reqURL
u.Path = path.Join(u.Path, id)
u.RawQuery = ""
u.Fragment = ""
return u.String()
}
// CopyRequest returns a clone of the provided *http.Request.
// The returned object is a shallow copy of the struct and a
// deep copy of its Header field.
func CopyRequest(r *http.Request) *http.Request {
r2 := *r
r2.Header = make(http.Header)
for k, s := range r.Header {
r2.Header[k] = s
}
return &r2
}

View file

@ -1,29 +0,0 @@
package http
import (
"errors"
"net/url"
)
// ParseNonEmptyURL checks that a string is a parsable URL which is also not empty
// since `url.Parse("")` does not return an error. Must contian a scheme and a host.
func ParseNonEmptyURL(u string) (*url.URL, error) {
if u == "" {
return nil, errors.New("url is empty")
}
ur, err := url.Parse(u)
if err != nil {
return nil, err
}
if ur.Scheme == "" {
return nil, errors.New("url scheme is empty")
}
if ur.Host == "" {
return nil, errors.New("url host is empty")
}
return ur, nil
}

Some files were not shown because too many files have changed in this diff Show more