add command storeconfig

add test integration command storeconfig

update doc
This commit is contained in:
Martin 2016-07-20 11:48:39 +02:00
parent ae31f19ef6
commit 1bb3d9be73
7 changed files with 170 additions and 27 deletions

View file

@ -293,7 +293,7 @@ Please refer to the [global configuration](/toml/#global-configuration) section
### Arguments ### Arguments
Each argument is described in the help section: Each argument (and command) is described in the help section:
```bash ```bash
$ traefik --help $ traefik --help
@ -326,3 +326,26 @@ We only need to enable `watch` option to make Træfɪk watch configuration backe
Routes to services will be created and updated instantly at any changes. Routes to services will be created and updated instantly at any changes.
Please refer to the [configuration backends](/toml/#configuration-backends) section to get documentation on it. Please refer to the [configuration backends](/toml/#configuration-backends) section to get documentation on it.
# Commands
Usage: `traefik [command] [--flag=flag_argument]`
List of Træfɪk available commands with description :                                                             
- `version` : Print version 
- `storeconfig` : Store the static traefik configuration into a Key-value stores. Please refer to the [Store Træfɪk configuration](/user-guide/kv-config/#store-trfk-configuration) section to get documentation on it.
Each command may have related flags.
All those related flags will be displayed with :
```bash
$ traefik [command] --help
```
Note that each command is described at the begining of the help section:
```bash
$ traefik --help
```

View file

@ -55,9 +55,12 @@ whoami4:
## Upload the configuration in the Key-value store ## Upload the configuration in the Key-value store
We should now fill the store with the Træfɪk global configuration, as we do with a [TOML file configuration](/toml). We should now fill the store with the Træfɪk global configuration, as we do with a [TOML file configuration](/toml).
To do that, we can send the Key-value pairs via [curl commands](https://www.consul.io/intro/getting-started/kv.html) or via the [Web UI](https://www.consul.io/intro/getting-started/ui.html) To do that, we can send the Key-value pairs via [curl commands](https://www.consul.io/intro/getting-started/kv.html) or via the [Web UI](https://www.consul.io/intro/getting-started/ui.html).
Here the toml configuration we would like to store in the Key-value Store : Hopefully, Træfɪk allows automation of this process using the `storeconfig` subcommand.
Please refer to the [store Træfɪk configuration](/user-guide/kv-config/#store-configuration-in-key-value-store) section to get documentation on it.
Here is the toml configuration we would like to store in the Key-value Store :
```toml ```toml
logLevel = "DEBUG" logLevel = "DEBUG"
@ -109,9 +112,9 @@ And there, the same global configuration in the Key-value Store (using `prefix =
| `/traefik/consul/prefix` | `traefik` | | `/traefik/consul/prefix` | `traefik` |
| `/traefik/web/address` | `:8081` | | `/traefik/web/address` | `:8081` |
Remember to specify the indexes (`0`,`1`, `2`, ... ) under prefixes `/traefik/defaultentrypoints/` and `/traefik/entrypoints/https/tls/certificates/` in order to match the global configuration structure. In case you are setting key values manually,:
- Remember to specify the indexes (`0`,`1`, `2`, ... ) under prefixes `/traefik/defaultentrypoints/` and `/traefik/entrypoints/https/tls/certificates/` in order to match the global configuration structure.
Be careful to give the correct IP address and port on the key `/traefik/consul/endpoint`. - Be careful to give the correct IP address and port on the key `/traefik/consul/endpoint`.
Note that we can either give path to certificate file or directly the file content itself. Note that we can either give path to certificate file or directly the file content itself.
@ -121,7 +124,7 @@ We will now launch Træfɪk in a container.
We use CLI flags to setup the connection between Træfɪk and Consul. We use CLI flags to setup the connection between Træfɪk and Consul.
All the rest of the global configuration is stored in Consul. All the rest of the global configuration is stored in Consul.
Here the [docker-compose file](https://docs.docker.com/compose/compose-file/) : Here is the [docker-compose file](https://docs.docker.com/compose/compose-file/) :
```yml ```yml
traefik: traefik:
@ -130,8 +133,6 @@ traefik:
ports: ports:
- "80:80" - "80:80"
- "8080:8080" - "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
``` ```
NB : Be careful to give the correct IP address and port in the flag `--consul.endpoint`. NB : Be careful to give the correct IP address and port in the flag `--consul.endpoint`.
@ -166,7 +167,7 @@ Note that this section is independent of the way Træfɪk got its static configu
It means that the static configuration can either come from the same Key-value store or from any other sources. It means that the static configuration can either come from the same Key-value store or from any other sources.
## Key-value storage structure ## Key-value storage structure
Here the toml configuration we would like to store in the store : Here is the toml configuration we would like to store in the store :
```toml ```toml
[file] [file]
@ -295,4 +296,17 @@ Once the `/traefik/alias` key is updated, the new `/traefik_configurations/2` co
| `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` | | `/traefik_configurations/2/backends/backend1/servers/server2/weight` | `5` |
Note that Træfɪk *will not watch for key changes in the `/traefik_configurations` prefix*. It will only watch for changes in the `/traefik/alias`. Note that Træfɪk *will not watch for key changes in the `/traefik_configurations` prefix*. It will only watch for changes in the `/traefik/alias`.
Further, if the `/traefik/alias` key is set, all other configuration with `/traefik/backends` or `/traefik/frontends` prefix are ignored. Further, if the `/traefik/alias` key is set, all other configuration with `/traefik/backends` or `/traefik/frontends` prefix are ignored.
# Store configuration in Key-value store
The static Træfɪk configuration in a key-value store can be automatically created and updated, using the [`storeconfig` subcommand](/basics/#commands).
```bash
$ traefik storeconfig [flags] ...
```
This command is here only to automate the [process which upload the configuration into the Key-value store](/user-guide/kv-config/#upload-the-configuration-in-the-key-value-store).
Træfɪk will not start but the [static configuration](/basics/#static-trfk-configuration) will be uploaded into the Key-value store.
Don't forget to [setup the connection between Træfɪk and Key-value store](/user-guide/kv-config/#launch-trfk).

18
glide.lock generated
View file

@ -1,6 +1,8 @@
hash: d46d9eb54571fad41c44e85508bc5e71a94801f4dfa9227686683bdd8f724544 hash: 745d05424943c3345ff5fca5b121c6af3930f62fc13195d87d9fcce6686620ea
updated: 2016-07-21T15:55:22.90786751+02:00 updated: 2016-07-22T15:14:53.608798979+02:00
imports: imports:
- name: github.com/abbot/go-http-auth
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
- name: github.com/boltdb/bolt - name: github.com/boltdb/bolt
version: 5cc10bbbc5c141029940133bb33c9e969512a698 version: 5cc10bbbc5c141029940133bb33c9e969512a698
- name: github.com/BurntSushi/toml - name: github.com/BurntSushi/toml
@ -18,11 +20,11 @@ imports:
- name: github.com/codegangsta/negroni - name: github.com/codegangsta/negroni
version: dc6b9d037e8dab60cbfc09c61d6932537829be8b version: dc6b9d037e8dab60cbfc09c61d6932537829be8b
- name: github.com/containous/flaeg - name: github.com/containous/flaeg
version: b98687da5c323650f4513fda6b6203fcbdec9313 version: da9515902135a2c9071c7464a1ae660b8b24d994
- name: github.com/containous/mux - name: github.com/containous/mux
version: a819b77bba13f0c0cbe36e437bc2e948411b3996 version: a819b77bba13f0c0cbe36e437bc2e948411b3996
- name: github.com/containous/staert - name: github.com/containous/staert
version: 436a2f21e5e28c7c761130720befe05381db0765 version: 8a848df89b01313ad890142bcd613a932f629a41
- name: github.com/coreos/etcd - name: github.com/coreos/etcd
version: 1c9e0a0e33051fed6c05c141e6fcbfe5c7f2a899 version: 1c9e0a0e33051fed6c05c141e6fcbfe5c7f2a899
subpackages: subpackages:
@ -34,7 +36,7 @@ imports:
subpackages: subpackages:
- spew - spew
- name: github.com/docker/distribution - name: github.com/docker/distribution
version: 857d0f15c0a4d8037175642e0ca3660829551cb5 version: 2b72dd3927b2958160a2336f16145c0c421aa6a4
subpackages: subpackages:
- reference - reference
- digest - digest
@ -155,7 +157,7 @@ imports:
- name: github.com/go-check/check - name: github.com/go-check/check
version: 4f90aeace3a26ad7021961c297b22c42160c7b25 version: 4f90aeace3a26ad7021961c297b22c42160c7b25
- name: github.com/gogo/protobuf - name: github.com/gogo/protobuf
version: e57a569e1882958f6b188cb42231d6db87701f2a version: 6abcf94fd4c97dcb423fdafd42fe9f96ca7e421b
subpackages: subpackages:
- proto - proto
- name: github.com/golang/glog - name: github.com/golang/glog
@ -224,7 +226,7 @@ imports:
- name: github.com/ogier/pflag - name: github.com/ogier/pflag
version: 45c278ab3607870051a2ea9040bb85fcb8557481 version: 45c278ab3607870051a2ea9040bb85fcb8557481
- name: github.com/opencontainers/runc - name: github.com/opencontainers/runc
version: ff88baa42fa5b2a1568a3a14665142fb4bdb3a2a version: fb221651e5120cd287a76c7c1b6c877520fbd034
subpackages: subpackages:
- libcontainer/user - libcontainer/user
- name: github.com/parnurzeal/gorequest - name: github.com/parnurzeal/gorequest
@ -329,7 +331,7 @@ testImports:
- name: github.com/gorilla/mux - name: github.com/gorilla/mux
version: 9fa818a44c2bf1396a17f9d5a3c0f6dd39d2ff8e version: 9fa818a44c2bf1396a17f9d5a3c0f6dd39d2ff8e
- name: github.com/libkermit/docker-check - name: github.com/libkermit/docker-check
version: cbe0ef03b3d23070eac4d00ba8828f2cc7f7e5a3 version: bb75a86b169c6c5d22c0ee98278124036f272d7b
- name: github.com/spf13/pflag - name: github.com/spf13/pflag
version: 5644820622454e71517561946e3d94b9f9db6842 version: 5644820622454e71517561946e3d94b9f9db6842
- name: github.com/vbatts/tar-split - name: github.com/vbatts/tar-split

View file

@ -8,7 +8,7 @@ import:
- package: github.com/cenkalti/backoff - package: github.com/cenkalti/backoff
- package: github.com/codegangsta/negroni - package: github.com/codegangsta/negroni
- package: github.com/containous/flaeg - package: github.com/containous/flaeg
version: b98687da5c323650f4513fda6b6203fcbdec9313 version: da9515902135a2c9071c7464a1ae660b8b24d994
- package: github.com/vulcand/oxy - package: github.com/vulcand/oxy
version: 8d476862d38b9be356eaa83b5712cad561be08a1 version: 8d476862d38b9be356eaa83b5712cad561be08a1
repo: https://github.com/containous/oxy.git repo: https://github.com/containous/oxy.git
@ -21,7 +21,7 @@ import:
- stream - stream
- utils - utils
- package: github.com/containous/staert - package: github.com/containous/staert
version: 436a2f21e5e28c7c761130720befe05381db0765 version: 8a848df89b01313ad890142bcd613a932f629a41
- package: github.com/docker/engine-api - package: github.com/docker/engine-api
version: 62043eb79d581a32ea849645277023c550732e52 version: 62043eb79d581a32ea849645277023c550732e52
subpackages: subpackages:
@ -93,7 +93,10 @@ import:
- detector - detector
- package: github.com/jarcoal/httpmock - package: github.com/jarcoal/httpmock
- package: github.com/mesosphere/mesos-dns - package: github.com/mesosphere/mesos-dns
vcs: git
repo: https://github.com/containous/mesos-dns.git
version: b47dc4c19f215e98da687b15b4c64e70f629bea5 version: b47dc4c19f215e98da687b15b4c64e70f629bea5
repo: https://github.com/containous/mesos-dns.git
vcs: git
- package: github.com/tv42/zbase32 - package: github.com/tv42/zbase32
- package: github.com/abbot/go-http-auth
- package: github.com/miekg/dns
version: 5d001d020961ae1c184f9f8152fdc73810481677

View file

@ -392,3 +392,38 @@ func (s *ConsulSuite) skipTestGlobalConfigurationWithClientTLS(c *check.C) {
c.Assert(err, checker.IsNil) c.Assert(err, checker.IsNil)
} }
func (s *ConsulSuite) TestCommandStoreConfig(c *check.C) {
s.setupConsul(c)
consulHost := s.composeProject.Container(c, "consul").NetworkSettings.IPAddress
cmd := exec.Command(traefikBinary, "storeconfig", "--configFile=fixtures/simple_web.toml", "--consul.endpoint="+consulHost+":8500")
err := cmd.Start()
c.Assert(err, checker.IsNil)
// wait for traefik finish without error
cmd.Wait()
//CHECK
checkmap := map[string]string{
"/traefik/loglevel": "DEBUG",
"/traefik/defaultentrypoints/0": "http",
"/traefik/entrypoints/http/address": ":8000",
"/traefik/web/address": ":8080",
"/traefik/consul/endpoint": (consulHost + ":8500"),
}
for key, value := range checkmap {
var p *store.KVPair
err = utils.Try(60*time.Second, func() error {
p, err = s.kv.Get(key)
if err != nil {
return err
}
return nil
})
c.Assert(err, checker.IsNil)
c.Assert(string(p.Value), checker.Equals, value)
}
}

View file

@ -431,3 +431,38 @@ func (s *EtcdSuite) TestCertificatesContentstWithSNIConfigHandshake(c *check.C)
err = cs.PeerCertificates[0].VerifyHostname("snitest.com") err = cs.PeerCertificates[0].VerifyHostname("snitest.com")
c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername")) c.Assert(err, checker.IsNil, check.Commentf("certificate did not match SNI servername"))
} }
func (s *EtcdSuite) TestCommandStoreConfig(c *check.C) {
etcdHost := s.composeProject.Container(c, "etcd").NetworkSettings.IPAddress
cmd := exec.Command(traefikBinary, "storeconfig", "--configFile=fixtures/simple_web.toml", "--etcd.endpoint="+etcdHost+":4001")
err := cmd.Start()
c.Assert(err, checker.IsNil)
// wait for traefik finish without error
cmd.Wait()
//CHECK
checkmap := map[string]string{
"/traefik/loglevel": "DEBUG",
"/traefik/defaultentrypoints/0": "http",
"/traefik/entrypoints/http/address": ":8000",
"/traefik/web/address": ":8080",
"/traefik/etcd/endpoint": (etcdHost + ":4001"),
}
for key, value := range checkmap {
var p *store.KVPair
err = utils.Try(60*time.Second, func() error {
p, err = s.kv.Get(key)
if err != nil {
return err
}
return nil
})
c.Assert(err, checker.IsNil)
c.Assert(string(p.Value), checker.Equals, value)
}
}

View file

@ -84,6 +84,28 @@ Complete documentation is available at https://traefik.io`,
}, },
} }
//storeconfig Command init
var kv *staert.KvSource
var err error
storeconfigCmd := &flaeg.Command{
Name: "storeconfig",
Description: `Store the static traefik configuration into a Key-value stores. Traefik will not start.`,
Config: traefikConfiguration,
DefaultPointersConfig: traefikPointersConfiguration,
Run: func() error {
if kv == nil {
return fmt.Errorf("Error using command storeconfig, no Key-value store defined")
}
jsonConf, _ := json.Marshal(traefikConfiguration.GlobalConfiguration)
fmtlog.Printf("Storing configuration: %s\n", jsonConf)
return kv.StoreConfig(traefikConfiguration.GlobalConfiguration)
},
Metadata: map[string]string{
"parseAllSources": "true",
},
}
//init flaeg source //init flaeg source
f := flaeg.New(traefikCmd, os.Args[1:]) f := flaeg.New(traefikCmd, os.Args[1:])
//add custom parsers //add custom parsers
@ -93,8 +115,9 @@ Complete documentation is available at https://traefik.io`,
f.AddParser(reflect.TypeOf(provider.Namespaces{}), &provider.Namespaces{}) f.AddParser(reflect.TypeOf(provider.Namespaces{}), &provider.Namespaces{})
f.AddParser(reflect.TypeOf([]acme.Domain{}), &acme.Domains{}) f.AddParser(reflect.TypeOf([]acme.Domain{}), &acme.Domains{})
//add version command //add commands
f.AddCommand(versionCmd) f.AddCommand(versionCmd)
f.AddCommand(storeconfigCmd)
if _, err := f.Parse(traefikCmd); err != nil { if _, err := f.Parse(traefikCmd); err != nil {
fmtlog.Println(err) fmtlog.Println(err)
os.Exit(-1) os.Exit(-1)
@ -110,20 +133,28 @@ Complete documentation is available at https://traefik.io`,
s.AddSource(f) s.AddSource(f)
if _, err := s.LoadConfig(); err != nil { if _, err := s.LoadConfig(); err != nil {
fmtlog.Println(fmt.Errorf("Error reading TOML config file %s : %s", toml.ConfigFileUsed(), err)) fmtlog.Println(fmt.Errorf("Error reading TOML config file %s : %s", toml.ConfigFileUsed(), err))
os.Exit(-1)
} }
traefikConfiguration.ConfigFile = toml.ConfigFileUsed() traefikConfiguration.ConfigFile = toml.ConfigFileUsed()
kv, err := CreateKvSource(traefikConfiguration) kv, err = CreateKvSource(traefikConfiguration)
if err != nil { if err != nil {
fmtlog.Println(err) fmtlog.Println(err)
os.Exit(-1) os.Exit(-1)
} }
if kv != nil { usedCmd, err := f.GetCommand()
if err != nil {
fmtlog.Println(err)
os.Exit(-1)
}
// IF a KV Store is enable and no sub-command called in args
if kv != nil && usedCmd == traefikCmd {
s.AddSource(kv) s.AddSource(kv)
if _, err := s.LoadConfig(); err != nil { if _, err := s.LoadConfig(); err != nil {
fmtlog.Println(err) fmtlog.Println(err)
os.Exit(-1)
} }
} }
@ -173,7 +204,7 @@ func run(traefikConfiguration *TraefikConfiguration) {
fi, err := os.OpenFile(globalConfiguration.TraefikLogsFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) fi, err := os.OpenFile(globalConfiguration.TraefikLogsFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
defer func() { defer func() {
if err := fi.Close(); err != nil { if err := fi.Close(); err != nil {
log.Error("Error closinf file", err) log.Error("Error closing file", err)
} }
}() }()
if err != nil { if err != nil {