2019-10-15 18:34:08 +03:00
package integration
import (
"fmt"
2021-11-25 13:10:06 +03:00
"net"
2019-10-15 18:34:08 +03:00
"net/http"
"os"
"time"
"github.com/go-check/check"
"github.com/hashicorp/consul/api"
2020-09-16 16:46:04 +03:00
"github.com/traefik/traefik/v2/integration/try"
2019-12-12 19:48:05 +03:00
checker "github.com/vdemeester/shakers"
2019-10-15 18:34:08 +03:00
)
type ConsulCatalogSuite struct {
BaseSuite
2021-11-25 13:10:06 +03:00
consulClient * api . Client
consulAgentClient * api . Client
consulURL string
2019-10-15 18:34:08 +03:00
}
func ( s * ConsulCatalogSuite ) SetUpSuite ( c * check . C ) {
s . createComposeProject ( c , "consul_catalog" )
2021-11-25 13:10:06 +03:00
s . composeUp ( c )
s . consulURL = "http://" + net . JoinHostPort ( s . getComposeServiceIP ( c , "consul" ) , "8500" )
var err error
s . consulClient , err = api . NewClient ( & api . Config {
Address : s . consulURL ,
2019-10-15 18:34:08 +03:00
} )
c . Check ( err , check . IsNil )
// Wait for consul to elect itself leader
err = s . waitToElectConsulLeader ( )
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
2021-11-25 13:10:06 +03:00
s . consulAgentClient , err = api . NewClient ( & api . Config {
Address : "http://" + net . JoinHostPort ( s . getComposeServiceIP ( c , "consul-agent" ) , "8500" ) ,
2019-11-27 18:24:06 +03:00
} )
c . Check ( err , check . IsNil )
2019-10-15 18:34:08 +03:00
}
func ( s * ConsulCatalogSuite ) waitToElectConsulLeader ( ) error {
return try . Do ( 15 * time . Second , func ( ) error {
leader , err := s . consulClient . Status ( ) . Leader ( )
if err != nil || len ( leader ) == 0 {
2020-05-11 13:06:07 +03:00
return fmt . Errorf ( "leader not found. %w" , err )
2019-10-15 18:34:08 +03:00
}
return nil
} )
}
2021-07-15 15:02:11 +03:00
func ( s * ConsulCatalogSuite ) waitForConnectCA ( ) error {
return try . Do ( 15 * time . Second , func ( ) error {
caroots , _ , err := s . consulClient . Connect ( ) . CARoots ( nil )
if err != nil || len ( caroots . Roots ) == 0 {
return fmt . Errorf ( "connect CA not fully initialized. %w" , err )
}
return nil
} )
}
2019-12-19 13:00:07 +03:00
func ( s * ConsulCatalogSuite ) registerService ( reg * api . AgentServiceRegistration , onAgent bool ) error {
2019-11-27 18:24:06 +03:00
client := s . consulClient
if onAgent {
client = s . consulAgentClient
}
2019-10-15 18:34:08 +03:00
2019-12-19 13:00:07 +03:00
return client . Agent ( ) . ServiceRegister ( reg )
2019-10-15 18:34:08 +03:00
}
2019-11-27 18:24:06 +03:00
func ( s * ConsulCatalogSuite ) deregisterService ( id string , onAgent bool ) error {
client := s . consulClient
if onAgent {
client = s . consulAgentClient
}
return client . Agent ( ) . ServiceDeregister ( id )
2019-10-15 18:34:08 +03:00
}
func ( s * ConsulCatalogSuite ) TestWithNotExposedByDefaultAndDefaultsSettings ( c * check . C ) {
2019-12-19 13:00:07 +03:00
reg1 := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg1 , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2019-12-19 13:00:07 +03:00
reg2 := & api . AgentServiceRegistration {
ID : "whoami2" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami2" ) ,
2019-12-19 13:00:07 +03:00
}
err = s . registerService ( reg2 , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2019-12-19 13:00:07 +03:00
reg3 := & api . AgentServiceRegistration {
ID : "whoami3" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami3" ) ,
2019-12-19 13:00:07 +03:00
}
err = s . registerService ( reg3 , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
}
file := s . adaptFile ( c , "fixtures/consul_catalog/default_not_exposed.toml" , tempObjects )
defer os . Remove ( file )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "whoami"
2020-02-13 12:26:04 +03:00
err = try . Request ( req , 2 * time . Second ,
try . StatusCodeIs ( 200 ) ,
try . BodyContainsOr ( "Hostname: whoami1" , "Hostname: whoami2" , "Hostname: whoami3" ) )
c . Assert ( err , checker . IsNil )
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 2 * time . Second ,
try . StatusCodeIs ( 200 ) ,
try . BodyContains (
fmt . Sprintf ( ` "http://%s:80":"UP" ` , reg1 . Address ) ,
fmt . Sprintf ( ` "http://%s:80":"UP" ` , reg2 . Address ) ,
fmt . Sprintf ( ` "http://%s:80":"UP" ` , reg3 . Address ) ,
) )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami2" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami3" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestByLabels ( c * check . C ) {
2021-11-25 13:10:06 +03:00
containerIP := s . getComposeServiceIP ( c , "whoami1" )
2019-12-19 13:00:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.http.routers.router1.rule=Path(`/whoami`)" ,
"traefik.http.routers.router1.service=service1" ,
"traefik.http.services.service1.loadBalancer.server.url=http://" + containerIP ,
} ,
Port : 80 ,
Address : containerIP ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
}
file := s . adaptFile ( c , "fixtures/consul_catalog/default_not_exposed.toml" , tempObjects )
defer os . Remove ( file )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
2021-11-25 13:10:06 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 5 * time . Second , try . StatusCodeIs ( http . StatusOK ) , try . BodyContainsOr ( "Hostname: whoami1" , "Hostname: whoami2" , "Hostname: whoami3" ) )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestSimpleConfiguration ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "whoami.consul.localhost"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
}
2022-01-28 19:16:07 +03:00
func ( s * ConsulCatalogSuite ) TestSimpleConfigurationWithWatch ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
ConsulAddress : s . consulURL ,
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple_watch.toml" , tempObjects )
defer os . Remove ( file )
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
}
err := s . registerService ( reg , false )
c . Assert ( err , checker . IsNil )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
defer s . killCmd ( cmd )
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "whoami.consul.localhost"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( http . StatusOK ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
c . Assert ( err , checker . IsNil )
whoamiIP := s . getComposeServiceIP ( c , "whoami1" )
reg . Check = & api . AgentServiceCheck {
CheckID : "some-ok-check" ,
TCP : whoamiIP + ":80" ,
Name : "some-ok-check" ,
Interval : "1s" ,
Timeout : "1s" ,
}
err = s . registerService ( reg , false )
c . Assert ( err , checker . IsNil )
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( http . StatusOK ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
c . Assert ( err , checker . IsNil )
reg . Check = & api . AgentServiceCheck {
CheckID : "some-failing-check" ,
TCP : ":80" ,
Name : "some-failing-check" ,
Interval : "1s" ,
Timeout : "1s" ,
}
err = s . registerService ( reg , false )
c . Assert ( err , checker . IsNil )
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
}
2019-11-14 13:10:06 +03:00
func ( s * ConsulCatalogSuite ) TestRegisterServiceWithoutIP ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-11-14 13:10:06 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
Address : "" ,
}
err := s . registerService ( reg , false )
2019-11-14 13:10:06 +03:00
c . Assert ( err , checker . IsNil )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-11-14 13:10:06 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8080/api/http/services" , nil )
c . Assert ( err , checker . IsNil )
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "whoami@consulcatalog" , "\"http://127.0.0.1:80\": \"UP\"" ) )
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2019-11-14 13:10:06 +03:00
c . Assert ( err , checker . IsNil )
}
2019-10-15 18:34:08 +03:00
func ( s * ConsulCatalogSuite ) TestDefaultConsulService ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "whoami.consul.localhost"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestConsulServiceWithTCPLabels ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
// Start a container with some tags
reg := & api . AgentServiceRegistration {
ID : "whoamitcp" ,
Name : "whoamitcp" ,
Tags : [ ] string {
"traefik.tcp.Routers.Super.Rule=HostSNI(`my.super.host`)" ,
"traefik.tcp.Routers.Super.tls=true" ,
"traefik.tcp.Services.Super.Loadbalancer.server.port=8080" ,
} ,
Port : 8080 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoamitcp" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
err = try . GetRequest ( "http://127.0.0.1:8080/api/rawdata" , 1500 * time . Millisecond , try . StatusCodeIs ( http . StatusOK ) , try . BodyContains ( "HostSNI(`my.super.host`)" ) )
c . Assert ( err , checker . IsNil )
who , err := guessWho ( "127.0.0.1:8000" , "my.super.host" , true )
c . Assert ( err , checker . IsNil )
c . Assert ( who , checker . Contains , "whoamitcp" )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoamitcp" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestConsulServiceWithLabels ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
// Start a container with some tags
reg1 := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string {
"traefik.http.Routers.Super.Rule=Host(`my.super.host`)" ,
} ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg1 , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
// Start another container by replacing a '.' by a '-'
2019-12-19 13:00:07 +03:00
reg2 := & api . AgentServiceRegistration {
ID : "whoami2" ,
Name : "whoami" ,
Tags : [ ] string {
"traefik.http.Routers.SuperHost.Rule=Host(`my-super.host`)" ,
} ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami2" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err = s . registerService ( reg2 , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "my-super.host"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
c . Assert ( err , checker . IsNil )
req , err = http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "my.super.host"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami2" ) )
c . Assert ( err , checker . IsNil )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami2" , false )
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestSameServiceIDOnDifferentConsulAgent ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-11-27 18:24:06 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/default_not_exposed.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
// Start a container with some tags
tags := [ ] string {
2019-11-27 18:24:06 +03:00
"traefik.enable=true" ,
"traefik.http.Routers.Super.service=whoami" ,
"traefik.http.Routers.Super.Rule=Host(`my.super.host`)" ,
}
2019-12-19 13:00:07 +03:00
reg1 := & api . AgentServiceRegistration {
ID : "whoami" ,
Name : "whoami" ,
Tags : tags ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg1 , false )
2019-11-27 18:24:06 +03:00
c . Assert ( err , checker . IsNil )
2019-12-19 13:00:07 +03:00
reg2 := & api . AgentServiceRegistration {
ID : "whoami" ,
Name : "whoami" ,
Tags : tags ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami2" ) ,
2019-12-19 13:00:07 +03:00
}
err = s . registerService ( reg2 , true )
2019-11-27 18:24:06 +03:00
c . Assert ( err , checker . IsNil )
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-11-27 18:24:06 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "my.super.host"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" , "Hostname: whoami2" ) )
c . Assert ( err , checker . IsNil )
req , err = http . NewRequest ( http . MethodGet , "http://127.0.0.1:8080/api/rawdata" , nil )
c . Assert ( err , checker . IsNil )
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) ,
2021-11-25 13:10:06 +03:00
try . BodyContainsOr ( s . getComposeServiceIP ( c , "whoami1" ) , s . getComposeServiceIP ( c , "whoami2" ) ) )
2019-11-27 18:24:06 +03:00
c . Assert ( err , checker . IsNil )
2021-02-10 16:48:03 +03:00
err = s . deregisterService ( "whoami" , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
2021-02-10 16:48:03 +03:00
err = s . deregisterService ( "whoami" , true )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestConsulServiceWithOneMissingLabels ( c * check . C ) {
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
2019-12-19 13:00:07 +03:00
// Start a container with some tags
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string {
"traefik.random.value=my.super.host" ,
} ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : s . getComposeServiceIP ( c , "whoami1" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg , false )
2019-10-15 18:34:08 +03:00
c . Assert ( err , checker . IsNil )
// Start traefik
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "my.super.host"
2022-08-31 09:24:08 +03:00
// TODO Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
2019-10-15 18:34:08 +03:00
// TODO validate : run on 80
// Expected a 404 as we did not configure anything
err = try . Request ( req , 1500 * time . Millisecond , try . StatusCodeIs ( http . StatusNotFound ) )
c . Assert ( err , checker . IsNil )
}
2019-12-19 13:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulServiceWithHealthCheck ( c * check . C ) {
2021-11-25 13:10:06 +03:00
whoamiIP := s . getComposeServiceIP ( c , "whoami1" )
2019-12-19 13:00:07 +03:00
tags := [ ] string {
"traefik.enable=true" ,
"traefik.http.routers.router1.rule=Path(`/whoami`)" ,
"traefik.http.routers.router1.service=service1" ,
2021-11-25 13:10:06 +03:00
"traefik.http.services.service1.loadBalancer.server.url=http://" + whoamiIP ,
2019-12-19 13:00:07 +03:00
}
reg1 := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : tags ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : whoamiIP ,
2019-12-19 13:00:07 +03:00
Check : & api . AgentServiceCheck {
CheckID : "some-failed-check" ,
TCP : "127.0.0.1:1234" ,
Name : "some-failed-check" ,
Interval : "1s" ,
Timeout : "1s" ,
} ,
}
err := s . registerService ( reg1 , false )
c . Assert ( err , checker . IsNil )
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-12-19 13:00:07 +03:00
}
file := s . adaptFile ( c , "fixtures/consul_catalog/simple.toml" , tempObjects )
defer os . Remove ( file )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
2020-10-09 10:32:03 +03:00
defer s . killCmd ( cmd )
2019-12-19 13:00:07 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 2 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
whoami2IP := s . getComposeServiceIP ( c , "whoami2" )
2019-12-19 13:00:07 +03:00
reg2 := & api . AgentServiceRegistration {
ID : "whoami2" ,
Name : "whoami" ,
Tags : tags ,
Port : 80 ,
2021-11-25 13:10:06 +03:00
Address : whoami2IP ,
2019-12-19 13:00:07 +03:00
Check : & api . AgentServiceCheck {
CheckID : "some-ok-check" ,
2021-11-25 13:10:06 +03:00
TCP : whoami2IP + ":80" ,
2019-12-19 13:00:07 +03:00
Name : "some-ok-check" ,
Interval : "1s" ,
Timeout : "1s" ,
} ,
}
err = s . registerService ( reg2 , false )
c . Assert ( err , checker . IsNil )
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/whoami" , nil )
c . Assert ( err , checker . IsNil )
req . Host = "whoami"
2022-08-31 09:24:08 +03:00
// TODO Need to wait for up to 10 seconds (for consul discovery or traefik to boot up ?)
2019-12-19 13:00:07 +03:00
err = try . Request ( req , 10 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami2" ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami2" , false )
c . Assert ( err , checker . IsNil )
}
2021-07-15 15:02:11 +03:00
func ( s * ConsulCatalogSuite ) TestConsulConnect ( c * check . C ) {
// Wait for consul to fully initialize connect CA
err := s . waitForConnectCA ( )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
connectIP := s . getComposeServiceIP ( c , "connect" )
2021-07-15 15:02:11 +03:00
reg := & api . AgentServiceRegistration {
ID : "uuid-api1" ,
Name : "uuid-api" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.consulcatalog.connect=true" ,
"traefik.http.routers.router1.rule=Path(`/`)" ,
"traefik.http.routers.router1.service=service1" ,
"traefik.http.services.service1.loadBalancer.server.url=https://" + connectIP ,
} ,
Connect : & api . AgentServiceConnect {
Native : true ,
} ,
Port : 443 ,
Address : connectIP ,
}
err = s . registerService ( reg , false )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
whoamiIP := s . getComposeServiceIP ( c , "whoami1" )
2021-07-15 15:02:11 +03:00
regWhoami := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.http.routers.router2.rule=Path(`/whoami`)" ,
"traefik.http.routers.router2.service=whoami" ,
} ,
Port : 80 ,
Address : whoamiIP ,
}
err = s . registerService ( regWhoami , false )
c . Assert ( err , checker . IsNil )
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2021-07-15 15:02:11 +03:00
}
file := s . adaptFile ( c , "fixtures/consul_catalog/connect.toml" , tempObjects )
defer os . Remove ( file )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
defer s . killCmd ( cmd )
err = try . GetRequest ( "http://127.0.0.1:8000/" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
c . Assert ( err , checker . IsNil )
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "uuid-api1" , false )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestConsulConnect_ByDefault ( c * check . C ) {
// Wait for consul to fully initialize connect CA
err := s . waitForConnectCA ( )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
connectIP := s . getComposeServiceIP ( c , "connect" )
2021-07-15 15:02:11 +03:00
reg := & api . AgentServiceRegistration {
ID : "uuid-api1" ,
Name : "uuid-api" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.http.routers.router1.rule=Path(`/`)" ,
"traefik.http.routers.router1.service=service1" ,
"traefik.http.services.service1.loadBalancer.server.url=https://" + connectIP ,
} ,
Connect : & api . AgentServiceConnect {
Native : true ,
} ,
Port : 443 ,
Address : connectIP ,
}
err = s . registerService ( reg , false )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
whoamiIP := s . getComposeServiceIP ( c , "whoami1" )
2021-07-15 15:02:11 +03:00
regWhoami := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami1" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.http.routers.router2.rule=Path(`/whoami`)" ,
"traefik.http.routers.router2.service=whoami" ,
} ,
Port : 80 ,
Address : whoamiIP ,
}
err = s . registerService ( regWhoami , false )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
whoami2IP := s . getComposeServiceIP ( c , "whoami2" )
2021-07-15 15:02:11 +03:00
regWhoami2 := & api . AgentServiceRegistration {
ID : "whoami2" ,
Name : "whoami2" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.consulcatalog.connect=false" ,
"traefik.http.routers.router2.rule=Path(`/whoami2`)" ,
"traefik.http.routers.router2.service=whoami2" ,
} ,
Port : 80 ,
Address : whoami2IP ,
}
err = s . registerService ( regWhoami2 , false )
c . Assert ( err , checker . IsNil )
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2021-07-15 15:02:11 +03:00
}
file := s . adaptFile ( c , "fixtures/consul_catalog/connect_by_default.toml" , tempObjects )
defer os . Remove ( file )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
defer s . killCmd ( cmd )
err = try . GetRequest ( "http://127.0.0.1:8000/" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
c . Assert ( err , checker . IsNil )
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 10 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
c . Assert ( err , checker . IsNil )
err = try . GetRequest ( "http://127.0.0.1:8000/whoami2" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "uuid-api1" , false )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami2" , false )
c . Assert ( err , checker . IsNil )
}
func ( s * ConsulCatalogSuite ) TestConsulConnect_NotAware ( c * check . C ) {
// Wait for consul to fully initialize connect CA
err := s . waitForConnectCA ( )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
connectIP := s . getComposeServiceIP ( c , "connect" )
2021-07-15 15:02:11 +03:00
reg := & api . AgentServiceRegistration {
ID : "uuid-api1" ,
Name : "uuid-api" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.consulcatalog.connect=true" ,
"traefik.http.routers.router1.rule=Path(`/`)" ,
"traefik.http.routers.router1.service=service1" ,
"traefik.http.services.service1.loadBalancer.server.url=https://" + connectIP ,
} ,
Connect : & api . AgentServiceConnect {
Native : true ,
} ,
Port : 443 ,
Address : connectIP ,
}
err = s . registerService ( reg , false )
c . Assert ( err , checker . IsNil )
2021-11-25 13:10:06 +03:00
whoamiIP := s . getComposeServiceIP ( c , "whoami1" )
2021-07-15 15:02:11 +03:00
regWhoami := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string {
"traefik.enable=true" ,
"traefik.http.routers.router2.rule=Path(`/whoami`)" ,
"traefik.http.routers.router2.service=whoami" ,
} ,
Port : 80 ,
Address : whoamiIP ,
}
err = s . registerService ( regWhoami , false )
c . Assert ( err , checker . IsNil )
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2021-07-15 15:02:11 +03:00
}
file := s . adaptFile ( c , "fixtures/consul_catalog/connect_not_aware.toml" , tempObjects )
defer os . Remove ( file )
cmd , display := s . traefikCmd ( withConfigFile ( file ) )
defer display ( c )
err = cmd . Start ( )
c . Assert ( err , checker . IsNil )
defer s . killCmd ( cmd )
err = try . GetRequest ( "http://127.0.0.1:8000/" , 10 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
c . Assert ( err , checker . IsNil )
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "uuid-api1" , false )
c . Assert ( err , checker . IsNil )
err = s . deregisterService ( "whoami1" , false )
c . Assert ( err , checker . IsNil )
}