Merge pull request #2803 from hashicorp/f-update-ct
Update consul-template
This commit is contained in:
commit
fe69901fb9
52
vendor/github.com/hashicorp/consul-template/config/config.go
generated
vendored
52
vendor/github.com/hashicorp/consul-template/config/config.go
generated
vendored
|
@ -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
|
// Create a new, empty config
|
||||||
var c Config
|
var c Config
|
||||||
|
|
||||||
|
|
16
vendor/github.com/hashicorp/consul-template/config/template.go
generated
vendored
16
vendor/github.com/hashicorp/consul-template/config/template.go
generated
vendored
|
@ -56,6 +56,10 @@ type TemplateConfig struct {
|
||||||
// This is required unless running in debug/dry mode.
|
// This is required unless running in debug/dry mode.
|
||||||
Destination *string `mapstructure:"destination"`
|
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
|
// Exec is the configuration for the command to run when the template renders
|
||||||
// successfully.
|
// successfully.
|
||||||
Exec *ExecConfig `mapstructure:"exec"`
|
Exec *ExecConfig `mapstructure:"exec"`
|
||||||
|
@ -105,6 +109,8 @@ func (c *TemplateConfig) Copy() *TemplateConfig {
|
||||||
|
|
||||||
o.Destination = c.Destination
|
o.Destination = c.Destination
|
||||||
|
|
||||||
|
o.ErrMissingKey = c.ErrMissingKey
|
||||||
|
|
||||||
if c.Exec != nil {
|
if c.Exec != nil {
|
||||||
o.Exec = c.Exec.Copy()
|
o.Exec = c.Exec.Copy()
|
||||||
}
|
}
|
||||||
|
@ -161,6 +167,10 @@ func (c *TemplateConfig) Merge(o *TemplateConfig) *TemplateConfig {
|
||||||
r.Destination = o.Destination
|
r.Destination = o.Destination
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.ErrMissingKey != nil {
|
||||||
|
r.ErrMissingKey = o.ErrMissingKey
|
||||||
|
}
|
||||||
|
|
||||||
if o.Exec != nil {
|
if o.Exec != nil {
|
||||||
r.Exec = r.Exec.Merge(o.Exec)
|
r.Exec = r.Exec.Merge(o.Exec)
|
||||||
}
|
}
|
||||||
|
@ -211,6 +221,10 @@ func (c *TemplateConfig) Finalize() {
|
||||||
c.Destination = String("")
|
c.Destination = String("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.ErrMissingKey == nil {
|
||||||
|
c.ErrMissingKey = Bool(false)
|
||||||
|
}
|
||||||
|
|
||||||
if c.Exec == nil {
|
if c.Exec == nil {
|
||||||
c.Exec = DefaultExecConfig()
|
c.Exec = DefaultExecConfig()
|
||||||
}
|
}
|
||||||
|
@ -258,6 +272,7 @@ func (c *TemplateConfig) GoString() string {
|
||||||
"CommandTimeout:%s, "+
|
"CommandTimeout:%s, "+
|
||||||
"Contents:%s, "+
|
"Contents:%s, "+
|
||||||
"Destination:%s, "+
|
"Destination:%s, "+
|
||||||
|
"ErrMissingKey:%s, "+
|
||||||
"Exec:%#v, "+
|
"Exec:%#v, "+
|
||||||
"Perms:%s, "+
|
"Perms:%s, "+
|
||||||
"Source:%s, "+
|
"Source:%s, "+
|
||||||
|
@ -270,6 +285,7 @@ func (c *TemplateConfig) GoString() string {
|
||||||
TimeDurationGoString(c.CommandTimeout),
|
TimeDurationGoString(c.CommandTimeout),
|
||||||
StringGoString(c.Contents),
|
StringGoString(c.Contents),
|
||||||
StringGoString(c.Destination),
|
StringGoString(c.Destination),
|
||||||
|
BoolGoString(c.ErrMissingKey),
|
||||||
c.Exec,
|
c.Exec,
|
||||||
FileModeGoString(c.Perms),
|
FileModeGoString(c.Perms),
|
||||||
StringGoString(c.Source),
|
StringGoString(c.Source),
|
||||||
|
|
21
vendor/github.com/hashicorp/consul-template/config/vault.go
generated
vendored
21
vendor/github.com/hashicorp/consul-template/config/vault.go
generated
vendored
|
@ -8,6 +8,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
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
|
// DefaultVaultRenewToken is the default value for if the Vault token should
|
||||||
// be renewed.
|
// be renewed.
|
||||||
DefaultVaultRenewToken = true
|
DefaultVaultRenewToken = true
|
||||||
|
@ -33,6 +38,10 @@ type VaultConfig struct {
|
||||||
// Enabled controls whether the Vault integration is active.
|
// Enabled controls whether the Vault integration is active.
|
||||||
Enabled *bool `mapstructure:"enabled"`
|
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 renews the Vault token.
|
||||||
RenewToken *bool `mapstructure:"renew_token"`
|
RenewToken *bool `mapstructure:"renew_token"`
|
||||||
|
|
||||||
|
@ -80,6 +89,8 @@ func (c *VaultConfig) Copy() *VaultConfig {
|
||||||
|
|
||||||
o.Enabled = c.Enabled
|
o.Enabled = c.Enabled
|
||||||
|
|
||||||
|
o.Grace = c.Grace
|
||||||
|
|
||||||
o.RenewToken = c.RenewToken
|
o.RenewToken = c.RenewToken
|
||||||
|
|
||||||
if c.Retry != nil {
|
if c.Retry != nil {
|
||||||
|
@ -127,6 +138,10 @@ func (c *VaultConfig) Merge(o *VaultConfig) *VaultConfig {
|
||||||
r.Enabled = o.Enabled
|
r.Enabled = o.Enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.Grace != nil {
|
||||||
|
r.Grace = o.Grace
|
||||||
|
}
|
||||||
|
|
||||||
if o.RenewToken != nil {
|
if o.RenewToken != nil {
|
||||||
r.RenewToken = o.RenewToken
|
r.RenewToken = o.RenewToken
|
||||||
}
|
}
|
||||||
|
@ -162,6 +177,10 @@ func (c *VaultConfig) Finalize() {
|
||||||
}, "")
|
}, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.Grace == nil {
|
||||||
|
c.Grace = TimeDuration(DefaultVaultGrace)
|
||||||
|
}
|
||||||
|
|
||||||
if c.RenewToken == nil {
|
if c.RenewToken == nil {
|
||||||
c.RenewToken = boolFromEnv([]string{
|
c.RenewToken = boolFromEnv([]string{
|
||||||
"VAULT_RENEW_TOKEN",
|
"VAULT_RENEW_TOKEN",
|
||||||
|
@ -239,6 +258,7 @@ func (c *VaultConfig) GoString() string {
|
||||||
return fmt.Sprintf("&VaultConfig{"+
|
return fmt.Sprintf("&VaultConfig{"+
|
||||||
"Address:%s, "+
|
"Address:%s, "+
|
||||||
"Enabled:%s, "+
|
"Enabled:%s, "+
|
||||||
|
"Grace:%s, "+
|
||||||
"RenewToken:%s, "+
|
"RenewToken:%s, "+
|
||||||
"Retry:%#v, "+
|
"Retry:%#v, "+
|
||||||
"SSL:%#v, "+
|
"SSL:%#v, "+
|
||||||
|
@ -247,6 +267,7 @@ func (c *VaultConfig) GoString() string {
|
||||||
"UnwrapToken:%s"+
|
"UnwrapToken:%s"+
|
||||||
"}",
|
"}",
|
||||||
StringGoString(c.Address),
|
StringGoString(c.Address),
|
||||||
|
TimeDurationGoString(c.Grace),
|
||||||
BoolGoString(c.Enabled),
|
BoolGoString(c.Enabled),
|
||||||
BoolGoString(c.RenewToken),
|
BoolGoString(c.RenewToken),
|
||||||
c.Retry,
|
c.Retry,
|
||||||
|
|
24
vendor/github.com/hashicorp/consul-template/dependency/catalog_datacenters.go
generated
vendored
24
vendor/github.com/hashicorp/consul-template/dependency/catalog_datacenters.go
generated
vendored
|
@ -6,6 +6,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/api"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,13 +21,16 @@ var (
|
||||||
|
|
||||||
// CatalogDatacentersQuery is the dependency to query all datacenters
|
// CatalogDatacentersQuery is the dependency to query all datacenters
|
||||||
type CatalogDatacentersQuery struct {
|
type CatalogDatacentersQuery struct {
|
||||||
|
ignoreFailing bool
|
||||||
|
|
||||||
stopCh chan struct{}
|
stopCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCatalogDatacentersQuery creates a new datacenter dependency.
|
// NewCatalogDatacentersQuery creates a new datacenter dependency.
|
||||||
func NewCatalogDatacentersQuery() (*CatalogDatacentersQuery, error) {
|
func NewCatalogDatacentersQuery(ignoreFailing bool) (*CatalogDatacentersQuery, error) {
|
||||||
return &CatalogDatacentersQuery{
|
return &CatalogDatacentersQuery{
|
||||||
stopCh: make(chan struct{}, 1),
|
ignoreFailing: ignoreFailing,
|
||||||
|
stopCh: make(chan struct{}, 1),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +68,22 @@ func (d *CatalogDatacentersQuery) Fetch(clients *ClientSet, opts *QueryOptions)
|
||||||
return nil, nil, errors.Wrapf(err, d.String())
|
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))
|
log.Printf("[TRACE] %s: returned %d results", d, len(result))
|
||||||
|
|
||||||
sort.Strings(result)
|
sort.Strings(result)
|
||||||
|
|
15
vendor/github.com/hashicorp/consul-template/dependency/dependency.go
generated
vendored
15
vendor/github.com/hashicorp/consul-template/dependency/dependency.go
generated
vendored
|
@ -1,7 +1,6 @@
|
||||||
package dependency
|
package dependency
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -42,19 +41,6 @@ type Dependency interface {
|
||||||
// ServiceTags is a slice of tags assigned to a Service
|
// ServiceTags is a slice of tags assigned to a Service
|
||||||
type ServiceTags []string
|
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
|
// 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
|
// client-agnostic, and the dependency determines which, if any, of the options
|
||||||
// to use.
|
// to use.
|
||||||
|
@ -63,6 +49,7 @@ type QueryOptions struct {
|
||||||
Datacenter string
|
Datacenter string
|
||||||
Near string
|
Near string
|
||||||
RequireConsistent bool
|
RequireConsistent bool
|
||||||
|
VaultGrace time.Duration
|
||||||
WaitIndex uint64
|
WaitIndex uint64
|
||||||
WaitTime time.Duration
|
WaitTime time.Duration
|
||||||
}
|
}
|
||||||
|
|
11
vendor/github.com/hashicorp/consul-template/dependency/vault_common.go
generated
vendored
11
vendor/github.com/hashicorp/consul-template/dependency/vault_common.go
generated
vendored
|
@ -26,3 +26,14 @@ func leaseDurationOrDefault(d int) int {
|
||||||
}
|
}
|
||||||
return d
|
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
|
||||||
|
}
|
||||||
|
|
91
vendor/github.com/hashicorp/consul-template/dependency/vault_read.go
generated
vendored
91
vendor/github.com/hashicorp/consul-template/dependency/vault_read.go
generated
vendored
|
@ -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
|
// If this is not the first query and we have a lease duration, sleep until we
|
||||||
// try to renew.
|
// try to renew.
|
||||||
if opts.WaitIndex != 0 && d.secret != nil && d.secret.LeaseDuration != 0 {
|
if opts.WaitIndex != 0 && d.secret != nil && d.secret.LeaseDuration != 0 {
|
||||||
dur := time.Duration(d.secret.LeaseDuration/2.0) * time.Second
|
dur := vaultRenewDuration(d.secret.LeaseDuration)
|
||||||
if dur == 0 {
|
|
||||||
dur = VaultDefaultLeaseDuration
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[TRACE] %s: long polling for %s", d, dur)
|
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 {
|
if err == nil {
|
||||||
log.Printf("[TRACE] %s: successfully renewed %s", d, d.secret.LeaseID)
|
log.Printf("[TRACE] %s: successfully renewed %s", d, d.secret.LeaseID)
|
||||||
|
|
||||||
|
// Print any warnings
|
||||||
|
d.printWarnings(renewal.Warnings)
|
||||||
|
|
||||||
secret := &Secret{
|
secret := &Secret{
|
||||||
RequestID: renewal.RequestID,
|
RequestID: renewal.RequestID,
|
||||||
LeaseID: renewal.LeaseID,
|
LeaseID: renewal.LeaseID,
|
||||||
|
@ -83,8 +83,25 @@ func (d *VaultReadQuery) Fetch(clients *ClientSet, opts *QueryOptions) (interfac
|
||||||
Renewable: renewal.Renewable,
|
Renewable: renewal.Renewable,
|
||||||
Data: d.secret.Data,
|
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
|
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)
|
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
|
// 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.
|
// not renewable, or the renewal failed, so attempt a fresh read.
|
||||||
log.Printf("[TRACE] %s: GET %s", d, &url.URL{
|
return d.readSecret(clients, opts)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanShare returns if this dependency is shareable.
|
// CanShare returns if this dependency is shareable.
|
||||||
|
@ -144,3 +133,39 @@ func (d *VaultReadQuery) String() string {
|
||||||
func (d *VaultReadQuery) Type() Type {
|
func (d *VaultReadQuery) Type() Type {
|
||||||
return TypeVault
|
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)
|
||||||
|
}
|
||||||
|
|
5
vendor/github.com/hashicorp/consul-template/dependency/vault_token.go
generated
vendored
5
vendor/github.com/hashicorp/consul-template/dependency/vault_token.go
generated
vendored
|
@ -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
|
// If this is not the first query and we have a lease duration, sleep until we
|
||||||
// try to renew.
|
// try to renew.
|
||||||
if opts.WaitIndex != 0 && d.leaseDuration != 0 {
|
if opts.WaitIndex != 0 && d.leaseDuration != 0 {
|
||||||
dur := time.Duration(d.leaseDuration/2.0) * time.Second
|
dur := vaultRenewDuration(d.leaseDuration)
|
||||||
if dur == 0 {
|
|
||||||
dur = VaultDefaultLeaseDuration
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[TRACE] %s: long polling for %s", d, dur)
|
log.Printf("[TRACE] %s: long polling for %s", d, dur)
|
||||||
|
|
||||||
|
|
104
vendor/github.com/hashicorp/consul-template/dependency/vault_write.go
generated
vendored
104
vendor/github.com/hashicorp/consul-template/dependency/vault_write.go
generated
vendored
|
@ -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
|
// If this is not the first query and we have a lease duration, sleep until we
|
||||||
// try to renew.
|
// try to renew.
|
||||||
if opts.WaitIndex != 0 && d.secret != nil && d.secret.LeaseDuration != 0 {
|
if opts.WaitIndex != 0 && d.secret != nil && d.secret.LeaseDuration != 0 {
|
||||||
dur := time.Duration(d.secret.LeaseDuration/2.0) * time.Second
|
dur := vaultRenewDuration(d.secret.LeaseDuration)
|
||||||
if dur == 0 {
|
|
||||||
dur = VaultDefaultLeaseDuration
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[TRACE] %s: long polling for %s", d, dur)
|
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 {
|
if err == nil {
|
||||||
log.Printf("[TRACE] %s: successfully renewed %s", d, d.secret.LeaseID)
|
log.Printf("[TRACE] %s: successfully renewed %s", d, d.secret.LeaseID)
|
||||||
|
|
||||||
|
// Print any warnings
|
||||||
|
d.printWarnings(renewal.Warnings)
|
||||||
|
|
||||||
secret := &Secret{
|
secret := &Secret{
|
||||||
RequestID: renewal.RequestID,
|
RequestID: renewal.RequestID,
|
||||||
LeaseID: renewal.LeaseID,
|
LeaseID: renewal.LeaseID,
|
||||||
LeaseDuration: d.secret.LeaseDuration,
|
Renewable: renewal.Renewable,
|
||||||
Renewable: renewal.Renewable,
|
Data: d.secret.Data,
|
||||||
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
|
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)
|
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
|
// 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.
|
// not renewable, or the renewal failed, so attempt a fresh write.
|
||||||
log.Printf("[TRACE] %s: PUT %s", d, &url.URL{
|
return d.writeSecret(clients, opts)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanShare returns if this dependency is shareable.
|
// 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))
|
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)
|
||||||
|
}
|
||||||
|
|
10
vendor/github.com/hashicorp/consul-template/manager/runner.go
generated
vendored
10
vendor/github.com/hashicorp/consul-template/manager/runner.go
generated
vendored
|
@ -776,10 +776,11 @@ func (r *Runner) init() error {
|
||||||
// destinations.
|
// destinations.
|
||||||
for _, ctmpl := range *r.config.Templates {
|
for _, ctmpl := range *r.config.Templates {
|
||||||
tmpl, err := template.NewTemplate(&template.NewTemplateInput{
|
tmpl, err := template.NewTemplate(&template.NewTemplateInput{
|
||||||
Source: config.StringVal(ctmpl.Source),
|
Source: config.StringVal(ctmpl.Source),
|
||||||
Contents: config.StringVal(ctmpl.Contents),
|
Contents: config.StringVal(ctmpl.Contents),
|
||||||
LeftDelim: config.StringVal(ctmpl.LeftDelim),
|
ErrMissingKey: config.BoolVal(ctmpl.ErrMissingKey),
|
||||||
RightDelim: config.StringVal(ctmpl.RightDelim),
|
LeftDelim: config.StringVal(ctmpl.LeftDelim),
|
||||||
|
RightDelim: config.StringVal(ctmpl.RightDelim),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.
|
// dependencies like reading a file from disk.
|
||||||
RetryFuncDefault: nil,
|
RetryFuncDefault: nil,
|
||||||
RetryFuncVault: watch.RetryFunc(c.Vault.Retry.RetryFunc()),
|
RetryFuncVault: watch.RetryFunc(c.Vault.Retry.RetryFunc()),
|
||||||
|
VaultGrace: config.TimeDurationVal(c.Vault.Grace),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "runner")
|
return nil, errors.Wrap(err, "runner")
|
||||||
|
|
17
vendor/github.com/hashicorp/consul-template/template/funcs.go
generated
vendored
17
vendor/github.com/hashicorp/consul-template/template/funcs.go
generated
vendored
|
@ -26,11 +26,22 @@ import (
|
||||||
var now = func() time.Time { return time.Now().UTC() }
|
var now = func() time.Time { return time.Now().UTC() }
|
||||||
|
|
||||||
// datacentersFunc returns or accumulates datacenter dependencies.
|
// datacentersFunc returns or accumulates datacenter dependencies.
|
||||||
func datacentersFunc(b *Brain, used, missing *dep.Set) func() ([]string, error) {
|
func datacentersFunc(b *Brain, used, missing *dep.Set) func(ignore ...bool) ([]string, error) {
|
||||||
return func() ([]string, error) {
|
return func(i ...bool) ([]string, error) {
|
||||||
result := []string{}
|
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 {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
18
vendor/github.com/hashicorp/consul-template/template/template.go
generated
vendored
18
vendor/github.com/hashicorp/consul-template/template/template.go
generated
vendored
|
@ -41,6 +41,10 @@ type Template struct {
|
||||||
|
|
||||||
// hexMD5 stores the hex version of the MD5
|
// hexMD5 stores the hex version of the MD5
|
||||||
hexMD5 string
|
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.
|
// NewTemplateInput is used as input when creating the template.
|
||||||
|
@ -51,6 +55,10 @@ type NewTemplateInput struct {
|
||||||
// Contents are the raw template contents.
|
// Contents are the raw template contents.
|
||||||
Contents string
|
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 and RightDelim are the template delimiters.
|
||||||
LeftDelim string
|
LeftDelim string
|
||||||
RightDelim string
|
RightDelim string
|
||||||
|
@ -77,6 +85,7 @@ func NewTemplate(i *NewTemplateInput) (*Template, error) {
|
||||||
t.contents = i.Contents
|
t.contents = i.Contents
|
||||||
t.leftDelim = i.LeftDelim
|
t.leftDelim = i.LeftDelim
|
||||||
t.rightDelim = i.RightDelim
|
t.rightDelim = i.RightDelim
|
||||||
|
t.errMissingKey = i.ErrMissingKey
|
||||||
|
|
||||||
if i.Source != "" {
|
if i.Source != "" {
|
||||||
contents, err := ioutil.ReadFile(i.Source)
|
contents, err := ioutil.ReadFile(i.Source)
|
||||||
|
@ -152,6 +161,12 @@ func (t *Template) Execute(i *ExecuteInput) (*ExecuteResult, error) {
|
||||||
missing: &missing,
|
missing: &missing,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
if t.errMissingKey {
|
||||||
|
tmpl.Option("missingkey=error")
|
||||||
|
} else {
|
||||||
|
tmpl.Option("missingkey=zero")
|
||||||
|
}
|
||||||
|
|
||||||
tmpl, err := tmpl.Parse(t.contents)
|
tmpl, err := tmpl.Parse(t.contents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "parse")
|
return nil, errors.Wrap(err, "parse")
|
||||||
|
@ -246,8 +261,5 @@ func funcMap(i *funcMapInput) template.FuncMap {
|
||||||
"multiply": multiply,
|
"multiply": multiply,
|
||||||
"divide": divide,
|
"divide": divide,
|
||||||
"modulo": modulo,
|
"modulo": modulo,
|
||||||
|
|
||||||
// Deprecated functions
|
|
||||||
"key_or_default": keyWithDefaultFunc(i.brain, i.used, i.missing),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
vendor/github.com/hashicorp/consul-template/watch/view.go
generated
vendored
12
vendor/github.com/hashicorp/consul-template/watch/view.go
generated
vendored
|
@ -44,6 +44,11 @@ type View struct {
|
||||||
|
|
||||||
// stopCh is used to stop polling on this View
|
// stopCh is used to stop polling on this View
|
||||||
stopCh chan struct{}
|
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.
|
// 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
|
// RetryFunc is a function which dictates how this view should retry on
|
||||||
// upstream errors.
|
// upstream errors.
|
||||||
RetryFunc RetryFunc
|
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.
|
// NewView constructs a new view with the given inputs.
|
||||||
|
@ -76,6 +86,7 @@ func NewView(i *NewViewInput) (*View, error) {
|
||||||
once: i.Once,
|
once: i.Once,
|
||||||
retryFunc: i.RetryFunc,
|
retryFunc: i.RetryFunc,
|
||||||
stopCh: make(chan struct{}, 1),
|
stopCh: make(chan struct{}, 1),
|
||||||
|
vaultGrace: i.VaultGrace,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +211,7 @@ func (v *View) fetch(doneCh, successCh chan<- struct{}, errCh chan<- error) {
|
||||||
AllowStale: allowStale,
|
AllowStale: allowStale,
|
||||||
WaitTime: defaultWaitTime,
|
WaitTime: defaultWaitTime,
|
||||||
WaitIndex: v.lastIndex,
|
WaitIndex: v.lastIndex,
|
||||||
|
VaultGrace: v.vaultGrace,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == dep.ErrStopped {
|
if err == dep.ErrStopped {
|
||||||
|
|
12
vendor/github.com/hashicorp/consul-template/watch/watcher.go
generated
vendored
12
vendor/github.com/hashicorp/consul-template/watch/watcher.go
generated
vendored
|
@ -42,6 +42,11 @@ type Watcher struct {
|
||||||
retryFuncConsul RetryFunc
|
retryFuncConsul RetryFunc
|
||||||
retryFuncDefault RetryFunc
|
retryFuncDefault RetryFunc
|
||||||
retryFuncVault 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 {
|
type NewWatcherInput struct {
|
||||||
|
@ -61,6 +66,11 @@ type NewWatcherInput struct {
|
||||||
RetryFuncConsul RetryFunc
|
RetryFuncConsul RetryFunc
|
||||||
RetryFuncDefault RetryFunc
|
RetryFuncDefault RetryFunc
|
||||||
RetryFuncVault 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.
|
// NewWatcher creates a new watcher using the given API client.
|
||||||
|
@ -75,6 +85,7 @@ func NewWatcher(i *NewWatcherInput) (*Watcher, error) {
|
||||||
retryFuncConsul: i.RetryFuncConsul,
|
retryFuncConsul: i.RetryFuncConsul,
|
||||||
retryFuncDefault: i.RetryFuncDefault,
|
retryFuncDefault: i.RetryFuncDefault,
|
||||||
retryFuncVault: i.RetryFuncVault,
|
retryFuncVault: i.RetryFuncVault,
|
||||||
|
vaultGrace: i.VaultGrace,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a watcher for the Vault renew if that config was specified
|
// 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,
|
MaxStale: w.maxStale,
|
||||||
Once: w.once,
|
Once: w.once,
|
||||||
RetryFunc: retryFunc,
|
RetryFunc: retryFunc,
|
||||||
|
VaultGrace: w.vaultGrace,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "watcher")
|
return false, errors.Wrap(err, "watcher")
|
||||||
|
|
38
vendor/vendor.json
vendored
38
vendor/vendor.json
vendored
|
@ -599,44 +599,44 @@
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Nu2j1GusM7ZH0uYrGzqr1K7yH7I=",
|
"checksumSHA1": "Nu2j1GusM7ZH0uYrGzqr1K7yH7I=",
|
||||||
"path": "github.com/hashicorp/consul-template/child",
|
"path": "github.com/hashicorp/consul-template/child",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "7TBPXChZZS84qZbzP7qFYeQding=",
|
"checksumSHA1": "QWcGW3wELSp/YsOVzCW02oEYR7c=",
|
||||||
"path": "github.com/hashicorp/consul-template/config",
|
"path": "github.com/hashicorp/consul-template/config",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "7rKifM082rlbHN9EcsVyu7VXLoo=",
|
"checksumSHA1": "mV7yjHpIfO4yRAdQaBlAqdGDKO8=",
|
||||||
"path": "github.com/hashicorp/consul-template/dependency",
|
"path": "github.com/hashicorp/consul-template/dependency",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Ci5EmLs/h7ke9bUg7a34UfTbB5U=",
|
"checksumSHA1": "ZTlPhrxNzME75A4ydXM88TFt3Qs=",
|
||||||
"path": "github.com/hashicorp/consul-template/manager",
|
"path": "github.com/hashicorp/consul-template/manager",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "oskgb0WteBKOItG8NNDduM7E/D0=",
|
"checksumSHA1": "oskgb0WteBKOItG8NNDduM7E/D0=",
|
||||||
"path": "github.com/hashicorp/consul-template/signals",
|
"path": "github.com/hashicorp/consul-template/signals",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "804hk7BQd6V2xjBwz+cE0hdzSlI=",
|
"checksumSHA1": "zSvJlNfZS3fCRlFaZ7r9Q+N17T8=",
|
||||||
"path": "github.com/hashicorp/consul-template/template",
|
"path": "github.com/hashicorp/consul-template/template",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "KjcelGP7qPh0ObKouBJuHmXUjqk=",
|
"checksumSHA1": "85W96Fo50FmrMaba7Dk12aDfwWs=",
|
||||||
"path": "github.com/hashicorp/consul-template/watch",
|
"path": "github.com/hashicorp/consul-template/watch",
|
||||||
"revision": "92746fc5cf86dbb113558bacec43459a65c8df14",
|
"revision": "ecbc27c1922fed2f562e7fb63e1ad24e818fa60e",
|
||||||
"revisionTime": "2017-05-26T18:30:17Z"
|
"revisionTime": "2017-07-05T14:04:00Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "jfELEMRhiTcppZmRH+ZwtkVS5Uw=",
|
"checksumSHA1": "jfELEMRhiTcppZmRH+ZwtkVS5Uw=",
|
||||||
|
|
Loading…
Reference in a new issue