Merge pull request #539 from aledbf/migrate-client-go
Migrate to client-go
This commit is contained in:
commit
12a0373d2e
2054 changed files with 414791 additions and 223145 deletions
1834
Godeps/Godeps.json
generated
1834
Godeps/Godeps.json
generated
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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{}
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
92
core/pkg/cache/main_test.go
vendored
92
core/pkg/cache/main_test.go
vendored
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2015 The Kubernetes Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cache
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
|
||||||
"k8s.io/kubernetes/pkg/client/cache"
|
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestStoreToIngressLister(t *testing.T) {
|
|
||||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
|
||||||
ids := sets.NewString("foo", "bar", "baz")
|
|
||||||
for id := range ids {
|
|
||||||
store.Add(&extensions.Ingress{ObjectMeta: api.ObjectMeta{Name: id}})
|
|
||||||
}
|
|
||||||
sml := StoreToIngressLister{store}
|
|
||||||
|
|
||||||
gotIngress := sml.List()
|
|
||||||
got := make([]string, len(gotIngress))
|
|
||||||
for ix := range gotIngress {
|
|
||||||
ing, ok := gotIngress[ix].(*extensions.Ingress)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("expected an Ingress type")
|
|
||||||
}
|
|
||||||
got[ix] = ing.Name
|
|
||||||
}
|
|
||||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
|
||||||
t.Errorf("expected %v, got %v", ids, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStoreToSecretsLister(t *testing.T) {
|
|
||||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
|
||||||
ids := sets.NewString("foo", "bar", "baz")
|
|
||||||
for id := range ids {
|
|
||||||
store.Add(&api.Secret{ObjectMeta: api.ObjectMeta{Name: id}})
|
|
||||||
}
|
|
||||||
sml := StoreToSecretsLister{store}
|
|
||||||
|
|
||||||
gotIngress := sml.List()
|
|
||||||
got := make([]string, len(gotIngress))
|
|
||||||
for ix := range gotIngress {
|
|
||||||
s, ok := gotIngress[ix].(*api.Secret)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("expected a Secret type")
|
|
||||||
}
|
|
||||||
got[ix] = s.Name
|
|
||||||
}
|
|
||||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
|
||||||
t.Errorf("expected %v, got %v", ids, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStoreToConfigmapLister(t *testing.T) {
|
|
||||||
store := cache.NewStore(cache.MetaNamespaceKeyFunc)
|
|
||||||
ids := sets.NewString("foo", "bar", "baz")
|
|
||||||
for id := range ids {
|
|
||||||
store.Add(&api.ConfigMap{ObjectMeta: api.ObjectMeta{Name: id}})
|
|
||||||
}
|
|
||||||
sml := StoreToConfigmapLister{store}
|
|
||||||
|
|
||||||
gotIngress := sml.List()
|
|
||||||
got := make([]string, len(gotIngress))
|
|
||||||
for ix := range gotIngress {
|
|
||||||
m, ok := gotIngress[ix].(*api.ConfigMap)
|
|
||||||
if !ok {
|
|
||||||
t.Errorf("expected an Ingress type")
|
|
||||||
}
|
|
||||||
got[ix] = m.Name
|
|
||||||
}
|
|
||||||
if !ids.HasAll(got...) || len(got) != len(ids) {
|
|
||||||
t.Errorf("expected %v, got %v", ids, got)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,8 +24,8 @@ import (
|
||||||
"regexp"
|
"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"
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
@ -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 "+
|
|
@ -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
|
|
@ -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
|
|
@ -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] }
|
||||||
|
|
|
@ -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},
|
||||||
}
|
}
|
||||||
|
|
71
core/pkg/ingress/store/main.go
Normal file
71
core/pkg/ingress/store/main.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
api "k8s.io/client-go/pkg/api/v1"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IngressLister makes a Store that lists Ingress.
|
||||||
|
type IngressLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretsLister makes a Store that lists Secrets.
|
||||||
|
type SecretsLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConfigMapLister makes a Store that lists Configmaps.
|
||||||
|
type ConfigMapLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceLister makes a Store that lists Services.
|
||||||
|
type ServiceLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeLister makes a Store that lists Nodes.
|
||||||
|
type NodeLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// EndpointLister makes a Store that lists Endpoints.
|
||||||
|
type EndpointLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetServiceEndpoints returns the endpoints of a service, matched on service name.
|
||||||
|
func (s *EndpointLister) GetServiceEndpoints(svc *api.Service) (ep api.Endpoints, err error) {
|
||||||
|
for _, m := range s.Store.List() {
|
||||||
|
ep = *m.(*api.Endpoints)
|
||||||
|
if svc.Name == ep.Name && svc.Namespace == ep.Namespace {
|
||||||
|
return ep, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = fmt.Errorf("could not find endpoints for service: %v", svc.Name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecretLister makes a Store that lists Secres.
|
||||||
|
type SecretLister struct {
|
||||||
|
cache.Store
|
||||||
|
}
|
|
@ -19,12 +19,10 @@ package ingress
|
||||||
import (
|
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.
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
|
@ -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
15
vendor/cloud.google.com/go/AUTHORS
generated
vendored
Normal 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
34
vendor/cloud.google.com/go/CONTRIBUTORS
generated
vendored
Normal 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>
|
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
22
vendor/github.com/blang/semver/LICENSE
generated
vendored
|
@ -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.
|
|
||||||
|
|
142
vendor/github.com/blang/semver/README.md
generated
vendored
142
vendor/github.com/blang/semver/README.md
generated
vendored
|
@ -1,142 +0,0 @@
|
||||||
semver for golang [](https://drone.io/github.com/blang/semver/latest) [](https://godoc.org/github.com/blang/semver) [](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.
|
|
23
vendor/github.com/blang/semver/json.go
generated
vendored
23
vendor/github.com/blang/semver/json.go
generated
vendored
|
@ -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
|
|
||||||
}
|
|
395
vendor/github.com/blang/semver/semver.go
generated
vendored
395
vendor/github.com/blang/semver/semver.go
generated
vendored
|
@ -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
|
|
||||||
}
|
|
28
vendor/github.com/blang/semver/sort.go
generated
vendored
28
vendor/github.com/blang/semver/sort.go
generated
vendored
|
@ -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))
|
|
||||||
}
|
|
30
vendor/github.com/blang/semver/sql.go
generated
vendored
30
vendor/github.com/blang/semver/sql.go
generated
vendored
|
@ -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
|
|
||||||
}
|
|
5
vendor/github.com/coreos/go-oidc/NOTICE
generated
vendored
5
vendor/github.com/coreos/go-oidc/NOTICE
generated
vendored
|
@ -1,5 +0,0 @@
|
||||||
CoreOS Project
|
|
||||||
Copyright 2014 CoreOS, Inc
|
|
||||||
|
|
||||||
This product includes software developed at CoreOS, Inc.
|
|
||||||
(http://www.coreos.com/).
|
|
7
vendor/github.com/coreos/go-oidc/http/client.go
generated
vendored
7
vendor/github.com/coreos/go-oidc/http/client.go
generated
vendored
|
@ -1,7 +0,0 @@
|
||||||
package http
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
type Client interface {
|
|
||||||
Do(*http.Request) (*http.Response, error)
|
|
||||||
}
|
|
156
vendor/github.com/coreos/go-oidc/http/http.go
generated
vendored
156
vendor/github.com/coreos/go-oidc/http/http.go
generated
vendored
|
@ -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
|
|
||||||
}
|
|
29
vendor/github.com/coreos/go-oidc/http/url.go
generated
vendored
29
vendor/github.com/coreos/go-oidc/http/url.go
generated
vendored
|
@ -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
Loading…
Reference in a new issue