Skip to content

Commit

Permalink
Merge remote-tracking branch 'oss/master' into okta-lib-baseurl
Browse files Browse the repository at this point in the history
* oss/master:
  Fix navigation and prameters in the 'gcp' auth backend docs. (#3317)
  changelog++
  Adding latency injector option to -dev mode for storage operations (#3289)
  • Loading branch information
Chris Hoffman committed Sep 11, 2017
2 parents b8e831d + bfff8b4 commit cf39e40
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 18 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.8.2.1 (September 11th, 2017) (Enterprise Only)

BUG FIXES:

* Fix an issue upgrading to 0.8.2 for Enterprise customers.

## 0.8.2 (September 5th, 2017)

SECURITY:
Expand Down
12 changes: 11 additions & 1 deletion command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,15 @@ func (c *ServerCommand) Run(args []string) int {
var dev, verifyOnly, devHA, devTransactional, devLeasedGeneric, devThreeNode bool
var configPath []string
var logLevel, devRootTokenID, devListenAddress, devPluginDir string
var devLatency, devLatencyJitter int
flags := c.Meta.FlagSet("server", meta.FlagSetDefault)
flags.BoolVar(&dev, "dev", false, "")
flags.StringVar(&devRootTokenID, "dev-root-token-id", "", "")
flags.StringVar(&devListenAddress, "dev-listen-address", "", "")
flags.StringVar(&devPluginDir, "dev-plugin-dir", "", "")
flags.StringVar(&logLevel, "log-level", "info", "")
flags.IntVar(&devLatency, "dev-latency", 0, "")
flags.IntVar(&devLatencyJitter, "dev-latency-jitter", 20, "")
flags.BoolVar(&verifyOnly, "verify-only", false, "")
flags.BoolVar(&devHA, "dev-ha", false, "")
flags.BoolVar(&devTransactional, "dev-transactional", false, "")
Expand Down Expand Up @@ -266,7 +269,14 @@ func (c *ServerCommand) Run(args []string) int {
if devPluginDir != "" {
coreConfig.PluginDirectory = devPluginDir
}

if devLatency > 0 {
injectLatency := time.Duration(devLatency) * time.Millisecond
if _, txnOK := backend.(physical.Transactional); txnOK {
coreConfig.Physical = physical.NewTransactionalLatencyInjector(backend, injectLatency, devLatencyJitter, c.logger)
} else {
coreConfig.Physical = physical.NewLatencyInjector(backend, injectLatency, devLatencyJitter, c.logger)
}
}
}

if devThreeNode {
Expand Down
90 changes: 90 additions & 0 deletions physical/latency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package physical

import (
"math/rand"
"time"

log "github.com/mgutz/logxi/v1"
)

const (
// DefaultJitterPercent is used if no cache size is specified for NewCache
DefaultJitterPercent = 20
)

// LatencyInjector is used to add latency into underlying physical requests
type LatencyInjector struct {
backend Backend
latency time.Duration
jitterPercent int
random *rand.Rand
}

// TransactionalLatencyInjector is the transactional version of the latency
// injector
type TransactionalLatencyInjector struct {
*LatencyInjector
Transactional
}

// NewLatencyInjector returns a wrapped physical backend to simulate latency
func NewLatencyInjector(b Backend, latency time.Duration, jitter int, logger log.Logger) *LatencyInjector {
if jitter < 0 || jitter > 100 {
jitter = DefaultJitterPercent
}
logger.Info("physical/latency: creating latency injector")

return &LatencyInjector{
backend: b,
latency: latency,
jitterPercent: jitter,
random: rand.New(rand.NewSource(int64(time.Now().Nanosecond()))),
}
}

// NewTransactionalLatencyInjector creates a new transactional LatencyInjector
func NewTransactionalLatencyInjector(b Backend, latency time.Duration, jitter int, logger log.Logger) *TransactionalLatencyInjector {
return &TransactionalLatencyInjector{
LatencyInjector: NewLatencyInjector(b, latency, jitter, logger),
Transactional: b.(Transactional),
}
}

func (l *LatencyInjector) addLatency() {
// Calculate a value between 1 +- jitter%
min := 100 - l.jitterPercent
max := 100 + l.jitterPercent
percent := l.random.Intn(max-min) + min
latencyDuration := time.Duration(int(l.latency) * percent / 100)
time.Sleep(latencyDuration)
}

// Put is a latent put request
func (l *LatencyInjector) Put(entry *Entry) error {
l.addLatency()
return l.backend.Put(entry)
}

// Get is a latent get request
func (l *LatencyInjector) Get(key string) (*Entry, error) {
l.addLatency()
return l.backend.Get(key)
}

// Delete is a latent delete request
func (l *LatencyInjector) Delete(key string) error {
l.addLatency()
return l.backend.Delete(key)
}

// List is a latent list request
func (l *LatencyInjector) List(prefix string) ([]string, error) {
l.addLatency()
return l.backend.List(prefix)
}

// Transaction is a latent transaction request
func (l *TransactionalLatencyInjector) Transaction(txns []TxnEntry) error {
l.addLatency()
return l.Transactional.Transaction(txns)
}
13 changes: 4 additions & 9 deletions vault/expiration.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (c *Core) setupExpiration() error {
c.logger.Error("expiration: error shutting down core: %v", err)
}
}
go c.expiration.Restore(errorFunc, 0)
go c.expiration.Restore(errorFunc)

return nil
}
Expand Down Expand Up @@ -268,7 +268,7 @@ func (m *ExpirationManager) Tidy() error {

// Restore is used to recover the lease states when starting.
// This is used after starting the vault.
func (m *ExpirationManager) Restore(errorFunc func(), loadDelay time.Duration) (retErr error) {
func (m *ExpirationManager) Restore(errorFunc func()) (retErr error) {
defer func() {
// Turn off restore mode. We can do this safely without the lock because
// if restore mode finished successfully, restore mode was already
Expand Down Expand Up @@ -322,7 +322,7 @@ func (m *ExpirationManager) Restore(errorFunc func(), loadDelay time.Duration) (
return
}

err := m.processRestore(leaseID, loadDelay)
err := m.processRestore(leaseID)
if err != nil {
errs <- err
continue
Expand Down Expand Up @@ -398,7 +398,7 @@ func (m *ExpirationManager) Restore(errorFunc func(), loadDelay time.Duration) (

// processRestore takes a lease and restores it in the expiration manager if it has
// not already been seen
func (m *ExpirationManager) processRestore(leaseID string, loadDelay time.Duration) error {
func (m *ExpirationManager) processRestore(leaseID string) error {
m.restoreRequestLock.RLock()
defer m.restoreRequestLock.RUnlock()

Expand All @@ -415,11 +415,6 @@ func (m *ExpirationManager) processRestore(leaseID string, loadDelay time.Durati
return nil
}

// Useful for testing to add latency to all load requests
if loadDelay > 0 {
time.Sleep(loadDelay)
}

// Load lease and restore expiration timer
_, err := m.loadEntryInternal(leaseID, true, false)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions vault/expiration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestExpiration_Tidy(t *testing.T) {
var err error

exp := mockExpiration(t)
if err := exp.Restore(nil, 0); err != nil {
if err := exp.Restore(nil); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -341,7 +341,7 @@ func benchmarkExpirationBackend(b *testing.B, physicalBackend physical.Backend,

b.ResetTimer()
for i := 0; i < b.N; i++ {
err = exp.Restore(nil, 0)
err = exp.Restore(nil)
// Restore
if err != nil {
b.Fatalf("err: %v", err)
Expand Down Expand Up @@ -399,7 +399,7 @@ func TestExpiration_Restore(t *testing.T) {
}

// Restore
err = exp.Restore(nil, 0)
err = exp.Restore(nil)
if err != nil {
t.Fatalf("err: %v", err)
}
Expand Down
10 changes: 5 additions & 5 deletions website/source/docs/auth/gcp.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ v0.8.0+ to use plugins.

The Vault authentication workflow for IAM service accounts is as follows:

1. A client with IAM service account credentials generates a signed JWT using the IAM [projects.serviceAccounts.signJwt](https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt) method. See [usage](#iam-authentication-token) for the expected format and example code.
1. A client with IAM service account credentials generates a signed JWT using the IAM [projects.serviceAccounts.signJwt](https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt) method. See [usage](#the-iam-authentication-token) for the expected format and example code.
2. The client sends this JWT to Vault in a login request with a role name. This role should have type `iam`
3. Vault grabs the `kid` header value, which contains the ID of the key-pair used to generate the JWT, and the `sub` ID/email to find the service account key. If the service account does not exist or the key is not linked to the service account, Vault will deny authentication.
4. Vault authorizes the confirmed service account against the given role. See [authorization section](#authorization) to see how each type of role handles authorization.
4. Vault authorizes the confirmed service account against the given role. See [authorization section](#authorization-workflow) to see how each type of role handles authorization.

[![IAM Login Workflow](/assets/images/vault-gcp-iam-auth-workflow.svg)](/assets/images/vault-gcp-iam-auth-workflow.svg)

Expand Down Expand Up @@ -241,7 +241,7 @@ to learn more about parameters.
```
$ vault write auth/gcp/role/dev-role \
type="iam" \
project="project-123456" \
project_id="project-123456" \
policies="prod,dev" \
service_accounts="[email protected],uuid123,..."
...
Expand Down Expand Up @@ -300,12 +300,12 @@ $ curl $VAULT_ADDR/v1/auth/gcp/config \

```
$ curl $VAULT_ADDR/v1/auth/gcp/role/dev-role \
-d '{ "type": "iam", "project": "project-123456", ...}'
-d '{ "type": "iam", "project_id": "project-123456", ...}'
```

#### Login to get a Vault Token

The endpoint for the GitHub login is `auth/gcp/login`.
The endpoint for the GCP login is `auth/gcp/login`.

The `gcp` mountpoint value in the url is the default mountpoint value.
If you have mounted the `gcp` backend with a different mountpoint, use that value.
Expand Down

0 comments on commit cf39e40

Please sign in to comment.