Allow config files to inherit from other config files
This commit is contained in:
parent
34867a2733
commit
f8aac8d4d7
101
config/prod.yml
101
config/prod.yml
|
@ -1,3 +1,7 @@
|
||||||
|
# Inherit config from this other config file
|
||||||
|
# so I only need to overwrite some values
|
||||||
|
inherit: 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
|
||||||
web_ui: false
|
web_ui: false
|
||||||
|
@ -76,104 +80,9 @@ database:
|
||||||
type: postgres
|
type: postgres
|
||||||
host: db
|
host: db
|
||||||
port: 5432
|
port: 5432
|
||||||
dbname: {{app_name_slug}}_development
|
dbname: app_production
|
||||||
user: postgres
|
user: postgres
|
||||||
password: ''
|
password: ''
|
||||||
#pool_size: 10
|
#pool_size: 10
|
||||||
#max_retries: 0
|
#max_retries: 0
|
||||||
#log_level: "debug"
|
#log_level: "debug"
|
||||||
|
|
||||||
# Define variables here that you want to use in filters
|
|
||||||
# sub-queries must be wrapped in ()
|
|
||||||
variables:
|
|
||||||
account_id: "(select account_id from users where id = $user_id)"
|
|
||||||
|
|
||||||
# Define defaults to for the field key and values below
|
|
||||||
defaults:
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
|
|
||||||
# Field and table names that you wish to block
|
|
||||||
blocklist:
|
|
||||||
- ar_internal_metadata
|
|
||||||
- schema_migrations
|
|
||||||
- secret
|
|
||||||
- password
|
|
||||||
- encrypted
|
|
||||||
- token
|
|
||||||
|
|
||||||
tables:
|
|
||||||
- name: customers
|
|
||||||
# remotes:
|
|
||||||
# - name: payments
|
|
||||||
# id: stripe_id
|
|
||||||
# url: http://rails_app:3000/stripe/$id
|
|
||||||
# path: data
|
|
||||||
# # pass_headers:
|
|
||||||
# # - cookie
|
|
||||||
# # - host
|
|
||||||
# set_headers:
|
|
||||||
# - name: Authorization
|
|
||||||
# value: Bearer <stripe_api_key>
|
|
||||||
|
|
||||||
- # You can create new fields that have a
|
|
||||||
# real db table backing them
|
|
||||||
name: me
|
|
||||||
table: users
|
|
||||||
|
|
||||||
roles_query: "SELECT * FROM users as usr WHERE id = $user_id"
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- name: anon
|
|
||||||
tables:
|
|
||||||
- name: products
|
|
||||||
limit: 10
|
|
||||||
|
|
||||||
query:
|
|
||||||
columns: ["id", "name", "description" ]
|
|
||||||
aggregation: false
|
|
||||||
|
|
||||||
insert:
|
|
||||||
block: false
|
|
||||||
|
|
||||||
update:
|
|
||||||
block: false
|
|
||||||
|
|
||||||
delete:
|
|
||||||
block: false
|
|
||||||
|
|
||||||
- name: user
|
|
||||||
tables:
|
|
||||||
- name: users
|
|
||||||
query:
|
|
||||||
filters: ["{ id: { _eq: $user_id } }"]
|
|
||||||
|
|
||||||
- name: products
|
|
||||||
query:
|
|
||||||
limit: 50
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
columns: ["id", "name", "description" ]
|
|
||||||
disable_functions: false
|
|
||||||
|
|
||||||
insert:
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
columns: ["id", "name", "description" ]
|
|
||||||
set:
|
|
||||||
- created_at: "now"
|
|
||||||
|
|
||||||
update:
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
columns:
|
|
||||||
- id
|
|
||||||
- name
|
|
||||||
set:
|
|
||||||
- updated_at: "now"
|
|
||||||
|
|
||||||
delete:
|
|
||||||
block: true
|
|
||||||
|
|
||||||
- name: admin
|
|
||||||
match: id = 1
|
|
||||||
tables:
|
|
||||||
- name: users
|
|
||||||
# query:
|
|
||||||
# filters: ["{ account_id: { _eq: $account_id } }"]
|
|
||||||
|
|
|
@ -1040,6 +1040,10 @@ Configuration files can either be in YAML or JSON their names are derived from t
|
||||||
We're tried to ensure that the config file is self documenting and easy to work with.
|
We're tried to ensure that the config file is self documenting and easy to work with.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# Inherit config from this other config file
|
||||||
|
# so I only need to overwrite some values
|
||||||
|
inherit: 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
|
||||||
web_ui: true
|
web_ui: true
|
||||||
|
|
16
serv/cmd.go
16
serv/cmd.go
|
@ -150,13 +150,25 @@ func initLog() *zerolog.Logger {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConf() (*config, error) {
|
func initConf() (*config, error) {
|
||||||
vi := newConfig()
|
vi := newConfig(getConfigName())
|
||||||
|
|
||||||
if err := vi.ReadInConfig(); err != nil {
|
if err := vi.ReadInConfig(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := &config{}
|
inherit := vi.GetString("inherit")
|
||||||
|
if len(inherit) != 0 {
|
||||||
|
vi = newConfig(inherit)
|
||||||
|
|
||||||
|
if err := vi.ReadInConfig(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vi.SetConfigName(getConfigName())
|
||||||
|
vi.MergeInConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &config{Viper: vi}
|
||||||
|
|
||||||
if err := vi.Unmarshal(c); err != nil {
|
if err := vi.Unmarshal(c); err != nil {
|
||||||
return nil, fmt.Errorf("unable to decode config, %v", err)
|
return nil, fmt.Errorf("unable to decode config, %v", err)
|
||||||
|
|
|
@ -15,13 +15,12 @@ func cmdConfDump(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
fname := fmt.Sprintf("%s.%s", getConfigName(), args[0])
|
fname := fmt.Sprintf("%s.%s", getConfigName(), args[0])
|
||||||
|
|
||||||
vi := newConfig()
|
conf, err := initConf()
|
||||||
|
if err != nil {
|
||||||
if err := vi.ReadInConfig(); err != nil {
|
logger.Fatal().Err(err).Msg("failed to read config")
|
||||||
logger.Fatal().Err(err).Send()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := vi.WriteConfigAs(fname); err != nil {
|
if err := conf.Viper.WriteConfigAs(fname); err != nil {
|
||||||
logger.Fatal().Err(err).Send()
|
logger.Fatal().Err(err).Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
|
*viper.Viper
|
||||||
|
|
||||||
AppName string `mapstructure:"app_name"`
|
AppName string `mapstructure:"app_name"`
|
||||||
Env string
|
Env string
|
||||||
HostPort string `mapstructure:"host_port"`
|
HostPort string `mapstructure:"host_port"`
|
||||||
|
@ -134,16 +136,16 @@ type configRole struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newConfig() *viper.Viper {
|
func newConfig(name string) *viper.Viper {
|
||||||
vi := viper.New()
|
vi := viper.New()
|
||||||
|
|
||||||
vi.SetEnvPrefix("SG")
|
vi.SetEnvPrefix("SG")
|
||||||
vi.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
vi.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
vi.AutomaticEnv()
|
vi.AutomaticEnv()
|
||||||
|
|
||||||
|
vi.SetConfigName(name)
|
||||||
vi.AddConfigPath(confPath)
|
vi.AddConfigPath(confPath)
|
||||||
vi.AddConfigPath("./config")
|
vi.AddConfigPath("./config")
|
||||||
vi.SetConfigName(getConfigName())
|
|
||||||
|
|
||||||
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)
|
||||||
|
|
10
serv/serv.go
10
serv/serv.go
|
@ -148,7 +148,15 @@ func startHTTP() {
|
||||||
db.Close()
|
db.Close()
|
||||||
})
|
})
|
||||||
|
|
||||||
fmt.Printf("%s listening on %s (%s)\n", serverName, hostPort, conf.Env)
|
var ident string
|
||||||
|
|
||||||
|
if len(conf.AppName) == 0 {
|
||||||
|
ident = conf.Env
|
||||||
|
} else {
|
||||||
|
ident = conf.AppName
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s listening on %s (%s)\n", serverName, hostPort, ident)
|
||||||
|
|
||||||
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
|
||||||
logger.Error().Err(err).Msg("server closed")
|
logger.Error().Err(err).Msg("server closed")
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
# Inherit config from this other config file
|
||||||
|
# so I only need to overwrite some values
|
||||||
|
inherit: 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
|
||||||
web_ui: false
|
web_ui: false
|
||||||
|
@ -82,98 +86,3 @@ database:
|
||||||
#pool_size: 10
|
#pool_size: 10
|
||||||
#max_retries: 0
|
#max_retries: 0
|
||||||
#log_level: "debug"
|
#log_level: "debug"
|
||||||
|
|
||||||
# Define variables here that you want to use in filters
|
|
||||||
# sub-queries must be wrapped in ()
|
|
||||||
variables:
|
|
||||||
account_id: "(select account_id from users where id = $user_id)"
|
|
||||||
|
|
||||||
# Define defaults to for the field key and values below
|
|
||||||
defaults:
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
|
|
||||||
# Field and table names that you wish to block
|
|
||||||
blocklist:
|
|
||||||
- ar_internal_metadata
|
|
||||||
- schema_migrations
|
|
||||||
- secret
|
|
||||||
- password
|
|
||||||
- encrypted
|
|
||||||
- token
|
|
||||||
|
|
||||||
tables:
|
|
||||||
- name: customers
|
|
||||||
# remotes:
|
|
||||||
# - name: payments
|
|
||||||
# id: stripe_id
|
|
||||||
# url: http://rails_app:3000/stripe/$id
|
|
||||||
# path: data
|
|
||||||
# # pass_headers:
|
|
||||||
# # - cookie
|
|
||||||
# # - host
|
|
||||||
# set_headers:
|
|
||||||
# - name: Authorization
|
|
||||||
# value: Bearer <stripe_api_key>
|
|
||||||
|
|
||||||
- # You can create new fields that have a
|
|
||||||
# real db table backing them
|
|
||||||
name: me
|
|
||||||
table: users
|
|
||||||
|
|
||||||
roles_query: "SELECT * FROM users as usr WHERE id = $user_id"
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- name: anon
|
|
||||||
tables:
|
|
||||||
- name: products
|
|
||||||
limit: 10
|
|
||||||
|
|
||||||
query:
|
|
||||||
columns: ["id", "name", "description" ]
|
|
||||||
aggregation: false
|
|
||||||
|
|
||||||
insert:
|
|
||||||
block: false
|
|
||||||
|
|
||||||
update:
|
|
||||||
block: false
|
|
||||||
|
|
||||||
delete:
|
|
||||||
block: false
|
|
||||||
|
|
||||||
- name: user
|
|
||||||
tables:
|
|
||||||
- name: users
|
|
||||||
query:
|
|
||||||
filters: ["{ id: { _eq: $user_id } }"]
|
|
||||||
|
|
||||||
- name: products
|
|
||||||
query:
|
|
||||||
limit: 50
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
columns: ["id", "name", "description" ]
|
|
||||||
disable_functions: false
|
|
||||||
|
|
||||||
insert:
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
columns: ["id", "name", "description" ]
|
|
||||||
set:
|
|
||||||
- created_at: "now"
|
|
||||||
|
|
||||||
update:
|
|
||||||
filters: ["{ user_id: { eq: $user_id } }"]
|
|
||||||
columns:
|
|
||||||
- id
|
|
||||||
- name
|
|
||||||
set:
|
|
||||||
- updated_at: "now"
|
|
||||||
|
|
||||||
delete:
|
|
||||||
deny: true
|
|
||||||
|
|
||||||
- name: admin
|
|
||||||
match: id = 1
|
|
||||||
tables:
|
|
||||||
- name: users
|
|
||||||
# query:
|
|
||||||
# filters: ["{ account_id: { _eq: $account_id } }"]
|
|
||||||
|
|
Loading…
Reference in New Issue