Add Support for Consul Connect
Co-authored-by: Florian Apolloner <apollo13@users.noreply.github.com>
This commit is contained in:
parent
3a180e2afc
commit
7e43e5615e
36 changed files with 2118 additions and 644 deletions
|
@ -54,6 +54,18 @@ func (s *ConsulCatalogSuite) waitToElectConsulLeader() error {
|
|||
})
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TearDownSuite(c *check.C) {
|
||||
// shutdown and delete compose project
|
||||
if s.composeProject != nil {
|
||||
|
@ -611,3 +623,221 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
|
|||
err = s.deregisterService("whoami2", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestConsulConnect(c *check.C) {
|
||||
// Wait for consul to fully initialize connect CA
|
||||
err := s.waitForConnectCA()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
connectIP := s.composeProject.Container(c, "connect").NetworkSettings.IPAddress
|
||||
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)
|
||||
|
||||
whoamiIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
|
||||
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
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
}
|
||||
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)
|
||||
|
||||
connectIP := s.composeProject.Container(c, "connect").NetworkSettings.IPAddress
|
||||
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)
|
||||
|
||||
whoamiIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
|
||||
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)
|
||||
|
||||
whoami2IP := s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress
|
||||
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
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
}
|
||||
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)
|
||||
|
||||
connectIP := s.composeProject.Container(c, "connect").NetworkSettings.IPAddress
|
||||
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)
|
||||
|
||||
whoamiIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
|
||||
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
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
|
21
integration/fixtures/consul_catalog/connect.toml
Normal file
21
integration/fixtures/consul_catalog/connect.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers]
|
||||
[providers.consulCatalog]
|
||||
exposedByDefault = false
|
||||
refreshInterval = "500ms"
|
||||
connectAware = true
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "{{ .ConsulAddress }}"
|
22
integration/fixtures/consul_catalog/connect_by_default.toml
Normal file
22
integration/fixtures/consul_catalog/connect_by_default.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers]
|
||||
[providers.consulCatalog]
|
||||
exposedByDefault = false
|
||||
refreshInterval = "500ms"
|
||||
connectAware = true
|
||||
connectByDefault = true
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "{{ .ConsulAddress }}"
|
21
integration/fixtures/consul_catalog/connect_not_aware.toml
Normal file
21
integration/fixtures/consul_catalog/connect_not_aware.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers]
|
||||
[providers.consulCatalog]
|
||||
exposedByDefault = false
|
||||
refreshInterval = "500ms"
|
||||
connectAware = false
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "{{ .ConsulAddress }}"
|
|
@ -741,6 +741,7 @@ spec:
|
|||
type: string
|
||||
type: object
|
||||
featurePolicy:
|
||||
description: 'Deprecated: use PermissionsPolicy instead.'
|
||||
type: string
|
||||
forceSTSHeader:
|
||||
type: boolean
|
||||
|
@ -752,6 +753,8 @@ spec:
|
|||
type: array
|
||||
isDevelopment:
|
||||
type: boolean
|
||||
permissionsPolicy:
|
||||
type: string
|
||||
publicKey:
|
||||
type: string
|
||||
referrerPolicy:
|
||||
|
@ -1142,6 +1145,10 @@ spec:
|
|||
description: If non-zero, controls the maximum idle (keep-alive) to
|
||||
keep per-host. If zero, DefaultMaxIdleConnsPerHost is used.
|
||||
type: integer
|
||||
peerCertURI:
|
||||
description: URI used to match against SAN URI during the peer certificate
|
||||
verification.
|
||||
type: string
|
||||
rootCAsSecrets:
|
||||
description: Add cert file for self-signed certificate.
|
||||
items:
|
||||
|
|
|
@ -2,7 +2,7 @@ consul:
|
|||
image: consul:1.6.2
|
||||
ports:
|
||||
- 8500:8500
|
||||
command: "agent -server -bootstrap -ui -client 0.0.0.0"
|
||||
command: "agent -server -bootstrap -ui -client 0.0.0.0 -hcl 'connect { enabled = true }'"
|
||||
consul-agent:
|
||||
image: consul:1.6.2
|
||||
ports:
|
||||
|
@ -22,3 +22,11 @@ whoami3:
|
|||
whoamitcp:
|
||||
image: traefik/whoamitcp
|
||||
hostname: whoamitcp
|
||||
connect:
|
||||
image: hashicorpnomad/uuid-api:v5
|
||||
links:
|
||||
- consul
|
||||
environment:
|
||||
PORT: 443
|
||||
BIND: 0.0.0.0
|
||||
CONSUL_HTTP_ADDR: http://consul:8500
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue