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"
2024-01-09 19:00:07 +03:00
"testing"
2019-10-15 18:34:08 +03:00
"time"
"github.com/hashicorp/consul/api"
2024-01-09 19:00:07 +03:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
2023-02-03 17:24:05 +03:00
"github.com/traefik/traefik/v3/integration/try"
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
}
2024-01-09 19:00:07 +03:00
func TestConsulCatalogSuite ( t * testing . T ) {
suite . Run ( t , new ( ConsulCatalogSuite ) )
}
func ( s * ConsulCatalogSuite ) SetupSuite ( ) {
s . BaseSuite . SetupSuite ( )
2021-11-25 13:10:06 +03:00
2024-01-09 19:00:07 +03:00
s . createComposeProject ( "consul_catalog" )
s . composeUp ( )
s . consulURL = "http://" + net . JoinHostPort ( s . getComposeServiceIP ( "consul" ) , "8500" )
2021-11-25 13:10:06 +03:00
var err error
s . consulClient , err = api . NewClient ( & api . Config {
Address : s . consulURL ,
2019-10-15 18:34:08 +03:00
} )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
// Wait for consul to elect itself leader
err = s . waitToElectConsulLeader ( )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
2021-11-25 13:10:06 +03:00
s . consulAgentClient , err = api . NewClient ( & api . Config {
2024-01-09 19:00:07 +03:00
Address : "http://" + net . JoinHostPort ( s . getComposeServiceIP ( "consul-agent" ) , "8500" ) ,
2019-11-27 18:24:06 +03:00
} )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
}
func ( s * ConsulCatalogSuite ) TearDownSuite ( ) {
s . BaseSuite . TearDownSuite ( )
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
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestWithNotExposedByDefaultAndDefaultsSettings ( ) {
2019-12-19 13:00:07 +03:00
reg1 := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg1 , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
reg2 := & api . AgentServiceRegistration {
ID : "whoami2" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami2" ) ,
2019-12-19 13:00:07 +03:00
}
err = s . registerService ( reg2 , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
reg3 := & api . AgentServiceRegistration {
ID : "whoami3" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami3" ) ,
2019-12-19 13:00:07 +03:00
}
err = s . registerService ( reg3 , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/default_not_exposed.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
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" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2020-02-13 12:26:04 +03:00
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 ) ,
) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami2" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami3" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestByLabels ( ) {
containerIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/default_not_exposed.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
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" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestSimpleConfiguration ( ) {
2019-10-15 18:34:08 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
2019-12-19 13:00:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
req . Host = "whoami.consul.localhost"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestSimpleConfigurationWithWatch ( ) {
2022-01-28 19:16:07 +03:00
tempObjects := struct {
ConsulAddress string
DefaultRule string
} {
ConsulAddress : s . consulURL ,
DefaultRule : "Host(`{{ normalize .Name }}.consul.localhost`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple_watch.toml" , tempObjects )
2022-01-28 19:16:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Tags : [ ] string { "traefik.enable=true" } ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2022-01-28 19:16:07 +03:00
}
err := s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2022-01-28 19:16:07 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
req . Host = "whoami.consul.localhost"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( http . StatusOK ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
2024-01-09 19:00:07 +03:00
whoamiIP := s . getComposeServiceIP ( "whoami1" )
2022-01-28 19:16:07 +03:00
reg . Check = & api . AgentServiceCheck {
CheckID : "some-ok-check" ,
TCP : whoamiIP + ":80" ,
Name : "some-ok-check" ,
Interval : "1s" ,
Timeout : "1s" ,
}
err = s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
2024-01-09 19:00:07 +03:00
err = try . Request ( req , 5 * time . Second , try . StatusCodeIs ( http . StatusOK ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
reg . Check = & api . AgentServiceCheck {
CheckID : "some-failing-check" ,
TCP : ":80" ,
Name : "some-failing-check" ,
Interval : "1s" ,
Timeout : "1s" ,
}
err = s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
2024-01-09 19:00:07 +03:00
err = try . Request ( req , 5 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2022-01-28 19:16:07 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestRegisterServiceWithoutIP ( ) {
2019-11-14 13:10:06 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-11-14 13:10:06 +03:00
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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-14 13:10:06 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-11-14 13:10:06 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8080/api/http/services" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-14 13:10:06 +03:00
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "whoami@consulcatalog" , "\"http://127.0.0.1:80\": \"UP\"" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-14 13:10:06 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-14 13:10:06 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestDefaultConsulService ( ) {
2019-10-15 18:34:08 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
2019-12-19 13:00:07 +03:00
reg := & api . AgentServiceRegistration {
ID : "whoami1" ,
Name : "whoami" ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
req . Host = "whoami.consul.localhost"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulServiceWithTCPLabels ( ) {
2019-10-15 18:34:08 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
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 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoamitcp" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
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`)" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
who , err := guessWho ( "127.0.0.1:8000" , "my.super.host" , true )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2024-01-09 19:00:07 +03:00
assert . Contains ( s . T ( ) , who , "whoamitcp" )
2019-10-15 18:34:08 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoamitcp" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulServiceWithLabels ( ) {
2019-10-15 18:34:08 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
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 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg1 , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
// 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 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami2" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err = s . registerService ( reg2 , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
req . Host = "my-super.host"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
req , err = http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
req . Host = "my.super.host"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami2" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
err = s . deregisterService ( "whoami2" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestSameServiceIDOnDifferentConsulAgent ( ) {
2019-11-27 18:24:06 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/default_not_exposed.toml" , tempObjects )
2019-11-27 18:24:06 +03:00
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 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2019-12-19 13:00:07 +03:00
}
err := s . registerService ( reg1 , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
2019-12-19 13:00:07 +03:00
reg2 := & api . AgentServiceRegistration {
ID : "whoami" ,
Name : "whoami" ,
Tags : tags ,
Port : 80 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami2" ) ,
2019-12-19 13:00:07 +03:00
}
err = s . registerService ( reg2 , true )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-11-27 18:24:06 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
req . Host = "my.super.host"
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) , try . BodyContainsOr ( "Hostname: whoami1" , "Hostname: whoami2" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
req , err = http . NewRequest ( http . MethodGet , "http://127.0.0.1:8080/api/rawdata" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
err = try . Request ( req , 2 * time . Second , try . StatusCodeIs ( 200 ) ,
2024-01-09 19:00:07 +03:00
try . BodyContainsOr ( s . getComposeServiceIP ( "whoami1" ) , s . getComposeServiceIP ( "whoami2" ) ) )
require . NoError ( s . T ( ) , err )
2019-11-27 18:24:06 +03:00
2021-02-10 16:48:03 +03:00
err = s . deregisterService ( "whoami" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
2021-02-10 16:48:03 +03:00
err = s . deregisterService ( "whoami" , true )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulServiceWithOneMissingLabels ( ) {
2019-10-15 18:34:08 +03:00
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`)" ,
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-10-15 18:34:08 +03:00
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 ,
2024-01-09 19:00:07 +03:00
Address : s . getComposeServiceIP ( "whoami1" ) ,
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
err := s . registerService ( reg , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
// Start traefik
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2019-10-15 18:34:08 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/version" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
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 ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-10-15 18:34:08 +03:00
}
2019-12-19 13:00:07 +03:00
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulServiceWithHealthCheck ( ) {
whoamiIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2019-12-19 13:00:07 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/simple.toml" , tempObjects )
2019-12-19 13:00:07 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
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 ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
2024-01-09 19:00:07 +03:00
whoami2IP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
req , err := http . NewRequest ( http . MethodGet , "http://127.0.0.1:8000/whoami" , nil )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
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" ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
err = s . deregisterService ( "whoami2" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2019-12-19 13:00:07 +03:00
}
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulConnect ( ) {
2021-07-15 15:02:11 +03:00
// Wait for consul to fully initialize connect CA
err := s . waitForConnectCA ( )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
connectIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
whoamiIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2021-07-15 15:02:11 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/connect.toml" , tempObjects )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "uuid-api1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulConnect_ByDefault ( ) {
2021-07-15 15:02:11 +03:00
// Wait for consul to fully initialize connect CA
err := s . waitForConnectCA ( )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
connectIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
whoamiIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
whoami2IP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2021-07-15 15:02:11 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/connect_by_default.toml" , tempObjects )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 10 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/whoami2" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "uuid-api1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "whoami2" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
}
2024-01-09 19:00:07 +03:00
func ( s * ConsulCatalogSuite ) TestConsulConnect_NotAware ( ) {
2021-07-15 15:02:11 +03:00
// Wait for consul to fully initialize connect CA
err := s . waitForConnectCA ( )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
connectIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
whoamiIP := s . getComposeServiceIP ( "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 )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
tempObjects := struct {
ConsulAddress string
} {
2021-11-25 13:10:06 +03:00
ConsulAddress : s . consulURL ,
2021-07-15 15:02:11 +03:00
}
2024-01-09 19:00:07 +03:00
file := s . adaptFile ( "fixtures/consul_catalog/connect_not_aware.toml" , tempObjects )
2021-07-15 15:02:11 +03:00
2024-01-09 19:00:07 +03:00
s . traefikCmd ( withConfigFile ( file ) )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/" , 10 * time . Second , try . StatusCodeIs ( http . StatusNotFound ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = try . GetRequest ( "http://127.0.0.1:8000/whoami" , 10 * time . Second , try . StatusCodeIs ( http . StatusOK ) )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "uuid-api1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
err = s . deregisterService ( "whoami1" , false )
2024-01-09 19:00:07 +03:00
require . NoError ( s . T ( ) , err )
2021-07-15 15:02:11 +03:00
}