Change config key inherit to inherits

This commit is contained in:
Vikram Rangnekar 2019-10-31 01:14:51 -04:00
parent b87ba1fcd0
commit 0deb3596c5
6 changed files with 130 additions and 87 deletions

View File

@ -1,6 +1,6 @@
# Inherit config from this other config file # Inherit config from this other config file
# so I only need to overwrite some values # so I only need to overwrite some values
inherit: dev inherits: dev
app_name: "Super Graph Production" app_name: "Super Graph Production"
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080

View File

@ -1042,7 +1042,7 @@ We're tried to ensure that the config file is self documenting and easy to work
```yaml ```yaml
# Inherit config from this other config file # Inherit config from this other config file
# so I only need to overwrite some values # so I only need to overwrite some values
inherit: base inherits: base
app_name: "Super Graph Development" app_name: "Super Graph Development"
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080

View File

@ -8,7 +8,6 @@ import (
"github.com/dosco/super-graph/psql" "github.com/dosco/super-graph/psql"
"github.com/dosco/super-graph/qcode" "github.com/dosco/super-graph/qcode"
"github.com/gobuffalo/flect"
"github.com/jackc/pgx/v4" "github.com/jackc/pgx/v4"
"github.com/jackc/pgx/v4/pgxpool" "github.com/jackc/pgx/v4/pgxpool"
"github.com/rs/zerolog" "github.com/rs/zerolog"
@ -156,37 +155,30 @@ func initConf() (*config, error) {
return nil, err return nil, err
} }
inherit := vi.GetString("inherit") inherits := vi.GetString("inherits")
if len(inherit) != 0 { if len(inherits) != 0 {
vi = newConfig(inherit) vi = newConfig(inherits)
if err := vi.ReadInConfig(); err != nil { if err := vi.ReadInConfig(); err != nil {
return nil, err return nil, err
} }
if vi.IsSet("inherits") {
logger.Fatal().Msgf("inherited config (%s) cannot itself inherit (%s)",
inherits,
vi.GetString("inherits"))
}
vi.SetConfigName(getConfigName()) vi.SetConfigName(getConfigName())
vi.MergeInConfig() vi.MergeInConfig()
} }
c := &config{Viper: vi} c := &config{}
if err := vi.Unmarshal(c); err != nil { if err := c.Init(vi); err != nil {
return nil, fmt.Errorf("unable to decode config, %v", err) return nil, fmt.Errorf("unable to decode config, %v", err)
} }
if len(c.Tables) == 0 {
c.Tables = c.DB.Tables
}
for k, v := range c.Inflections {
flect.AddPlural(k, v)
}
for i := range c.Tables {
t := c.Tables[i]
t.Name = flect.Pluralize(strings.ToLower(t.Name))
}
authFailBlock = getAuthFailBlock(c) authFailBlock = getAuthFailBlock(c)
logLevel, err := zerolog.ParseLevel(c.LogLevel) logLevel, err := zerolog.ParseLevel(c.LogLevel)
@ -195,35 +187,6 @@ func initConf() (*config, error) {
} }
zerolog.SetGlobalLevel(logLevel) zerolog.SetGlobalLevel(logLevel)
for k, v := range c.DB.Vars {
c.DB.Vars[k] = sanitize(v)
}
c.RolesQuery = sanitize(c.RolesQuery)
rolesMap := make(map[string]struct{})
for i := range c.Roles {
role := &c.Roles[i]
if _, ok := rolesMap[role.Name]; ok {
logger.Fatal().Msgf("duplicate role '%s' found", role.Name)
}
role.Name = sanitize(role.Name)
role.Match = sanitize(role.Match)
rolesMap[role.Name] = struct{}{}
}
if _, ok := rolesMap["user"]; !ok {
c.Roles = append(c.Roles, configRole{Name: "user"})
}
if _, ok := rolesMap["anon"]; !ok {
c.Roles = append(c.Roles, configRole{Name: "anon"})
}
c.Validate()
return c, nil return c, nil
} }

View File

