allow to work with multiple configs
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
@@ -1,21 +1,22 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/google/uuid"
|
||||
yamlcodec "go.unistack.org/micro-codec-yaml/v3"
|
||||
mtime "go.unistack.org/micro/v3/util/time"
|
||||
)
|
||||
|
||||
type AppConfig struct {
|
||||
ChecksDir string `json:"checks_dir,omitempty" yaml:"checks_dir,omitempty"`
|
||||
Checks []*CheckConfig `json:"checks,omitempty" yaml:"checks,omitempty"`
|
||||
MultiUser bool `json:"multi_user,omitempty" yaml:"multi_user,omitempty"`
|
||||
}
|
||||
var Filesytem fs.FS
|
||||
|
||||
type MeterConfig struct {
|
||||
Addr string `json:"addr,omitempty" yaml:"addr,omitempty"`
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
func init() {
|
||||
dir, _ := os.Getwd()
|
||||
Filesytem = os.DirFS(dir)
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
@@ -23,13 +24,25 @@ type Config struct {
|
||||
Meter *MeterConfig `json:"meter,omitempty" yaml:"meter,omitempty"`
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
ChecksFiles []string `json:"checks_files,omitempty" yaml:"checks_files,omitempty"`
|
||||
Checks []*CheckConfig `json:"checks,omitempty" yaml:"checks,omitempty"`
|
||||
MultiUser bool `json:"multi_user,omitempty" yaml:"multi_user,omitempty"`
|
||||
}
|
||||
|
||||
type MeterConfig struct {
|
||||
Addr string `json:"addr,omitempty" yaml:"addr,omitempty"`
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
}
|
||||
|
||||
type CheckConfig struct {
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
Tasks []*TaskConfig `json:"tasks,omitempty" yaml:"tasks,omitempty"`
|
||||
Timeout mtime.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"`
|
||||
Interval mtime.Duration `json:"interval,omitempty" yaml:"interval,omitempty"`
|
||||
Active bool `json:"active,omitempty" yaml:"active,omitempty"`
|
||||
User string `json:"user,omitempty" yaml:"user,omitempty"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
User string `json:"user,omitempty" yaml:"user,omitempty"`
|
||||
Tasks []*TaskConfig `json:"tasks,omitempty" yaml:"tasks,omitempty"`
|
||||
TasksFiles []string `json:"tasks_files,omitempty" yaml:"tasks_files,omitempty"`
|
||||
Timeout mtime.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"`
|
||||
Interval mtime.Duration `json:"interval,omitempty" yaml:"interval,omitempty"`
|
||||
Active bool `json:"active,omitempty" yaml:"active,omitempty"`
|
||||
}
|
||||
|
||||
type HTTPConfig struct {
|
||||
@@ -66,11 +79,84 @@ type TaskConfig struct {
|
||||
Active bool `json:"active,omitempty" yaml:"active,omitempty"`
|
||||
}
|
||||
|
||||
func Parse(r io.Reader, cfg interface{}) error {
|
||||
buf, err := io.ReadAll(r)
|
||||
func Load(fileSystem fs.FS, name string, cfg *Config) error {
|
||||
if err := load(fileSystem, name, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, checksPatternFile := range cfg.App.ChecksFiles {
|
||||
checkRoot := filepath.Dir(checksPatternFile)
|
||||
checksFiles := fsWalkDir(fileSystem, checkRoot, checksPatternFile)
|
||||
for _, checkFile := range checksFiles {
|
||||
checks := []*CheckConfig{}
|
||||
if err := load(fileSystem, checkFile, &checks); err != nil {
|
||||
return err
|
||||
}
|
||||
for ckecksIdx := range checks {
|
||||
for _, tasksPatternFile := range checks[ckecksIdx].TasksFiles {
|
||||
taskRoot := filepath.Join(filepath.Dir(checksPatternFile), filepath.Dir(tasksPatternFile))
|
||||
tasksFiles := fsWalkDir(fileSystem, taskRoot, filepath.Join(filepath.Dir(checksPatternFile), tasksPatternFile))
|
||||
for tasksIdx := range tasksFiles {
|
||||
tasks := []*TaskConfig{}
|
||||
if err := load(fileSystem, tasksFiles[tasksIdx], &tasks); err != nil {
|
||||
return err
|
||||
}
|
||||
checks[ckecksIdx].Tasks = append(checks[ckecksIdx].Tasks, tasks...)
|
||||
}
|
||||
}
|
||||
cfg.App.Checks = append(cfg.App.Checks, checks[ckecksIdx])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !cfg.App.MultiUser {
|
||||
for _, check := range cfg.App.Checks {
|
||||
check.User = uuid.Nil.String()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fsWalkDir(fileSystem fs.FS, root string, pattern string) []string {
|
||||
var files []string
|
||||
fs.WalkDir(fileSystem, root, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if d.IsDir() || !d.Type().IsRegular() {
|
||||
return nil
|
||||
}
|
||||
var ok bool
|
||||
if ok, err = filepath.Match(pattern, path); err == nil && ok {
|
||||
files = append(files, path)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return files
|
||||
}
|
||||
|
||||
func load(fileSystem fs.FS, name string, cfg interface{}) error {
|
||||
f, err := fileSystem.Open(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return yamlcodec.NewCodec().Unmarshal(buf, cfg)
|
||||
c := yamlcodec.NewCodec()
|
||||
var buf []byte
|
||||
|
||||
if buf, err = io.ReadAll(f); err == nil {
|
||||
if err = f.Close(); err == nil {
|
||||
err = c.Unmarshal(buf, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load config %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user