1
0
Fork 0

Refactor into dual Rancher API/Metadata providers

Introduces Rancher's metadata service as an optional provider source for
Traefik, enabled by setting `rancher.MetadataService`.

The provider uses a long polling technique to watch the metadata service and
obtain near instantaneous updates. Alternatively it can be configured to poll
the metadata service every `rancher.RefreshSeconds` by setting
`rancher.MetadataPoll`.

The refactor splits API and metadata service code into separate source
files respectively, and specific configuration is deferred to
sub-structs.

Incorporates bugfix #1414
This commit is contained in:
Martin Baillie 2017-05-08 11:20:38 +10:00 committed by Ludovic Fernandez
parent 984ea1040f
commit 9cb07d026f
14 changed files with 1006 additions and 272 deletions

View file

@ -0,0 +1,64 @@
package metadata
import (
"encoding/json"
"fmt"
"time"
"github.com/Sirupsen/logrus"
)
func (m *client) OnChangeWithError(intervalSeconds int, do func(string)) error {
return m.onChangeFromVersionWithError("init", intervalSeconds, do)
}
func (m *client) onChangeFromVersionWithError(version string, intervalSeconds int, do func(string)) error {
for {
newVersion, err := m.waitVersion(intervalSeconds, version)
if err != nil {
return err
} else if version == newVersion {
logrus.Debug("No changes in metadata version")
} else {
logrus.Debugf("Metadata Version has been changed. Old version: %s. New version: %s.", version, newVersion)
version = newVersion
do(newVersion)
}
}
return nil
}
func (m *client) OnChange(intervalSeconds int, do func(string)) {
version := "init"
updateVersionAndDo := func(v string) {
version = v
do(version)
}
interval := time.Duration(intervalSeconds)
for {
if err := m.onChangeFromVersionWithError(version, intervalSeconds, updateVersionAndDo); err != nil {
logrus.Errorf("Error reading metadata version: %v", err)
}
time.Sleep(interval * time.Second)
}
}
type timeout interface {
Timeout() bool
}
func (m *client) waitVersion(maxWait int, version string) (string, error) {
for {
resp, err := m.SendRequest(fmt.Sprintf("/version?wait=true&value=%s&maxWait=%d", version, maxWait))
if err != nil {
t, ok := err.(timeout)
if ok && t.Timeout() {
continue
}
return "", err
}
err = json.Unmarshal(resp, &version)
return version, err
}
}