From ce4b2828ec800f0d1782b97b9400bd71154e5bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20R=C3=BCger?= Date: Tue, 18 Sep 2018 15:42:24 +0200 Subject: [PATCH] server: Read config from file --- README.md | 4 ++ config.yml.example | 37 ++++++++++++++++ go.mod | 1 + go.sum | 4 ++ server.go | 107 +++++++++++++++++++++++++++++++-------------- 5 files changed, 119 insertions(+), 34 deletions(-) create mode 100644 config.yml.example diff --git a/README.md b/README.md index 3c93191a..23b1b33c 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,7 @@ Flags: -u, --username username for the registry (default: ) --listen-address address to listen on (default: ) --asset-path Path to assets and templates (default: ) + --config Path to config file (default: ) -f, --force-non-ssl force allow use of non-ssl (default: false) --once generate the templates once and then exit (default: false) --skip-ping skip pinging the registry while establishing connection (default: false) @@ -227,6 +228,9 @@ Flags: -p, --password password for the registry (default: ) ``` +Alternatively you can provide configuration to `reg server` via a file passed to +`reg server` via as `--config`. See also config.yml.example in this repository. + **Screenshots:** ![home.png](server/home.png) diff --git a/config.yml.example b/config.yml.example new file mode 100644 index 00000000..9d4be25f --- /dev/null +++ b/config.yml.example @@ -0,0 +1,37 @@ +### Reg Server Settings + +## Path to server TLS certificate: +# cert: +## Path to server TLS key: +# key: +## Address to listen on: +# listen-address: 0.0.0.0 +## Port to listen on: +# port: 8080 +## Path Assets are stored under: +# asset-path: /var/lib/reg +## Generate static website and exit: +# once: false +## Refresh interval: +# interval: 1h0m0s +## Debug output +# debug: false +## Skip initial ping +# skip-ping: false +## Timeout +# timeout: 1m0s + + +### Registry and Clair Server Settings +## Registry Server: +# registry: r.j3ss.co +## Username to authenticate against registry server +# username: +## Password to authenticate against registry server +# password: +## If true, do not verify TLS certificates +# insecure: false +## Force allow use of non-TLS connections +# force-nonssl: false +## Clair Server: +# clair: diff --git a/go.mod b/go.mod index 4e7583e8..914297a8 100644 --- a/go.mod +++ b/go.mod @@ -35,5 +35,6 @@ require ( github.com/sirupsen/logrus v1.4.2 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect google.golang.org/grpc v1.23.1 + gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7 gotest.tools v2.2.0+incompatible // indirect ) diff --git a/go.sum b/go.sum index 71f46e16..ff078b3f 100644 --- a/go.sum +++ b/go.sum @@ -54,8 +54,10 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -115,8 +117,10 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.1 h1:q4XQuHFC6I28BKZpo6IYyb3mNO+l7lSOxRuYTCiDfXk= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7 h1:+t9dhfO+GNOIGJof6kPOAenx7YgrZMTdRPV+EsnPabk= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= diff --git a/server.go b/server.go index fcd4cd71..0c84d85d 100644 --- a/server.go +++ b/server.go @@ -4,7 +4,9 @@ import ( "context" "flag" "fmt" + "gopkg.in/yaml.v2" "html/template" + "io/ioutil" "net/http" "os" "path/filepath" @@ -29,39 +31,76 @@ func (cmd *serverCommand) LongHelp() string { return serverHelp } func (cmd *serverCommand) Hidden() bool { return false } func (cmd *serverCommand) Register(fs *flag.FlagSet) { - fs.DurationVar(&cmd.interval, "interval", time.Hour, "interval to generate new index.html's at") + fs.DurationVar(&cmd.Interval, "interval", time.Hour, "interval to generate new index.html's at") - fs.StringVar(&cmd.registryServer, "registry", "", "URL to the private registry (ex. r.j3ss.co)") - fs.StringVar(&cmd.registryServer, "r", "", "URL to the private registry (ex. r.j3ss.co)") + fs.StringVar(&cmd.RegistryServer, "registry", "", "URL to the private registry (ex. r.j3ss.co)") + fs.StringVar(&cmd.RegistryServer, "r", "", "URL to the private registry (ex. r.j3ss.co)") - fs.StringVar(&cmd.clairServer, "clair", "", "url to clair instance") + fs.StringVar(&cmd.ClairServer, "clair", "", "url to clair instance") - fs.StringVar(&cmd.cert, "cert", "", "path to ssl cert") - fs.StringVar(&cmd.key, "key", "", "path to ssl key") - fs.StringVar(&cmd.listenAddress, "listen-address", "", "address to listen on") - fs.StringVar(&cmd.port, "port", "8080", "port for server to run on") - fs.StringVar(&cmd.assetPath, "asset-path", "", "Path to assets and templates") + fs.StringVar(&cmd.Cert, "cert", "", "path to ssl cert") + fs.StringVar(&cmd.Key, "key", "", "path to ssl key") + fs.StringVar(&cmd.ListenAddress, "listen-address", "", "address to listen on") + fs.StringVar(&cmd.Port, "port", "8080", "port for server to run on") - fs.BoolVar(&cmd.generateAndExit, "once", false, "generate the templates once and then exit") + fs.StringVar(&cmd.AssetPath, "asset-path", "", "Path to assets and templates") + fs.StringVar(&cmd.configPath, "config", "", "Path to config file") + + fs.BoolVar(&cmd.GenerateAndExit, "once", false, "generate the templates once and then exit") } type serverCommand struct { - interval time.Duration - registryServer string - clairServer string - - generateAndExit bool - - cert string - key string - listenAddress string - port string - assetPath string + Interval time.Duration `yaml:"interval"` + RegistryServer string `yaml:"registry"` + ClairServer string `yaml:"clair"` + GenerateAndExit bool `yaml:"once"` + Cert string `yaml:"cert"` + Key string `yaml:"key"` + ListenAddress string `yaml:"listen-address"` + Port string `yaml:"port"` + AssetPath string `yaml:"asset-path"` + configPath string + + Password string `yaml:"password"` + Username string `yaml:"username"` + Insecure bool `yaml:"insecure"` + Debug bool `yaml:"debug"` + SkipPing bool `yaml:"skip-ping"` + ForceNonSSL bool `yaml:"force-nonssl"` + Timeout time.Duration `yaml:"timeout"` } func (cmd *serverCommand) Run(ctx context.Context, args []string) error { // Create the registry client. - r, err := createRegistryClient(ctx, cmd.registryServer) + if len(cmd.configPath) > 0 { + config, err := ioutil.ReadFile(cmd.configPath) + if err != nil { + return err + } + yaml.Unmarshal(config, cmd) + if err != nil { + return err + } + if len(cmd.Username) > 0 { + username = cmd.Username + } + if len(cmd.Password) > 0 { + password = cmd.Password + } + if cmd.Debug { + debug = cmd.Debug + } + if cmd.Insecure { + insecure = cmd.Insecure + } + if cmd.SkipPing { + skipPing = cmd.SkipPing + } + if cmd.Timeout != 0 { + timeout = cmd.Timeout + } + } + r, err := createRegistryClient(ctx, cmd.RegistryServer) if err != nil { return err } @@ -69,25 +108,25 @@ func (cmd *serverCommand) Run(ctx context.Context, args []string) error { // Create the registry controller for the handlers. rc := registryController{ reg: r, - generateOnly: cmd.generateAndExit, + generateOnly: cmd.GenerateAndExit, } // Create a clair client if the user passed in a server address. - if len(cmd.clairServer) > 0 { - rc.cl, err = clair.New(cmd.clairServer, clair.Opt{ + if len(cmd.ClairServer) > 0 { + rc.cl, err = clair.New(cmd.ClairServer, clair.Opt{ Insecure: insecure, Debug: debug, Timeout: timeout, }) if err != nil { - return fmt.Errorf("creation of clair client at %s failed: %v", cmd.clairServer, err) + return fmt.Errorf("creation of clair client at %s failed: %v", cmd.ClairServer, err) } } else { rc.cl = nil } // Get the path to the asset directory. - assetDir := cmd.assetPath - if len(cmd.assetPath) <= 0 { + assetDir := cmd.AssetPath + if len(cmd.AssetPath) <= 0 { assetDir, err = os.Getwd() if err != nil { return err @@ -131,12 +170,12 @@ func (cmd *serverCommand) Run(ctx context.Context, args []string) error { return fmt.Errorf("creating index failed: %v", err) } - if cmd.generateAndExit { + if cmd.GenerateAndExit { logrus.Info("output generated, exiting...") return nil } - rc.interval = cmd.interval + rc.interval = cmd.Interval ticker := time.NewTicker(rc.interval) go func() { // Create more indexes every X minutes based off interval. @@ -174,12 +213,12 @@ func (cmd *serverCommand) Run(ctx context.Context, args []string) error { // Set up the server. server := &http.Server{ - Addr: cmd.listenAddress + ":" + cmd.port, + Addr: cmd.ListenAddress + ":" + cmd.Port, Handler: mux, } - logrus.Infof("Starting server on port %q", cmd.port) - if len(cmd.cert) > 0 && len(cmd.key) > 0 { - return server.ListenAndServeTLS(cmd.cert, cmd.key) + logrus.Infof("Starting server on port %q", cmd.Port) + if len(cmd.Cert) > 0 && len(cmd.Key) > 0 { + return server.ListenAndServeTLS(cmd.Cert, cmd.Key) } return server.ListenAndServe() } -- 2.34.1