From 97ca1f277dc8b6973d6fa67add5593a9c395ce60 Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Mon, 25 Sep 2017 14:15:16 +0200 Subject: Added webapp Dashboard + logic to interact with server. Signed-off-by: Sebastien Douheret --- lib/xdsconfig/config.go | 78 +++++++++++++++++++++++------- lib/xdsconfig/configfile.go | 112 ++++++++++++++++++++++++++++++++++++++++++++ lib/xdsconfig/fileconfig.go | 111 ------------------------------------------- 3 files changed, 173 insertions(+), 128 deletions(-) create mode 100644 lib/xdsconfig/configfile.go delete mode 100644 lib/xdsconfig/fileconfig.go (limited to 'lib/xdsconfig') diff --git a/lib/xdsconfig/config.go b/lib/xdsconfig/config.go index 854d383..9cff862 100644 --- a/lib/xdsconfig/config.go +++ b/lib/xdsconfig/config.go @@ -2,6 +2,8 @@ package xdsconfig import ( "fmt" + "io" + "path/filepath" "os" @@ -12,14 +14,20 @@ import ( // Config parameters (json format) of /config command type Config struct { - Version string `json:"version"` - APIVersion string `json:"apiVersion"` - VersionGitTag string `json:"gitTag"` + Version string + APIVersion string + VersionGitTag string + Options Options + FileConf FileConfig + Log *logrus.Logger + LogVerboseOut io.Writer +} - // Private / un-exported fields - HTTPPort string `json:"-"` - FileConf *FileConfig `json:"-"` - Log *logrus.Logger `json:"-"` +// Options set at the command line +type Options struct { + ConfigFile string + LogLevel string + LogFile string } // Config default values @@ -32,39 +40,75 @@ const ( func Init(ctx *cli.Context, log *logrus.Logger) (*Config, error) { var err error + defaultWebAppDir := "${EXEPATH}/www" + defaultSTHomeDir := "${HOME}/.xds/agent/syncthing-config" + // Define default configuration c := Config{ Version: ctx.App.Metadata["version"].(string), APIVersion: DefaultAPIVersion, VersionGitTag: ctx.App.Metadata["git-tag"].(string), - HTTPPort: "8010", - FileConf: &FileConfig{ - LogsDir: "/tmp/logs", + Options: Options{ + ConfigFile: ctx.GlobalString("config"), + LogLevel: ctx.GlobalString("log"), + LogFile: ctx.GlobalString("logfile"), + }, + + FileConf: FileConfig{ + HTTPPort: "8800", + WebAppDir: defaultWebAppDir, + LogsDir: "/tmp/logs", + // SEB XDSAPIKey: "1234abcezam", + ServersConf: []XDSServerConf{ + XDSServerConf{ + URL: "http://localhost:8000", + ConnRetry: 10, + }, + }, SThgConf: &SyncThingConf{ - Home: "${HOME}/.xds/agent/syncthing-config", + Home: defaultSTHomeDir, }, }, Log: log, } // config file settings overwrite default config - c.FileConf, err = updateConfigFromFile(&c, ctx.GlobalString("config")) + err = readGlobalConfig(&c, c.Options.ConfigFile) if err != nil { return nil, err } + // Handle where Logs are redirected: + // default 'stdout' (logfile option default value) + // else use file (or filepath) set by --logfile option + // that may be overwritten by LogsDir field of config file + logF := c.Options.LogFile + logD := c.FileConf.LogsDir + if logF != "stdout" { + if logD != "" { + lf := filepath.Base(logF) + if lf == "" || lf == "." { + lf = "xds-agent.log" + } + logF = filepath.Join(logD, lf) + } else { + logD = filepath.Dir(logF) + } + } + if logD == "" || logD == "." { + logD = "/tmp/xds/logs" + } + c.Options.LogFile = logF + c.FileConf.LogsDir = logD + if c.FileConf.LogsDir != "" && !common.Exists(c.FileConf.LogsDir) { if err := os.MkdirAll(c.FileConf.LogsDir, 0770); err != nil { return nil, fmt.Errorf("Cannot create logs dir: %v", err) } } + c.Log.Infoln("Logs file: ", c.Options.LogFile) c.Log.Infoln("Logs directory: ", c.FileConf.LogsDir) return &c, nil } - -// UpdateAll Update the current configuration -func (c *Config) UpdateAll(newCfg Config) error { - return fmt.Errorf("Not Supported") -} diff --git a/lib/xdsconfig/configfile.go b/lib/xdsconfig/configfile.go new file mode 100644 index 0000000..a47038b --- /dev/null +++ b/lib/xdsconfig/configfile.go @@ -0,0 +1,112 @@ +package xdsconfig + +import ( + "encoding/json" + "os" + "path" + + common "github.com/iotbzh/xds-common/golib" +) + +type SyncThingConf struct { + BinDir string `json:"binDir"` + Home string `json:"home"` + GuiAddress string `json:"gui-address"` + GuiAPIKey string `json:"gui-apikey"` +} + +type XDSServerConf struct { + URL string `json:"url"` + ConnRetry int `json:"connRetry"` + + // private/not exported fields + ID string `json:"-"` + APIBaseURL string `json:"-"` + APIPartialURL string `json:"-"` +} + +type FileConfig struct { + HTTPPort string `json:"httpPort"` + WebAppDir string `json:"webAppDir"` + LogsDir string `json:"logsDir"` + // SEB A SUP ? XDSAPIKey string `json:"xds-apikey"` + ServersConf []XDSServerConf `json:"xdsServers"` + SThgConf *SyncThingConf `json:"syncthing"` +} + +// readGlobalConfig reads configuration from a config file. +// Order to determine which config file is used: +// 1/ from command line option: "--config myConfig.json" +// 2/ $HOME/.xds/agent/agent-config.json file +// 3/ /agent-config.json file +// 4/ /agent-config.json file + +func readGlobalConfig(c *Config, confFile string) error { + + searchIn := make([]string, 0, 3) + if confFile != "" { + searchIn = append(searchIn, confFile) + } + if homeDir := common.GetUserHome(); homeDir != "" { + searchIn = append(searchIn, path.Join(homeDir, ".xds", "agent", "agent-config.json")) + } + + searchIn = append(searchIn, "/etc/xds-agent/agent-config.json") + + searchIn = append(searchIn, path.Join(common.GetExePath(), "agent-config.json")) + + var cFile *string + for _, p := range searchIn { + if _, err := os.Stat(p); err == nil { + cFile = &p + break + } + } + if cFile == nil { + c.Log.Infof("No config file found") + return nil + } + + c.Log.Infof("Use config file: %s", *cFile) + + // TODO move on viper package to support comments in JSON and also + // bind with flags (command line options) + // see https://github.com/spf13/viper#working-with-flags + + fd, _ := os.Open(*cFile) + defer fd.Close() + + // Decode config file content and save it in a first variable + fCfg := FileConfig{} + if err := json.NewDecoder(fd).Decode(&fCfg); err != nil { + return err + } + + // Decode config file content and overwrite default settings + fd.Seek(0, 0) + json.NewDecoder(fd).Decode(&c.FileConf) + + // Disable Syncthing support when there is no syncthing field in config + if fCfg.SThgConf == nil { + c.FileConf.SThgConf = nil + } + + // Support environment variables (IOW ${MY_ENV_VAR} syntax) in agent-config.json + vars := []*string{ + &c.FileConf.LogsDir, + &c.FileConf.WebAppDir, + } + if c.FileConf.SThgConf != nil { + vars = append(vars, &c.FileConf.SThgConf.Home, + &c.FileConf.SThgConf.BinDir) + } + for _, field := range vars { + var err error + *field, err = common.ResolveEnvVar(*field) + if err != nil { + return err + } + } + + return nil +} diff --git a/lib/xdsconfig/fileconfig.go b/lib/xdsconfig/fileconfig.go deleted file mode 100644 index efe94bf..0000000 --- a/lib/xdsconfig/fileconfig.go +++ /dev/null @@ -1,111 +0,0 @@ -package xdsconfig - -import ( - "encoding/json" - "os" - "os/user" - "path" - "path/filepath" - - common "github.com/iotbzh/xds-common/golib" -) - -type SyncThingConf struct { - BinDir string `json:"binDir"` - Home string `json:"home"` - GuiAddress string `json:"gui-address"` - GuiAPIKey string `json:"gui-apikey"` -} - -type FileConfig struct { - HTTPPort string `json:"httpPort"` - LogsDir string `json:"logsDir"` - XDSAPIKey string `json:"xds-apikey"` - SThgConf *SyncThingConf `json:"syncthing"` -} - -// getConfigFromFile reads configuration from a config file. -// Order to determine which config file is used: -// 1/ from command line option: "--config myConfig.json" -// 2/ $HOME/.xds/agent/agent-config.json file -// 3/ /agent-config.json file -// 4/ /agent-config.json file - -func updateConfigFromFile(c *Config, confFile string) (*FileConfig, error) { - - searchIn := make([]string, 0, 3) - if confFile != "" { - searchIn = append(searchIn, confFile) - } - if usr, err := user.Current(); err == nil { - searchIn = append(searchIn, path.Join(usr.HomeDir, ".xds", "agent", "agent-config.json")) - } - - searchIn = append(searchIn, "/etc/xds-agent/agent-config.json") - - exePath := os.Args[0] - ee, _ := os.Executable() - exeAbsPath, err := filepath.Abs(ee) - if err == nil { - exePath, err = filepath.EvalSymlinks(exeAbsPath) - if err == nil { - exePath = filepath.Dir(ee) - } else { - exePath = filepath.Dir(exeAbsPath) - } - } - searchIn = append(searchIn, path.Join(exePath, "agent-config.json")) - - var cFile *string - for _, p := range searchIn { - if _, err := os.Stat(p); err == nil { - cFile = &p - break - } - } - // Use default settings - fCfg := *c.FileConf - - // Read config file when existing - if cFile != nil { - c.Log.Infof("Use config file: %s", *cFile) - - // TODO move on viper package to support comments in JSON and also - // bind with flags (command line options) - // see https://github.com/spf13/viper#working-with-flags - - fd, _ := os.Open(*cFile) - defer fd.Close() - if err := json.NewDecoder(fd).Decode(&fCfg); err != nil { - return nil, err - } - } - - // Support environment variables (IOW ${MY_ENV_VAR} syntax) in agent-config.json - vars := []*string{ - &fCfg.LogsDir, - } - if fCfg.SThgConf != nil { - vars = append(vars, &fCfg.SThgConf.Home, &fCfg.SThgConf.BinDir) - } - for _, field := range vars { - var err error - *field, err = common.ResolveEnvVar(*field) - if err != nil { - return nil, err - } - } - - // Config file settings overwrite default config - if fCfg.HTTPPort != "" { - c.HTTPPort = fCfg.HTTPPort - } - - // Set default apikey - // FIXME - rework with dynamic key - if fCfg.XDSAPIKey == "" { - fCfg.XDSAPIKey = "1234abcezam" - } - - return &fCfg, nil -} -- cgit 1.2.3-korg