Merge pull request #2803 from hashicorp/f-update-ct

Update consul-template
This commit is contained in:
Michael Schurter 2017-07-07 15:03:46 -07:00 committed by GitHub
commit fe69901fb9
15 changed files with 273 additions and 173 deletions

View file

@ -242,58 +242,6 @@ func Parse(s string) (*Config, error) {
}
}
// TODO: Deprecations
if vault, ok := parsed["vault"].(map[string]interface{}); ok {
if val, ok := vault["renew"]; ok {
log.Println(`[WARN] vault.renew has been renamed to vault.renew_token. ` +
`Update your configuration files and change "renew" to "renew_token".`)
vault["renew_token"] = val
delete(vault, "renew")
}
}
if auth, ok := parsed["auth"].(map[string]interface{}); ok {
log.Println("[WARN] auth has been moved under the consul stanza. " +
"Update your configuration files and place auth inside consul { }.")
if _, ok := parsed["consul"]; !ok {
parsed["consul"] = make(map[string]interface{})
}
parsed["consul"].(map[string]interface{})["auth"] = auth
delete(parsed, "auth")
}
if retry, ok := parsed["retry"].(string); ok {
log.Println("[WARN] retry has been moved under the consul stanza. " +
"Update your configuration files and place retry inside consul { }.")
if _, ok := parsed["consul"]; !ok {
parsed["consul"] = make(map[string]interface{})
}
parsed["consul"].(map[string]interface{})["retry"] = map[string]interface{}{
"backoff": retry,
}
delete(parsed, "retry")
}
if ssl, ok := parsed["ssl"].(map[string]interface{}); ok {
log.Println("[WARN] ssl has been moved under the consul stanza. " +
"Update your configuration files and place ssl inside consul { }.")
if _, ok := parsed["consul"]; !ok {
parsed["consul"] = make(map[string]interface{})
}
parsed["consul"].(map[string]interface{})["ssl"] = ssl
delete(parsed, "ssl")
}
if token, ok := parsed["token"].(string); ok {
log.Println("[WARN] token has been moved under the consul stanza. " +
"Update your configuration files and place token inside consul { }.")
if _, ok := parsed["consul"]; !ok {
parsed["consul"] = make(map[string]interface{})
}
parsed["consul"].(map[string]interface{})["token"] = token
delete(parsed, "token")
}
// Create a new, empty config
var c Config

View file

