- changing the resource options to full names rather than shortcuts, make its more obvious
- adding a delay in the revoke option
This commit is contained in:
parent
f1807db7e2
commit
08d1667cb6
22
README.md
22
README.md
|
@ -13,6 +13,7 @@ Usage of bin/vault-sidekick:
|
||||||
-alsologtostderr=false: log to standard error as well as files
|
-alsologtostderr=false: log to standard error as well as files
|
||||||
-auth="": a configuration file in a json or yaml containing authentication arguments
|
-auth="": a configuration file in a json or yaml containing authentication arguments
|
||||||
-cn=: a resource to retrieve and monitor from vault (e.g. pki:name:cert.name, secret:db_password, aws:s3_backup)
|
-cn=: a resource to retrieve and monitor from vault (e.g. pki:name:cert.name, secret:db_password, aws:s3_backup)
|
||||||
|
-ca-cert="": a CA certificate to use in order to validate the vault service certificate
|
||||||
-delete-token=false: once the we have connected to vault, delete the token file from disk
|
-delete-token=false: once the we have connected to vault, delete the token file from disk
|
||||||
-dryrun=false: perform a dry run, printing the content to screen
|
-dryrun=false: perform a dry run, printing the content to screen
|
||||||
-log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
|
-log_backtrace_at=:0: when logging hits line file:N, emit a stack trace
|
||||||
|
@ -44,10 +45,10 @@ spec:
|
||||||
args:
|
args:
|
||||||
- -output=/etc/secrets
|
- -output=/etc/secrets
|
||||||
- -cn=pki:example.com:cn=commons.example.com,rv=true,up=2h
|
- -cn=pki:example.com:cn=commons.example.com,rv=true,up=2h
|
||||||
- -cn=secret:db/prod/username:fn=.credentials
|
- -cn=secret:db/prod/username:file=.credentials
|
||||||
- -cn=secret:db/prod/password
|
- -cn=secret:db/prod/password
|
||||||
- -cn=aws:s3_backsup:fn=.s3_creds
|
- -cn=aws:s3_backsup:file=.s3_creds
|
||||||
- -cn=template:database_credentials:tpl=/etc/templates/db.tmpl,fn=/etc/credentials
|
- -cn=template:database_credentials:tpl=/etc/templates/db.tmpl,file=/etc/credentials
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: secrets
|
- name: secrets
|
||||||
mountPath: /etc/secrets
|
mountPath: /etc/secrets
|
||||||
|
@ -73,16 +74,16 @@ expire, in order ensure the rotation of secrets. If you don't want this behaviou
|
||||||
your using the mysql dynamic secrets, you want to renew the secret not replace it
|
your using the mysql dynamic secrets, you want to renew the secret not replace it
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
[jest@starfury vault-sidekick]$ build/vault-sidekick -cn=mysql:my_database:fmt=yaml,rn=true
|
[jest@starfury vault-sidekick]$ build/vault-sidekick -cn=mysql:my_database:fmt=yaml,renew=true
|
||||||
or an iam policy renewed every hour
|
or an iam policy renewed every hour
|
||||||
[jest@starfury vault-sidekick]$ build/vault-sidekick -cn=aws:aws_policy_path:fmt=yaml,rn=true,up=1h
|
[jest@starfury vault-sidekick]$ build/vault-sidekick -cn=aws:aws_policy_path:fmt=yaml,renew=true,update=1h
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Or you want to rotate the secret every **1h** and **revoke** the previous one
|
Or you want to rotate the secret every **1h** and **revoke** the previous one
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
[jest@starfury vault-sidekick]$ build/vault-sidekick -cn=aws:my_s3_bucket:fmt=yaml,up=1h,rv=true
|
[jest@starfury vault-sidekick]$ build/vault-sidekick -cn=aws:my_s3_bucket:fmt=yaml,update=1h,revoke=true
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output Formatting**
|
**Output Formatting**
|
||||||
|
@ -116,9 +117,10 @@ Format: 'cert' is less of a format of more file scheme i.e. is just extracts the
|
||||||
|
|
||||||
**Resource Options**
|
**Resource Options**
|
||||||
|
|
||||||
- **fn**: (filaname) by default all file are relative to the output directory specified and will have the name NAME.RESOURCE; the fn options allows you to switch names and paths to write the files
|
- **file**: (filaname) by default all file are relative to the output directory specified and will have the name NAME.RESOURCE; the fn options allows you to switch names and paths to write the files
|
||||||
- **up**: (update) override the lease time of this resource and get/renew a secret on the specified duration e.g 1m, 2d, 5m10s
|
- **update**: (update) override the lease time of this resource and get/renew a secret on the specified duration e.g 1m, 2d, 5m10s
|
||||||
- **rn**: (renewal) override the default behavour on this resource, renew the resource when coming close to expiration e.g true, TRUE
|
- **renew**: (renewal) override the default behavour on this resource, renew the resource when coming close to expiration e.g true, TRUE
|
||||||
- **rv**: (revoke) revoke the old lease when you get retrieve a old one e.g. true, TRUE (default to allow the lease to expire and naturally revoke)
|
- **delay**: (renewal-delay) delay the revoking the lease of a resource for x period once time e.g 1m, 1h20s
|
||||||
|
- **revoke**: (revoke) revoke the old lease when you get retrieve a old one e.g. true, TRUE (default to allow the lease to expire and naturally revoke)
|
||||||
- **fmt**: (format) allows you to specify the output format of the resource / secret, e.g json, yaml, ini, txt
|
- **fmt**: (format) allows you to specify the output format of the resource / secret, e.g json, yaml, ini, txt
|
||||||
- **cn**: (comman name) is used in conjunction with the PKI resource. The common argument is passed as an argument when make a request to issue the certs.
|
- **cn**: (comman name) is used in conjunction with the PKI resource. The common argument is passed as an argument when make a request to issue the certs.
|
||||||
|
|
|
@ -23,8 +23,8 @@ spec:
|
||||||
- -tls-skip-verify=true
|
- -tls-skip-verify=true
|
||||||
- -auth=/etc/token/vault-token.yml
|
- -auth=/etc/token/vault-token.yml
|
||||||
- -output=/etc/secrets
|
- -output=/etc/secrets
|
||||||
- -cn=secret:db:up=3h,rv=true
|
- -cn=secret:db:update=3h,revoke=true
|
||||||
- -cn=pki:example-dot-com:cn=demo.example.com,fmt=cert,fn=demo.example.com
|
- -cn=pki:example-dot-com:cn=demo.example.com,fmt=cert,file=demo.example.com
|
||||||
- -vault=https://vault.services.cluster.local:8200
|
- -vault=https://vault.services.cluster.local:8200
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: secrets
|
- name: secrets
|
||||||
|
|
17
utils.go
17
utils.go
|
@ -48,13 +48,6 @@ func showUsage(message string, args ...interface{}) {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// randomWait waits for a random amount of time
|
|
||||||
// min : the minimum amount of time willing to wait
|
|
||||||
// max : the maximum amount of time willing to wait
|
|
||||||
func randomWait(min, max int) <-chan time.Time {
|
|
||||||
return time.After(time.Duration(getRandomWithin(min, max)) * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
// hasKey checks to see if a key is present
|
// hasKey checks to see if a key is present
|
||||||
// key : the key we are looking for
|
// key : the key we are looking for
|
||||||
// data : a map of strings to something we are looking at
|
// data : a map of strings to something we are looking at
|
||||||
|
@ -85,12 +78,12 @@ func readConfigFile(filename string) (map[string]string, error) {
|
||||||
// step: we only read in json or yaml formats
|
// step: we only read in json or yaml formats
|
||||||
suffix := path.Ext(filename)
|
suffix := path.Ext(filename)
|
||||||
switch suffix {
|
switch suffix {
|
||||||
case ".json":
|
|
||||||
return readJSONFile(filename)
|
|
||||||
case ".yaml":
|
case ".yaml":
|
||||||
return readYAMLFile(filename)
|
return readYAMLFile(filename)
|
||||||
case ".yml":
|
case ".yml":
|
||||||
return readYAMLFile(filename)
|
return readYAMLFile(filename)
|
||||||
|
default:
|
||||||
|
return readJSONFile(filename)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unsupported config file format: %s", suffix)
|
return nil, fmt.Errorf("unsupported config file format: %s", suffix)
|
||||||
}
|
}
|
||||||
|
@ -129,11 +122,11 @@ func readYAMLFile(filename string) (map[string]string, error) {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// randomInt generate a random integer between min and max
|
// getDurationWithin generate a random integer between min and max
|
||||||
// min : the smallest number we can accept
|
// min : the smallest number we can accept
|
||||||
// max : the largest number we can accept
|
// max : the largest number we can accept
|
||||||
func getRandomWithin(min, max int) int {
|
func getDurationWithin(min, max int) time.Duration {
|
||||||
return rand.Intn(max-min) + min
|
return time.Duration(rand.Intn(max-min) + min)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getEnv checks to see if an environment variable exists otherwise uses the default
|
// getEnv checks to see if an environment variable exists otherwise uses the default
|
||||||
|
|
38
vault.go
38
vault.go
|
@ -72,7 +72,7 @@ func NewVaultService(url string) (*VaultService, error) {
|
||||||
service.config = api.DefaultConfig()
|
service.config = api.DefaultConfig()
|
||||||
service.config.Address = url
|
service.config.Address = url
|
||||||
service.listeners = make([]chan VaultEvent, 0)
|
service.listeners = make([]chan VaultEvent, 0)
|
||||||
service.config.HttpClient.Transport, err = service.getHTTPTransport()
|
service.config.HttpClient.Transport, err = service.buildHTTPTransport()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ func NewVaultService(url string) (*VaultService, error) {
|
||||||
return service, nil
|
return service, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *VaultService) getHTTPTransport() (*http.Transport, error) {
|
func (r *VaultService) buildHTTPTransport() (*http.Transport, error) {
|
||||||
transport := &http.Transport{}
|
transport := &http.Transport{}
|
||||||
|
|
||||||
// step: are we skip the tls verify?
|
// step: are we skip the tls verify?
|
||||||
|
@ -143,7 +143,7 @@ func (r *VaultService) vaultServiceProcessor() {
|
||||||
// the channel to receive renewal notifications on
|
// the channel to receive renewal notifications on
|
||||||
renewChannel := make(chan *watchedResource, 10)
|
renewChannel := make(chan *watchedResource, 10)
|
||||||
retrieveChannel := make(chan *watchedResource, 10)
|
retrieveChannel := make(chan *watchedResource, 10)
|
||||||
revokeChannel := make(chan string, 10)
|
revokeChannel := make(chan *watchedResource, 10)
|
||||||
statsChannel := time.NewTicker(options.statsInterval)
|
statsChannel := time.NewTicker(options.statsInterval)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
@ -156,6 +156,7 @@ func (r *VaultService) vaultServiceProcessor() {
|
||||||
items = append(items, x)
|
items = append(items, x)
|
||||||
// step: push into the retrieval channel
|
// step: push into the retrieval channel
|
||||||
r.scheduleNow(x, retrieveChannel)
|
r.scheduleNow(x, retrieveChannel)
|
||||||
|
|
||||||
// Retrieve a resource from vault
|
// Retrieve a resource from vault
|
||||||
// - we retrieve the resource from vault
|
// - we retrieve the resource from vault
|
||||||
// - if we error attempting to retrieve the secret, we background and reschedule an attempt to add it
|
// - if we error attempting to retrieve the secret, we background and reschedule an attempt to add it
|
||||||
|
@ -173,7 +174,7 @@ func (r *VaultService) vaultServiceProcessor() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("failed to retrieve the resource: %s from vault, error: %s", x.resource, err)
|
glog.Errorf("failed to retrieve the resource: %s from vault, error: %s", x.resource, err)
|
||||||
// reschedule the attempt for later
|
// reschedule the attempt for later
|
||||||
r.scheduleIn(x, retrieveChannel, 3, 10)
|
r.scheduleIn(x, retrieveChannel, getDurationWithin(3, 10))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +182,14 @@ func (r *VaultService) vaultServiceProcessor() {
|
||||||
|
|
||||||
// step: if we had a previous lease and the option is to revoke, lets throw into the revoke channel
|
// step: if we had a previous lease and the option is to revoke, lets throw into the revoke channel
|
||||||
if leaseID != "" && x.resource.revoked {
|
if leaseID != "" && x.resource.revoked {
|
||||||
revokeChannel <- leaseID
|
// step: make a rough copy
|
||||||
|
copy := &watchedResource{
|
||||||
|
secret: &api.Secret{
|
||||||
|
LeaseID: x.secret.LeaseID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
r.scheduleIn(copy, revokeChannel, x.resource.revokeDelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
// step: setup a timer for renewal
|
// step: setup a timer for renewal
|
||||||
|
@ -221,7 +229,7 @@ func (r *VaultService) vaultServiceProcessor() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("failed to renew the resounce: %s for renewal, error: %s", x.resource, err)
|
glog.Errorf("failed to renew the resounce: %s for renewal, error: %s", x.resource, err)
|
||||||
// reschedule the attempt for later
|
// reschedule the attempt for later
|
||||||
r.scheduleIn(x, renewChannel, 3, 10)
|
r.scheduleIn(x, renewChannel, getDurationWithin(3, 10))
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,11 +247,11 @@ func (r *VaultService) vaultServiceProcessor() {
|
||||||
// step: update any listener upstream
|
// step: update any listener upstream
|
||||||
r.upstream(x)
|
r.upstream(x)
|
||||||
|
|
||||||
case lease := <-revokeChannel:
|
// We receive a lease ID along on the channel, just revoke the lease when you can
|
||||||
|
case x := <-revokeChannel:
|
||||||
err := r.revoke(lease)
|
err := r.revoke(x.secret.LeaseID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("failed to revoke the lease: %s, error: %s", lease, err)
|
glog.Errorf("failed to revoke the lease: %s, error: %s", x.secret.LeaseID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The statistics timer has gone off; we iterate the watched items and
|
// The statistics timer has gone off; we iterate the watched items and
|
||||||
|
@ -282,20 +290,20 @@ func (r VaultService) authenticate(auth map[string]string) (string, error) {
|
||||||
// rn : a pointer to the watched resource you wish to reschedule
|
// rn : a pointer to the watched resource you wish to reschedule
|
||||||
// ch : the channel the resource should be placed into
|
// ch : the channel the resource should be placed into
|
||||||
func (r VaultService) scheduleNow(rn *watchedResource, ch chan *watchedResource) {
|
func (r VaultService) scheduleNow(rn *watchedResource, ch chan *watchedResource) {
|
||||||
r.scheduleIn(rn, ch, 0, 0)
|
r.scheduleIn(rn, ch, time.Duration(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
// scheduleIn ... schedules an event back into a channel after n seconds
|
// scheduleIn ... schedules an event back into a channel after n seconds
|
||||||
// rn : a pointer to the watched resource you wish to reschedule
|
// rn : a referrence some reason you wish to pass
|
||||||
// ch : the channel the resource should be placed into
|
// ch : the channel the resource should be placed into
|
||||||
// min : the minimum amount of time i'm willing to wait
|
// min : the minimum amount of time i'm willing to wait
|
||||||
// max : the maximum amount of time i'm willing to wait
|
// max : the maximum amount of time i'm willing to wait
|
||||||
func (r VaultService) scheduleIn(rn *watchedResource, ch chan *watchedResource, min, max int) {
|
func (r VaultService) scheduleIn(rn *watchedResource, ch chan *watchedResource, duration time.Duration) {
|
||||||
go func(x *watchedResource) {
|
go func(x *watchedResource) {
|
||||||
glog.V(3).Infof("rescheduling the resource: %s, channel: %v", rn.resource, ch)
|
glog.V(3).Infof("rescheduling the resource: %s, channel: %v", rn.resource, ch)
|
||||||
// step: are we doing a random wait?
|
// step: are we doing a random wait?
|
||||||
if min > 0 {
|
if duration > 0 {
|
||||||
<-randomWait(min, max)
|
<-time.After(duration)
|
||||||
}
|
}
|
||||||
ch <- x
|
ch <- x
|
||||||
}(rn)
|
}(rn)
|
||||||
|
|
|
@ -25,19 +25,21 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// optionFilename option to set the filename of the resource
|
// optionFilename option to set the filename of the resource
|
||||||
optionFilename = "fn"
|
optionFilename = "file"
|
||||||
// optionFormat ... option to set the output format (yaml, xml, json)
|
// optionFormat set the output format (yaml, xml, json)
|
||||||
optionFormat = "fmt"
|
optionFormat = "fmt"
|
||||||
// optionCommonName ... use by the PKI resource
|
// optionCommonName set the PKI common name of the resource
|
||||||
optionCommonName = "cn"
|
optionCommonName = "cn"
|
||||||
// optionTemplatePath ... the full path to a template
|
// optionTemplatePath is the full path to a template
|
||||||
optionTemplatePath = "tpl"
|
optionTemplatePath = "tpl"
|
||||||
// optionRenewal ... a duration to renew the resource
|
// optionRenewal sets the duration to renew the resource
|
||||||
optionRenewal = "rn"
|
optionRenewal = "renew"
|
||||||
// optionRevoke ... revoke an old lease when retrieving a new one
|
// optionRevoke revokes an old lease when retrieving a new one
|
||||||
optionRevoke = "rv"
|
optionRevoke = "revoke"
|
||||||
// optionUpdate ... override the lease of the resource
|
// optionRevokeDelay
|
||||||
optionUpdate = "up"
|
optionsRevokeDelay = "delay"
|
||||||
|
// optionUpdate overrides the lease of the resource
|
||||||
|
optionUpdate = "update"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -76,6 +78,8 @@ type VaultResource struct {
|
||||||
renewable bool
|
renewable bool
|
||||||
// whether the resource should be revoked?
|
// whether the resource should be revoked?
|
||||||
revoked bool
|
revoked bool
|
||||||
|
// the revoke delay
|
||||||
|
revokeDelay time.Duration
|
||||||
// the lease duration
|
// the lease duration
|
||||||
update time.Duration
|
update time.Duration
|
||||||
// additional options to the resource
|
// additional options to the resource
|
||||||
|
@ -150,6 +154,12 @@ func (r *VaultResource) isValidOptions() error {
|
||||||
return fmt.Errorf("the revoke option: %s is invalid, should be a boolean", val)
|
return fmt.Errorf("the revoke option: %s is invalid, should be a boolean", val)
|
||||||
}
|
}
|
||||||
r.revoked = choice
|
r.revoked = choice
|
||||||
|
case optionsRevokeDelay:
|
||||||
|
duration, err := time.ParseDuration(val)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("the revoke delay option: %s is not value, should be a duration format", val)
|
||||||
|
}
|
||||||
|
r.revokeDelay = duration
|
||||||
case optionRenewal:
|
case optionRenewal:
|
||||||
choice, err := strconv.ParseBool(val)
|
choice, err := strconv.ParseBool(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
resourceRegex = regexp.MustCompile("^([\\w]+):([\\w\\\\/\\-_\\.]+):?(.*)")
|
resourceRegex = regexp.MustCompile("^([\\w]+):([\\w\\\\/\\-_\\.]+):?(.*)")
|
||||||
resourceOptionsRegex = regexp.MustCompile("([\\w\\d]{2,3})=([\\w\\d\\/\\.\\-_]+)[,]?")
|
resourceOptionsRegex = regexp.MustCompile("([\\w\\d]{2,6})=([\\w\\d\\/\\.\\-_]+)[,]?")
|
||||||
)
|
)
|
||||||
|
|
||||||
// VaultResources is a collection of type resource
|
// VaultResources is a collection of type resource
|
||||||
|
|
|
@ -25,25 +25,25 @@ import (
|
||||||
func TestSetResources(t *testing.T) {
|
func TestSetResources(t *testing.T) {
|
||||||
var items VaultResources
|
var items VaultResources
|
||||||
|
|
||||||
assert.Nil(t, items.Set("secret:test:fn=filename.test,fmt=yaml"))
|
assert.Nil(t, items.Set("secret:test:file=filename.test,fmt=yaml"))
|
||||||
assert.Nil(t, items.Set("secret:test:fn=filename.test,"))
|
assert.Nil(t, items.Set("secret:test:file=filename.test,"))
|
||||||
assert.Nil(t, items.Set("secret:/db/prod/username"))
|
assert.Nil(t, items.Set("secret:/db/prod/username"))
|
||||||
assert.Nil(t, items.Set("secret:/db/prod:fn=filename.test,fmt=yaml"))
|
assert.Nil(t, items.Set("secret:/db/prod:file=filename.test,fmt=yaml"))
|
||||||
assert.Nil(t, items.Set("secret:test:fn=filename.test,"))
|
assert.Nil(t, items.Set("secret:test:fn=filename.test,"))
|
||||||
assert.Nil(t, items.Set("pki:example-dot-com:cn=blah.example.com"))
|
assert.Nil(t, items.Set("pki:example-dot-com:cn=blah.example.com"))
|
||||||
assert.Nil(t, items.Set("pki:example-dot-com:cn=blah.example.com,fn=/etc/certs/ssl/blah.example.com"))
|
assert.Nil(t, items.Set("pki:example-dot-com:cn=blah.example.com,file=/etc/certs/ssl/blah.example.com"))
|
||||||
assert.Nil(t, items.Set("pki:example-dot-com:cn=blah.example.com,rn=10s"))
|
assert.Nil(t, items.Set("pki:example-dot-com:cn=blah.example.com,renew=10s"))
|
||||||
assert.NotNil(t, items.Set("secret:"))
|
assert.NotNil(t, items.Set("secret:"))
|
||||||
assert.NotNil(t, items.Set("secret:test:fn=filename.test,fmt="))
|
assert.NotNil(t, items.Set("secret:test:file=filename.test,fmt="))
|
||||||
assert.NotNil(t, items.Set("secret::fn=filename.test,fmt=yaml"))
|
assert.NotNil(t, items.Set("secret::file=filename.test,fmt=yaml"))
|
||||||
assert.NotNil(t, items.Set("secret:te1st:fn=filename.test,fmt="))
|
assert.NotNil(t, items.Set("secret:te1st:file=filename.test,fmt="))
|
||||||
assert.NotNil(t, items.Set("fn=filename.test,fmt=yaml"))
|
assert.NotNil(t, items.Set("file=filename.test,fmt=yaml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResources(t *testing.T) {
|
func TestResources(t *testing.T) {
|
||||||
var items VaultResources
|
var items VaultResources
|
||||||
items.Set("secret:test:fn=filename.test,fmt=yaml")
|
items.Set("secret:test:file=filename.test,fmt=yaml")
|
||||||
items.Set("secret:test:fn=fileame.test")
|
items.Set("secret:test:file=fileame.test")
|
||||||
|
|
||||||
if passed := assert.Equal(t, len(items.items), 2); !passed {
|
if passed := assert.Equal(t, len(items.items), 2); !passed {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (r *watchedResource) notifyOnRenewal(ch chan *watchedResource) {
|
||||||
|
|
||||||
// calculateRenewal calculate the renewal between
|
// calculateRenewal calculate the renewal between
|
||||||
func (r watchedResource) calculateRenewal() time.Duration {
|
func (r watchedResource) calculateRenewal() time.Duration {
|
||||||
return time.Duration(getRandomWithin(
|
return time.Duration(getDurationWithin(
|
||||||
int(float64(r.secret.LeaseDuration)*renewalMinimum),
|
int(float64(r.secret.LeaseDuration)*renewalMinimum),
|
||||||
int(float64(r.secret.LeaseDuration)*renewalMaximum))) * time.Second
|
int(float64(r.secret.LeaseDuration)*renewalMaximum))) * time.Second
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue