dragonfly/manager/config/config.go

330 lines
7.8 KiB
Go

/*
* Copyright 2020 The Dragonfly Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package config
import (
"crypto/tls"
"errors"
"time"
"github.com/docker/go-connections/tlsconfig"
"d7y.io/dragonfly/v2/cmd/dependency/base"
)
type Config struct {
// Base options
base.Options `yaml:",inline" mapstructure:",squash"`
// Server configuration
Server *ServerConfig `yaml:"server" mapstructure:"server"`
// Database configuration
Database *DatabaseConfig `yaml:"database" mapstructure:"database"`
// Cache configuration
Cache *CacheConfig `yaml:"cache" mapstructure:"cache"`
// Metrics configuration
Metrics *RestConfig `yaml:"metrics" mapstructure:"metrics"`
}
type ServerConfig struct {
// Server name
Name string `yaml:"name" mapstructure:"name"`
// Server log directory
LogDir string `yaml:"logDir" mapstructure:"logDir"`
// Console resource path
PublicPath string `yaml:"publicPath" mapstructure:"publicPath"`
// GRPC server configuration
GRPC *TCPListenConfig `yaml:"grpc" mapstructure:"grpc"`
// REST server configuration
REST *RestConfig `yaml:"rest" mapstructure:"rest"`
}
type DatabaseConfig struct {
// Mysql configuration
Mysql *MysqlConfig `yaml:"mysql" mapstructure:"mysql"`
// Redis configuration
Redis *RedisConfig `yaml:"redis" mapstructure:"redis"`
}
type MysqlConfig struct {
// Server username
User string `yaml:"user" mapstructure:"user"`
// Server password
Password string `yaml:"password" mapstructure:"password"`
// Server host
Host string `yaml:"host" mapstructure:"host"`
// Server port
Port int `yaml:"port" mapstructure:"port"`
// Server DB name
DBName string `yaml:"dbname" mapstructure:"dbname"`
// Enable migration
Migrate bool `yaml:"migrate" mapstructure:"migrate"`
// TLS configuration
TLS *TLSConfig `yaml:"tls" mapstructure:"tls"`
}
type TLSConfig struct {
// Client certificate file path
Cert string `yaml:"cert" mapstructure:"cert"`
// Client key file path
Key string `yaml:"key" mapstructure:"key"`
// CA file path
CA string `yaml:"ca" mapstructure:"ca"`
// InsecureSkipVerify controls whether a client verifies the
// server's certificate chain and host name.
InsecureSkipVerify bool `yaml:"insecureSkipVerify" mapstructure:"insecureSkipVerify"`
}
// Generate client tls config
func (t *TLSConfig) Client() (*tls.Config, error) {
return tlsconfig.Client(tlsconfig.Options{
CAFile: t.CA,
CertFile: t.Cert,
KeyFile: t.Key,
InsecureSkipVerify: t.InsecureSkipVerify,
})
}
type RedisConfig struct {
// Server host
Host string `yaml:"host" mapstructure:"host"`
// Server port
Port int `yaml:"port" mapstructure:"port"`
// Server password
Password string `yaml:"password" mapstructure:"password"`
// Server cache DB name
CacheDB int `yaml:"cacheDB" mapstructure:"cacheDB"`
// Server broker DB name
BrokerDB int `yaml:"brokerDB" mapstructure:"brokerDB"`
// Server backend DB name
BackendDB int `yaml:"backendDB" mapstructure:"backendDB"`
}
type CacheConfig struct {
// Redis cache configuration
Redis *RedisCacheConfig `yaml:"redis" mapstructure:"redis"`
// Local cache configuration
Local *LocalCacheConfig `yaml:"local" mapstructure:"local"`
}
type RedisCacheConfig struct {
// Cache TTL
TTL time.Duration `yaml:"ttl" mapstructure:"ttl"`
}
type LocalCacheConfig struct {
// Size of LFU cache
Size int `yaml:"size" mapstructure:"size"`
// Cache TTL
TTL time.Duration `yaml:"ttl" mapstructure:"ttl"`
}
type RestConfig struct {
// REST server address
Addr string `yaml:"addr" mapstructure:"addr"`
}
type TCPListenConfig struct {
// Listen stands listen interface, like: 0.0.0.0, 192.168.0.1
Listen string `mapstructure:"listen" yaml:"listen"`
// PortRange stands listen port
PortRange TCPListenPortRange `yaml:"port" mapstructure:"port"`
}
type TCPListenPortRange struct {
Start int
End int
}
// New config instance
func New() *Config {
return &Config{
Server: &ServerConfig{
Name: "d7y/manager",
PublicPath: "manager/console/dist",
GRPC: &TCPListenConfig{
PortRange: TCPListenPortRange{
Start: 65003,
End: 65003,
},
},
REST: &RestConfig{
Addr: ":8080",
},
},
Database: &DatabaseConfig{
Redis: &RedisConfig{
CacheDB: 0,
BrokerDB: 1,
BackendDB: 2,
},
Mysql: &MysqlConfig{
Migrate: true,
},
},
Cache: &CacheConfig{
Redis: &RedisCacheConfig{
TTL: 30 * time.Second,
},
Local: &LocalCacheConfig{
Size: 10000,
TTL: 30 * time.Second,
},
},
}
}
// Validate config values
func (cfg *Config) Validate() error {
if cfg.Server == nil {
return errors.New("empty server config is not specified")
}
if cfg.Server.Name == "" {
return errors.New("empty server name config is not specified")
}
if cfg.Server.GRPC == nil {
return errors.New("empty grpc server config is not specified")
}
if cfg.Server.REST == nil {
return errors.New("empty rest server config is not specified")
}
if cfg.Database == nil {
return errors.New("empty database config is not specified")
}
if cfg.Database.Redis == nil {
return errors.New("empty database redis config is not specified")
}
if cfg.Database.Redis.Host == "" {
return errors.New("empty database redis host is not specified")
}
if cfg.Database.Redis.Port <= 0 {
return errors.New("empty database redis port is not specified")
}
if cfg.Database.Redis.CacheDB < 0 {
return errors.New("empty database redis cacheDB is not specified")
}
if cfg.Database.Redis.BrokerDB < 0 {
return errors.New("empty database redis brokerDB is not specified")
}
if cfg.Database.Redis.BackendDB < 0 {
return errors.New("empty database redis backendDB is not specified")
}
if cfg.Database.Mysql == nil {
return errors.New("empty database mysql config is not specified")
}
if cfg.Database.Mysql.User == "" {
return errors.New("empty database mysql user is not specified")
}
if cfg.Database.Mysql.Password == "" {
return errors.New("empty database mysql password is not specified")
}
if cfg.Database.Mysql.Host == "" {
return errors.New("empty database mysql host is not specified")
}
if cfg.Database.Mysql.Port <= 0 {
return errors.New("empty database mysql port is not specified")
}
if cfg.Database.Mysql.DBName == "" {
return errors.New("empty database mysql dbName is not specified")
}
if cfg.Database.Mysql.TLS != nil {
if cfg.Database.Mysql.TLS.Cert == "" {
return errors.New("empty database mysql tls cert is not specified")
}
if cfg.Database.Mysql.TLS.Key == "" {
return errors.New("empty database mysql tls key is not specified")
}
if cfg.Database.Mysql.TLS.CA == "" {
return errors.New("empty database mysql tls ca is not specified")
}
}
if cfg.Cache == nil {
return errors.New("empty cache config is not specified")
}
if cfg.Cache.Redis == nil {
return errors.New("empty cache redis config is not specified")
}
if cfg.Cache.Redis.TTL == 0 {
return errors.New("empty cache redis TTL is not specified")
}
if cfg.Cache.Local == nil {
return errors.New("empty cache local config is not specified")
}
if cfg.Cache.Local.Size == 0 {
return errors.New("empty cache local size is not specified")
}
if cfg.Cache.Local.TTL == 0 {
return errors.New("empty cache local TTL is not specified")
}
if cfg.Metrics != nil && cfg.Metrics.Addr == "" {
return errors.New("empty metrics addr is not specified")
}
return nil
}