@ -56,6 +56,10 @@ type TemplateConfig struct {
// This is required unless running in debug/dry mode.
Destination *string `mapstructure:"destination"`
// ErrMissingKey is used to control how the template behaves when attempting
// to index a struct or map key that does not exist.
ErrMissingKey *bool `mapstructure:"error_on_missing_key"`
// Exec is the configuration for the command to run when the template renders
// successfully.
Exec *ExecConfig `mapstructure:"exec"`
@ -105,6 +109,8 @@ func (c *TemplateConfig) Copy() *TemplateConfig {
o.Destination = c.Destination
o.ErrMissingKey = c.ErrMissingKey
if c.Exec != nil {
o.Exec = c.Exec.Copy()
}
@ -161,6 +167,10 @@ func (c *TemplateConfig) Merge(o *TemplateConfig) *TemplateConfig {
r.Destination = o.Destination
}
if o.ErrMissingKey != nil {
r.ErrMissingKey = o.ErrMissingKey
}
if o.Exec != nil {
r.Exec = r.Exec.Merge(o.Exec)
}
@ -211,6 +221,10 @@ func (c *TemplateConfig) Finalize() {
c.Destination = String("")
}
if c.ErrMissingKey == nil {
c.ErrMissingKey = Bool(false)
}
if c.Exec == nil {
c.Exec = DefaultExecConfig()
}
@ -258,6 +272,7 @@ func (c *TemplateConfig) GoString() string {
"CommandTimeout:%s, "+
"Contents:%s, "+
"Destination:%s, "+
"ErrMissingKey:%s, "+
"Exec:%#v, "+
"Perms:%s, "+
"Source:%s, "+
@ -270,6 +285,7 @@ func (c *TemplateConfig) GoString() string {
TimeDurationGoString(c.CommandTimeout),
StringGoString(c.Contents),
StringGoString(c.Destination),
BoolGoString(c.ErrMissingKey),
c.Exec,
FileModeGoString(c.Perms),
StringGoString(c.Source),

View file

@ -8,6 +8,11 @@ import (
)
const (
// DefaultVaultGrace is the default grace period before which to read a new
// secret from Vault. If a lease is due to expire in 5 minutes, Consul
// Template will read a new secret at that time minus this value.
DefaultVaultGrace = 15 * time.Second
// DefaultVaultRenewToken is the default value for if the Vault token should
// be renewed.
DefaultVaultRenewToken = true
@ -33,6 +38,10 @@ type VaultConfig struct {
// Enabled controls whether the Vault integration is active.
Enabled *bool `mapstructure:"enabled"`
// Grace is the amount of time before a lease is about to expire to force a
// new secret to be read.
Grace *time.Duration `mapstructure:"grace"`
// RenewToken renews the Vault token.
RenewToken *bool `mapstructure:"renew_token"`
@ -80,6 +89,8 @@ func (c *VaultConfig) Copy() *VaultConfig {
o.Enabled = c.Enabled
o.Grace = c.Grace
o.RenewToken = c.RenewToken
if c.Retry != nil {
@ -127,6 +138,10 @@ func (c *VaultConfig) Merge(o *VaultConfig) *VaultConfig {
r.Enabled = o.Enabled
}
if o.Grace != nil {
r.Grace = o.Grace
}
if o.RenewToken != nil {
r.RenewToken = o.RenewToken
}
@ -162,6 +177,10 @@ func (c *VaultConfig) Finalize() {
}, "")
}
if c.Grace == nil {
c.Grace = TimeDuration(DefaultVaultGrace)
}
if c.RenewToken == nil {
c.RenewToken = boolFromEnv([]string{
"VAULT_RENEW_TOKEN",
@ -239,6 +258,7 @@ func (c *VaultConfig) GoString() string {
return fmt.Sprintf("&VaultConfig{"+
"Address:%s, "+
"Enabled:%s, "+
"Grace:%s, "+
"RenewToken:%s, "+
"Retry:%#v, "+
"SSL:%#v, "+
@ -247,6 +267,7 @@ func (c *VaultConfig) GoString() string {
"UnwrapToken:%s"+
"}",
StringGoString(c.Address),
TimeDurationGoString(c.Grace),
BoolGoString(c.Enabled),
BoolGoString(c.RenewToken),
c.Retry,

View file

@ -6,6 +6,7 @@ import (
"sort"
"time"
"github.com/hashicorp/consul/api"
"github.com/pkg/errors"
)
@ -20,13 +21,16 @@ var (
// CatalogDatacentersQuery is the dependency to query all datacenters
type CatalogDatacentersQuery struct {
ignoreFailing bool
stopCh chan struct{}
}
// NewCatalogDatacentersQuery creates a new datacenter dependency.
func NewCatalogDatacentersQuery() (*CatalogDatacentersQuery, error) {
func NewCatalogDatacentersQuery(ignoreFailing bool) (*CatalogDatacentersQuery, error) {
return &CatalogDatacentersQuery{
stopCh: make(chan struct{}, 1),
ignoreFailing: ignoreFailing,
stopCh: make(chan struct{}, 1),
}, nil
}
@ -64,6 +68,22 @@ func (d *CatalogDatacentersQuery) Fetch(clients *ClientSet, opts *QueryOptions)
return nil, nil, errors.Wrapf(err, d.String())
}
// If the user opted in for skipping "down" datacenters, figure out which
// datacenters are down.
if d.ignoreFailing {
dcs := make([]string, 0, len(result))
for _, dc := range result {
if _, _, err := clients.Consul().Catalog().Services(&api.QueryOptions{
Datacenter: dc,
AllowStale: false,
RequireConsistent: true,
}); err == nil {
dcs = append(dcs, dc)
}
}
result = dcs
}
log.Printf("[TRACE] %s: returned %d results", d, len(result))
sort.Strings(result)

View file

@ -1,7 +1,6 @@
package dependency
import (
"log"
"net/url"
"regexp"
"sort"
@ -42,19 +41,6 @@ type Dependency interface {
// ServiceTags is a slice of tags assigned to a Service
type ServiceTags []string
// Contains returns true if the tags exists in the ServiceTags slice.
// This is deprecated and should not be used.
func (t ServiceTags) Contains(s string) bool {
log.Printf("[WARN] .Tags.Contains is deprecated. Use the built-in\n" +
"functions 'in' or 'contains' with a pipe instead.")
for _, v := range t {
if v == s {
return true
}
}
return false
}
// QueryOptions is a list of options to send with the query. These options are
// client-agnostic, and the dependency determines which, if any, of the options
// to use.
@ -63,6 +49,7 @@ type QueryOptions struct {
Datacenter string
Near string
RequireConsistent bool
VaultGrace time.Duration
WaitIndex uint64
WaitTime time.Duration
}

View file

@ -26,3 +26,14 @@ func leaseDurationOrDefault(d int) int {
}
return d
}
// vaultRenewDuration accepts a given renew duration (lease duration) and
// returns the cooresponding time.Duration. If the duration is 0 (not provided),
// this falls back to the VaultDefaultLeaseDuration.
func vaultRenewDuration(d int) time.Duration {
dur := time.Duration(d/2.0) * time.Second
if dur == 0 {
dur = VaultDefaultLeaseDuration
}
return dur
}

View file

@ -50,10 +50,7 @@ func (d *VaultReadQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfac
// If this is not the first query and we have a lease duration, sleep until we
// try to renew.
if opts.WaitIndex != 0 && d.secret != nil && d.secret.LeaseDuration != 0 {
dur := time.Duration(d.secret.LeaseDuration/2.0) * time.Second
if dur == 0 {
dur = VaultDefaultLeaseDuration
}
dur := vaultRenewDuration(d.secret.LeaseDuration)
log.Printf("[TRACE] %s: long polling for %s", d, dur)
@ -76,6 +73,9 @@ func (d *VaultReadQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfac
if err == nil {
log.Printf("[TRACE] %s: successfully renewed %s", d, d.secret.LeaseID)
// Print any warnings
d.printWarnings(renewal.Warnings)
secret := &Secret{
RequestID: renewal.RequestID,
LeaseID: renewal.LeaseID,
@ -83,8 +83,25 @@ func (d *VaultReadQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfac
Renewable: renewal.Renewable,
Data: d.secret.Data,
}
// For some older versions of Vault, the renewal did not include the
// remaining lease duration, so just use the original lease duration,
// because it's the best we can do.
if renewal.LeaseDuration != 0 {
secret.LeaseDuration = renewal.LeaseDuration
}
d.secret = secret
// If the remaining time on the lease is less than or equal to our
// configured grace period, generate a new credential now. This will help
// minimize downtime, since Vault will revoke credentials immediately
// when their maximum TTL expires.
remaining := time.Duration(d.secret.LeaseDuration) * time.Second
if remaining <= opts.VaultGrace {
log.Printf("[DEBUG] %s: remaining lease (%s) < grace (%s), acquiring new",
d, remaining, opts.VaultGrace)
return d.readSecret(clients, opts)
}
return respWithMetadata(secret)
}
@ -94,35 +111,7 @@ func (d *VaultReadQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfac
// If we got this far, we either didn't have a secret to renew, the secret was
// not renewable, or the renewal failed, so attempt a fresh read.
log.Printf("[TRACE] %s: GET %s", d, &url.URL{
Path: "/v1/" + d.path,
RawQuery: opts.String(),
})
vaultSecret, err := clients.Vault().Logical().Read(d.path)
if err != nil {
return nil, nil, errors.Wrap(err, d.String())
}
// The secret could be nil if it does not exist.
if vaultSecret == nil {
return nil, nil, fmt.Errorf("%s: no secret exists at %s", d, d.path)
}
// Print any warnings.
for _, w := range vaultSecret.Warnings {
log.Printf("[WARN] %s: %s", d, w)
}
// Create our cloned secret.
secret := &Secret{
LeaseID: vaultSecret.LeaseID,
LeaseDuration: leaseDurationOrDefault(vaultSecret.LeaseDuration),
Renewable: vaultSecret.Renewable,
Data: vaultSecret.Data,
}
d.secret = secret
return respWithMetadata(secret)
return d.readSecret(clients, opts)
}
// CanShare returns if this dependency is shareable.
@ -144,3 +133,39 @@ func (d *VaultReadQuery) String() string {
func (d *VaultReadQuery) Type() Type {
return TypeVault
}
func (d *VaultReadQuery) printWarnings(warnings []string) {
for _, w := range warnings {
log.Printf("[WARN] %s: %s", d, w)
}
}
func (d *VaultReadQuery) readSecret(clients *ClientSet, opts *QueryOptions) (interface{}, *ResponseMetadata, error) {
log.Printf("[TRACE] %s: GET %s", d, &url.URL{
Path: "/v1/" + d.path,
RawQuery: opts.String(),
})
vaultSecret, err := clients.Vault().Logical().Read(d.path)
if err != nil {
return nil, nil, errors.Wrap(err, d.String())
}
// The secret could be nil if it does not exist.
if vaultSecret == nil {
return nil, nil, fmt.Errorf("%s: no secret exists at %s", d, d.path)
}
// Print any warnings.
d.printWarnings(vaultSecret.Warnings)
// Create our cloned secret.
secret := &Secret{
LeaseID: vaultSecret.LeaseID,
LeaseDuration: leaseDurationOrDefault(vaultSecret.LeaseDuration),
Renewable: vaultSecret.Renewable,
Data: vaultSecret.Data,
}
d.secret = secret
return respWithMetadata(secret)
}

View file

@ -46,10 +46,7 @@ func (d *VaultTokenQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfa
// If this is not the first query and we have a lease duration, sleep until we
// try to renew.
if opts.WaitIndex != 0 && d.leaseDuration != 0 {
dur := time.Duration(d.leaseDuration/2.0) * time.Second
if dur == 0 {
dur = VaultDefaultLeaseDuration
}
dur := vaultRenewDuration(d.leaseDuration)
log.Printf("[TRACE] %s: long polling for %s", d, dur)

View file

@ -57,10 +57,7 @@ func (d *VaultWriteQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfa
// If this is not the first query and we have a lease duration, sleep until we
// try to renew.
if opts.WaitIndex != 0 && d.secret != nil && d.secret.LeaseDuration != 0 {
dur := time.Duration(d.secret.LeaseDuration/2.0) * time.Second
if dur == 0 {
dur = VaultDefaultLeaseDuration
}
dur := vaultRenewDuration(d.secret.LeaseDuration)
log.Printf("[TRACE] %s: long polling for %s", d, dur)
@ -83,15 +80,34 @@ func (d *VaultWriteQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfa
if err == nil {
log.Printf("[TRACE] %s: successfully renewed %s", d, d.secret.LeaseID)
// Print any warnings
d.printWarnings(renewal.Warnings)
secret := &Secret{
RequestID: renewal.RequestID,
LeaseID: renewal.LeaseID,
LeaseDuration: d.secret.LeaseDuration,
Renewable: renewal.Renewable,
Data: d.secret.Data,
RequestID: renewal.RequestID,
LeaseID: renewal.LeaseID,
Renewable: renewal.Renewable,
Data: d.secret.Data,
}
// For some older versions of Vault, the renewal did not include the
// remaining lease duration, so just use the original lease duration,
// because it's the best we can do.
if renewal.LeaseDuration != 0 {
secret.LeaseDuration = renewal.LeaseDuration
}
d.secret = secret
// If the remaining time on the lease is less than or equal to our
// configured grace period, generate a new credential now. This will help
// minimize downtime, since Vault will revoke credentials immediately
// when their maximum TTL expires.
remaining := time.Duration(d.secret.LeaseDuration) * time.Second
if remaining <= opts.VaultGrace {
log.Printf("[DEBUG] %s: remaining lease (%s) < grace (%s), acquiring new",
d, remaining, opts.VaultGrace)
return d.writeSecret(clients, opts)
}
return respWithMetadata(secret)
}
@ -101,36 +117,7 @@ func (d *VaultWriteQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfa
// If we got this far, we either didn't have a secret to renew, the secret was
// not renewable, or the renewal failed, so attempt a fresh write.
log.Printf("[TRACE] %s: PUT %s", d, &url.URL{
Path: "/v1/" + d.path,
RawQuery: opts.String(),
})
vaultSecret, err := clients.Vault().Logical().Write(d.path, d.data)
if err != nil {
return nil, nil, errors.Wrap(err, d.String())
}
// The secret could be nil if it does not exist.
if vaultSecret == nil {
return nil, nil, fmt.Errorf("%s: no secret exists at %s", d, d.path)
}
// Print any warnings.
for _, w := range vaultSecret.Warnings {
log.Printf("[WARN] %s: %s", d, w)
}
// Create our cloned secret.
secret := &Secret{
LeaseID: vaultSecret.LeaseID,
LeaseDuration: leaseDurationOrDefault(vaultSecret.LeaseDuration),
Renewable: vaultSecret.Renewable,
Data: vaultSecret.Data,
}
d.secret = secret
return respWithMetadata(secret)
return d.writeSecret(clients, opts)
}
// CanShare returns if this dependency is shareable.
@ -170,3 +157,42 @@ func sha1Map(m map[string]interface{}) string {
return fmt.Sprintf("%.4x", h.Sum(nil))
}
func (d *VaultWriteQuery) printWarnings(warnings []string) {
for _, w := range warnings {
log.Printf("[WARN] %s: %s", d, w)
}
}
func (d *VaultWriteQuery) writeSecret(clients *ClientSet, opts *QueryOptions) (interface{}, *ResponseMetadata, error) {
log.Printf("[TRACE] %s: PUT %s", d, &url.URL{
Path: "/v1/" + d.path,
RawQuery: opts.String(),
})
vaultSecret, err := clients.Vault().Logical().Write(d.path, d.data)
if err != nil {
return nil, nil, errors.Wrap(err, d.String())
}
// The secret could be nil if it does not exist.
if vaultSecret == nil {
return nil, nil, fmt.Errorf("%s: no secret exists at %s", d, d.path)
}
// Print any warnings.
for _, w := range vaultSecret.Warnings {
log.Printf("[WARN] %s: %s", d, w)
}
// Create our cloned secret.
secret := &Secret{
LeaseID: vaultSecret.LeaseID,
LeaseDuration: leaseDurationOrDefault(vaultSecret.LeaseDuration),
Renewable: vaultSecret.Renewable,
Data: vaultSecret.Data,
}
d.secret = secret
return respWithMetadata(secret)
}

View file

@ -776,10 +776,11 @@ func (r *Runner) init() error {
// destinations.
for _, ctmpl := range *r.config.Templates {
tmpl, err := template.NewTemplate(&template.NewTemplateInput{
Source: config.StringVal(ctmpl.Source),
Contents: config.StringVal(ctmpl.Contents),
LeftDelim: config.StringVal(ctmpl.LeftDelim),
RightDelim: config.StringVal(ctmpl.RightDelim),
Source: config.StringVal(ctmpl.Source),
Contents: config.StringVal(ctmpl.Contents),
ErrMissingKey: config.BoolVal(ctmpl.ErrMissingKey),
LeftDelim: config.StringVal(ctmpl.LeftDelim),
RightDelim: config.StringVal(ctmpl.RightDelim),
})
if err != nil {
return err
@ -1173,6 +1174,7 @@ func newWatcher(c *config.Config, clients *dep.ClientSet, once bool) (*watch.Wat
// dependencies like reading a file from disk.
RetryFuncDefault: nil,
RetryFuncVault: watch.RetryFunc(c.Vault.Retry.RetryFunc()),
VaultGrace: config.TimeDurationVal(c.Vault.Grace),
})
if err != nil {
return nil, errors.Wrap(err, "runner")

View file

@ -26,11 +26,22 @@ import (
var now = func() time.Time { return time.Now().UTC() }
// datacentersFunc returns or accumulates datacenter dependencies.
func datacentersFunc(b *Brain, used, missing *dep.Set) func() ([]string, error) {
return func() ([]string, error) {
func datacentersFunc(b *Brain, used, missing *dep.Set) func(ignore ...bool) ([]string, error) {
return func(i ...bool) ([]string, error) {
result := []string{}
d, err := dep.NewCatalogDatacentersQuery()
var ignore bool
switch len(i) {
case 0:
ignore = false
case 1:
ignore = i[0]
default:
return result, fmt.Errorf("datacenters: wrong number of arguments, expected 0 or 1"+
", but got %d", len(i))
}
d, err := dep.NewCatalogDatacentersQuery(ignore)
if err != nil {
return result, err
}

View file

@ -41,6 +41,10 @@ type Template struct {
// hexMD5 stores the hex version of the MD5
hexMD5 string
// errMissingKey causes the template processing to exit immediately if a map
// is indexed with a key that does not exist.
errMissingKey bool
}
// NewTemplateInput is used as input when creating the template.
@ -51,6 +55,10 @@ type NewTemplateInput struct {
// Contents are the raw template contents.
Contents string
// ErrMissingKey causes the template parser to exit immediately with an error
// when a map is indexed with a key that does not exist.
ErrMissingKey bool
// LeftDelim and RightDelim are the template delimiters.
LeftDelim string
RightDelim string
@ -77,6 +85,7 @@ func NewTemplate(i *NewTemplateInput) (*Template, error) {
t.contents = i.Contents
t.leftDelim = i.LeftDelim
t.rightDelim = i.RightDelim
t.errMissingKey = i.ErrMissingKey
if i.Source != "" {
contents, err := ioutil.ReadFile(i.Source)
@ -152,6 +161,12 @@ func (t *Template) Execute(i *ExecuteInput) (*ExecuteResult, error) {
missing: &missing,
}))
if t.errMissingKey {
tmpl.Option("missingkey=error")
} else {
tmpl.Option("missingkey=zero")
}
tmpl, err := tmpl.Parse(t.contents)
if err != nil {
return nil, errors.Wrap(err, "parse")
@ -246,8 +261,5 @@ func funcMap(i *funcMapInput) template.FuncMap {
"multiply": multiply,
"divide": divide,
"modulo": modulo,
// Deprecated functions
"key_or_default": keyWithDefaultFunc(i.brain, i.used, i.missing),
}
}

View file

@ -44,6 +44,11 @@ type View struct {
// stopCh is used to stop polling on this View
stopCh chan struct{}
// vaultGrace is the grace period between a lease and the max TTL for which
// Consul Template will generate a new secret instead of renewing an existing
// one.
vaultGrace time.Duration
}
// NewViewInput is used as input to the NewView function.
@ -65,6 +70,11 @@ type NewViewInput struct {
// RetryFunc is a function which dictates how this view should retry on
// upstream errors.
RetryFunc RetryFunc
// VaultGrace is the grace period between a lease and the max TTL for which
// Consul Template will generate a new secret instead of renewing an existing
// one.
VaultGrace time.Duration
}
// NewView constructs a new view with the given inputs.
@ -76,6 +86,7 @@ func NewView(i *NewViewInput) (*View, error) {
once: i.Once,
retryFunc: i.RetryFunc,
stopCh: make(chan struct{}, 1),
vaultGrace: i.VaultGrace,
}, nil
}
@ -200,6 +211,7 @@ func (v *View) fetch(doneCh, successCh chan<- struct{}, errCh chan<- error) {
AllowStale: allowStale,
WaitTime: defaultWaitTime,
WaitIndex: v.lastIndex,
VaultGrace: v.vaultGrace,
})
if err != nil {
if err == dep.ErrStopped {

View file

@ -42,6 +42,11 @@ type Watcher struct {
retryFuncConsul RetryFunc
retryFuncDefault RetryFunc
retryFuncVault RetryFunc
// vaultGrace is the grace period between a lease and the max TTL for which
// Consul Template will generate a new secret instead of renewing an existing
// one.
vaultGrace time.Duration
}
type NewWatcherInput struct {
@ -61,6 +66,11 @@ type NewWatcherInput struct {
RetryFuncConsul RetryFunc
RetryFuncDefault RetryFunc
RetryFuncVault RetryFunc
// VaultGrace is the grace period between a lease and the max TTL for which
// Consul Template will generate a new secret instead of renewing an existing
// one.
VaultGrace time.Duration
}
// NewWatcher creates a new watcher using the given API client.
@ -75,6 +85,7 @@ func NewWatcher(i *NewWatcherInput) (*Watcher, error) {
retryFuncConsul: i.RetryFuncConsul,
retryFuncDefault: i.RetryFuncDefault,
retryFuncVault: i.RetryFuncVault,
vaultGrace: i.VaultGrace,
}
// Start a watcher for the Vault renew if that config was specified
@ -138,6 +149,7 @@ func (w *Watcher) Add(d dep.Dependency) (bool, error) {
MaxStale: w.maxStale,
Once: w.once,
RetryFunc: retryFunc,
VaultGrace: w.vaultGrace,
})
if err != nil {
return false, errors.Wrap(err, "watcher")

38
vendor/vendor.json vendored
View file

@ -599,44 +599,44 @@
{
"checksumSHA1": "Nu2j1GusM7ZH0uYrGzqr1K7yH7I=",
"path": "github.com/hashicorp/consul-template/child",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "7TBPXChZZS84qZbzP7qFYeQding=",
"checksumSHA1": "QWcGW3wELSp/YsOVzCW02oEYR7c=",
"path": "github.com/hashicorp/consul-template/config",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "7rKifM082rlbHN9EcsVyu7VXLoo=",
"checksumSHA1": "mV7yjHpIfO4yRAdQaBlAqdGDKO8=",
"path": "github.com/hashicorp/consul-template/dependency",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "Ci5EmLs/h7ke9bUg7a34UfTbB5U=",
"checksumSHA1": "ZTlPhrxNzME75A4ydXM88TFt3Qs=",
"path": "github.com/hashicorp/consul-template/manager",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "oskgb0WteBKOItG8NNDduM7E/D0=",
"path": "github.com/hashicorp/consul-template/signals",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "804hk7BQd6V2xjBwz+cE0hdzSlI=",
"checksumSHA1": "zSvJlNfZS3fCRlFaZ7r9Q+N17T8=",
"path": "github.com/hashicorp/consul-template/template",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "KjcelGP7qPh0ObKouBJuHmXUjqk=",
"checksumSHA1": "85W96Fo50FmrMaba7Dk12aDfwWs=",
"path": "github.com/hashicorp/consul-template/watch",
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
"revisionTime": "2017-05-26T18:30:17Z"
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
"revisionTime": "2017-07-05T14:04:00Z"
},
{
"checksumSHA1": "jfELEMRhiTcppZmRH+ZwtkVS5Uw=",