Ignore ErrKeyNotFound error for the KV provider

This commit is contained in:
Yakun Sun 2023-09-25 22:38:07 +08:00 committed by GitHub
parent c3880a69ca
commit 173154cf59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 0 deletions

View file

@ -4,6 +4,7 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
@ -28,6 +29,13 @@ type ConsulSuite struct {
consulURL string
}
func (s *ConsulSuite) resetStore(c *check.C) {
err := s.kvClient.DeleteTree(context.Background(), "traefik")
if err != nil && !errors.Is(err, store.ErrKeyNotFound) {
c.Fatal(err)
}
}
func (s *ConsulSuite) setupStore(c *check.C) {
s.createComposeProject(c, "consul")
s.composeUp(c)
@ -155,3 +163,71 @@ func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
c.Error(text)
}
}
func (s *ConsulSuite) assertWhoami(c *check.C, host string, expectedStatusCode int) {
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000", nil)
if err != nil {
c.Fatal(err)
}
req.Host = host
resp, err := try.ResponseUntilStatusCode(req, 15*time.Second, expectedStatusCode)
resp.Body.Close()
c.Assert(err, checker.IsNil)
}
func (s *ConsulSuite) TestDeleteRootKey(c *check.C) {
// This test case reproduce the issue: https://github.com/traefik/traefik/issues/8092
s.setupStore(c)
s.resetStore(c)
file := s.adaptFile(c, "fixtures/consul/simple.toml", struct{ ConsulAddress string }{s.consulURL})
defer os.Remove(file)
ctx := context.Background()
svcaddr := net.JoinHostPort(s.getComposeServiceIP(c, "whoami"), "80")
data := map[string]string{
"traefik/http/routers/Router0/entryPoints/0": "web",
"traefik/http/routers/Router0/rule": "Host(`kv1.localhost`)",
"traefik/http/routers/Router0/service": "simplesvc0",
"traefik/http/routers/Router1/entryPoints/0": "web",
"traefik/http/routers/Router1/rule": "Host(`kv2.localhost`)",
"traefik/http/routers/Router1/service": "simplesvc1",
"traefik/http/services/simplesvc0/loadBalancer/servers/0/url": "http://" + svcaddr,
"traefik/http/services/simplesvc1/loadBalancer/servers/0/url": "http://" + svcaddr,
}
for k, v := range data {
err := s.kvClient.Put(ctx, k, []byte(v), nil)
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)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,
try.BodyContains(`"Router0@consul":`, `"Router1@consul":`, `"simplesvc0@consul":`, `"simplesvc1@consul":`),
)
c.Assert(err, checker.IsNil)
s.assertWhoami(c, "kv1.localhost", http.StatusOK)
s.assertWhoami(c, "kv2.localhost", http.StatusOK)
// delete router1
err = s.kvClient.DeleteTree(ctx, "traefik/http/routers/Router1")
c.Assert(err, checker.IsNil)
s.assertWhoami(c, "kv1.localhost", http.StatusOK)
s.assertWhoami(c, "kv2.localhost", http.StatusNotFound)
// delete simple services and router0
err = s.kvClient.DeleteTree(ctx, "traefik")
c.Assert(err, checker.IsNil)
s.assertWhoami(c, "kv1.localhost", http.StatusNotFound)
s.assertWhoami(c, "kv2.localhost", http.StatusNotFound)
}

View file

@ -2,6 +2,8 @@ version: "3.8"
services:
consul:
image: consul:1.6
whoami:
image: traefik/whoami
networks:
default:

View file

@ -136,6 +136,16 @@ func (p *Provider) watchKv(ctx context.Context, configurationChan chan<- dynamic
func (p *Provider) buildConfiguration(ctx context.Context) (*dynamic.Configuration, error) {
pairs, err := p.kvClient.List(ctx, p.RootKey, nil)
if err != nil {
if errors.Is(err, store.ErrKeyNotFound) {
// This empty configuration satisfies the pkg/server/configurationwatcher.go isEmptyConfiguration func constraints,
// and will not be discarded by the configuration watcher.
return &dynamic.Configuration{
HTTP: &dynamic.HTTPConfiguration{
Routers: make(map[string]*dynamic.Router),
},
}, nil
}
return nil, err
}