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

Add command storeconfig #551

Merged
merged 1 commit into from
Jul 22, 2016
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
25 changes: 24 additions & 1 deletion docs/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ Please refer to the [global configuration](/toml/#global-configuration) section

### Arguments

Each argument is described in the help section:
Each argument (and command) is described in the help section:

```bash
$ traefik --help
Expand Down Expand Up @@ -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.

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
```

34 changes: 24 additions & 10 deletions docs/user-guide/kv-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,12 @@ whoami4:
## 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).
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
logLevel = "DEBUG"
Expand Down Expand Up @@ -109,9 +112,9 @@ And there, the same global configuration in the Key-value Store (using `prefix =
| `/traefik/consul/prefix` | `traefik` |
| `/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.

Be careful to give the correct IP address and port on the key `/traefik/consul/endpoint`.
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`.

Note that we can either give path to certificate file or directly the file content itself.

Expand All @@ -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.
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
traefik:
Expand All @@ -130,8 +133,6 @@ traefik:
ports:
- "80:80"
- "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`.
Expand Down Expand Up @@ -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.

## 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
[file]
Expand Down Expand Up @@ -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` |

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 changes: 10 additions & 8 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import:
- package: github.com/cenkalti/backoff
- package: github.com/codegangsta/negroni
- package: github.com/containous/flaeg
version: b98687da5c323650f4513fda6b6203fcbdec9313
version: da9515902135a2c9071c7464a1ae660b8b24d994
- package: github.com/vulcand/oxy
version: 8d476862d38b9be356eaa83b5712cad561be08a1
repo: https://github.com/containous/oxy.git
Expand All @@ -21,7 +21,7 @@ import:
- stream
- utils
- package: github.com/containous/staert
version: 436a2f21e5e28c7c761130720befe05381db0765
version: 8a848df89b01313ad890142bcd613a932f629a41
- package: github.com/docker/engine-api
version: 62043eb79d581a32ea849645277023c550732e52
subpackages:
Expand Down Expand Up @@ -93,7 +93,10 @@ import:
- detector
- package: github.com/jarcoal/httpmock
- package: github.com/mesosphere/mesos-dns
vcs: git
repo: https://github.com/containous/mesos-dns.git
version: b47dc4c19f215e98da687b15b4c64e70f629bea5
repo: https://github.com/containous/mesos-dns.git
vcs: git
- package: github.com/tv42/zbase32
- package: github.com/abbot/go-http-auth
- package: github.com/miekg/dns
version: 5d001d020961ae1c184f9f8152fdc73810481677
35 changes: 35 additions & 0 deletions integration/consul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,3 +392,38 @@ func (s *ConsulSuite) skipTestGlobalConfigurationWithClientTLS(c *check.C) {
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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

60 seconds might be a little too much to wait for 👼

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied it like that form "TestNominalConfiguration" 😅
How long do you think ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say 15 seconds should be enough 👼.

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)

}
}
35 changes: 35 additions & 0 deletions integration/etcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,38 @@ func (s *EtcdSuite) TestCertificatesContentstWithSNIConfigHandshake(c *check.C)
err = cs.PeerCertificates[0].VerifyHostname("snitest.com")
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)

}
}
39 changes: 35 additions & 4 deletions traefik.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ Complete documentation is available at https://traefik.io`,
},
}

//storeconfig Command init
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for later: we might want to split traefik.go a little bit 👼
(having a file for storeconfig command, same for version, …)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would like to add a file "commands.go" ?
With commands definition inside ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure yet 👼

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
f := flaeg.New(traefikCmd, os.Args[1:])
//add custom parsers
Expand All @@ -93,8 +115,9 @@ Complete documentation is available at https://traefik.io`,
f.AddParser(reflect.TypeOf(provider.Namespaces{}), &provider.Namespaces{})
f.AddParser(reflect.TypeOf([]acme.Domain{}), &acme.Domains{})

//add version command
//add commands
f.AddCommand(versionCmd)
f.AddCommand(storeconfigCmd)
if _, err := f.Parse(traefikCmd); err != nil {
fmtlog.Println(err)
os.Exit(-1)
Expand All @@ -110,20 +133,28 @@ Complete documentation is available at https://traefik.io`,
s.AddSource(f)
if _, err := s.LoadConfig(); err != nil {
fmtlog.Println(fmt.Errorf("Error reading TOML config file %s : %s", toml.ConfigFileUsed(), err))
os.Exit(-1)
}

traefikConfiguration.ConfigFile = toml.ConfigFileUsed()

kv, err := CreateKvSource(traefikConfiguration)
kv, err = CreateKvSource(traefikConfiguration)
if err != nil {
fmtlog.Println(err)
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)
if _, err := s.LoadConfig(); err != nil {
fmtlog.Println(err)
os.Exit(-1)
}
}

Expand Down Expand Up @@ -173,7 +204,7 @@ func run(traefikConfiguration *TraefikConfiguration) {
fi, err := os.OpenFile(globalConfiguration.TraefikLogsFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
defer func() {
if err := fi.Close(); err != nil {
log.Error("Error closinf file", err)
log.Error("Error closing file", err)
}
}()
if err != nil {
Expand Down