Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: permit to read config from yaml not from env #256

Merged
merged 1 commit into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions cmd/dagu.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ func loadGlobalConfig(c *cli.Context) (cfg *admin.Config, err error) {
cf := utils.StringWithFallback(c.String("config"), settings.MustGet(settings.SETTING__ADMIN_CONFIG))
cfg, err = l.LoadAdminConfig(cf)
if err == admin.ErrConfigNotFound {
cfg = admin.DefaultConfig()
err = nil
cfg, err = admin.DefaultConfig()
}
if err != nil {
return nil, fmt.Errorf("loading admin config failed: %w", err)
Expand Down
8 changes: 5 additions & 3 deletions cmd/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ func Test_serverCommand(t *testing.T) {
app := makeApp()
dir := utils.MustTempDir("dagu_test_server")
os.Setenv("HOME", dir)
settings.ChangeHomeDir(dir)

port := findPort(t)
os.Setenv(settings.SETTING__ADMIN_PORT, port)
settings.ChangeHomeDir(dir)
settings.Set(settings.SETTING__ADMIN_PORT, port)

done := make(chan struct{})
go func() {
Expand All @@ -34,7 +34,9 @@ func Test_serverCommand(t *testing.T) {

time.Sleep(time.Millisecond * 100)

cfg := admin.DefaultConfig()
cfg, err := admin.DefaultConfig()
require.NoError(t, err)

res, err := http.Post(
fmt.Sprintf("http://%s:%s/shutdown", cfg.Host, cfg.Port),
"application/json",
Expand Down
212 changes: 112 additions & 100 deletions internal/admin/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,46 +24,135 @@ type Config struct {
LogEncodingCharset string
LogDir string
BaseConfig string
NavbarColor string
NavbarTitle string
}

func (cfg *Config) Init() {
if cfg.Env == nil {
cfg.Env = []string{}
func newConfig() *Config {
return &Config{
Env: []string{},
}
}

func (cfg *Config) setup() {
cfg.Command = utils.StringWithFallback(cfg.Command, "dagu")
cfg.DAGs = utils.StringWithFallback(cfg.DAGs,
settings.MustGet(settings.SETTING__ADMIN_DAGS_DIR))
cfg.LogDir = utils.StringWithFallback(cfg.LogDir,
settings.MustGet(settings.SETTING__ADMIN_LOGS_DIR))
cfg.Host = utils.StringWithFallback(cfg.Host, "127.0.0.1")
cfg.Port = utils.StringWithFallback(cfg.Port,
settings.MustGet(settings.SETTING__ADMIN_PORT))
func DefaultConfig() (*Config, error) {
cfg := newConfig()
err := cfg.setup()
return cfg, err
}

func defaultConfig() *Config {
return &Config{
Command: "dagu",
DAGs: settings.MustGet(settings.SETTING__ADMIN_DAGS_DIR),
LogDir: settings.MustGet(settings.SETTING__ADMIN_LOGS_DIR),
Host: "127.0.0.1",
Port: settings.MustGet(settings.SETTING__ADMIN_PORT),
NavbarColor: settings.MustGet(settings.SETTING__ADMIN_NAVBAR_COLOR),
NavbarTitle: settings.MustGet(settings.SETTING__ADMIN_NAVBAR_TITLE),
}
}

func (cfg *Config) setup() error {
// TODO: refactor to avoid loading unnecessary configs
def := defaultConfig()
setDef := func(val *string, def string) {
*val = utils.StringWithFallback(*val, def)
}
setDef(&cfg.Command, def.Command)
setDef(&cfg.DAGs, def.DAGs)
setDef(&cfg.LogDir, def.LogDir)
setDef(&cfg.Host, def.Host)
setDef(&cfg.Port, def.Port)
setDef(&cfg.NavbarColor, def.NavbarColor)
setDef(&cfg.NavbarTitle, def.NavbarTitle)

if len(cfg.Env) == 0 {
env := utils.DefaultEnv()
env, err := loadVariables(env)
if err != nil {
panic(err)
return err
}
cfg.Env = buildConfigEnv(env)
}
return nil
}

func buildFromDefinition(def *configDefinition) (cfg *Config, err error) {
cfg = &Config{}
cfg.Init()
cfg = newConfig()

for _, fn := range []func(cfg *Config, def *configDefinition) error{
buildEnvs,
buildHostPort,
buildDAGsDir,
buildCommand,
buildWorkDir,
buildBasicAuthOpts,
buidEncodingOpts,
buildBaseConfig,
func(cfg *Config, def *configDefinition) error {
env, err := loadVariables(def.Env)
if err != nil {
return err
}
cfg.Env = buildConfigEnv(env)
return nil
},
func(cfg *Config, def *configDefinition) (err error) {
cfg.Host, err = utils.ParseVariable(def.Host)
if def.Port != 0 {
cfg.Port = strconv.Itoa(def.Port)
}
return err
},
func(cfg *Config, def *configDefinition) (err error) {
val, err := utils.ParseVariable(def.Dags)
if err == nil && len(val) > 0 {
if !filepath.IsAbs(val) {
return fmt.Errorf("DAGs directory should be absolute path. was %s", val)
}
cfg.DAGs, err = filepath.Abs(val)
if err != nil {
return fmt.Errorf("failed to resolve DAGs directory: %w", err)
}
}
return err
},
func(cfg *Config, def *configDefinition) (err error) {
cfg.Command, err = utils.ParseVariable(def.Command)
return err
},
func(cfg *Config, def *configDefinition) (err error) {
cfg.WorkDir, err = utils.ParseVariable(def.WorkDir)
if err == nil && strings.TrimSpace(cfg.WorkDir) == "" {
cfg.WorkDir, err = os.Getwd()
if err != nil {
return fmt.Errorf("failed to resolve working directory: %w", err)
}
}
return err
},
func(cfg *Config, def *configDefinition) (err error) {
cfg.BasicAuthUsername, err = utils.ParseVariable(def.BasicAuthUsername)
if err != nil {
return err
}
cfg.BasicAuthPassword, err = utils.ParseVariable(def.BasicAuthPassword)
if err != nil {
return err
}
return nil
},
func(cfg *Config, def *configDefinition) (err error) {
cfg.LogEncodingCharset, err = utils.ParseVariable(def.LogEncodingCharset)
return err
},
func(cfg *Config, def *configDefinition) (err error) {
cfg.BaseConfig, err = utils.ParseVariable(strings.TrimSpace(def.BaseConfig))
if err != nil {
return err
}
if cfg.BaseConfig == "" {
cfg.BaseConfig = settings.MustGet(settings.SETTING__BASE_CONFIG)
}
return nil
},
func(cfg *Config, def *configDefinition) error {
cfg.NavbarColor = def.NavbarColor
cfg.NavbarTitle = def.NavbarTitle
return nil
},
} {
if err := fn(cfg, def); err != nil {
return nil, err
Expand All @@ -76,83 +165,6 @@ func buildFromDefinition(def *configDefinition) (cfg *Config, err error) {
return cfg, nil
}

func buildEnvs(cfg *Config, def *configDefinition) error {
env, err := loadVariables(def.Env)
if err != nil {
return err
}
cfg.Env = buildConfigEnv(env)
return nil
}

func buildHostPort(cfg *Config, def *configDefinition) (err error) {
cfg.Host, err = utils.ParseVariable(def.Host)
if def.Port == 0 {
cfg.Port = settings.MustGet(settings.SETTING__ADMIN_PORT)
} else {
cfg.Port = strconv.Itoa(def.Port)
}
return err
}

func buildDAGsDir(cfg *Config, def *configDefinition) (err error) {
val, err := utils.ParseVariable(def.Dags)
if err == nil && len(val) > 0 {
if !filepath.IsAbs(val) {
return fmt.Errorf("DAGs directory should be absolute path. was %s", val)
}
cfg.DAGs, err = filepath.Abs(val)
if err != nil {
return fmt.Errorf("failed to resolve DAGs directory: %w", err)
}
}
return err
}

func buildBaseConfig(cfg *Config, def *configDefinition) (err error) {
cfg.BaseConfig, err = utils.ParseVariable(strings.TrimSpace(def.BaseConfig))
if err != nil {
return err
}
if cfg.BaseConfig == "" {
cfg.BaseConfig = settings.MustGet(settings.SETTING__BASE_CONFIG)
}
return nil
}

func buildCommand(cfg *Config, def *configDefinition) (err error) {
cfg.Command, err = utils.ParseVariable(def.Command)
return err
}

func buildWorkDir(cfg *Config, def *configDefinition) (err error) {
cfg.WorkDir, err = utils.ParseVariable(def.WorkDir)
if err == nil && strings.TrimSpace(cfg.WorkDir) == "" {
cfg.WorkDir, err = os.Getwd()
if err != nil {
return fmt.Errorf("failed to resolve working directory: %w", err)
}
}
return err
}

func buildBasicAuthOpts(cfg *Config, def *configDefinition) (err error) {
cfg.BasicAuthUsername, err = utils.ParseVariable(def.BasicAuthUsername)
if err != nil {
return err
}
cfg.BasicAuthPassword, err = utils.ParseVariable(def.BasicAuthPassword)
if err != nil {
return err
}
return nil
}

func buidEncodingOpts(cfg *Config, def *configDefinition) (err error) {
cfg.LogEncodingCharset, err = utils.ParseVariable(def.LogEncodingCharset)
return err
}

func buildConfigEnv(vars map[string]string) []string {
ret := []string{}
for k, v := range vars {
Expand Down
8 changes: 7 additions & 1 deletion internal/admin/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ basicAuthPassword: password
logEncodingCharset: utf-8
logDir: /var/log/dagu
baseConfig: /dagu/config.yaml
navbarColor: red
navbarTitle: Dagu test
`

func TestLoadConfig(t *testing.T) {
Expand All @@ -42,6 +44,8 @@ func TestLoadConfig(t *testing.T) {
Env: []string{},
LogDir: "/var/log/dagu",
BaseConfig: "/dagu/config.yaml",
NavbarColor: "red",
NavbarTitle: "Dagu test",
},
},
{
Expand All @@ -59,7 +63,9 @@ func TestLoadConfig(t *testing.T) {
Env: []string{},
LogDir: settings.MustGet(
settings.SETTING__ADMIN_LOGS_DIR),
BaseConfig: settings.MustGet(settings.SETTING__BASE_CONFIG),
BaseConfig: settings.MustGet(settings.SETTING__BASE_CONFIG),
NavbarColor: "",
NavbarTitle: "Dagu",
},
},
} {
Expand Down
2 changes: 2 additions & 0 deletions internal/admin/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ type configDefinition struct {
BasicAuthUsername string
BasicAuthPassword string
LogEncodingCharset string
NavbarColor string
NavbarTitle string
}
4 changes: 2 additions & 2 deletions internal/admin/handlers/dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ type DAGHandlerConfig struct {
LogEncodingCharset string
}

func HandleGetDAG(hc *DAGHandlerConfig) http.HandlerFunc {
renderFunc := useTemplate("index.gohtml", "dag")
func HandleGetDAG(hc *DAGHandlerConfig, tc *TemplateConfig) http.HandlerFunc {
renderFunc := useTemplate("index.gohtml", "dag", tc)

return func(w http.ResponseWriter, r *http.Request) {
dn, err := getPathParameter(r)
Expand Down
48 changes: 26 additions & 22 deletions internal/admin/handlers/html.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,41 @@ import (
"text/template"

"github.com/yohamta/dagu/internal/constants"
"github.com/yohamta/dagu/internal/settings"
)

var defaultFuncs = template.FuncMap{
"defTitle": func(ip interface{}) string {
v, ok := ip.(string)
if !ok || (ok && v == "") {
return ""
}
return v
},
"version": func() string {
return constants.Version
},
"navbarColor": func() string {
c, _ := settings.Get(settings.SETTING__ADMIN_NAVBAR_COLOR)
return c
},
"navbarTitle": func() string {
val, _ := settings.Get(settings.SETTING__ADMIN_NAVBAR_TITLE)
return val
},
type TemplateConfig struct {
NavbarColor string
NavbarTitle string
}

func defaultFuncs(tc *TemplateConfig) template.FuncMap {
return template.FuncMap{
"defTitle": func(ip interface{}) string {
v, ok := ip.(string)
if !ok || (ok && v == "") {
return ""
}
return v
},
"version": func() string {
return constants.Version
},
"navbarColor": func() string {
return tc.NavbarColor
},
"navbarTitle": func() string {
return tc.NavbarTitle
},
}
}

//go:embed web/templates/* web/assets/*
var assets embed.FS
var templatePath = "web/templates/"

func useTemplate(layout string, name string) func(http.ResponseWriter, interface{}) {
func useTemplate(layout string, name string, tc *TemplateConfig) func(http.ResponseWriter, interface{}) {
files := append(baseTemplates(), path.Join(templatePath, layout))
tmpl, err := template.New(name).Funcs(defaultFuncs).ParseFS(assets, files...)
tmpl, err := template.New(name).Funcs(defaultFuncs(tc)).ParseFS(assets, files...)
if err != nil {
panic(err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/admin/handlers/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ type DAGListHandlerConfig struct {
DAGsDir string
}

func HandleGetList(hc *DAGListHandlerConfig) http.HandlerFunc {
renderFunc := useTemplate("index.gohtml", "index")
func HandleGetList(hc *DAGListHandlerConfig, tc *TemplateConfig) http.HandlerFunc {
renderFunc := useTemplate("index.gohtml", "index", tc)
return func(w http.ResponseWriter, r *http.Request) {
dir := filepath.Join(hc.DAGsDir)
dags, errs, err := controller.GetDAGs(dir)
Expand Down
Loading