2016-04-19 19:23:08 +02:00
package provider
2016-04-20 13:26:51 +02:00
import (
2016-04-26 22:26:25 +02:00
"encoding/json"
2016-04-20 13:26:51 +02:00
"github.com/containous/traefik/provider/k8s"
"github.com/containous/traefik/types"
"reflect"
"testing"
)
func TestLoadIngresses ( t * testing . T ) {
ingresses := [ ] k8s . Ingress { {
2016-05-20 17:34:57 +01:00
ObjectMeta : k8s . ObjectMeta {
Namespace : "testing" ,
} ,
2016-04-20 13:26:51 +02:00
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
2016-05-26 12:09:36 +01:00
ServicePort : k8s . FromInt ( 80 ) ,
2016-04-20 13:26:51 +02:00
} ,
} ,
} ,
} ,
} ,
} ,
{
Host : "bar" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Backend : k8s . IngressBackend {
ServiceName : "service3" ,
2016-05-26 12:09:36 +01:00
ServicePort : k8s . FromString ( "https" ) ,
2016-04-20 13:26:51 +02:00
} ,
} ,
{
Backend : k8s . IngressBackend {
ServiceName : "service2" ,
ServicePort : k8s . FromInt ( 802 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} }
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
2016-05-20 17:34:57 +01:00
Name : "service1" ,
UID : "1" ,
Namespace : "testing" ,
2016-04-20 13:26:51 +02:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
2016-05-20 17:34:57 +01:00
Port : 80 ,
2016-04-20 13:26:51 +02:00
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
2016-05-20 17:34:57 +01:00
Name : "service2" ,
UID : "2" ,
Namespace : "testing" ,
2016-04-20 13:26:51 +02:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.2" ,
Ports : [ ] k8s . ServicePort {
{
Port : 802 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
2016-05-20 17:34:57 +01:00
Name : "service3" ,
UID : "3" ,
Namespace : "testing" ,
2016-04-20 13:26:51 +02:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.3" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
2016-05-26 12:09:36 +01:00
Port : 80 ,
} ,
{
Name : "https" ,
2016-04-26 22:26:25 +02:00
Port : 443 ,
2016-04-20 13:26:51 +02:00
} ,
} ,
} ,
} ,
}
2016-05-20 17:34:57 +01:00
endpoints := [ ] k8s . Endpoints {
{
ObjectMeta : k8s . ObjectMeta {
Name : "service1" ,
UID : "1" ,
Namespace : "testing" ,
} ,
Subsets : [ ] k8s . EndpointSubset {
{
Addresses : [ ] k8s . EndpointAddress {
{
IP : "10.10.0.1" ,
} ,
} ,
Ports : [ ] k8s . EndpointPort {
{
Port : 8080 ,
} ,
} ,
} ,
{
Addresses : [ ] k8s . EndpointAddress {
{
IP : "10.21.0.1" ,
} ,
} ,
Ports : [ ] k8s . EndpointPort {
{
Port : 8080 ,
} ,
} ,
} ,
} ,
} ,
2016-05-26 12:09:36 +01:00
{
ObjectMeta : k8s . ObjectMeta {
Name : "service3" ,
UID : "3" ,
Namespace : "testing" ,
} ,
Subsets : [ ] k8s . EndpointSubset {
{
Addresses : [ ] k8s . EndpointAddress {
{
IP : "10.15.0.1" ,
} ,
} ,
Ports : [ ] k8s . EndpointPort {
{
Name : "http" ,
Port : 8080 ,
} ,
{
Name : "https" ,
Port : 8443 ,
} ,
} ,
} ,
{
Addresses : [ ] k8s . EndpointAddress {
{
IP : "10.15.0.2" ,
} ,
} ,
Ports : [ ] k8s . EndpointPort {
{
Name : "http" ,
Port : 9080 ,
} ,
{
Name : "https" ,
Port : 9443 ,
} ,
} ,
} ,
} ,
} ,
2016-05-20 17:34:57 +01:00
}
2016-04-20 13:26:51 +02:00
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
2016-05-20 17:34:57 +01:00
endpoints : endpoints ,
2016-04-20 13:26:51 +02:00
watchChan : watchChan ,
}
provider := Kubernetes { }
actual , err := provider . loadIngresses ( client )
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := & types . Configuration {
Backends : map [ string ] * types . Backend {
"foo/bar" : {
Servers : map [ string ] types . Server {
2016-05-20 17:34:57 +01:00
"http://10.10.0.1:8080" : {
URL : "http://10.10.0.1:8080" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-05-20 17:34:57 +01:00
} ,
"http://10.21.0.1:8080" : {
URL : "http://10.21.0.1:8080" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-20 13:26:51 +02:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
"bar" : {
Servers : map [ string ] types . Server {
"2" : {
URL : "http://10.0.0.2:802" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-20 13:26:51 +02:00
} ,
2016-05-26 12:09:36 +01:00
"https://10.15.0.1:8443" : {
URL : "https://10.15.0.1:8443" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-05-26 12:09:36 +01:00
} ,
"https://10.15.0.2:9443" : {
URL : "https://10.15.0.2:9443" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-20 13:26:51 +02:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
} ,
Frontends : map [ string ] * types . Frontend {
"foo/bar" : {
2016-05-10 07:43:24 -04:00
Backend : "foo/bar" ,
PassHostHeader : true ,
2016-08-02 16:48:53 -07:00
Priority : len ( "/bar" ) ,
2016-04-20 13:26:51 +02:00
Routes : map [ string ] types . Route {
"/bar" : {
2016-05-05 19:57:35 +02:00
Rule : "PathPrefix:/bar" ,
2016-04-20 13:26:51 +02:00
} ,
"foo" : {
Rule : "Host:foo" ,
} ,
} ,
} ,
"bar" : {
2016-05-10 07:43:24 -04:00
Backend : "bar" ,
PassHostHeader : true ,
2016-04-20 13:26:51 +02:00
Routes : map [ string ] types . Route {
"bar" : {
Rule : "Host:bar" ,
} ,
} ,
} ,
} ,
}
2016-04-26 22:26:25 +02:00
actualJSON , _ := json . Marshal ( actual )
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
2016-04-20 13:26:51 +02:00
}
}
2016-05-17 13:50:06 +03:00
func TestRuleType ( t * testing . T ) {
ingresses := [ ] k8s . Ingress {
{
ObjectMeta : k8s . ObjectMeta {
Annotations : map [ string ] string { "traefik.frontend.rule.type" : "PathPrefixStrip" } , //camel case
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo1" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar1" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
2016-05-15 12:16:27 +03:00
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2016-05-17 13:50:06 +03:00
{
ObjectMeta : k8s . ObjectMeta {
Annotations : map [ string ] string { "traefik.frontend.rule.type" : "path" } , //lower case
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo1" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar2" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Annotations : map [ string ] string { "traefik.frontend.rule.type" : "PathPrefix" } , //path prefix
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo2" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar1" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Annotations : map [ string ] string { "traefik.frontend.rule.type" : "PathStrip" } , //path strip
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo2" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar2" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Annotations : map [ string ] string { "traefik.frontend.rule.type" : "PathXXStrip" } , //wrong rule
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo1" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar3" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
2016-05-15 12:16:27 +03:00
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
Name : "service1" ,
UID : "1" ,
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
}
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
watchChan : watchChan ,
}
2016-05-19 17:44:33 +02:00
provider := Kubernetes { DisablePassHostHeaders : true }
2016-05-16 01:24:23 +03:00
actualConfig , err := provider . loadIngresses ( client )
actual := actualConfig . Frontends
2016-05-15 12:16:27 +03:00
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := map [ string ] * types . Frontend {
2016-05-17 13:50:06 +03:00
"foo1/bar1" : {
2016-08-02 16:48:53 -07:00
Backend : "foo1/bar1" ,
Priority : len ( "/bar1" ) ,
2016-05-17 13:50:06 +03:00
Routes : map [ string ] types . Route {
"/bar1" : {
Rule : "PathPrefixStrip:/bar1" ,
} ,
"foo1" : {
Rule : "Host:foo1" ,
} ,
} ,
} ,
"foo1/bar2" : {
2016-08-02 16:48:53 -07:00
Backend : "foo1/bar2" ,
Priority : len ( "/bar2" ) ,
2016-05-17 13:50:06 +03:00
Routes : map [ string ] types . Route {
"/bar2" : {
Rule : "Path:/bar2" ,
} ,
"foo1" : {
Rule : "Host:foo1" ,
} ,
} ,
} ,
"foo2/bar1" : {
2016-08-02 16:48:53 -07:00
Backend : "foo2/bar1" ,
Priority : len ( "/bar1" ) ,
2016-05-17 13:50:06 +03:00
Routes : map [ string ] types . Route {
"/bar1" : {
Rule : "PathPrefix:/bar1" ,
} ,
"foo2" : {
Rule : "Host:foo2" ,
} ,
} ,
} ,
"foo2/bar2" : {
2016-08-02 16:48:53 -07:00
Backend : "foo2/bar2" ,
Priority : len ( "/bar2" ) ,
2016-05-17 13:50:06 +03:00
Routes : map [ string ] types . Route {
"/bar2" : {
Rule : "PathStrip:/bar2" ,
} ,
"foo2" : {
Rule : "Host:foo2" ,
} ,
} ,
} ,
"foo1/bar3" : {
2016-08-02 16:48:53 -07:00
Backend : "foo1/bar3" ,
Priority : len ( "/bar3" ) ,
2016-05-15 12:16:27 +03:00
Routes : map [ string ] types . Route {
2016-05-17 13:50:06 +03:00
"/bar3" : {
Rule : "PathPrefix:/bar3" ,
2016-05-15 12:16:27 +03:00
} ,
2016-05-17 13:50:06 +03:00
"foo1" : {
Rule : "Host:foo1" ,
2016-05-15 12:16:27 +03:00
} ,
} ,
} ,
}
2016-05-16 01:24:23 +03:00
actualJSON , _ := json . Marshal ( actual )
2016-05-15 12:16:27 +03:00
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
}
}
2016-05-10 07:43:24 -04:00
func TestGetPassHostHeader ( t * testing . T ) {
ingresses := [ ] k8s . Ingress { {
2016-05-18 16:46:19 +01:00
ObjectMeta : k8s . ObjectMeta {
Namespace : "awesome" ,
} ,
2016-05-10 07:43:24 -04:00
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} }
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Name : "service1" ,
Namespace : "awesome" ,
UID : "1" ,
2016-05-10 07:43:24 -04:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
}
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
watchChan : watchChan ,
}
2016-05-19 17:44:33 +02:00
provider := Kubernetes { DisablePassHostHeaders : true }
2016-05-10 07:43:24 -04:00
actual , err := provider . loadIngresses ( client )
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := & types . Configuration {
Backends : map [ string ] * types . Backend {
"foo/bar" : {
Servers : map [ string ] types . Server {
"1" : {
URL : "http://10.0.0.1:801" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-05-10 07:43:24 -04:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
} ,
Frontends : map [ string ] * types . Frontend {
"foo/bar" : {
2016-08-02 16:48:53 -07:00
Backend : "foo/bar" ,
Priority : len ( "/bar" ) ,
2016-05-10 07:43:24 -04:00
Routes : map [ string ] types . Route {
"/bar" : {
2016-05-05 19:57:35 +02:00
Rule : "PathPrefix:/bar" ,
2016-05-10 07:43:24 -04:00
} ,
"foo" : {
Rule : "Host:foo" ,
} ,
} ,
} ,
} ,
}
actualJSON , _ := json . Marshal ( actual )
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
}
}
2016-05-18 16:46:19 +01:00
func TestOnlyReferencesServicesFromOwnNamespace ( t * testing . T ) {
ingresses := [ ] k8s . Ingress {
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Backend : k8s . IngressBackend {
ServiceName : "service" ,
ServicePort : k8s . FromInt ( 80 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
Name : "service" ,
UID : "1" ,
Namespace : "awesome" ,
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 80 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Name : "service" ,
UID : "2" ,
Namespace : "not-awesome" ,
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.2" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 80 ,
} ,
} ,
} ,
} ,
}
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
watchChan : watchChan ,
}
provider := Kubernetes { }
actual , err := provider . loadIngresses ( client )
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := & types . Configuration {
Backends : map [ string ] * types . Backend {
"foo" : {
Servers : map [ string ] types . Server {
"1" : {
URL : "http://10.0.0.1:80" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-05-18 16:46:19 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
} ,
Frontends : map [ string ] * types . Frontend {
"foo" : {
Backend : "foo" ,
PassHostHeader : true ,
Routes : map [ string ] types . Route {
"foo" : {
Rule : "Host:foo" ,
} ,
} ,
} ,
} ,
}
actualJSON , _ := json . Marshal ( actual )
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
}
}
2016-04-28 01:23:55 +01:00
func TestLoadNamespacedIngresses ( t * testing . T ) {
ingresses := [ ] k8s . Ingress {
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
{
Host : "bar" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Backend : k8s . IngressBackend {
ServiceName : "service3" ,
ServicePort : k8s . FromInt ( 443 ) ,
} ,
} ,
{
Backend : k8s . IngressBackend {
ServiceName : "service2" ,
ServicePort : k8s . FromInt ( 802 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "not-awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "baz" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/baz" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Namespace : "awesome" ,
Name : "service1" ,
UID : "1" ,
2016-04-28 01:23:55 +01:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Name : "service1" ,
Namespace : "not-awesome" ,
UID : "1" ,
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Name : "service2" ,
Namespace : "awesome" ,
UID : "2" ,
2016-04-28 01:23:55 +01:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.2" ,
Ports : [ ] k8s . ServicePort {
{
Port : 802 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Name : "service3" ,
Namespace : "awesome" ,
UID : "3" ,
2016-04-28 01:23:55 +01:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.3" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 443 ,
} ,
} ,
} ,
} ,
}
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
watchChan : watchChan ,
}
provider := Kubernetes {
Namespaces : [ ] string { "awesome" } ,
}
actual , err := provider . loadIngresses ( client )
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := & types . Configuration {
Backends : map [ string ] * types . Backend {
"foo/bar" : {
Servers : map [ string ] types . Server {
"1" : {
URL : "http://10.0.0.1:801" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
"bar" : {
Servers : map [ string ] types . Server {
"2" : {
URL : "http://10.0.0.2:802" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
"3" : {
URL : "https://10.0.0.3:443" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
} ,
Frontends : map [ string ] * types . Frontend {
"foo/bar" : {
2016-05-10 07:43:24 -04:00
Backend : "foo/bar" ,
PassHostHeader : true ,
2016-08-02 16:48:53 -07:00
Priority : len ( "/bar" ) ,
2016-04-28 01:23:55 +01:00
Routes : map [ string ] types . Route {
"/bar" : {
2016-05-05 19:57:35 +02:00
Rule : "PathPrefix:/bar" ,
2016-04-28 01:23:55 +01:00
} ,
"foo" : {
Rule : "Host:foo" ,
} ,
} ,
} ,
"bar" : {
2016-05-10 07:43:24 -04:00
Backend : "bar" ,
PassHostHeader : true ,
2016-04-28 01:23:55 +01:00
Routes : map [ string ] types . Route {
"bar" : {
Rule : "Host:bar" ,
} ,
} ,
} ,
} ,
}
actualJSON , _ := json . Marshal ( actual )
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
}
}
func TestLoadMultipleNamespacedIngresses ( t * testing . T ) {
ingresses := [ ] k8s . Ingress {
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "foo" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
{
Host : "bar" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Backend : k8s . IngressBackend {
ServiceName : "service3" ,
ServicePort : k8s . FromInt ( 443 ) ,
} ,
} ,
{
Backend : k8s . IngressBackend {
ServiceName : "service2" ,
ServicePort : k8s . FromInt ( 802 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "somewhat-awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "awesome" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/quix" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "not-awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
Host : "baz" ,
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/baz" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
}
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Name : "service1" ,
Namespace : "awesome" ,
UID : "1" ,
2016-04-28 01:23:55 +01:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Namespace : "somewhat-awesome" ,
Name : "service1" ,
UID : "17" ,
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.4" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
Namespace : "awesome" ,
Name : "service2" ,
UID : "2" ,
2016-04-28 01:23:55 +01:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.2" ,
Ports : [ ] k8s . ServicePort {
{
Port : 802 ,
} ,
} ,
} ,
} ,
{
ObjectMeta : k8s . ObjectMeta {
2016-05-18 16:46:19 +01:00
Namespace : "awesome" ,
Name : "service3" ,
UID : "3" ,
2016-04-28 01:23:55 +01:00
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.3" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 443 ,
} ,
} ,
} ,
} ,
}
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
watchChan : watchChan ,
}
provider := Kubernetes {
Namespaces : [ ] string { "awesome" , "somewhat-awesome" } ,
}
actual , err := provider . loadIngresses ( client )
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := & types . Configuration {
Backends : map [ string ] * types . Backend {
"foo/bar" : {
Servers : map [ string ] types . Server {
"1" : {
URL : "http://10.0.0.1:801" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
"bar" : {
Servers : map [ string ] types . Server {
"2" : {
URL : "http://10.0.0.2:802" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
"3" : {
URL : "https://10.0.0.3:443" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
"awesome/quix" : {
Servers : map [ string ] types . Server {
2016-05-18 16:46:19 +01:00
"17" : {
URL : "http://10.0.0.4:801" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-04-28 01:23:55 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
} ,
Frontends : map [ string ] * types . Frontend {
"foo/bar" : {
2016-05-10 07:43:24 -04:00
Backend : "foo/bar" ,
PassHostHeader : true ,
2016-08-02 16:48:53 -07:00
Priority : len ( "/bar" ) ,
2016-04-28 01:23:55 +01:00
Routes : map [ string ] types . Route {
"/bar" : {
2016-05-05 19:57:35 +02:00
Rule : "PathPrefix:/bar" ,
2016-04-28 01:23:55 +01:00
} ,
"foo" : {
Rule : "Host:foo" ,
} ,
} ,
} ,
"bar" : {
2016-05-10 07:43:24 -04:00
Backend : "bar" ,
PassHostHeader : true ,
2016-04-28 01:23:55 +01:00
Routes : map [ string ] types . Route {
"bar" : {
Rule : "Host:bar" ,
} ,
} ,
} ,
"awesome/quix" : {
2016-05-10 07:43:24 -04:00
Backend : "awesome/quix" ,
PassHostHeader : true ,
2016-08-02 16:48:53 -07:00
Priority : len ( "/quix" ) ,
2016-04-28 01:23:55 +01:00
Routes : map [ string ] types . Route {
"/quix" : {
2016-05-05 19:57:35 +02:00
Rule : "PathPrefix:/quix" ,
2016-04-28 01:23:55 +01:00
} ,
"awesome" : {
Rule : "Host:awesome" ,
} ,
} ,
} ,
} ,
}
actualJSON , _ := json . Marshal ( actual )
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
2016-05-25 13:16:19 +01:00
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
}
}
func TestHostlessIngress ( t * testing . T ) {
ingresses := [ ] k8s . Ingress { {
ObjectMeta : k8s . ObjectMeta {
Namespace : "awesome" ,
} ,
Spec : k8s . IngressSpec {
Rules : [ ] k8s . IngressRule {
{
IngressRuleValue : k8s . IngressRuleValue {
HTTP : & k8s . HTTPIngressRuleValue {
Paths : [ ] k8s . HTTPIngressPath {
{
Path : "/bar" ,
Backend : k8s . IngressBackend {
ServiceName : "service1" ,
ServicePort : k8s . FromInt ( 801 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
} }
services := [ ] k8s . Service {
{
ObjectMeta : k8s . ObjectMeta {
Name : "service1" ,
Namespace : "awesome" ,
UID : "1" ,
} ,
Spec : k8s . ServiceSpec {
ClusterIP : "10.0.0.1" ,
Ports : [ ] k8s . ServicePort {
{
Name : "http" ,
Port : 801 ,
} ,
} ,
} ,
} ,
}
watchChan := make ( chan interface { } )
client := clientMock {
ingresses : ingresses ,
services : services ,
watchChan : watchChan ,
}
2016-05-26 15:55:50 +02:00
provider := Kubernetes { DisablePassHostHeaders : true }
2016-05-25 13:16:19 +01:00
actual , err := provider . loadIngresses ( client )
if err != nil {
t . Fatalf ( "error %+v" , err )
}
expected := & types . Configuration {
Backends : map [ string ] * types . Backend {
"/bar" : {
Servers : map [ string ] types . Server {
"1" : {
URL : "http://10.0.0.1:801" ,
2016-11-23 14:49:55 +01:00
Weight : 0 ,
2016-05-25 13:16:19 +01:00
} ,
} ,
CircuitBreaker : nil ,
LoadBalancer : nil ,
} ,
} ,
Frontends : map [ string ] * types . Frontend {
"/bar" : {
2016-08-02 16:48:53 -07:00
Backend : "/bar" ,
Priority : len ( "/bar" ) ,
2016-05-25 13:16:19 +01:00
Routes : map [ string ] types . Route {
"/bar" : {
Rule : "PathPrefix:/bar" ,
} ,
} ,
} ,
} ,
}
actualJSON , _ := json . Marshal ( actual )
expectedJSON , _ := json . Marshal ( expected )
if ! reflect . DeepEqual ( actual , expected ) {
2016-04-28 01:23:55 +01:00
t . Fatalf ( "expected %+v, got %+v" , string ( expectedJSON ) , string ( actualJSON ) )
}
}
2016-04-20 13:26:51 +02:00
type clientMock struct {
ingresses [ ] k8s . Ingress
services [ ] k8s . Service
2016-05-20 17:34:57 +01:00
endpoints [ ] k8s . Endpoints
2016-04-20 13:26:51 +02:00
watchChan chan interface { }
}
2016-07-12 01:25:01 -04:00
func ( c clientMock ) GetIngresses ( labelString string , predicate func ( k8s . Ingress ) bool ) ( [ ] k8s . Ingress , error ) {
2016-04-28 01:23:55 +01:00
var ingresses [ ] k8s . Ingress
for _ , ingress := range c . ingresses {
if predicate ( ingress ) {
ingresses = append ( ingresses , ingress )
}
}
return ingresses , nil
2016-04-20 13:26:51 +02:00
}
2016-07-12 01:25:01 -04:00
func ( c clientMock ) WatchIngresses ( labelString string , predicate func ( k8s . Ingress ) bool , stopCh <- chan bool ) ( chan interface { } , chan error , error ) {
2016-04-20 13:26:51 +02:00
return c . watchChan , make ( chan error ) , nil
}
2016-05-26 00:53:51 +01:00
func ( c clientMock ) GetService ( name , namespace string ) ( k8s . Service , error ) {
2016-05-18 16:46:19 +01:00
for _ , service := range c . services {
2016-05-26 00:53:51 +01:00
if service . Namespace == namespace && service . Name == name {
return service , nil
2016-05-18 16:46:19 +01:00
}
}
2016-05-26 00:53:51 +01:00
return k8s . Service { } , nil
2016-04-20 13:26:51 +02:00
}
2016-05-20 17:34:57 +01:00
func ( c clientMock ) GetEndpoints ( name , namespace string ) ( k8s . Endpoints , error ) {
for _ , endpoints := range c . endpoints {
if endpoints . Namespace == namespace && endpoints . Name == name {
return endpoints , nil
}
}
return k8s . Endpoints { } , nil
}
2016-07-12 01:25:01 -04:00
func ( c clientMock ) WatchAll ( labelString string , stopCh <- chan bool ) ( chan interface { } , chan error , error ) {
2016-04-25 16:56:06 +02:00
return c . watchChan , make ( chan error ) , nil
}