@ -1,10 +1,13 @@
package serv package serv
import ( import (
"fmt"
"os"
"regexp" "regexp"
"strings" "strings"
"unicode" "unicode"
"github.com/gobuffalo/flect"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -100,40 +103,42 @@ type configRemote struct {
} `mapstructure:"set_headers"` } `mapstructure:"set_headers"`
} }
type configRoleTable struct {
Name string
Query struct {
Limit int
Filters []string
Columns []string
DisableFunctions bool `mapstructure:"disable_functions"`
Block bool
}
Insert struct {
Filters []string
Columns []string
Presets map[string]string
Block bool
}
Update struct {
Filters []string
Columns []string
Presets map[string]string
Block bool
}
Delete struct {
Filters []string
Columns []string
Block bool
}
}
type configRole struct { type configRole struct {
Name string Name string
Match string Match string
Tables []struct { Tables []configRoleTable
Name string
Query struct {
Limit int
Filters []string
Columns []string
DisableFunctions bool `mapstructure:"disable_functions"`
Block bool
}
Insert struct {
Filters []string
Columns []string
Presets map[string]string
Block bool
}
Update struct {
Filters []string
Columns []string
Presets map[string]string
Block bool
}
Delete struct {
Filters []string
Columns []string
Block bool
}
}
} }
func newConfig(name string) *viper.Viper { func newConfig(name string) *viper.Viper {
@ -147,6 +152,10 @@ func newConfig(name string) *viper.Viper {
vi.AddConfigPath(confPath) vi.AddConfigPath(confPath)
vi.AddConfigPath("./config") vi.AddConfigPath("./config")
if dir, _ := os.Getwd(); strings.HasSuffix(dir, "/serv") {
vi.AddConfigPath("../config")
}
vi.SetDefault("host_port", "0.0.0.0:8080") vi.SetDefault("host_port", "0.0.0.0:8080")
vi.SetDefault("web_ui", false) vi.SetDefault("web_ui", false)
vi.SetDefault("enable_tracing", false) vi.SetDefault("enable_tracing", false)
@ -170,11 +179,69 @@ func newConfig(name string) *viper.Viper {
return vi return vi
} }
func (c *config) Validate() { func (c *config) Init(vi *viper.Viper) error {
if err := vi.Unmarshal(c); err != nil {
return fmt.Errorf("unable to decode config, %v", err)
}
c.Viper = vi
if len(c.Tables) == 0 {
c.Tables = c.DB.Tables
}
for k, v := range c.Inflections {
flect.AddPlural(k, v)
}
for i := range c.Tables {
t := c.Tables[i]
t.Name = flect.Pluralize(strings.ToLower(t.Name))
t.Table = flect.Pluralize(strings.ToLower(t.Table))
}
for i := range c.Roles {
r := c.Roles[i]
r.Name = strings.ToLower(r.Name)
}
for k, v := range c.DB.Vars {
c.DB.Vars[k] = sanitize(v)
}
c.RolesQuery = sanitize(c.RolesQuery)
rolesMap := make(map[string]struct{})
for i := range c.Roles {
role := &c.Roles[i]
if _, ok := rolesMap[role.Name]; ok {
logger.Fatal().Msgf("duplicate role '%s' found", role.Name)
}
role.Name = sanitize(role.Name)
role.Match = sanitize(role.Match)
rolesMap[role.Name] = struct{}{}
}
if _, ok := rolesMap["user"]; !ok {
c.Roles = append(c.Roles, configRole{Name: "user"})
}
if _, ok := rolesMap["anon"]; !ok {
c.Roles = append(c.Roles, configRole{Name: "anon"})
}
c.validate()
return nil
}
func (c *config) validate() {
rm := make(map[string]struct{}) rm := make(map[string]struct{})
for i := range c.Roles { for i := range c.Roles {
name := strings.ToLower(c.Roles[i].Name) name := c.Roles[i].Name
if _, ok := rm[name]; ok { if _, ok := rm[name]; ok {
logger.Fatal().Msgf("duplicate config for role '%s'", c.Roles[i].Name) logger.Fatal().Msgf("duplicate config for role '%s'", c.Roles[i].Name)
} }
@ -184,7 +251,8 @@ func (c *config) Validate() {
tm := make(map[string]struct{}) tm := make(map[string]struct{})
for i := range c.Tables { for i := range c.Tables {
name := strings.ToLower(c.Tables[i].Name) name := c.Tables[i].Name
if _, ok := tm[name]; ok { if _, ok := tm[name]; ok {
logger.Fatal().Msgf("duplicate config for table '%s'", c.Tables[i].Name) logger.Fatal().Msgf("duplicate config for table '%s'", c.Tables[i].Name)
} }
@ -206,8 +274,7 @@ func (c *config) getAliasMap() map[string][]string {
continue continue
} }
k := strings.ToLower(t.Table) m[t.Table] = append(m[t.Table], t.Name)
m[k] = append(m[k], strings.ToLower(t.Name))
} }
return m return m
} }

13
serv/config_test.go Normal file
View File

@ -0,0 +1,13 @@
package serv
import (
"testing"
)
func TestInitConf(t *testing.T) {
_, err := initConf()
if err != nil {
t.Fatal(err.Error())
}
}

View File

@ -1,6 +1,6 @@
# Inherit config from this other config file # Inherit config from this other config file
# so I only need to overwrite some values # so I only need to overwrite some values
inherit: dev inherits: dev
app_name: "{{app_name}} Production" app_name: "{{app_name}} Production"
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080