Skip to content

Commit

Permalink
router: Read router definitions from database
Browse files Browse the repository at this point in the history
  • Loading branch information
cezarsa committed Jul 13, 2020
1 parent a122277 commit 0771f10
Show file tree
Hide file tree
Showing 36 changed files with 1,011 additions and 231 deletions.
8 changes: 4 additions & 4 deletions api/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func (s *S) TestRoutersList(c *check.C) {
config.Set("routers:router2:type", "bar")
defer config.Unset("routers:router1:type")
defer config.Unset("routers:router2:type")
router.Register("foo", func(_, _ string) (router.Router, error) { return nil, nil })
router.Register("bar", func(_, _ string) (router.Router, error) { return nil, nil })
router.Register("foo", func(_ string, _ router.ConfigGetter) (router.Router, error) { return nil, nil })
router.Register("bar", func(_ string, _ router.ConfigGetter) (router.Router, error) { return nil, nil })
defer router.Unregister("foo")
defer router.Unregister("bar")
recorder := httptest.NewRecorder()
Expand All @@ -66,8 +66,8 @@ func (s *S) TestRoutersListAppCreatePermissionTeam(c *check.C) {
config.Set("routers:router2:type", "bar")
defer config.Unset("routers:router1:type")
defer config.Unset("routers:router2:type")
router.Register("foo", func(_, _ string) (router.Router, error) { return nil, nil })
router.Register("bar", func(_, _ string) (router.Router, error) { return nil, nil })
router.Register("foo", func(_ string, _ router.ConfigGetter) (router.Router, error) { return nil, nil })
router.Register("bar", func(_ string, _ router.ConfigGetter) (router.Router, error) { return nil, nil })
defer router.Unregister("foo")
defer router.Unregister("bar")
token := userWithPermission(c, permission.Permission{
Expand Down
4 changes: 4 additions & 0 deletions api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ func setupServices() error {
if err != nil {
return err
}
servicemanager.RouterTemplate, err = router.TemplateService()
if err != nil {
return err
}
servicemanager.AppVersion, err = version.AppVersionService()
return err
}
Expand Down
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2250,7 +2250,7 @@ func (app *App) GetRoutersWithAddr() ([]appTypes.AppRouter, error) {
Value: addr,
})
routers[i].Address = addr
rType, _, _ := router.Type(routerName)
rType, _ := router.Type(routerName)
routers[i].Type = rType
}
return routers, multi.ToError()
Expand Down
2 changes: 2 additions & 0 deletions provision/docker/container/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/tsuru/tsuru/provision/docker/types"
"github.com/tsuru/tsuru/provision/dockercommon"
"github.com/tsuru/tsuru/router/routertest"
servicemock "github.com/tsuru/tsuru/servicemanager/mock"
check "gopkg.in/check.v1"
)

Expand Down Expand Up @@ -45,6 +46,7 @@ func (s *S) SetUpSuite(c *check.C) {
config.Set("docker:user", s.user)
config.Set("docker:repository-namespace", "tsuru")
config.Set("routers:fake:type", "fakeType")
servicemock.SetMockService(&servicemock.MockService{})
}

func (s *S) SetUpTest(c *check.C) {
Expand Down
2 changes: 1 addition & 1 deletion provision/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ type ProcessLabelsOpts struct {
func ProcessLabels(opts ProcessLabelsOpts) (*LabelSet, error) {
var routerNames, routerTypes []string
for _, appRouter := range opts.App.GetRouters() {
routerType, _, err := router.Type(appRouter.Name)
routerType, err := router.Type(appRouter.Name)
if err != nil {
return nil, errors.WithStack(err)
}
Expand Down
2 changes: 2 additions & 0 deletions provision/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/tsuru/config"
"github.com/tsuru/tsuru/db"
"github.com/tsuru/tsuru/db/dbtest"
servicemock "github.com/tsuru/tsuru/servicemanager/mock"
_ "github.com/tsuru/tsuru/storage/mongodb"
check "gopkg.in/check.v1"
)
Expand All @@ -22,6 +23,7 @@ func (s *S) SetUpSuite(c *check.C) {
var err error
s.storage, err = db.Conn()
c.Assert(err, check.IsNil)
servicemock.SetMockService(&servicemock.MockService{})
}

func (s *S) TearDownSuite(c *check.C) {
Expand Down
75 changes: 37 additions & 38 deletions redis/redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"time"

"github.com/pkg/errors"
"github.com/tsuru/config"
"github.com/tsuru/tsuru/log"
"github.com/tsuru/tsuru/router"
redis "gopkg.in/redis.v3"
)

Expand Down Expand Up @@ -145,14 +145,6 @@ func redisServer(addr string, redisConfig *CommonConfig) (Client, error) {
return &ClientWrapper{Client: client}, nil
}

func NewRedis(prefix string) (Client, error) {
return NewRedisDefaultConfig(prefix, &CommonConfig{
PoolSize: 1000,
PoolTimeout: time.Second,
IdleTimeout: 2 * time.Minute,
})
}

func createServerList(addrs string) []string {
parts := strings.Split(addrs, ",")
for i := range parts {
Expand All @@ -161,99 +153,106 @@ func createServerList(addrs string) []string {
return parts
}

func NewRedisDefaultConfig(prefix string, defaultConfig *CommonConfig) (client Client, err error) {
func NewRedisDefaultConfig(name string, config router.ConfigGetter, defaultConfig *CommonConfig) (client Client, err error) {
defer func() {
if client != nil {
collector.Add(prefix, client)
collector.Add(name, client)
}
}()
db, err := config.GetInt(prefix + ":redis-db")
if defaultConfig == nil {
defaultConfig = &CommonConfig{
PoolSize: 1000,
PoolTimeout: time.Second,
IdleTimeout: 2 * time.Minute,
}
}
db, err := config.GetInt("redis-db")
if err != nil && defaultConfig.TryLegacy {
db, err = config.GetInt(prefix + ":db")
db, err = config.GetInt("db")
}
if err == nil {
defaultConfig.DB = int64(db)
}
password, err := config.GetString(prefix + ":redis-password")
password, err := config.GetString("redis-password")
if err != nil && defaultConfig.TryLegacy {
password, err = config.GetString(prefix + ":password")
password, err = config.GetString("password")
}
if err == nil {
defaultConfig.Password = password
}
poolSize, err := config.GetInt(prefix + ":redis-pool-size")
poolSize, err := config.GetInt("redis-pool-size")
if err == nil {
defaultConfig.PoolSize = poolSize
}
maxRetries, err := config.GetInt(prefix + ":redis-max-retries")
maxRetries, err := config.GetInt("redis-max-retries")
if err == nil {
defaultConfig.MaxRetries = maxRetries
}
poolTimeout, err := config.GetFloat(prefix + ":redis-pool-timeout")
poolTimeout, err := config.GetFloat("redis-pool-timeout")
if err == nil {
defaultConfig.PoolTimeout = time.Duration(poolTimeout * float64(time.Second))
}
idleTimeout, err := config.GetFloat(prefix + ":redis-pool-idle-timeout")
idleTimeout, err := config.GetFloat("redis-pool-idle-timeout")
if err == nil {
defaultConfig.IdleTimeout = time.Duration(idleTimeout * float64(time.Second))
}
dialTimeout, err := config.GetFloat(prefix + ":redis-dial-timeout")
dialTimeout, err := config.GetFloat("redis-dial-timeout")
if err == nil {
defaultConfig.DialTimeout = time.Duration(dialTimeout * float64(time.Second))
}
readTimeout, err := config.GetFloat(prefix + ":redis-read-timeout")
readTimeout, err := config.GetFloat("redis-read-timeout")
if err == nil {
defaultConfig.ReadTimeout = time.Duration(readTimeout * float64(time.Second))
}
writeTimeout, err := config.GetFloat(prefix + ":redis-write-timeout")
writeTimeout, err := config.GetFloat("redis-write-timeout")
if err == nil {
defaultConfig.WriteTimeout = time.Duration(writeTimeout * float64(time.Second))
}
sentinels, err := config.GetString(prefix + ":redis-sentinel-addrs")
sentinels, err := config.GetString("redis-sentinel-addrs")
if err == nil {
masterName, _ := config.GetString(prefix + ":redis-sentinel-master")
masterName, _ := config.GetString("redis-sentinel-master")
if masterName == "" {
return nil, errors.Errorf("%s:redis-sentinel-master must be specified if using redis-sentinel", prefix)
return nil, errors.Errorf("%s:redis-sentinel-master must be specified if using redis-sentinel", name)
}
log.Debugf("Connecting to redis sentinel from %q config prefix. Addrs: %s. Master: %s. DB: %d.", prefix, sentinels, masterName, db)
log.Debugf("Connecting to redis sentinel from %q config prefix. Addrs: %s. Master: %s. DB: %d.", name, sentinels, masterName, db)
return newRedisSentinel(createServerList(sentinels), masterName, defaultConfig)
}
cluster, err := config.GetString(prefix + ":redis-cluster-addrs")
cluster, err := config.GetString("redis-cluster-addrs")
if err == nil {
if defaultConfig.DB != 0 {
return nil, errors.Errorf("could not initialize redis from %q config, using redis-cluster with db != 0 is not supported", prefix)
return nil, errors.Errorf("could not initialize redis from %q config, using redis-cluster with db != 0 is not supported", name)
}
if defaultConfig.MaxRetries != 0 {
return nil, errors.Errorf("could not initialize redis from %q config, using redis-cluster with max-retries > 0 is not supported", prefix)
return nil, errors.Errorf("could not initialize redis from %q config, using redis-cluster with max-retries > 0 is not supported", name)
}
log.Debugf("Connecting to redis cluster from %q config prefix. Addrs: %s. DB: %d.", prefix, cluster, db)
log.Debugf("Connecting to redis cluster from %q config prefix. Addrs: %s. DB: %d.", name, cluster, db)
return redisCluster(createServerList(cluster), defaultConfig)
}
server, err := config.GetString(prefix + ":redis-server")
server, err := config.GetString("redis-server")
if err == nil {
log.Debugf("Connecting to redis server from %q config prefix. Addr: %s. DB: %d.", prefix, server, db)
log.Debugf("Connecting to redis server from %q config prefix. Addr: %s. DB: %d.", name, server, db)
return redisServer(server, defaultConfig)
}
host, err := config.GetString(prefix + ":redis-host")
host, err := config.GetString("redis-host")
if err != nil && defaultConfig.TryLegacy {
host, err = config.GetString(prefix + ":host")
host, err = config.GetString("host")
}
if err == nil {
portStr := "6379"
port, err := config.Get(prefix + ":redis-port")
port, err := config.Get("redis-port")
if err != nil && defaultConfig.TryLegacy {
port, err = config.Get(prefix + ":port")
port, err = config.Get("port")
}
if err == nil {
portStr = fmt.Sprintf("%v", port)
}
addr := fmt.Sprintf("%s:%s", host, portStr)
log.Debugf("Connecting to redis host/port from %q config prefix. Addr: %s. DB: %d.", prefix, addr, db)
log.Debugf("Connecting to redis host/port from %q config prefix. Addr: %s. DB: %d.", name, addr, db)
return redisServer(addr, defaultConfig)
}
if defaultConfig.TryLocal {
addr := "localhost:6379"
log.Debugf("Connecting to redis on localhost from %q config prefix. Addr: %s. DB: %d.", prefix, addr, db)
log.Debugf("Connecting to redis on localhost from %q config prefix. Addr: %s. DB: %d.", name, addr, db)
return redisServer(addr, defaultConfig)
}
return nil, ErrNoRedisConfig
Expand Down
61 changes: 31 additions & 30 deletions redis/redis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/tsuru/config"
"github.com/tsuru/tsuru/router"
check "gopkg.in/check.v1"
redis "gopkg.in/redis.v3"
)
Expand Down Expand Up @@ -42,116 +43,116 @@ func (s *S) setConfig(key string, value interface{}) {

func (s *S) TestNewRedisSimpleServer(c *check.C) {
s.setConfig("redis-server", "localhost:6379")
r, err := NewRedis(s.prefix)
r, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.IsNil)
c.Assert(r, check.NotNil)
c.Assert(collector.clients[s.prefix], check.NotNil)
c.Assert(collector.clients["mine"], check.NotNil)
}

func (s *S) TestNewRedisSimpleServerUsePassword(c *check.C) {
s.setConfig("redis-server", "localhost:6379")
s.setConfig("redis-password", "invalid-password")
cli, err := NewRedis(s.prefix)
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "ERR Client sent AUTH, but no password is set")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisSimpleServerUseDB(c *check.C) {
s.setConfig("redis-server", "localhost:6379")
s.setConfig("redis-db", "0")
r, err := NewRedis(s.prefix)
r, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.IsNil)
err = r.Set("tsuru-test-key", "b", time.Minute).Err()
c.Assert(err, check.IsNil)
defer r.Del("tsuru-test-key")
s.setConfig("redis-db", "1")
r, err = NewRedis(s.prefix)
r, err = NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.IsNil)
err = r.Get("tsuru-test-key").Err()
c.Assert(err, check.Equals, redis.Nil)
c.Assert(collector.clients[s.prefix], check.NotNil)
c.Assert(collector.clients["mine"], check.NotNil)
}

func (s *S) TestNewRedisSentinel(c *check.C) {
s.setConfig("redis-sentinel-addrs", "127.0.0.1:6380,127.0.0.1:6381")
s.setConfig("redis-sentinel-master", "mymaster")
cli, err := NewRedis(s.prefix)
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "redis: all sentinels are unreachable")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisSentinelNoMaster(c *check.C) {
s.setConfig("redis-sentinel-addrs", "127.0.0.1:6380,127.0.0.1:6381")
cli, err := NewRedis(s.prefix)
c.Assert(err, check.ErrorMatches, "test-redis:redis-sentinel-master must be specified if using redis-sentinel")
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "mine:redis-sentinel-master must be specified if using redis-sentinel")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisCluster(c *check.C) {
s.setConfig("redis-cluster-addrs", "127.0.0.1:6380,127.0.0.1:6381")
cli, err := NewRedis(s.prefix)
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "dial tcp 127.0.0.1:\\d+:.*")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisClusterStripWhitespace(c *check.C) {
s.setConfig("redis-cluster-addrs", " 127.0.0.1:6380 , 127.0.0.1:6381")
cli, err := NewRedis(s.prefix)
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "dial tcp 127.0.0.1:\\d+:.*?")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisClusterWithMaxRetries(c *check.C) {
s.setConfig("redis-cluster-addrs", "127.0.0.1:6380,127.0.0.1:6381")
s.setConfig("redis-max-retries", 1)
cli, err := NewRedis(s.prefix)
c.Assert(err, check.ErrorMatches, "could not initialize redis from \"test-redis\" config, using redis-cluster with max-retries > 0 is not supported")
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "could not initialize redis from \"mine\" config, using redis-cluster with max-retries > 0 is not supported")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisClusterWithDB(c *check.C) {
s.setConfig("redis-cluster-addrs", "127.0.0.1:6380,127.0.0.1:6381")
s.setConfig("redis-db", 1)
cli, err := NewRedis(s.prefix)
c.Assert(err, check.ErrorMatches, "could not initialize redis from \"test-redis\" config, using redis-cluster with db != 0 is not supported")
cli, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.ErrorMatches, "could not initialize redis from \"mine\" config, using redis-cluster with db != 0 is not supported")
c.Assert(cli, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}

func (s *S) TestNewRedisHostPort(c *check.C) {
s.setConfig("redis-host", "localhost")
s.setConfig("redis-port", 6379)
r, err := NewRedis(s.prefix)
r, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.IsNil)
c.Assert(r, check.NotNil)
c.Assert(collector.clients[s.prefix], check.NotNil)
c.Assert(collector.clients["mine"], check.NotNil)
}

func (s *S) TestNewRedisHostPortLegacy(c *check.C) {
s.setConfig("host", "localhost")
s.setConfig("port", 6379)
r, err := NewRedisDefaultConfig(s.prefix, &CommonConfig{TryLegacy: true})
r, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, &CommonConfig{TryLegacy: true})
c.Assert(err, check.IsNil)
c.Assert(r, check.NotNil)
c.Assert(collector.clients[s.prefix], check.NotNil)
c.Assert(collector.clients["mine"], check.NotNil)
}

func (s *S) TestNewRedisTryLocal(c *check.C) {
r, err := NewRedisDefaultConfig(s.prefix, &CommonConfig{TryLocal: true})
r, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, &CommonConfig{TryLocal: true})
c.Assert(err, check.IsNil)
c.Assert(r, check.NotNil)
c.Assert(collector.clients[s.prefix], check.NotNil)
c.Assert(collector.clients["mine"], check.NotNil)
}

func (s *S) TestNewRedisNotConfigured(c *check.C) {
r, err := NewRedis(s.prefix)
r, err := NewRedisDefaultConfig("mine", &router.StaticConfigGetter{Prefix: s.prefix}, nil)
c.Assert(err, check.Equals, ErrNoRedisConfig)
c.Assert(r, check.IsNil)
c.Assert(collector.clients[s.prefix], check.IsNil)
c.Assert(collector.clients["mine"], check.IsNil)
}
Loading

0 comments on commit 0771f10

Please sign in to comment.