Merge branch 'master' into new-guides

This commit is contained in:
Andy Manoske 2018-02-06 13:09:22 -08:00 committed by GitHub
commit 4d33d5fa34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 642 additions and 308 deletions

View file

@ -1,14 +1,25 @@
## 0.9.4 (Unreleased)
IMPROVEMENTS:
* auth/centrify: Add CLI helper
BUG FIXES:
* api/renewer: Honor increment value in renew auth calls [GH-3904]
* auth/approle: Fix inability to use limited-use-count secret IDs on
replication performance secondaries
* auth/approle: Cleanup of secret ID accessors during tidy and removal of
dangling accessor entries [GH-3924]
* auth/okta: Return configured durations as seconds, not nanoseconds [GH-3871]
* auth/token: Token creation via the CLI no longer forces periodic token
creation. Passing an explicit zero value for the period no longer create
periodic tokens [GH-3880]
periodic tokens. [GH-3880]
* command/ssh: Create and reuse the api client [GH-3909]
* storage/etcd3: Fix memory ballooning with standby instances [GH-3798]
* storage/etcd3: Fix large lists (like token loading at startup) not being
handled [GH-3772]
* storage/zookeeper: Update vendoring to fix freezing issues [GH-3896]
* plugin/gRPC: Fixed an issue with list requests and raw responses coming from
plugins using gRPC transport [GH-3881]

View file

@ -195,7 +195,7 @@ func (r *Renewer) renewAuth() error {
}
// Renew the auth.
renewal, err := client.Auth().Token().RenewTokenAsSelf(token, 0)
renewal, err := client.Auth().Token().RenewTokenAsSelf(token, r.increment)
if err != nil {
return err
}

View file

@ -4,6 +4,7 @@ import (
"context"
"sync"
"github.com/hashicorp/vault/helper/consts"
"github.com/hashicorp/vault/helper/locksutil"
"github.com/hashicorp/vault/helper/salt"
"github.com/hashicorp/vault/logical"
@ -142,7 +143,9 @@ func (b *backend) invalidate(_ context.Context, key string) {
// to delay the removal of SecretIDs by a minute.
func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error {
// Initiate clean-up of expired SecretID entries
b.tidySecretID(ctx, req.Storage)
if b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary) {
b.tidySecretID(ctx, req.Storage)
}
return nil
}

View file

@ -6,6 +6,7 @@ import (
"strings"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
@ -51,9 +52,14 @@ func (b *backend) pathLoginUpdateAliasLookahead(ctx context.Context, req *logica
// Returns the Auth object indicating the authentication and authorization information
// if the credentials provided are validated by the backend.
func (b *backend) pathLoginUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
role, roleName, metadata, _, err := b.validateCredentials(ctx, req, data)
if err != nil || role == nil {
return logical.ErrorResponse(fmt.Sprintf("failed to validate credentials: %v", err)), nil
role, roleName, metadata, _, userErr, intErr := b.validateCredentials(ctx, req, data)
switch {
case intErr != nil:
return nil, errwrap.Wrapf("failed to validate credentials: {{err}}", intErr)
case userErr != nil:
return logical.ErrorResponse(fmt.Sprintf("failed to validate credentials: %v", userErr)), nil
case role == nil:
return logical.ErrorResponse("failed to validate credentials; could not find role"), nil
}
// Always include the role name, for later filtering

View file

@ -38,6 +38,16 @@ func (b *backend) tidySecretID(ctx context.Context, s logical.Storage) error {
return err
}
// List all the accessors and add them all to a map
accessorHashes, err := s.List(ctx, "accessor/")
if err != nil {
return err
}
accessorMap := make(map[string]bool, len(accessorHashes))
for _, accessorHash := range accessorHashes {
accessorMap[accessorHash] = true
}
var result error
for _, roleNameHMAC := range roleNameHMACs {
// roleNameHMAC will already have a '/' suffix. Don't append another one.
@ -77,14 +87,46 @@ func (b *backend) tidySecretID(ctx context.Context, s logical.Storage) error {
// ExpirationTime not being set indicates non-expiring SecretIDs
if !result.ExpirationTime.IsZero() && time.Now().After(result.ExpirationTime) {
// Clean up the accessor of the secret ID first
err = b.deleteSecretIDAccessorEntry(ctx, s, result.SecretIDAccessor)
if err != nil {
lock.Unlock()
return err
}
if err := s.Delete(ctx, entryIndex); err != nil {
lock.Unlock()
return fmt.Errorf("error deleting SecretID %s from storage: %s", secretIDHMAC, err)
}
}
// At this point, the secret ID is not expired and is valid. Delete
// the corresponding accessor from the accessorMap. This will leave
// only the dangling accessors in the map which can then be cleaned
// up later.
salt, err := b.Salt()
if err != nil {
lock.Unlock()
return err
}
delete(accessorMap, salt.SaltID(result.SecretIDAccessor))
lock.Unlock()
}
}
// Accessor indexes were not getting cleaned up until 0.9.3. This is a fix
// to clean up the dangling accessor entries.
for accessorHash, _ := range accessorMap {
// Ideally, locking should be performed here. But for that, accessors
// are required in plaintext, which are not available. Hence performing
// a racy cleanup.
err = s.Delete(ctx, "accessor/"+accessorHash)
if err != nil {
return err
}
}
return result
}

View file

@ -0,0 +1,79 @@
package approle
import (
"context"
"testing"
"github.com/hashicorp/vault/logical"
)
func TestAppRole_TidyDanglingAccessors(t *testing.T) {
var resp *logical.Response
var err error
b, storage := createBackendWithStorage(t)
// Create a role
createRole(t, b, storage, "role1", "a,b,c")
// Create a secret-id
roleSecretIDReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "role/role1/secret-id",
Storage: storage,
}
resp, err = b.HandleRequest(context.Background(), roleSecretIDReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}
accessorHashes, err := storage.List(context.Background(), "accessor/")
if err != nil {
t.Fatal(err)
}
if len(accessorHashes) != 1 {
t.Fatalf("bad: len(accessorHashes); expect 1, got %d", len(accessorHashes))
}
entry1, err := logical.StorageEntryJSON(
"accessor/invalid1",
&secretIDAccessorStorageEntry{
SecretIDHMAC: "samplesecretidhmac",
},
)
err = storage.Put(context.Background(), entry1)
if err != nil {
t.Fatal(err)
}
entry2, err := logical.StorageEntryJSON(
"accessor/invalid2",
&secretIDAccessorStorageEntry{
SecretIDHMAC: "samplesecretidhmac2",
},
)
err = storage.Put(context.Background(), entry2)
if err != nil {
t.Fatal(err)
}
accessorHashes, err = storage.List(context.Background(), "accessor/")
if err != nil {
t.Fatal(err)
}
if len(accessorHashes) != 3 {
t.Fatalf("bad: len(accessorHashes); expect 3, got %d", len(accessorHashes))
}
err = b.tidySecretID(context.Background(), storage)
if err != nil {
t.Fatal(err)
}
accessorHashes, err = storage.List(context.Background(), "accessor/")
if err != nil {
t.Fatal(err)
}
if len(accessorHashes) != 1 {
t.Fatalf("bad: len(accessorHashes); expect 1, got %d", len(accessorHashes))
}
}

View file

@ -9,6 +9,7 @@ import (
"strings"
"time"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/cidrutil"
"github.com/hashicorp/vault/helper/locksutil"
@ -95,26 +96,26 @@ func (b *backend) validateRoleID(ctx context.Context, s logical.Storage, roleID
}
// Validates the supplied RoleID and SecretID
func (b *backend) validateCredentials(ctx context.Context, req *logical.Request, data *framework.FieldData) (*roleStorageEntry, string, map[string]string, string, error) {
func (b *backend) validateCredentials(ctx context.Context, req *logical.Request, data *framework.FieldData) (*roleStorageEntry, string, map[string]string, string, error, error) {
metadata := make(map[string]string)
// RoleID must be supplied during every login
roleID := strings.TrimSpace(data.Get("role_id").(string))
if roleID == "" {
return nil, "", metadata, "", fmt.Errorf("missing role_id")
return nil, "", metadata, "", fmt.Errorf("missing role_id"), nil
}
// Validate the RoleID and get the Role entry
role, roleName, err := b.validateRoleID(ctx, req.Storage, roleID)
if err != nil {
return nil, "", metadata, "", err
return nil, "", metadata, "", nil, err
}
if role == nil || roleName == "" {
return nil, "", metadata, "", fmt.Errorf("failed to validate role_id")
return nil, "", metadata, "", fmt.Errorf("failed to validate role_id"), nil
}
// Calculate the TTL boundaries since this reflects the properties of the token issued
if role.TokenTTL, role.TokenMaxTTL, err = b.SanitizeTTL(role.TokenTTL, role.TokenMaxTTL); err != nil {
return nil, "", metadata, "", err
return nil, "", metadata, "", nil, err
}
var secretID string
@ -123,7 +124,7 @@ func (b *backend) validateCredentials(ctx context.Context, req *logical.Request,
// to be specified and validate it.
secretID = strings.TrimSpace(data.Get("secret_id").(string))
if secretID == "" {
return nil, "", metadata, "", fmt.Errorf("missing secret_id")
return nil, "", metadata, "", fmt.Errorf("missing secret_id"), nil
}
if role.LowerCaseRoleName {
@ -135,29 +136,29 @@ func (b *backend) validateCredentials(ctx context.Context, req *logical.Request,
var valid bool
valid, metadata, err = b.validateBindSecretID(ctx, req, roleName, secretID, role.HMACKey, role.BoundCIDRList)
if err != nil {
return nil, "", metadata, "", err
return nil, "", metadata, "", nil, err
}
if !valid {
return nil, "", metadata, "", fmt.Errorf("invalid secret_id %q", secretID)
return nil, "", metadata, "", fmt.Errorf("invalid secret_id %q", secretID), nil
}
}
if role.BoundCIDRList != "" {
// If 'bound_cidr_list' was set, verify the CIDR restrictions
if req.Connection == nil || req.Connection.RemoteAddr == "" {
return nil, "", metadata, "", fmt.Errorf("failed to get connection information")
return nil, "", metadata, "", fmt.Errorf("failed to get connection information"), nil
}
belongs, err := cidrutil.IPBelongsToCIDRBlocksString(req.Connection.RemoteAddr, role.BoundCIDRList, ",")
if err != nil {
return nil, "", metadata, "", fmt.Errorf("failed to verify the CIDR restrictions set on the role: %v", err)
return nil, "", metadata, "", nil, errwrap.Wrapf("failed to verify the CIDR restrictions set on the role: {{err}}", err)
}
if !belongs {
return nil, "", metadata, "", fmt.Errorf("source address %q unauthorized through CIDR restrictions on the role", req.Connection.RemoteAddr)
return nil, "", metadata, "", fmt.Errorf("source address %q unauthorized through CIDR restrictions on the role", req.Connection.RemoteAddr), nil
}
}
return role, roleName, metadata, secretID, nil
return role, roleName, metadata, secretID, nil, nil
}
// validateBindSecretID is used to determine if the given SecretID is a valid one.
@ -250,9 +251,9 @@ func (b *backend) validateBindSecretID(ctx context.Context, req *logical.Request
result.SecretIDNumUses -= 1
result.LastUpdatedTime = time.Now()
if entry, err := logical.StorageEntryJSON(entryIndex, &result); err != nil {
return false, nil, fmt.Errorf("failed to decrement the use count for secret ID %q", secretID)
return false, nil, fmt.Errorf("failed to create storage entry while decrementing the secret ID use count: %v", err)
} else if err = req.Storage.Put(ctx, entry); err != nil {
return false, nil, fmt.Errorf("failed to decrement the use count for secret ID %q", secretID)
return false, nil, fmt.Errorf("failed to decrement the secret ID use count: %v", err)
}
}

View file

@ -9,6 +9,7 @@ import (
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/hashicorp/vault/helper/consts"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
"github.com/patrickmn/go-cache"
@ -143,29 +144,33 @@ func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error
// Run the tidy operations for the first time. Then run it when current
// time matches the nextTidyTime.
if b.nextTidyTime.IsZero() || !time.Now().Before(b.nextTidyTime) {
// safety_buffer defaults to 180 days for roletag blacklist
safety_buffer := 15552000
tidyBlacklistConfigEntry, err := b.lockedConfigTidyRoleTags(ctx, req.Storage)
if err != nil {
return err
}
skipBlacklistTidy := false
// check if tidying of role tags was configured
if tidyBlacklistConfigEntry != nil {
// check if periodic tidying of role tags was disabled
if tidyBlacklistConfigEntry.DisablePeriodicTidy {
skipBlacklistTidy = true
if b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary) {
// safety_buffer defaults to 180 days for roletag blacklist
safety_buffer := 15552000
tidyBlacklistConfigEntry, err := b.lockedConfigTidyRoleTags(ctx, req.Storage)
if err != nil {
return err
}
skipBlacklistTidy := false
// check if tidying of role tags was configured
if tidyBlacklistConfigEntry != nil {
// check if periodic tidying of role tags was disabled
if tidyBlacklistConfigEntry.DisablePeriodicTidy {
skipBlacklistTidy = true
}
// overwrite the default safety_buffer with the configured value
safety_buffer = tidyBlacklistConfigEntry.SafetyBuffer
}
// tidy role tags if explicitly not disabled
if !skipBlacklistTidy {
b.tidyBlacklistRoleTag(ctx, req.Storage, safety_buffer)
}
// overwrite the default safety_buffer with the configured value
safety_buffer = tidyBlacklistConfigEntry.SafetyBuffer
}
// tidy role tags if explicitly not disabled
if !skipBlacklistTidy {
b.tidyBlacklistRoleTag(ctx, req.Storage, safety_buffer)
}
// reset the safety_buffer to 72h
safety_buffer = 259200
// We don't check for replication state for whitelist identities as
// these are locally stored
safety_buffer := 259200
tidyWhitelistConfigEntry, err := b.lockedConfigTidyIdentities(ctx, req.Storage)
if err != nil {
return err

View file

@ -287,7 +287,7 @@ func TestBackend_ConfigTidyIdentities(t *testing.T) {
t.Fatalf("failed to read config/tidy/identity-whitelist endpoint")
}
if resp.Data["safety_buffer"].(int) != 60 || !resp.Data["disable_periodic_tidy"].(bool) {
t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%s disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool))
t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%d disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool))
}
// test delete operation
@ -342,7 +342,7 @@ func TestBackend_ConfigTidyRoleTags(t *testing.T) {
t.Fatalf("failed to read config/tidy/roletag-blacklist endpoint")
}
if resp.Data["safety_buffer"].(int) != 60 || !resp.Data["disable_periodic_tidy"].(bool) {
t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%s disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool))
t.Fatalf("bad: expected: safety_buffer:60 disable_periodic_tidy:true actual: safety_buffer:%d disable_periodic_tidy:%t\n", resp.Data["safety_buffer"].(int), resp.Data["disable_periodic_tidy"].(bool))
}
// test delete operation
@ -1587,7 +1587,7 @@ func TestBackendAcc_LoginWithCallerIdentity(t *testing.T) {
// and ensure a renew no longer works
resp, err = b.pathLoginRenew(context.Background(), renewReq, empty_login_fd)
if err == nil || (resp != nil && !resp.IsError()) {
t.Errorf("bad: expected failed renew due to changed AWS role ID: resp: %#v", resp, err)
t.Errorf("bad: expected failed renew due to changed AWS role ID: resp: %#v", resp)
}
// Undo the fake resolver...
b.resolveArnToUniqueIDFunc = b.resolveArnToRealUniqueId

View file

@ -319,23 +319,23 @@ func (b *backend) parseAndVerifyRoleTagValue(ctx context.Context, s logical.Stor
for _, tagItem := range tagItems {
var err error
switch {
case strings.Contains(tagItem, "i="):
case strings.HasPrefix(tagItem, "i="):
rTag.InstanceID = strings.TrimPrefix(tagItem, "i=")
case strings.Contains(tagItem, "r="):
case strings.HasPrefix(tagItem, "r="):
rTag.Role = strings.TrimPrefix(tagItem, "r=")
case strings.Contains(tagItem, "p="):
case strings.HasPrefix(tagItem, "p="):
rTag.Policies = strings.Split(strings.TrimPrefix(tagItem, "p="), ",")
case strings.Contains(tagItem, "d="):
case strings.HasPrefix(tagItem, "d="):
rTag.DisallowReauthentication, err = strconv.ParseBool(strings.TrimPrefix(tagItem, "d="))
if err != nil {
return nil, err
}
case strings.Contains(tagItem, "m="):
case strings.HasPrefix(tagItem, "m="):
rTag.AllowInstanceMigration, err = strconv.ParseBool(strings.TrimPrefix(tagItem, "m="))
if err != nil {
return nil, err
}
case strings.Contains(tagItem, "t="):
case strings.HasPrefix(tagItem, "t="):
rTag.MaxTTL, err = time.ParseDuration(fmt.Sprintf("%ss", strings.TrimPrefix(tagItem, "t=")))
if err != nil {
return nil, err

View file

@ -1062,8 +1062,7 @@ func testConnState(certPath, keyPath, rootCertPath string) (tls.ConnectionState,
InsecureSkipVerify: false,
RootCAs: rootCAs,
}
dialConf := new(tls.Config)
*dialConf = *listenConf
dialConf := listenConf.Clone()
// start a server
list, err := tls.Listen("tcp", "127.0.0.1:0", listenConf)
if err != nil {

View file

@ -61,7 +61,7 @@ certificate.`,
"policies": &framework.FieldSchema{
Type: framework.TypeCommaStringSlice,
Description: "Comma-seperated list of policies.",
Description: "Comma-separated list of policies.",
},
"lease": &framework.FieldSchema{

View file

@ -261,7 +261,7 @@ func TestBackend_configDefaultsAfterUpdate(t *testing.T) {
defaultDenyNullBind := true
if cfg["deny_null_bind"] != defaultDenyNullBind {
t.Errorf("Default mismatch: deny_null_bind. Expected: '%s', received :'%s'", defaultDenyNullBind, cfg["deny_null_bind"])
t.Errorf("Default mismatch: deny_null_bind. Expected: '%t', received :'%s'", defaultDenyNullBind, cfg["deny_null_bind"])
}
return nil

View file

@ -44,7 +44,7 @@ func Backend() *backend {
secretAccessKeys(&b),
},
WALRollback: walRollback,
WALRollback: b.walRollback,
WALRollbackMinAge: 5 * time.Minute,
BackendType: logical.TypeLogical,
}

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"github.com/hashicorp/vault/helper/consts"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
@ -12,7 +13,11 @@ var walRollbackMap = map[string]framework.WALRollbackFunc{
"user": pathUserRollback,
}
func walRollback(ctx context.Context, req *logical.Request, kind string, data interface{}) error {
func (b *backend) walRollback(ctx context.Context, req *logical.Request, kind string, data interface{}) error {
if !b.System().LocalMount() && b.System().ReplicationState().HasState(consts.ReplicationPerformancePrimary) {
return nil
}
f, ok := walRollbackMap[kind]
if !ok {
return fmt.Errorf("unknown type to rollback")

View file

@ -143,7 +143,7 @@ func TestBackend_RoleUpgrade(t *testing.T) {
}
if !reflect.DeepEqual(role, roleEnt) {
t.Fatal("bad role %#v", role)
t.Fatalf("bad role %#v", role)
}
// Upgrade case
@ -162,7 +162,7 @@ func TestBackend_RoleUpgrade(t *testing.T) {
}
if !reflect.DeepEqual(role, roleEnt) {
t.Fatal("bad role %#v", role)
t.Fatalf("bad role %#v", role)
}
}

View file

@ -154,7 +154,7 @@ This path lets you manage the roles that can be created with this backend.
The "sql" parameter customizes the SQL string used to create the login to
the server. The parameter can be a sequence of SQL queries, each semi-colon
seperated. Some substitution will be done to the SQL string for certain keys.
separated. Some substitution will be done to the SQL string for certain keys.
The names of the variables must be surrounded by "{{" and "}}" to be replaced.
* "name" - The random username generated for the DB user.

View file

@ -192,7 +192,7 @@ const pathRoleHelpDesc = `
This path lets you manage the roles that can be created with this backend.
The "sql" parameter customizes the SQL string used to create the role.
This can be a sequence of SQL queries, each semi-colon seperated. Some
This can be a sequence of SQL queries, each semi-colon separated. Some
substitution will be done to the SQL string for certain keys.
The names of the variables must be surrounded by "{{" and "}}" to be replaced.

View file

@ -7,6 +7,7 @@ import (
"strings"
"time"
"github.com/hashicorp/vault/helper/consts"
"github.com/hashicorp/vault/helper/parseutil"
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
@ -315,7 +316,7 @@ func (b *backend) getRole(ctx context.Context, s logical.Storage, n string) (*ro
modified = true
}
if modified {
if modified && (b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary)) {
jsonEntry, err := logical.StorageEntryJSON("role/"+n, &result)
if err != nil {
return nil, err

View file

@ -45,7 +45,6 @@ type BaseCommand struct {
tokenHelper token.TokenHelper
// For testing
client *api.Client
}
@ -110,6 +109,8 @@ func (c *BaseCommand) Client() (*api.Client, error) {
client.SetToken(token)
}
c.client = client
return client, nil
}

View file

@ -185,11 +185,12 @@ func init() {
}
loginHandlers := map[string]LoginHandler{
"aws": &credAws.CLIHandler{},
"cert": &credCert.CLIHandler{},
"github": &credGitHub.CLIHandler{},
"ldap": &credLdap.CLIHandler{},
"okta": &credOkta.CLIHandler{},
"aws": &credAws.CLIHandler{},
"centrify": &credCentrify.CLIHandler{},
"cert": &credCert.CLIHandler{},
"github": &credGitHub.CLIHandler{},
"ldap": &credLdap.CLIHandler{},
"okta": &credOkta.CLIHandler{},
"radius": &credUserpass.CLIHandler{
DefaultMount: "radius",
},

View file

@ -192,7 +192,7 @@ func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
}
}
if !found {
t.Fatalf("expected entity ID %q to be part of Italians group")
t.Fatalf("expected entity ID %q to be part of Italians group", entityID)
}
secret, err = client.Logical().Read("identity/group/id/" + scientistsGroupID)
@ -207,7 +207,7 @@ func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
}
}
if !found {
t.Fatalf("expected entity ID %q to be part of Scientists group")
t.Fatalf("expected entity ID %q to be part of Scientists group", entityID)
}
secret, err = client.Logical().Read("identity/group/id/" + devopsGroupID)
@ -222,7 +222,7 @@ func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
}
}
if !found {
t.Fatalf("expected entity ID %q to be part of devops group")
t.Fatalf("expected entity ID %q to be part of devops group", entityID)
}
identityStore := cores[0].IdentityStore()
@ -308,7 +308,7 @@ func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
}
}
if !found {
t.Fatalf("expected entity ID %q to be part of Italians group")
t.Fatalf("expected entity ID %q to be part of Italians group", entityID)
}
secret, err = client.Logical().Read("identity/group/id/" + scientistsGroupID)
@ -323,7 +323,7 @@ func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
}
}
if !found {
t.Fatalf("expected entity ID %q to be part of Italians group")
t.Fatalf("expected entity ID %q to be part of scientists group", entityID)
}
secret, err = client.Logical().Read("identity/group/id/" + devopsGroupID)
@ -339,7 +339,7 @@ func TestIdentityStore_Integ_GroupAliases(t *testing.T) {
}
}
if !found {
t.Fatalf("expected entity ID %q to be part of devops group")
t.Fatalf("expected entity ID %q to be part of devops group", entityID)
}
// Remove user tesla from the devops group in LDAP backend

View file

@ -36,7 +36,7 @@ func TestTCPListener_tls(t *testing.T) {
wd, _ := os.Getwd()
wd += "/test-fixtures/reload/"
td, err := ioutil.TempDir("", fmt.Sprintf("vault-test-%d", rand.New(rand.NewSource(time.Now().Unix())).Int63))
td, err := ioutil.TempDir("", fmt.Sprintf("vault-test-%d", rand.New(rand.NewSource(time.Now().Unix())).Int63()))
if err != nil {
t.Fatal(err)
}

View file

@ -244,6 +244,13 @@ func (c *SSHCommand) Run(args []string) int {
sshArgs = args[1:]
}
// Set the client in the command
_, err = c.Client()
if err != nil {
c.UI.Error(err.Error())
return 1
}
// Credentials are generated only against a registered role. If user
// does not specify a role with the SSH command, then lookup API is used
// to fetch all the roles with which this IP is associated. If there is
@ -331,13 +338,7 @@ func (c *SSHCommand) handleTypeCA(username, ip string, sshArgs []string) int {
return 1
}
client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
return 1
}
sshClient := client.SSHWithMountPoint(c.flagMountPoint)
sshClient := c.client.SSHWithMountPoint(c.flagMountPoint)
// Attempt to sign the public key
secret, err := sshClient.SignKey(c.flagRole, map[string]interface{}{
@ -611,12 +612,7 @@ func (c *SSHCommand) handleTypeDynamic(username, ip string, sshArgs []string) in
// generateCredential generates a credential for the given role and returns the
// decoded secret data.
func (c *SSHCommand) generateCredential(username, ip string) (*api.Secret, *SSHCredentialResp, error) {
client, err := c.Client()
if err != nil {
return nil, nil, err
}
sshClient := client.SSHWithMountPoint(c.flagMountPoint)
sshClient := c.client.SSHWithMountPoint(c.flagMountPoint)
// Attempt to generate the credential.
secret, err := sshClient.Credential(c.flagRole, map[string]interface{}{
@ -683,11 +679,7 @@ func (c *SSHCommand) defaultRole(mountPoint, ip string) (string, error) {
data := map[string]interface{}{
"ip": ip,
}
client, err := c.Client()
if err != nil {
return "", err
}
secret, err := client.Logical().Write(mountPoint+"/lookup", data)
secret, err := c.client.Logical().Write(mountPoint+"/lookup", data)
if err != nil {
return "", fmt.Errorf("Error finding roles for IP %q: %q", ip, err)

View file

@ -52,12 +52,12 @@ func ParseHexFormatted(in, sep string) []byte {
// of the marshaled public key
func GetSubjKeyID(privateKey crypto.Signer) ([]byte, error) {
if privateKey == nil {
return nil, errutil.InternalError{"passed-in private key is nil"}
return nil, errutil.InternalError{Err: "passed-in private key is nil"}
}
marshaledKey, err := x509.MarshalPKIXPublicKey(privateKey.Public())
if err != nil {
return nil, errutil.InternalError{fmt.Sprintf("error marshalling public key: %s", err)}
return nil, errutil.InternalError{Err: fmt.Sprintf("error marshalling public key: %s", err)}
}
subjKeyID := sha1.Sum(marshaledKey)
@ -71,7 +71,7 @@ func ParsePKIMap(data map[string]interface{}) (*ParsedCertBundle, error) {
result := &CertBundle{}
err := mapstructure.Decode(data, result)
if err != nil {
return nil, errutil.UserError{err.Error()}
return nil, errutil.UserError{Err: err.Error()}
}
return result.ToParsedCertBundle()
@ -97,7 +97,7 @@ func ParsePKIJSON(input []byte) (*ParsedCertBundle, error) {
return ParsePKIMap(secret.Data)
}
return nil, errutil.UserError{"unable to parse out of either secret data or a secret object"}
return nil, errutil.UserError{Err: "unable to parse out of either secret data or a secret object"}
}
// ParsePEMBundle takes a string of concatenated PEM-format certificate
@ -106,7 +106,7 @@ func ParsePKIJSON(input []byte) (*ParsedCertBundle, error) {
// certificates may follow. There must be at most one private key.
func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
if len(pemBundle) == 0 {
return nil, errutil.UserError{"empty pem bundle"}
return nil, errutil.UserError{Err: "empty pem bundle"}
}
pemBundle = strings.TrimSpace(pemBundle)
@ -119,12 +119,12 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
for len(pemBytes) > 0 {
pemBlock, pemBytes = pem.Decode(pemBytes)
if pemBlock == nil {
return nil, errutil.UserError{"no data found"}
return nil, errutil.UserError{Err: "no data found"}
}
if signer, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil {
if parsedBundle.PrivateKeyType != UnknownPrivateKey {
return nil, errutil.UserError{"more than one private key given; provide only one private key in the bundle"}
return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"}
}
parsedBundle.PrivateKeyFormat = ECBlock
parsedBundle.PrivateKeyType = ECPrivateKey
@ -133,7 +133,7 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
} else if signer, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil {
if parsedBundle.PrivateKeyType != UnknownPrivateKey {
return nil, errutil.UserError{"more than one private key given; provide only one private key in the bundle"}
return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"}
}
parsedBundle.PrivateKeyType = RSAPrivateKey
parsedBundle.PrivateKeyFormat = PKCS1Block
@ -143,7 +143,7 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) {
parsedBundle.PrivateKeyFormat = PKCS8Block
if parsedBundle.PrivateKeyType != UnknownPrivateKey {
return nil, errutil.UserError{"More than one private key given; provide only one private key in the bundle"}
return nil, errutil.UserError{Err: "More than one private key given; provide only one private key in the bundle"}
}
switch signer := signer.(type) {
case *rsa.PrivateKey:

View file

@ -147,7 +147,7 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
if len(c.PrivateKey) > 0 {
pemBlock, _ = pem.Decode([]byte(c.PrivateKey))
if pemBlock == nil {
return nil, errutil.UserError{"Error decoding private key from cert bundle"}
return nil, errutil.UserError{Err: "Error decoding private key from cert bundle"}
}
result.PrivateKeyBytes = pemBlock.Bytes
@ -161,7 +161,7 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
case PKCS8Block:
t, err := getPKCS8Type(pemBlock.Bytes)
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Error getting key type from pkcs#8: %v", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Error getting key type from pkcs#8: %v", err)}
}
result.PrivateKeyType = t
switch t {
@ -171,24 +171,24 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
c.PrivateKeyType = RSAPrivateKey
}
default:
return nil, errutil.UserError{fmt.Sprintf("Unsupported key block type: %s", pemBlock.Type)}
return nil, errutil.UserError{Err: fmt.Sprintf("Unsupported key block type: %s", pemBlock.Type)}
}
result.PrivateKey, err = result.getSigner()
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Error getting signer: %s", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Error getting signer: %s", err)}
}
}
if len(c.Certificate) > 0 {
pemBlock, _ = pem.Decode([]byte(c.Certificate))
if pemBlock == nil {
return nil, errutil.UserError{"Error decoding certificate from cert bundle"}
return nil, errutil.UserError{Err: "Error decoding certificate from cert bundle"}
}
result.CertificateBytes = pemBlock.Bytes
result.Certificate, err = x509.ParseCertificate(result.CertificateBytes)
if err != nil {
return nil, errutil.UserError{"Error encountered parsing certificate bytes from raw bundle"}
return nil, errutil.UserError{Err: "Error encountered parsing certificate bytes from raw bundle"}
}
}
switch {
@ -196,12 +196,12 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
for _, cert := range c.CAChain {
pemBlock, _ := pem.Decode([]byte(cert))
if pemBlock == nil {
return nil, errutil.UserError{"Error decoding certificate from cert bundle"}
return nil, errutil.UserError{Err: "Error decoding certificate from cert bundle"}
}
parsedCert, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
return nil, errutil.UserError{"Error encountered parsing certificate bytes from raw bundle"}
return nil, errutil.UserError{Err: "Error encountered parsing certificate bytes from raw bundle"}
}
certBlock := &CertBlock{
@ -215,12 +215,12 @@ func (c *CertBundle) ToParsedCertBundle() (*ParsedCertBundle, error) {
case len(c.IssuingCA) > 0:
pemBlock, _ = pem.Decode([]byte(c.IssuingCA))
if pemBlock == nil {
return nil, errutil.UserError{"Error decoding ca certificate from cert bundle"}
return nil, errutil.UserError{Err: "Error decoding ca certificate from cert bundle"}
}
parsedCert, err := x509.ParseCertificate(pemBlock.Bytes)
if err != nil {
return nil, errutil.UserError{"Error encountered parsing certificate bytes from raw bundle3"}
return nil, errutil.UserError{Err: "Error encountered parsing certificate bytes from raw bundle3"}
}
result.SerialNumber = result.Certificate.SerialNumber
@ -343,20 +343,20 @@ func (p *ParsedCertBundle) getSigner() (crypto.Signer, error) {
var err error
if p.PrivateKeyBytes == nil || len(p.PrivateKeyBytes) == 0 {
return nil, errutil.UserError{"Given parsed cert bundle does not have private key information"}
return nil, errutil.UserError{Err: "Given parsed cert bundle does not have private key information"}
}
switch p.PrivateKeyFormat {
case ECBlock:
signer, err = x509.ParseECPrivateKey(p.PrivateKeyBytes)
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Unable to parse CA's private EC key: %s", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Unable to parse CA's private EC key: %s", err)}
}
case PKCS1Block:
signer, err = x509.ParsePKCS1PrivateKey(p.PrivateKeyBytes)
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Unable to parse CA's private RSA key: %s", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Unable to parse CA's private RSA key: %s", err)}
}
case PKCS8Block:
@ -365,12 +365,12 @@ func (p *ParsedCertBundle) getSigner() (crypto.Signer, error) {
case *rsa.PrivateKey, *ecdsa.PrivateKey:
return k.(crypto.Signer), nil
default:
return nil, errutil.UserError{"Found unknown private key type in pkcs#8 wrapping"}
return nil, errutil.UserError{Err: "Found unknown private key type in pkcs#8 wrapping"}
}
}
return nil, errutil.UserError{fmt.Sprintf("Failed to parse pkcs#8 key: %v", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Failed to parse pkcs#8 key: %v", err)}
default:
return nil, errutil.UserError{"Unable to determine type of private key; only RSA and EC are supported"}
return nil, errutil.UserError{Err: "Unable to determine type of private key; only RSA and EC are supported"}
}
return signer, nil
}
@ -385,7 +385,7 @@ func (p *ParsedCertBundle) SetParsedPrivateKey(privateKey crypto.Signer, private
func getPKCS8Type(bs []byte) (PrivateKeyType, error) {
k, err := x509.ParsePKCS8PrivateKey(bs)
if err != nil {
return UnknownPrivateKey, errutil.UserError{fmt.Sprintf("Failed to parse pkcs#8 key: %v", err)}
return UnknownPrivateKey, errutil.UserError{Err: fmt.Sprintf("Failed to parse pkcs#8 key: %v", err)}
}
switch k.(type) {
@ -394,7 +394,7 @@ func getPKCS8Type(bs []byte) (PrivateKeyType, error) {
case *rsa.PrivateKey:
return RSAPrivateKey, nil
default:
return UnknownPrivateKey, errutil.UserError{"Found unknown private key type in pkcs#8 wrapping"}
return UnknownPrivateKey, errutil.UserError{Err: "Found unknown private key type in pkcs#8 wrapping"}
}
}
@ -408,7 +408,7 @@ func (c *CSRBundle) ToParsedCSRBundle() (*ParsedCSRBundle, error) {
if len(c.PrivateKey) > 0 {
pemBlock, _ = pem.Decode([]byte(c.PrivateKey))
if pemBlock == nil {
return nil, errutil.UserError{"Error decoding private key from cert bundle"}
return nil, errutil.UserError{Err: "Error decoding private key from cert bundle"}
}
result.PrivateKeyBytes = pemBlock.Bytes
@ -426,25 +426,25 @@ func (c *CSRBundle) ToParsedCSRBundle() (*ParsedCSRBundle, error) {
result.PrivateKeyType = RSAPrivateKey
c.PrivateKeyType = "rsa"
} else {
return nil, errutil.UserError{fmt.Sprintf("Unknown private key type in bundle: %s", c.PrivateKeyType)}
return nil, errutil.UserError{Err: fmt.Sprintf("Unknown private key type in bundle: %s", c.PrivateKeyType)}
}
}
result.PrivateKey, err = result.getSigner()
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Error getting signer: %s", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Error getting signer: %s", err)}
}
}
if len(c.CSR) > 0 {
pemBlock, _ = pem.Decode([]byte(c.CSR))
if pemBlock == nil {
return nil, errutil.UserError{"Error decoding certificate from cert bundle"}
return nil, errutil.UserError{Err: "Error decoding certificate from cert bundle"}
}
result.CSRBytes = pemBlock.Bytes
result.CSR, err = x509.ParseCertificateRequest(result.CSRBytes)
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Error encountered parsing certificate bytes from raw bundle: %v", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Error encountered parsing certificate bytes from raw bundle: %v", err)}
}
}
@ -474,7 +474,7 @@ func (p *ParsedCSRBundle) ToCSRBundle() (*CSRBundle, error) {
result.PrivateKeyType = "ec"
block.Type = "EC PRIVATE KEY"
default:
return nil, errutil.InternalError{"Could not determine private key type when creating block"}
return nil, errutil.InternalError{Err: "Could not determine private key type when creating block"}
}
result.PrivateKey = strings.TrimSpace(string(pem.EncodeToMemory(&block)))
}
@ -491,24 +491,24 @@ func (p *ParsedCSRBundle) getSigner() (crypto.Signer, error) {
var err error
if p.PrivateKeyBytes == nil || len(p.PrivateKeyBytes) == 0 {
return nil, errutil.UserError{"Given parsed cert bundle does not have private key information"}
return nil, errutil.UserError{Err: "Given parsed cert bundle does not have private key information"}
}
switch p.PrivateKeyType {
case ECPrivateKey:
signer, err = x509.ParseECPrivateKey(p.PrivateKeyBytes)
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Unable to parse CA's private EC key: %s", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Unable to parse CA's private EC key: %s", err)}
}
case RSAPrivateKey:
signer, err = x509.ParsePKCS1PrivateKey(p.PrivateKeyBytes)
if err != nil {
return nil, errutil.UserError{fmt.Sprintf("Unable to parse CA's private RSA key: %s", err)}
return nil, errutil.UserError{Err: fmt.Sprintf("Unable to parse CA's private RSA key: %s", err)}
}
default:
return nil, errutil.UserError{"Unable to determine type of private key; only RSA and EC are supported"}
return nil, errutil.UserError{Err: "Unable to determine type of private key; only RSA and EC are supported"}
}
return signer, nil
}

View file

@ -953,8 +953,6 @@ func (p *Policy) VerifySignature(context, input []byte, sig, algorithm string) (
default:
return false, errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)}
}
return false, errutil.InternalError{Err: "no valid key type found"}
}
func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) error {

View file

@ -36,7 +36,7 @@ func (p *ProxyProtoConfig) SetAuthorizedAddrs(addrs interface{}) error {
for _, v := range addrs.([]interface{}) {
stringAddr, ok := v.(string)
if !ok {
return fmt.Errorf("error parsing %q as string")
return fmt.Errorf("error parsing %v as string", v)
}
stringAddrs = append(stringAddrs, stringAddr)
}

View file

@ -349,7 +349,7 @@ func TestGlobbedStringsMatch(t *testing.T) {
actual := GlobbedStringsMatch(tc.item, tc.val)
if actual != tc.expect {
t.Fatalf("Bad testcase %#v, expected %b, got %b", tc, tc.expect, actual)
t.Fatalf("Bad testcase %#v, expected %t, got %t", tc, tc.expect, actual)
}
}
}

View file

@ -23,7 +23,7 @@ type ResponseWrapInfo struct {
// WrappedEntityID is the entity identifier of the caller who initiated the
// wrapping request
WrappedEntityID string `json:"wrapped_entity_id" structs:"wrapped_entity_id" mapstructure:"wrapped_entity_id sentinel:"""`
WrappedEntityID string `json:"wrapped_entity_id" structs:"wrapped_entity_id" mapstructure:"wrapped_entity_id" sentinel:""`
// The format to use. This doesn't get returned, it's only internal.
Format string `json:"format" structs:"format" mapstructure:"format" sentinel:""`

View file

@ -122,7 +122,7 @@ func TestHTTP_Wrapping(t *testing.T) {
t.Fatalf("mistmatched ttls: %d vs %d", creationTTL, wrapInfo.TTL)
}
if secret.Data["creation_time"].(string) != wrapInfo.CreationTime.Format(time.RFC3339Nano) {
t.Fatalf("mistmatched creation times: %d vs %d", secret.Data["creation_time"].(string), wrapInfo.CreationTime.Format(time.RFC3339Nano))
t.Fatalf("mistmatched creation times: %q vs %q", secret.Data["creation_time"].(string), wrapInfo.CreationTime.Format(time.RFC3339Nano))
}
}
@ -310,7 +310,7 @@ func TestHTTP_Wrapping(t *testing.T) {
// Check for correct CreationPath before rewrap
if wrapInfo.CreationPath != "secret/foo" {
t.Fatal("error on wrapInfo.CreationPath: expected: secret/foo, got: %s", wrapInfo.CreationPath)
t.Fatalf("error on wrapInfo.CreationPath: expected: secret/foo, got: %s", wrapInfo.CreationPath)
}
// Test rewrapping
@ -323,7 +323,7 @@ func TestHTTP_Wrapping(t *testing.T) {
// Check for correct Creation path after rewrap
if wrapInfo.CreationPath != "secret/foo" {
t.Fatal("error on wrapInfo.CreationPath: expected: secret/foo, got: %s", wrapInfo.CreationPath)
t.Fatalf("error on wrapInfo.CreationPath: expected: secret/foo, got: %s", wrapInfo.CreationPath)
}
// Should be expired and fail

View file

@ -271,7 +271,7 @@ func testSalting(t *testing.T, ctx context.Context, storage logical.Storage, sal
Value: []byte(`{"foo": "bar"}`),
})
if err != nil {
t.Fatal("err: %v", err)
t.Fatalf("err: %v", err)
}
// A read should transparently upgrade
resp, err = b.HandleRequest(ctx, &logical.Request{

View file

@ -143,7 +143,7 @@ func testBackend(t *testing.T) (logical.Backend, func()) {
Factory: mock.Factory,
},
}
client, _ := gplugin.TestPluginRPCConn(t, pluginMap)
client, _ := gplugin.TestPluginRPCConn(t, pluginMap, nil)
cleanup := func() {
client.Close()
}

View file

@ -0,0 +1,12 @@
package plugin
import (
"math"
"google.golang.org/grpc"
)
var largeMsgGRPCCallOpts []grpc.CallOption = []grpc.CallOption{
grpc.MaxCallSendMsgSize(math.MaxInt32),
grpc.MaxCallRecvMsgSize(math.MaxInt32),
}

View file

@ -53,7 +53,7 @@ func (b *backendGRPCPluginClient) HandleRequest(ctx context.Context, req *logica
reply, err := b.client.HandleRequest(ctx, &pb.HandleRequestArgs{
Request: protoReq,
})
}, largeMsgGRPCCallOpts...)
if err != nil {
if b.doneCtx.Err() != nil {
return nil, ErrPluginShutdown
@ -115,7 +115,7 @@ func (b *backendGRPCPluginClient) HandleExistenceCheck(ctx context.Context, req
defer cancel()
reply, err := b.client.HandleExistenceCheck(ctx, &pb.HandleExistenceCheckArgs{
Request: protoReq,
})
}, largeMsgGRPCCallOpts...)
if err != nil {
if b.doneCtx.Err() != nil {
return false, false, ErrPluginShutdown

View file

@ -25,7 +25,7 @@ type GRPCStorageClient struct {
func (s *GRPCStorageClient) List(ctx context.Context, prefix string) ([]string, error) {
reply, err := s.client.List(ctx, &pb.StorageListArgs{
Prefix: prefix,
})
}, largeMsgGRPCCallOpts...)
if err != nil {
return reply.Keys, err
}
@ -38,7 +38,7 @@ func (s *GRPCStorageClient) List(ctx context.Context, prefix string) ([]string,
func (s *GRPCStorageClient) Get(ctx context.Context, key string) (*logical.StorageEntry, error) {
reply, err := s.client.Get(ctx, &pb.StorageGetArgs{
Key: key,
})
}, largeMsgGRPCCallOpts...)
if err != nil {
return nil, err
}
@ -51,7 +51,7 @@ func (s *GRPCStorageClient) Get(ctx context.Context, key string) (*logical.Stora
func (s *GRPCStorageClient) Put(ctx context.Context, entry *logical.StorageEntry) error {
reply, err := s.client.Put(ctx, &pb.StoragePutArgs{
Entry: pb.LogicalStorageEntryToProtoStorageEntry(entry),
})
}, largeMsgGRPCCallOpts...)
if err != nil {
return err
}

View file

@ -123,6 +123,15 @@ func (s *gRPCSystemViewClient) MlockEnabled() bool {
return reply.Enabled
}
func (s *gRPCSystemViewClient) LocalMount() bool {
reply, err := s.client.LocalMount(context.Background(), &pb.Empty{})
if err != nil {
return false
}
return reply.Local
}
type gRPCSystemViewServer struct {
impl logical.SystemView
}
@ -200,3 +209,10 @@ func (s *gRPCSystemViewServer) MlockEnabled(ctx context.Context, _ *pb.Empty) (*
Enabled: enabled,
}, nil
}
func (s *gRPCSystemViewServer) LocalMount(ctx context.Context, _ *pb.Empty) (*pb.LocalMountReply, error) {
local := s.impl.LocalMount()
return &pb.LocalMountReply{
Local: local,
}, nil
}

View file

@ -47,6 +47,7 @@ It has these top-level messages:
ResponseWrapDataArgs
ResponseWrapDataReply
MlockEnabledReply
LocalMountReply
*/
package pb
@ -1384,6 +1385,22 @@ func (m *MlockEnabledReply) GetEnabled() bool {
return false
}
type LocalMountReply struct {
Local bool `sentinel:"" protobuf:"varint,1,opt,name=local" json:"local,omitempty"`
}
func (m *LocalMountReply) Reset() { *m = LocalMountReply{} }
func (m *LocalMountReply) String() string { return proto.CompactTextString(m) }
func (*LocalMountReply) ProtoMessage() {}
func (*LocalMountReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} }
func (m *LocalMountReply) GetLocal() bool {
if m != nil {
return m.Local
}
return false
}
func init() {
proto.RegisterType((*Empty)(nil), "pb.Empty")
proto.RegisterType((*Header)(nil), "pb.Header")
@ -1424,6 +1441,7 @@ func init() {
proto.RegisterType((*ResponseWrapDataArgs)(nil), "pb.ResponseWrapDataArgs")
proto.RegisterType((*ResponseWrapDataReply)(nil), "pb.ResponseWrapDataReply")
proto.RegisterType((*MlockEnabledReply)(nil), "pb.MlockEnabledReply")
proto.RegisterType((*LocalMountReply)(nil), "pb.LocalMountReply")
}
// Reference imports to suppress errors if they are not otherwise used.
@ -1870,6 +1888,7 @@ type SystemViewClient interface {
ReplicationState(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ReplicationStateReply, error)
ResponseWrapData(ctx context.Context, in *ResponseWrapDataArgs, opts ...grpc.CallOption) (*ResponseWrapDataReply, error)
MlockEnabled(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MlockEnabledReply, error)
LocalMount(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LocalMountReply, error)
}
type systemViewClient struct {
@ -1952,6 +1971,15 @@ func (c *systemViewClient) MlockEnabled(ctx context.Context, in *Empty, opts ...
return out, nil
}
func (c *systemViewClient) LocalMount(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*LocalMountReply, error) {
out := new(LocalMountReply)
err := grpc.Invoke(ctx, "/pb.SystemView/LocalMount", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for SystemView service
type SystemViewServer interface {
@ -1963,6 +1991,7 @@ type SystemViewServer interface {
ReplicationState(context.Context, *Empty) (*ReplicationStateReply, error)
ResponseWrapData(context.Context, *ResponseWrapDataArgs) (*ResponseWrapDataReply, error)
MlockEnabled(context.Context, *Empty) (*MlockEnabledReply, error)
LocalMount(context.Context, *Empty) (*LocalMountReply, error)
}
func RegisterSystemViewServer(s *grpc.Server, srv SystemViewServer) {
@ -2113,6 +2142,24 @@ func _SystemView_MlockEnabled_Handler(srv interface{}, ctx context.Context, dec
return interceptor(ctx, in, info, handler)
}
func _SystemView_LocalMount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SystemViewServer).LocalMount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.SystemView/LocalMount",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SystemViewServer).LocalMount(ctx, req.(*Empty))
}
return interceptor(ctx, in, info, handler)
}
var _SystemView_serviceDesc = grpc.ServiceDesc{
ServiceName: "pb.SystemView",
HandlerType: (*SystemViewServer)(nil),
@ -2149,6 +2196,10 @@ var _SystemView_serviceDesc = grpc.ServiceDesc{
MethodName: "MlockEnabled",
Handler: _SystemView_MlockEnabled_Handler,
},
{
MethodName: "LocalMount",
Handler: _SystemView_LocalMount_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "logical/plugin/pb/backend.proto",
@ -2157,131 +2208,133 @@ var _SystemView_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("logical/plugin/pb/backend.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 2014 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xdb, 0x72, 0xdb, 0xc8,
0xd1, 0x2e, 0x92, 0x22, 0x09, 0x36, 0x49, 0x1d, 0x46, 0xb2, 0x7f, 0x88, 0xf6, 0xfe, 0x62, 0xb0,
0x65, 0x85, 0xeb, 0xaa, 0xa5, 0x6c, 0xe6, 0xe4, 0x4d, 0x6a, 0x37, 0xa5, 0xc8, 0x5a, 0xaf, 0xb2,
0xf6, 0xae, 0x0a, 0x62, 0xb2, 0x49, 0x25, 0x55, 0xdc, 0x11, 0xd0, 0xa2, 0x50, 0x02, 0x01, 0x64,
0x30, 0x90, 0xcc, 0xab, 0x3c, 0x42, 0xee, 0x36, 0x4f, 0x92, 0x77, 0x48, 0x55, 0xae, 0xf3, 0x1a,
0xb9, 0xc8, 0x13, 0xa4, 0xe6, 0x00, 0x70, 0x40, 0x52, 0xb1, 0x53, 0x95, 0xdc, 0x4d, 0x7f, 0xdd,
0x33, 0x3d, 0xd3, 0xd3, 0xfd, 0xf5, 0x00, 0x70, 0x10, 0xc6, 0xd3, 0xc0, 0xa3, 0xe1, 0x51, 0x12,
0x66, 0xd3, 0x20, 0x3a, 0x4a, 0x2e, 0x8f, 0x2e, 0xa9, 0x77, 0x83, 0x91, 0x3f, 0x4c, 0x58, 0xcc,
0x63, 0x52, 0x4d, 0x2e, 0x7b, 0x07, 0xd3, 0x38, 0x9e, 0x86, 0x78, 0x24, 0x91, 0xcb, 0xec, 0xea,
0x88, 0x07, 0x33, 0x4c, 0x39, 0x9d, 0x25, 0xca, 0xc8, 0x69, 0x42, 0xfd, 0x74, 0x96, 0xf0, 0xb9,
0xd3, 0x87, 0xc6, 0x17, 0x48, 0x7d, 0x64, 0xe4, 0x21, 0x34, 0xae, 0xe5, 0xc8, 0xae, 0xf4, 0x6b,
0x83, 0x96, 0xab, 0x25, 0xe7, 0x77, 0x00, 0xe7, 0x62, 0xce, 0x29, 0x63, 0x31, 0x23, 0xfb, 0x60,
0x21, 0x63, 0x13, 0x3e, 0x4f, 0xd0, 0xae, 0xf4, 0x2b, 0x83, 0xae, 0xdb, 0x44, 0xc6, 0xc6, 0xf3,
0x04, 0xc9, 0xff, 0x81, 0x18, 0x4e, 0x66, 0xe9, 0xd4, 0xae, 0xf6, 0x2b, 0x62, 0x05, 0x64, 0xec,
0x4d, 0x3a, 0xcd, 0xe7, 0x78, 0xb1, 0x8f, 0x76, 0xad, 0x5f, 0x19, 0xd4, 0xe4, 0x9c, 0x93, 0xd8,
0x47, 0xe7, 0xbb, 0x0a, 0xd4, 0xcf, 0x29, 0xbf, 0x4e, 0x09, 0x81, 0x0d, 0x16, 0xc7, 0x5c, 0x3b,
0x97, 0x63, 0x32, 0x80, 0xad, 0x2c, 0xa2, 0x19, 0xbf, 0xc6, 0x88, 0x07, 0x1e, 0xe5, 0xe8, 0xdb,
0x55, 0xa9, 0x5e, 0x86, 0xc9, 0x87, 0xd0, 0x0d, 0x63, 0x8f, 0x86, 0x93, 0x94, 0xc7, 0x8c, 0x4e,
0x85, 0x1f, 0x61, 0xd7, 0x91, 0xe0, 0x85, 0xc2, 0xc8, 0x53, 0xd8, 0x49, 0x91, 0x86, 0x93, 0x3b,
0x46, 0x93, 0xc2, 0x70, 0x43, 0x2d, 0x28, 0x14, 0xdf, 0x30, 0x9a, 0x68, 0x5b, 0xe7, 0x4f, 0x0d,
0x68, 0xba, 0xf8, 0x87, 0x0c, 0x53, 0x4e, 0x36, 0xa1, 0x1a, 0xf8, 0xf2, 0xb4, 0x2d, 0xb7, 0x1a,
0xf8, 0x64, 0x08, 0xc4, 0xc5, 0x24, 0x14, 0xae, 0x83, 0x38, 0x3a, 0x09, 0xb3, 0x94, 0x23, 0xd3,
0x67, 0x5e, 0xa3, 0x21, 0x8f, 0xa1, 0x15, 0x27, 0xc8, 0x24, 0x26, 0x03, 0xd0, 0x72, 0x17, 0x80,
0x38, 0x78, 0x42, 0xf9, 0xb5, 0xbd, 0x21, 0x15, 0x72, 0x2c, 0x30, 0x9f, 0x72, 0x6a, 0xd7, 0x15,
0x26, 0xc6, 0xc4, 0x81, 0x46, 0x8a, 0x1e, 0x43, 0x6e, 0x37, 0xfa, 0x95, 0x41, 0x7b, 0x04, 0xc3,
0xe4, 0x72, 0x78, 0x21, 0x11, 0x57, 0x6b, 0xc8, 0x63, 0xd8, 0x10, 0x71, 0xb1, 0x9b, 0xd2, 0xc2,
0x12, 0x16, 0xc7, 0x19, 0xbf, 0x76, 0x25, 0x4a, 0x46, 0xd0, 0x54, 0x77, 0x9a, 0xda, 0x56, 0xbf,
0x36, 0x68, 0x8f, 0x6c, 0x61, 0xa0, 0x4f, 0x39, 0x54, 0x69, 0x90, 0x9e, 0x46, 0x9c, 0xcd, 0xdd,
0xdc, 0x90, 0x7c, 0x0f, 0x3a, 0x5e, 0x18, 0x60, 0xc4, 0x27, 0x3c, 0xbe, 0xc1, 0xc8, 0x6e, 0xc9,
0x1d, 0xb5, 0x15, 0x36, 0x16, 0x10, 0x19, 0xc1, 0x03, 0xd3, 0x64, 0x42, 0x3d, 0x0f, 0xd3, 0x34,
0x66, 0x36, 0x48, 0xdb, 0x5d, 0xc3, 0xf6, 0x58, 0xab, 0xc4, 0xb2, 0x7e, 0x90, 0x26, 0x21, 0x9d,
0x4f, 0x22, 0x3a, 0x43, 0xbb, 0xad, 0x96, 0xd5, 0xd8, 0x57, 0x74, 0x86, 0xe4, 0x00, 0xda, 0xb3,
0x38, 0x8b, 0xf8, 0x24, 0x89, 0x83, 0x88, 0xdb, 0x1d, 0x69, 0x01, 0x12, 0x3a, 0x17, 0x08, 0xf9,
0x00, 0x94, 0xa4, 0x92, 0xb1, 0xab, 0xe2, 0x2a, 0x11, 0x99, 0x8e, 0x4f, 0x60, 0x53, 0xa9, 0x8b,
0xfd, 0x6c, 0x4a, 0x93, 0xae, 0x44, 0x8b, 0x9d, 0x3c, 0x83, 0x96, 0xcc, 0x87, 0x20, 0xba, 0x8a,
0xed, 0x2d, 0x19, 0xb7, 0x5d, 0x23, 0x2c, 0x22, 0x27, 0xce, 0xa2, 0xab, 0xd8, 0xb5, 0xee, 0xf4,
0x88, 0x7c, 0x0a, 0x8f, 0x4a, 0xe7, 0x65, 0x38, 0xa3, 0x41, 0x14, 0x44, 0xd3, 0x49, 0x96, 0x62,
0x6a, 0x6f, 0xcb, 0x0c, 0xb7, 0x8d, 0x53, 0xbb, 0xb9, 0xc1, 0xaf, 0x52, 0x4c, 0xc9, 0x23, 0x68,
0x89, 0xbc, 0xe5, 0xf3, 0x49, 0xe0, 0xdb, 0x3b, 0x72, 0x4b, 0x96, 0x02, 0xce, 0x7c, 0xf2, 0x7d,
0xd8, 0x4a, 0xe2, 0x30, 0xf0, 0xe6, 0x93, 0xf8, 0x16, 0x19, 0x0b, 0x7c, 0xb4, 0x49, 0xbf, 0x32,
0xb0, 0xdc, 0x4d, 0x05, 0x7f, 0xad, 0xd1, 0x75, 0xa5, 0xb1, 0x2b, 0x0d, 0x97, 0xe1, 0xde, 0xe7,
0xd0, 0x31, 0xaf, 0x96, 0x6c, 0x43, 0xed, 0x06, 0xe7, 0x3a, 0x9d, 0xc5, 0x90, 0xf4, 0xa1, 0x7e,
0x4b, 0xc3, 0x0c, 0x65, 0x0a, 0xeb, 0xc4, 0x52, 0x53, 0x5c, 0xa5, 0xf8, 0x69, 0xf5, 0x45, 0xc5,
0xa1, 0x50, 0x3f, 0x0e, 0x03, 0x9a, 0x2e, 0xc5, 0xbd, 0xf2, 0xee, 0xb8, 0x57, 0xd7, 0xc5, 0x9d,
0xc0, 0x86, 0xbc, 0x79, 0x55, 0x0f, 0x72, 0xec, 0xfc, 0xb3, 0x06, 0x1b, 0x22, 0x5f, 0xc9, 0x8f,
0xa0, 0x1b, 0x22, 0x4d, 0x71, 0x12, 0x27, 0xa2, 0x46, 0x52, 0xe9, 0xa5, 0x3d, 0xda, 0x16, 0x3b,
0x7b, 0x2d, 0x14, 0x5f, 0x2b, 0xdc, 0xed, 0x84, 0x86, 0x24, 0x58, 0x20, 0x88, 0x38, 0xb2, 0x88,
0x86, 0x13, 0x59, 0x3f, 0xca, 0x73, 0x27, 0x07, 0x5f, 0x8a, 0x3a, 0x5a, 0x4e, 0xbd, 0xda, 0x6a,
0xea, 0xf5, 0xc0, 0x92, 0xe1, 0x0e, 0x30, 0xd5, 0xfc, 0x50, 0xc8, 0x64, 0x04, 0xd6, 0x0c, 0x39,
0xd5, 0xe5, 0x29, 0xaa, 0xe8, 0x61, 0x5e, 0x66, 0xc3, 0x37, 0x5a, 0xa1, 0x6a, 0xa8, 0xb0, 0x5b,
0x29, 0xa2, 0xc6, 0x6a, 0x11, 0xf5, 0xc0, 0x2a, 0xe2, 0xd5, 0x54, 0x49, 0x91, 0xcb, 0x82, 0x99,
0x13, 0x64, 0x41, 0xec, 0xdb, 0x96, 0xcc, 0x2d, 0x2d, 0x09, 0x5e, 0x8d, 0xb2, 0x99, 0xca, 0xba,
0x96, 0xe2, 0xd5, 0x28, 0x9b, 0xad, 0x26, 0x19, 0x2c, 0x25, 0xd9, 0x01, 0xd4, 0xa9, 0xb8, 0x49,
0x59, 0x75, 0xed, 0x51, 0x4b, 0xee, 0x5f, 0x00, 0xae, 0xc2, 0xc9, 0x10, 0xba, 0x53, 0x16, 0x67,
0xc9, 0x44, 0x8a, 0x98, 0xda, 0x1d, 0x79, 0x50, 0xc3, 0xb0, 0x23, 0xf5, 0xc7, 0x4a, 0xdd, 0xfb,
0x19, 0x74, 0x4b, 0x47, 0x5f, 0x93, 0x63, 0x7b, 0x66, 0x8e, 0xb5, 0xcc, 0xbc, 0xfa, 0x73, 0x05,
0x3a, 0xe6, 0x9d, 0x8a, 0xc9, 0xe3, 0xf1, 0x6b, 0x39, 0xb9, 0xe6, 0x8a, 0xa1, 0x20, 0x50, 0x86,
0x11, 0xde, 0xd1, 0xcb, 0x50, 0x2d, 0x60, 0xb9, 0x0b, 0x40, 0x68, 0x83, 0xc8, 0x63, 0x38, 0xc3,
0x88, 0xeb, 0xfe, 0xb2, 0x00, 0xc8, 0x27, 0x00, 0x41, 0x9a, 0x66, 0x38, 0x11, 0x2d, 0x50, 0x92,
0x6c, 0x7b, 0xd4, 0x1b, 0xaa, 0xfe, 0x38, 0xcc, 0xfb, 0xe3, 0x70, 0x9c, 0xf7, 0x47, 0xb7, 0x25,
0xad, 0x85, 0xec, 0xfc, 0x11, 0x1a, 0x8a, 0x5f, 0xff, 0xa7, 0xf9, 0xb8, 0x0f, 0x96, 0x5a, 0x3b,
0xf0, 0x75, 0x2e, 0x36, 0xa5, 0x7c, 0xe6, 0x3b, 0x7f, 0xab, 0x80, 0xe5, 0x62, 0x9a, 0xc4, 0x51,
0x8a, 0x06, 0xff, 0x57, 0xde, 0xc9, 0xff, 0xd5, 0xb5, 0xfc, 0x9f, 0x77, 0x95, 0x9a, 0xd1, 0x55,
0x7a, 0x60, 0x31, 0xf4, 0x03, 0x86, 0x1e, 0xd7, 0x1d, 0xa8, 0x90, 0x85, 0xee, 0x8e, 0x32, 0x41,
0x5c, 0xa9, 0x4c, 0xf5, 0x96, 0x5b, 0xc8, 0xe4, 0xb9, 0x49, 0x9b, 0xaa, 0x21, 0xed, 0x29, 0xda,
0x54, 0xdb, 0x5d, 0xe5, 0x4d, 0xe7, 0xaf, 0x55, 0xd8, 0x5e, 0x56, 0xaf, 0xb9, 0xec, 0x3d, 0xa8,
0xab, 0x2a, 0xd1, 0x99, 0xc2, 0x57, 0xea, 0xa3, 0xb6, 0x54, 0x1f, 0x3f, 0x87, 0xae, 0xc7, 0x50,
0x76, 0xd3, 0xf7, 0xbd, 0xe5, 0x4e, 0x3e, 0x41, 0x40, 0xe4, 0x23, 0xd8, 0x16, 0xbb, 0x4c, 0xd0,
0x5f, 0x90, 0x96, 0x6a, 0xbd, 0x5b, 0x1a, 0x2f, 0x68, 0xeb, 0x29, 0xec, 0xe4, 0xa6, 0x8b, 0x02,
0x6b, 0x94, 0x6c, 0x4f, 0xf3, 0x3a, 0x7b, 0x08, 0x8d, 0xab, 0x98, 0xcd, 0x28, 0xd7, 0x15, 0xad,
0x25, 0x91, 0x16, 0xc5, 0x7e, 0x65, 0xeb, 0xb7, 0x54, 0x5a, 0xe4, 0xa0, 0x78, 0x10, 0x89, 0x0a,
0x2e, 0x1e, 0x2b, 0xb2, 0xba, 0x2d, 0xd7, 0xca, 0x1f, 0x29, 0xce, 0x6f, 0x60, 0x6b, 0xa9, 0x3f,
0xad, 0x09, 0xe4, 0xc2, 0x7d, 0xb5, 0xe4, 0xbe, 0xb4, 0x72, 0x6d, 0x69, 0xe5, 0xdf, 0xc2, 0xce,
0x17, 0x34, 0xf2, 0x43, 0xd4, 0xeb, 0x1f, 0xb3, 0xa9, 0x64, 0x7c, 0xfd, 0x5c, 0x9a, 0xe8, 0x87,
0x50, 0xd7, 0x6d, 0x69, 0xe4, 0xcc, 0x27, 0x4f, 0xa0, 0xc9, 0x94, 0xb5, 0x4e, 0xbc, 0xb6, 0xd1,
0x40, 0xdd, 0x5c, 0xe7, 0x7c, 0x0b, 0xa4, 0xb4, 0xb4, 0x78, 0x29, 0xcd, 0xc9, 0x40, 0x24, 0xa0,
0x4a, 0x0a, 0x9d, 0xd8, 0x1d, 0x33, 0x8f, 0xdc, 0x42, 0x4b, 0xfa, 0x50, 0x43, 0xc6, 0xb4, 0x8b,
0x4d, 0x61, 0xb4, 0x78, 0x97, 0xba, 0x42, 0xe5, 0xfc, 0x10, 0x76, 0x2e, 0x12, 0xf4, 0x02, 0x1a,
0xca, 0x37, 0xa5, 0x72, 0x70, 0x00, 0x75, 0x11, 0xe4, 0xbc, 0x66, 0x25, 0x89, 0x29, 0xb5, 0xc2,
0x9d, 0x6f, 0xc1, 0x56, 0xfb, 0x3a, 0x7d, 0x1b, 0xa4, 0x1c, 0x23, 0x0f, 0x4f, 0xae, 0xd1, 0xbb,
0xf9, 0x2f, 0x9e, 0xfc, 0x16, 0xf6, 0xd7, 0x79, 0xc8, 0xf7, 0xd7, 0xf6, 0x84, 0x34, 0xb9, 0x8a,
0xb3, 0x48, 0xf9, 0xb0, 0x5c, 0x90, 0xd0, 0xe7, 0x02, 0x11, 0xf7, 0x88, 0x62, 0x5e, 0xaa, 0xa9,
0x4f, 0x4b, 0x79, 0x3c, 0x6a, 0xf7, 0xc7, 0xe3, 0xbb, 0x0a, 0xb4, 0x2e, 0x90, 0x67, 0x89, 0x3c,
0xcb, 0x23, 0x68, 0x5d, 0xb2, 0xf8, 0x06, 0xd9, 0xe2, 0x28, 0x96, 0x02, 0xce, 0x7c, 0xf2, 0x1c,
0x1a, 0x27, 0x71, 0x74, 0x15, 0x4c, 0xe5, 0x0b, 0xbb, 0x3d, 0xda, 0x57, 0xec, 0xa2, 0xe7, 0x0e,
0x95, 0x4e, 0xf5, 0x35, 0x6d, 0xd8, 0xfb, 0x04, 0xda, 0x06, 0xfc, 0x1f, 0x71, 0xfe, 0xff, 0x03,
0xc8, 0xb5, 0x55, 0x04, 0xb6, 0xd5, 0x41, 0xf4, 0x4c, 0xb1, 0xf1, 0x03, 0x68, 0x89, 0xb7, 0x84,
0x52, 0x13, 0xd8, 0x30, 0x3e, 0x37, 0xe4, 0xd8, 0x79, 0x02, 0x3b, 0x67, 0xd1, 0x2d, 0x0d, 0x03,
0x9f, 0x72, 0xfc, 0x12, 0xe7, 0xf2, 0x80, 0x2b, 0x3b, 0x70, 0x2e, 0xa0, 0xa3, 0x1f, 0xf4, 0xef,
0xb5, 0xc7, 0x8e, 0xde, 0xe3, 0xbf, 0x2f, 0x91, 0x8f, 0x60, 0x4b, 0x2f, 0xfa, 0x3a, 0xd0, 0x05,
0x22, 0x3a, 0x34, 0xc3, 0xab, 0xe0, 0xad, 0x5e, 0x5a, 0x4b, 0xce, 0x0b, 0xd8, 0x36, 0x4c, 0x8b,
0xe3, 0xdc, 0xe0, 0x3c, 0xcd, 0x3f, 0x74, 0xc4, 0x38, 0x8f, 0x40, 0x75, 0x11, 0x01, 0x07, 0x36,
0xf5, 0xcc, 0x57, 0xc8, 0xef, 0x39, 0xdd, 0x97, 0xc5, 0x46, 0x5e, 0xa1, 0x5e, 0xfc, 0x10, 0xea,
0x28, 0x4e, 0x6a, 0x36, 0x28, 0x33, 0x02, 0xae, 0x52, 0xaf, 0x71, 0xf8, 0xa2, 0x70, 0x78, 0x9e,
0x29, 0x87, 0xef, 0xb9, 0x96, 0xf3, 0x61, 0xb1, 0x8d, 0xf3, 0x8c, 0xdf, 0x77, 0xa3, 0x4f, 0x60,
0x47, 0x1b, 0xbd, 0xc4, 0x10, 0x39, 0xde, 0x73, 0xa4, 0x43, 0x20, 0x25, 0xb3, 0xfb, 0x96, 0x7b,
0x0c, 0xd6, 0x78, 0xfc, 0xba, 0xd0, 0x96, 0x99, 0xcf, 0xf9, 0x14, 0x76, 0x2e, 0x32, 0x3f, 0x3e,
0x67, 0xc1, 0x6d, 0x10, 0xe2, 0x54, 0x39, 0xcb, 0xbf, 0xb3, 0x2a, 0xc6, 0x77, 0xd6, 0xda, 0x5e,
0xe3, 0x0c, 0x80, 0x94, 0xa6, 0x17, 0xf7, 0x96, 0x66, 0x7e, 0xac, 0x0b, 0x54, 0x8e, 0x9d, 0x01,
0x74, 0xc6, 0x54, 0x74, 0x73, 0x5f, 0xd9, 0xd8, 0xd0, 0xe4, 0x4a, 0xd6, 0x66, 0xb9, 0xe8, 0x8c,
0x60, 0xef, 0x84, 0x7a, 0xd7, 0x41, 0x34, 0x7d, 0x19, 0xa4, 0xe2, 0xd9, 0xa2, 0x67, 0xf4, 0xc0,
0xf2, 0x35, 0xa0, 0xa7, 0x14, 0xb2, 0xf3, 0x31, 0x3c, 0x30, 0xbe, 0x26, 0x2f, 0x38, 0xcd, 0xe3,
0xb1, 0x07, 0xf5, 0x54, 0x48, 0x72, 0x46, 0xdd, 0x55, 0x82, 0xf3, 0x15, 0xec, 0x99, 0xed, 0x55,
0x3c, 0x2e, 0xf2, 0x83, 0xcb, 0xb6, 0x5f, 0x31, 0xda, 0xbe, 0x8e, 0x59, 0x75, 0xd1, 0x2d, 0xb6,
0xa1, 0xf6, 0xcb, 0x6f, 0xc6, 0x3a, 0xd9, 0xc5, 0xd0, 0xf9, 0xbd, 0x70, 0x5f, 0x5e, 0x4f, 0xb9,
0x2f, 0xf5, 0xfe, 0xca, 0xfb, 0xf4, 0xfe, 0x35, 0xf9, 0xf6, 0x31, 0xec, 0xbc, 0x09, 0x63, 0xef,
0xe6, 0x34, 0x32, 0xa2, 0x61, 0x43, 0x13, 0x23, 0x33, 0x18, 0xb9, 0x38, 0xfa, 0x47, 0x15, 0x9a,
0xbf, 0x50, 0xff, 0x39, 0xc8, 0x67, 0xd0, 0x2d, 0x35, 0x12, 0xf2, 0x40, 0x7e, 0xb1, 0x2c, 0xb7,
0xad, 0xde, 0xc3, 0x15, 0x58, 0x79, 0x79, 0x06, 0x1d, 0xb3, 0x4d, 0x10, 0xd9, 0x12, 0xe4, 0xef,
0x90, 0x9e, 0x5c, 0x69, 0xb5, 0x87, 0x5c, 0xc0, 0xde, 0x3a, 0x02, 0x27, 0x8f, 0x17, 0x1e, 0x56,
0x9b, 0x47, 0xef, 0x83, 0xfb, 0xb4, 0x39, 0xf1, 0x37, 0x4f, 0x42, 0xa4, 0x51, 0x96, 0x98, 0x3b,
0x58, 0x0c, 0xc9, 0x73, 0xe8, 0x96, 0x48, 0x4e, 0x9d, 0x73, 0x85, 0xf7, 0xcc, 0x29, 0x87, 0x50,
0x97, 0xc4, 0x4a, 0xba, 0x25, 0xfe, 0xee, 0x6d, 0x16, 0xa2, 0xf2, 0xdd, 0x87, 0x0d, 0xf9, 0xb1,
0x66, 0x38, 0x96, 0x33, 0x0a, 0xd6, 0x1d, 0xfd, 0xbd, 0x02, 0xcd, 0xfc, 0xc7, 0xc9, 0x73, 0xd8,
0x10, 0xfc, 0x45, 0x76, 0x0d, 0x0a, 0xc8, 0xb9, 0xaf, 0xb7, 0xb7, 0x04, 0x2a, 0x07, 0x43, 0xa8,
0xbd, 0x42, 0x4e, 0x88, 0xa1, 0xd4, 0x44, 0xd6, 0xdb, 0x2d, 0x63, 0x85, 0xfd, 0x79, 0x56, 0xb6,
0xd7, 0x3c, 0x54, 0xb2, 0x2f, 0x18, 0xe6, 0x27, 0xd0, 0x50, 0x0c, 0xa1, 0x82, 0xb2, 0xc2, 0x2d,
0xea, 0xf2, 0x57, 0xb9, 0x64, 0xf4, 0x97, 0x1a, 0xc0, 0xc5, 0x3c, 0xe5, 0x38, 0xfb, 0x75, 0x80,
0x77, 0xe4, 0x29, 0x6c, 0xbd, 0xc4, 0x2b, 0x9a, 0x85, 0x5c, 0xbe, 0xe3, 0x45, 0x25, 0x18, 0x31,
0x91, 0x4f, 0x91, 0x82, 0x68, 0x0e, 0xa1, 0xfd, 0x86, 0xbe, 0x7d, 0xb7, 0xdd, 0x67, 0xd0, 0x2d,
0xf1, 0x87, 0xde, 0xe2, 0x32, 0x23, 0xe9, 0x2d, 0xae, 0x32, 0xcd, 0x21, 0x34, 0x35, 0xab, 0x98,
0x3e, 0x24, 0xff, 0x96, 0xd8, 0xe6, 0xc7, 0xb0, 0xb5, 0xc4, 0x29, 0xa6, 0xbd, 0xfc, 0xb9, 0xb3,
0x96, 0x73, 0x5e, 0x88, 0x77, 0x78, 0x99, 0x57, 0xcc, 0x89, 0xfb, 0xaa, 0x96, 0xd7, 0x11, 0xcf,
0xab, 0xf2, 0x0b, 0x5e, 0x7e, 0xbf, 0xd8, 0xcb, 0xa5, 0x9f, 0x13, 0x4f, 0xbe, 0xd0, 0x3a, 0x0a,
0x79, 0x06, 0x1d, 0xb3, 0xfa, 0x57, 0x4a, 0x70, 0x85, 0x1a, 0x2e, 0x1b, 0xf2, 0x15, 0xff, 0x83,
0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x0c, 0x80, 0xb2, 0xf5, 0x00, 0x15, 0x00, 0x00,
// 2042 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x5f, 0x73, 0xdb, 0xc6,
0x11, 0x1f, 0x92, 0x22, 0x09, 0x2e, 0x49, 0xfd, 0x39, 0xcb, 0x2e, 0x44, 0x3b, 0x15, 0x8b, 0x8c,
0x15, 0xc6, 0xd3, 0x50, 0x36, 0xfb, 0xcf, 0x69, 0x27, 0xe9, 0xa8, 0xb2, 0xe2, 0xa8, 0x91, 0x12,
0x0d, 0xa4, 0x36, 0xed, 0xb4, 0x33, 0xcc, 0x09, 0x58, 0x51, 0x18, 0x81, 0x00, 0x7a, 0x38, 0x48,
0xe6, 0x53, 0x3f, 0x42, 0xdf, 0xd2, 0xaf, 0xd4, 0x99, 0x3e, 0xf7, 0x13, 0xf4, 0xbd, 0x0f, 0xfd,
0x04, 0x9d, 0xfb, 0x03, 0xf0, 0x40, 0x52, 0xb5, 0x3b, 0xd3, 0xbc, 0xdd, 0xfe, 0x76, 0xef, 0xf6,
0x6e, 0xb1, 0xfb, 0xdb, 0x3b, 0xc0, 0x6e, 0x18, 0x4f, 0x02, 0x8f, 0x86, 0xfb, 0x49, 0x98, 0x4d,
0x82, 0x68, 0x3f, 0xb9, 0xdc, 0xbf, 0xa4, 0xde, 0x0d, 0x46, 0xfe, 0x30, 0x61, 0x31, 0x8f, 0x49,
0x35, 0xb9, 0xec, 0xed, 0x4e, 0xe2, 0x78, 0x12, 0xe2, 0xbe, 0x44, 0x2e, 0xb3, 0xab, 0x7d, 0x1e,
0x4c, 0x31, 0xe5, 0x74, 0x9a, 0x28, 0x23, 0xa7, 0x09, 0xf5, 0xa3, 0x69, 0xc2, 0x67, 0x4e, 0x1f,
0x1a, 0x9f, 0x23, 0xf5, 0x91, 0x91, 0x47, 0xd0, 0xb8, 0x96, 0x23, 0xbb, 0xd2, 0xaf, 0x0d, 0x5a,
0xae, 0x96, 0x9c, 0x3f, 0x00, 0x9c, 0x89, 0x39, 0x47, 0x8c, 0xc5, 0x8c, 0xec, 0x80, 0x85, 0x8c,
0x8d, 0xf9, 0x2c, 0x41, 0xbb, 0xd2, 0xaf, 0x0c, 0xba, 0x6e, 0x13, 0x19, 0xbb, 0x98, 0x25, 0x48,
0xbe, 0x07, 0x62, 0x38, 0x9e, 0xa6, 0x13, 0xbb, 0xda, 0xaf, 0x88, 0x15, 0x90, 0xb1, 0xd3, 0x74,
0x92, 0xcf, 0xf1, 0x62, 0x1f, 0xed, 0x5a, 0xbf, 0x32, 0xa8, 0xc9, 0x39, 0x87, 0xb1, 0x8f, 0xce,
0xb7, 0x15, 0xa8, 0x9f, 0x51, 0x7e, 0x9d, 0x12, 0x02, 0x6b, 0x2c, 0x8e, 0xb9, 0x76, 0x2e, 0xc7,
0x64, 0x00, 0x1b, 0x59, 0x44, 0x33, 0x7e, 0x8d, 0x11, 0x0f, 0x3c, 0xca, 0xd1, 0xb7, 0xab, 0x52,
0xbd, 0x08, 0x93, 0xf7, 0xa1, 0x1b, 0xc6, 0x1e, 0x0d, 0xc7, 0x29, 0x8f, 0x19, 0x9d, 0x08, 0x3f,
0xc2, 0xae, 0x23, 0xc1, 0x73, 0x85, 0x91, 0x67, 0xb0, 0x95, 0x22, 0x0d, 0xc7, 0x77, 0x8c, 0x26,
0x85, 0xe1, 0x9a, 0x5a, 0x50, 0x28, 0xbe, 0x66, 0x34, 0xd1, 0xb6, 0xce, 0x5f, 0x1a, 0xd0, 0x74,
0xf1, 0x4f, 0x19, 0xa6, 0x9c, 0xac, 0x43, 0x35, 0xf0, 0xe5, 0x69, 0x5b, 0x6e, 0x35, 0xf0, 0xc9,
0x10, 0x88, 0x8b, 0x49, 0x28, 0x5c, 0x07, 0x71, 0x74, 0x18, 0x66, 0x29, 0x47, 0xa6, 0xcf, 0xbc,
0x42, 0x43, 0x9e, 0x40, 0x2b, 0x4e, 0x90, 0x49, 0x4c, 0x06, 0xa0, 0xe5, 0xce, 0x01, 0x71, 0xf0,
0x84, 0xf2, 0x6b, 0x7b, 0x4d, 0x2a, 0xe4, 0x58, 0x60, 0x3e, 0xe5, 0xd4, 0xae, 0x2b, 0x4c, 0x8c,
0x89, 0x03, 0x8d, 0x14, 0x3d, 0x86, 0xdc, 0x6e, 0xf4, 0x2b, 0x83, 0xf6, 0x08, 0x86, 0xc9, 0xe5,
0xf0, 0x5c, 0x22, 0xae, 0xd6, 0x90, 0x27, 0xb0, 0x26, 0xe2, 0x62, 0x37, 0xa5, 0x85, 0x25, 0x2c,
0x0e, 0x32, 0x7e, 0xed, 0x4a, 0x94, 0x8c, 0xa0, 0xa9, 0xbe, 0x69, 0x6a, 0x5b, 0xfd, 0xda, 0xa0,
0x3d, 0xb2, 0x85, 0x81, 0x3e, 0xe5, 0x50, 0xa5, 0x41, 0x7a, 0x14, 0x71, 0x36, 0x73, 0x73, 0x43,
0xf2, 0x03, 0xe8, 0x78, 0x61, 0x80, 0x11, 0x1f, 0xf3, 0xf8, 0x06, 0x23, 0xbb, 0x25, 0x77, 0xd4,
0x56, 0xd8, 0x85, 0x80, 0xc8, 0x08, 0x1e, 0x9a, 0x26, 0x63, 0xea, 0x79, 0x98, 0xa6, 0x31, 0xb3,
0x41, 0xda, 0x3e, 0x30, 0x6c, 0x0f, 0xb4, 0x4a, 0x2c, 0xeb, 0x07, 0x69, 0x12, 0xd2, 0xd9, 0x38,
0xa2, 0x53, 0xb4, 0xdb, 0x6a, 0x59, 0x8d, 0x7d, 0x49, 0xa7, 0x48, 0x76, 0xa1, 0x3d, 0x8d, 0xb3,
0x88, 0x8f, 0x93, 0x38, 0x88, 0xb8, 0xdd, 0x91, 0x16, 0x20, 0xa1, 0x33, 0x81, 0x90, 0xf7, 0x40,
0x49, 0x2a, 0x19, 0xbb, 0x2a, 0xae, 0x12, 0x91, 0xe9, 0xf8, 0x14, 0xd6, 0x95, 0xba, 0xd8, 0xcf,
0xba, 0x34, 0xe9, 0x4a, 0xb4, 0xd8, 0xc9, 0x73, 0x68, 0xc9, 0x7c, 0x08, 0xa2, 0xab, 0xd8, 0xde,
0x90, 0x71, 0x7b, 0x60, 0x84, 0x45, 0xe4, 0xc4, 0x71, 0x74, 0x15, 0xbb, 0xd6, 0x9d, 0x1e, 0x91,
0x4f, 0xe0, 0x71, 0xe9, 0xbc, 0x0c, 0xa7, 0x34, 0x88, 0x82, 0x68, 0x32, 0xce, 0x52, 0x4c, 0xed,
0x4d, 0x99, 0xe1, 0xb6, 0x71, 0x6a, 0x37, 0x37, 0xf8, 0x4d, 0x8a, 0x29, 0x79, 0x0c, 0x2d, 0x91,
0xb7, 0x7c, 0x36, 0x0e, 0x7c, 0x7b, 0x4b, 0x6e, 0xc9, 0x52, 0xc0, 0xb1, 0x4f, 0x3e, 0x80, 0x8d,
0x24, 0x0e, 0x03, 0x6f, 0x36, 0x8e, 0x6f, 0x91, 0xb1, 0xc0, 0x47, 0x9b, 0xf4, 0x2b, 0x03, 0xcb,
0x5d, 0x57, 0xf0, 0x57, 0x1a, 0x5d, 0x55, 0x1a, 0x0f, 0xa4, 0xe1, 0x22, 0xdc, 0xfb, 0x0c, 0x3a,
0xe6, 0xa7, 0x25, 0x9b, 0x50, 0xbb, 0xc1, 0x99, 0x4e, 0x67, 0x31, 0x24, 0x7d, 0xa8, 0xdf, 0xd2,
0x30, 0x43, 0x99, 0xc2, 0x3a, 0xb1, 0xd4, 0x14, 0x57, 0x29, 0x7e, 0x5e, 0x7d, 0x59, 0x71, 0x28,
0xd4, 0x0f, 0xc2, 0x80, 0xa6, 0x0b, 0x71, 0xaf, 0xbc, 0x3d, 0xee, 0xd5, 0x55, 0x71, 0x27, 0xb0,
0x26, 0xbf, 0xbc, 0xaa, 0x07, 0x39, 0x76, 0xfe, 0x5d, 0x83, 0x35, 0x91, 0xaf, 0xe4, 0x27, 0xd0,
0x0d, 0x91, 0xa6, 0x38, 0x8e, 0x13, 0x51, 0x23, 0xa9, 0xf4, 0xd2, 0x1e, 0x6d, 0x8a, 0x9d, 0x9d,
0x08, 0xc5, 0x57, 0x0a, 0x77, 0x3b, 0xa1, 0x21, 0x09, 0x16, 0x08, 0x22, 0x8e, 0x2c, 0xa2, 0xe1,
0x58, 0xd6, 0x8f, 0xf2, 0xdc, 0xc9, 0xc1, 0x57, 0xa2, 0x8e, 0x16, 0x53, 0xaf, 0xb6, 0x9c, 0x7a,
0x3d, 0xb0, 0x64, 0xb8, 0x03, 0x4c, 0x35, 0x3f, 0x14, 0x32, 0x19, 0x81, 0x35, 0x45, 0x4e, 0x75,
0x79, 0x8a, 0x2a, 0x7a, 0x94, 0x97, 0xd9, 0xf0, 0x54, 0x2b, 0x54, 0x0d, 0x15, 0x76, 0x4b, 0x45,
0xd4, 0x58, 0x2e, 0xa2, 0x1e, 0x58, 0x45, 0xbc, 0x9a, 0x2a, 0x29, 0x72, 0x59, 0x30, 0x73, 0x82,
0x2c, 0x88, 0x7d, 0xdb, 0x92, 0xb9, 0xa5, 0x25, 0xc1, 0xab, 0x51, 0x36, 0x55, 0x59, 0xd7, 0x52,
0xbc, 0x1a, 0x65, 0xd3, 0xe5, 0x24, 0x83, 0x85, 0x24, 0xdb, 0x85, 0x3a, 0x15, 0x5f, 0x52, 0x56,
0x5d, 0x7b, 0xd4, 0x92, 0xfb, 0x17, 0x80, 0xab, 0x70, 0x32, 0x84, 0xee, 0x84, 0xc5, 0x59, 0x32,
0x96, 0x22, 0xa6, 0x76, 0x47, 0x1e, 0xd4, 0x30, 0xec, 0x48, 0xfd, 0x81, 0x52, 0xf7, 0x7e, 0x01,
0xdd, 0xd2, 0xd1, 0x57, 0xe4, 0xd8, 0xb6, 0x99, 0x63, 0x2d, 0x33, 0xaf, 0xfe, 0x5a, 0x81, 0x8e,
0xf9, 0x4d, 0xc5, 0xe4, 0x8b, 0x8b, 0x13, 0x39, 0xb9, 0xe6, 0x8a, 0xa1, 0x20, 0x50, 0x86, 0x11,
0xde, 0xd1, 0xcb, 0x50, 0x2d, 0x60, 0xb9, 0x73, 0x40, 0x68, 0x83, 0xc8, 0x63, 0x38, 0xc5, 0x88,
0xeb, 0xfe, 0x32, 0x07, 0xc8, 0xc7, 0x00, 0x41, 0x9a, 0x66, 0x38, 0x16, 0x2d, 0x50, 0x92, 0x6c,
0x7b, 0xd4, 0x1b, 0xaa, 0xfe, 0x38, 0xcc, 0xfb, 0xe3, 0xf0, 0x22, 0xef, 0x8f, 0x6e, 0x4b, 0x5a,
0x0b, 0xd9, 0xf9, 0x33, 0x34, 0x14, 0xbf, 0x7e, 0xa7, 0xf9, 0xb8, 0x03, 0x96, 0x5a, 0x3b, 0xf0,
0x75, 0x2e, 0x36, 0xa5, 0x7c, 0xec, 0x3b, 0x7f, 0xaf, 0x80, 0xe5, 0x62, 0x9a, 0xc4, 0x51, 0x8a,
0x06, 0xff, 0x57, 0xde, 0xca, 0xff, 0xd5, 0x95, 0xfc, 0x9f, 0x77, 0x95, 0x9a, 0xd1, 0x55, 0x7a,
0x60, 0x31, 0xf4, 0x03, 0x86, 0x1e, 0xd7, 0x1d, 0xa8, 0x90, 0x85, 0xee, 0x8e, 0x32, 0x41, 0x5c,
0xa9, 0x4c, 0xf5, 0x96, 0x5b, 0xc8, 0xe4, 0x85, 0x49, 0x9b, 0xaa, 0x21, 0x6d, 0x2b, 0xda, 0x54,
0xdb, 0x5d, 0xe6, 0x4d, 0xe7, 0x6f, 0x55, 0xd8, 0x5c, 0x54, 0xaf, 0xf8, 0xd8, 0xdb, 0x50, 0x57,
0x55, 0xa2, 0x33, 0x85, 0x2f, 0xd5, 0x47, 0x6d, 0xa1, 0x3e, 0x7e, 0x09, 0x5d, 0x8f, 0xa1, 0xec,
0xa6, 0xef, 0xfa, 0x95, 0x3b, 0xf9, 0x04, 0x01, 0x91, 0x0f, 0x61, 0x53, 0xec, 0x32, 0x41, 0x7f,
0x4e, 0x5a, 0xaa, 0xf5, 0x6e, 0x68, 0xbc, 0xa0, 0xad, 0x67, 0xb0, 0x95, 0x9b, 0xce, 0x0b, 0xac,
0x51, 0xb2, 0x3d, 0xca, 0xeb, 0xec, 0x11, 0x34, 0xae, 0x62, 0x36, 0xa5, 0x5c, 0x57, 0xb4, 0x96,
0x44, 0x5a, 0x14, 0xfb, 0x95, 0xad, 0xdf, 0x52, 0x69, 0x91, 0x83, 0xe2, 0x42, 0x24, 0x2a, 0xb8,
0xb8, 0xac, 0xc8, 0xea, 0xb6, 0x5c, 0x2b, 0xbf, 0xa4, 0x38, 0xbf, 0x83, 0x8d, 0x85, 0xfe, 0xb4,
0x22, 0x90, 0x73, 0xf7, 0xd5, 0x92, 0xfb, 0xd2, 0xca, 0xb5, 0x85, 0x95, 0x7f, 0x0f, 0x5b, 0x9f,
0xd3, 0xc8, 0x0f, 0x51, 0xaf, 0x7f, 0xc0, 0x26, 0x92, 0xf1, 0xf5, 0x75, 0x69, 0xac, 0x2f, 0x42,
0x5d, 0xb7, 0xa5, 0x91, 0x63, 0x9f, 0x3c, 0x85, 0x26, 0x53, 0xd6, 0x3a, 0xf1, 0xda, 0x46, 0x03,
0x75, 0x73, 0x9d, 0xf3, 0x0d, 0x90, 0xd2, 0xd2, 0xe2, 0xa6, 0x34, 0x23, 0x03, 0x91, 0x80, 0x2a,
0x29, 0x74, 0x62, 0x77, 0xcc, 0x3c, 0x72, 0x0b, 0x2d, 0xe9, 0x43, 0x0d, 0x19, 0xd3, 0x2e, 0xd6,
0x85, 0xd1, 0xfc, 0x5e, 0xea, 0x0a, 0x95, 0xf3, 0x63, 0xd8, 0x3a, 0x4f, 0xd0, 0x0b, 0x68, 0x28,
0xef, 0x94, 0xca, 0xc1, 0x2e, 0xd4, 0x45, 0x90, 0xf3, 0x9a, 0x95, 0x24, 0xa6, 0xd4, 0x0a, 0x77,
0xbe, 0x01, 0x5b, 0xed, 0xeb, 0xe8, 0x4d, 0x90, 0x72, 0x8c, 0x3c, 0x3c, 0xbc, 0x46, 0xef, 0xe6,
0xff, 0x78, 0xf2, 0x5b, 0xd8, 0x59, 0xe5, 0x21, 0xdf, 0x5f, 0xdb, 0x13, 0xd2, 0xf8, 0x2a, 0xce,
0x22, 0xe5, 0xc3, 0x72, 0x41, 0x42, 0x9f, 0x09, 0x44, 0x7c, 0x47, 0x14, 0xf3, 0x52, 0x4d, 0x7d,
0x5a, 0xca, 0xe3, 0x51, 0xbb, 0x3f, 0x1e, 0xdf, 0x56, 0xa0, 0x75, 0x8e, 0x3c, 0x4b, 0xe4, 0x59,
0x1e, 0x43, 0xeb, 0x92, 0xc5, 0x37, 0xc8, 0xe6, 0x47, 0xb1, 0x14, 0x70, 0xec, 0x93, 0x17, 0xd0,
0x38, 0x8c, 0xa3, 0xab, 0x60, 0x22, 0x6f, 0xd8, 0xed, 0xd1, 0x8e, 0x62, 0x17, 0x3d, 0x77, 0xa8,
0x74, 0xaa, 0xaf, 0x69, 0xc3, 0xde, 0xc7, 0xd0, 0x36, 0xe0, 0xff, 0x89, 0xf3, 0xbf, 0x0f, 0x20,
0xd7, 0x56, 0x11, 0xd8, 0x54, 0x07, 0xd1, 0x33, 0xc5, 0xc6, 0x77, 0xa1, 0x25, 0xee, 0x12, 0x4a,
0x4d, 0x60, 0xcd, 0x78, 0x6e, 0xc8, 0xb1, 0xf3, 0x14, 0xb6, 0x8e, 0xa3, 0x5b, 0x1a, 0x06, 0x3e,
0xe5, 0xf8, 0x05, 0xce, 0xe4, 0x01, 0x97, 0x76, 0xe0, 0x9c, 0x43, 0x47, 0x5f, 0xe8, 0xdf, 0x69,
0x8f, 0x1d, 0xbd, 0xc7, 0xff, 0x5e, 0x22, 0x1f, 0xc2, 0x86, 0x5e, 0xf4, 0x24, 0xd0, 0x05, 0x22,
0x3a, 0x34, 0xc3, 0xab, 0xe0, 0x8d, 0x5e, 0x5a, 0x4b, 0xce, 0x4b, 0xd8, 0x34, 0x4c, 0x8b, 0xe3,
0xdc, 0xe0, 0x2c, 0xcd, 0x1f, 0x3a, 0x62, 0x9c, 0x47, 0xa0, 0x3a, 0x8f, 0x80, 0x03, 0xeb, 0x7a,
0xe6, 0x6b, 0xe4, 0xf7, 0x9c, 0xee, 0x8b, 0x62, 0x23, 0xaf, 0x51, 0x2f, 0xbe, 0x07, 0x75, 0x14,
0x27, 0x35, 0x1b, 0x94, 0x19, 0x01, 0x57, 0xa9, 0x57, 0x38, 0x7c, 0x59, 0x38, 0x3c, 0xcb, 0x94,
0xc3, 0x77, 0x5c, 0xcb, 0x79, 0xbf, 0xd8, 0xc6, 0x59, 0xc6, 0xef, 0xfb, 0xa2, 0x4f, 0x61, 0x4b,
0x1b, 0xbd, 0xc2, 0x10, 0x39, 0xde, 0x73, 0xa4, 0x3d, 0x20, 0x25, 0xb3, 0xfb, 0x96, 0x7b, 0x02,
0xd6, 0xc5, 0xc5, 0x49, 0xa1, 0x2d, 0x33, 0x9f, 0xf3, 0x09, 0x6c, 0x9d, 0x67, 0x7e, 0x7c, 0xc6,
0x82, 0xdb, 0x20, 0xc4, 0x89, 0x72, 0x96, 0xbf, 0xb3, 0x2a, 0xc6, 0x3b, 0x6b, 0x65, 0xaf, 0x71,
0x06, 0x40, 0x4a, 0xd3, 0x8b, 0xef, 0x96, 0x66, 0x7e, 0xac, 0x0b, 0x54, 0x8e, 0x9d, 0x01, 0x74,
0x2e, 0xa8, 0xe8, 0xe6, 0xbe, 0xb2, 0xb1, 0xa1, 0xc9, 0x95, 0xac, 0xcd, 0x72, 0xd1, 0x19, 0xc1,
0xf6, 0x21, 0xf5, 0xae, 0x83, 0x68, 0xf2, 0x2a, 0x48, 0xc5, 0xb5, 0x45, 0xcf, 0xe8, 0x81, 0xe5,
0x6b, 0x40, 0x4f, 0x29, 0x64, 0xe7, 0x23, 0x78, 0x68, 0xbc, 0x26, 0xcf, 0x39, 0xcd, 0xe3, 0xb1,
0x0d, 0xf5, 0x54, 0x48, 0x72, 0x46, 0xdd, 0x55, 0x82, 0xf3, 0x25, 0x6c, 0x9b, 0xed, 0x55, 0x5c,
0x2e, 0xf2, 0x83, 0xcb, 0xb6, 0x5f, 0x31, 0xda, 0xbe, 0x8e, 0x59, 0x75, 0xde, 0x2d, 0x36, 0xa1,
0xf6, 0xeb, 0xaf, 0x2f, 0x74, 0xb2, 0x8b, 0xa1, 0xf3, 0x47, 0xe1, 0xbe, 0xbc, 0x9e, 0x72, 0x5f,
0xea, 0xfd, 0x95, 0x77, 0xe9, 0xfd, 0x2b, 0xf2, 0xed, 0x23, 0xd8, 0x3a, 0x0d, 0x63, 0xef, 0xe6,
0x28, 0x32, 0xa2, 0x61, 0x43, 0x13, 0x23, 0x33, 0x18, 0xb9, 0xe8, 0x7c, 0x00, 0x1b, 0x27, 0xe2,
0x2d, 0x7f, 0x2a, 0x1e, 0x11, 0x45, 0x14, 0xe4, 0xf3, 0x5e, 0x9b, 0x2a, 0x61, 0xf4, 0xaf, 0x2a,
0x34, 0x7f, 0xa5, 0x7e, 0x88, 0x90, 0x4f, 0xa1, 0x5b, 0xea, 0x38, 0xe4, 0xa1, 0x7c, 0xda, 0x2c,
0xf6, 0xb7, 0xde, 0xa3, 0x25, 0x58, 0x79, 0x78, 0x0e, 0x1d, 0xb3, 0x9f, 0x10, 0xd9, 0x3b, 0xe4,
0x7f, 0x93, 0x9e, 0x5c, 0x69, 0xb9, 0xd9, 0x9c, 0xc3, 0xf6, 0x2a, 0xa6, 0x27, 0x4f, 0xe6, 0x1e,
0x96, 0xbb, 0x4c, 0xef, 0xbd, 0xfb, 0xb4, 0x79, 0x87, 0x68, 0x1e, 0x86, 0x48, 0xa3, 0x2c, 0x31,
0x77, 0x30, 0x1f, 0x92, 0x17, 0xd0, 0x2d, 0xb1, 0xa1, 0x3a, 0xe7, 0x12, 0x41, 0x9a, 0x53, 0xf6,
0xa0, 0x2e, 0x19, 0x98, 0x74, 0x4b, 0x44, 0xdf, 0x5b, 0x2f, 0x44, 0xe5, 0xbb, 0x0f, 0x6b, 0xf2,
0x55, 0x67, 0x38, 0x96, 0x33, 0x0a, 0x7a, 0x1e, 0xfd, 0xa3, 0x02, 0xcd, 0xfc, 0x0f, 0xcb, 0x0b,
0x58, 0x13, 0x44, 0x47, 0x1e, 0x18, 0x5c, 0x91, 0x93, 0x64, 0x6f, 0x7b, 0x01, 0x54, 0x0e, 0x86,
0x50, 0x7b, 0x8d, 0x9c, 0x10, 0x43, 0xa9, 0x19, 0xaf, 0xf7, 0xa0, 0x8c, 0x15, 0xf6, 0x67, 0x59,
0xd9, 0x5e, 0x13, 0x56, 0xc9, 0xbe, 0xa0, 0xa2, 0x9f, 0x41, 0x43, 0x51, 0x89, 0x0a, 0xca, 0x12,
0x09, 0xa9, 0x8f, 0xbf, 0x4c, 0x3a, 0xa3, 0x7f, 0xd6, 0x00, 0xce, 0x67, 0x29, 0xc7, 0xe9, 0x6f,
0x03, 0xbc, 0x23, 0xcf, 0x60, 0xe3, 0x15, 0x5e, 0xd1, 0x2c, 0xe4, 0xf2, 0xc2, 0x2f, 0x4a, 0xc6,
0x88, 0x89, 0xbc, 0xb3, 0x14, 0x8c, 0xb4, 0x07, 0xed, 0x53, 0xfa, 0xe6, 0xed, 0x76, 0x9f, 0x42,
0xb7, 0x44, 0x34, 0x7a, 0x8b, 0x8b, 0xd4, 0xa5, 0xb7, 0xb8, 0x4c, 0x49, 0x7b, 0xd0, 0xd4, 0xf4,
0x63, 0xfa, 0x90, 0x44, 0x5d, 0xa2, 0xa5, 0x9f, 0xc2, 0xc6, 0x02, 0xf9, 0x98, 0xf6, 0xf2, 0x2f,
0xd0, 0x4a, 0x72, 0x7a, 0x29, 0x2e, 0xec, 0x65, 0x02, 0x32, 0x27, 0xee, 0xa8, 0xa2, 0x5f, 0xc5,
0x50, 0xaf, 0xcb, 0x57, 0x7d, 0xf9, 0xd0, 0xb1, 0x17, 0x39, 0x22, 0x67, 0xa8, 0x7c, 0xa1, 0x55,
0x5c, 0xf3, 0x1c, 0x3a, 0x26, 0x4d, 0x2c, 0x95, 0xe0, 0x32, 0x87, 0xfc, 0x10, 0x60, 0xce, 0x14,
0xa6, 0xbd, 0x4c, 0x8f, 0x05, 0x12, 0xb9, 0x6c, 0xc8, 0xc7, 0xc1, 0x8f, 0xfe, 0x13, 0x00, 0x00,
0xff, 0xff, 0x54, 0xbe, 0x6c, 0x5a, 0x57, 0x15, 0x00, 0x00,
}

View file

@ -435,6 +435,10 @@ message MlockEnabledReply {
bool enabled = 1;
}
message LocalMountReply {
bool local = 1;
}
service SystemView {
rpc DefaultLeaseTTL(Empty) returns (TTLReply);
rpc MaxLeaseTTL(Empty) returns (TTLReply);
@ -444,6 +448,5 @@ service SystemView {
rpc ReplicationState(Empty) returns (ReplicationStateReply);
rpc ResponseWrapData(ResponseWrapDataArgs) returns (ResponseWrapDataReply);
rpc MlockEnabled(Empty) returns (MlockEnabledReply);
rpc LocalMount(Empty) returns (LocalMountReply);
}

View file

@ -31,7 +31,7 @@ func TestTranslation_Errors(t *testing.T) {
e := ProtoErrToErr(pe)
if !reflect.DeepEqual(e, err) {
t.Fatal("Errs did not match: %#v, %#v", e, err)
t.Fatalf("Errs did not match: %#v, %#v", e, err)
}
}
}
@ -49,7 +49,7 @@ func TestTranslation_StorageEntry(t *testing.T) {
e := ProtoStorageEntryToLogicalStorageEntry(p)
if !reflect.DeepEqual(c, e) {
t.Fatal("Entries did not match: %#v, %#v", e, c)
t.Fatalf("Entries did not match: %#v, %#v", e, c)
}
}
}

View file

@ -119,6 +119,16 @@ func (s *SystemViewClient) MlockEnabled() bool {
return reply.MlockEnabled
}
func (s *SystemViewClient) LocalMount() bool {
var reply LocalMountReply
err := s.client.Call("Plugin.LocalMount", new(interface{}), &reply)
if err != nil {
return false
}
return reply.Local
}
type SystemViewServer struct {
impl logical.SystemView
}
@ -202,6 +212,15 @@ func (s *SystemViewServer) MlockEnabled(_ interface{}, reply *MlockEnabledReply)
return nil
}
func (s *SystemViewServer) LocalMount(_ interface{}, reply *LocalMountReply) error {
local := s.impl.LocalMount()
*reply = LocalMountReply{
Local: local,
}
return nil
}
type DefaultLeaseTTLReply struct {
DefaultLeaseTTL time.Duration
}
@ -245,3 +264,7 @@ type ResponseWrapDataReply struct {
type MlockEnabledReply struct {
MlockEnabled bool
}
type LocalMountReply struct {
Local bool
}

View file

@ -39,6 +39,10 @@ type SystemView interface {
// despite known slowdowns.
CachingDisabled() bool
// When run from a system view attached to a request, indicates whether the
// request is affecting a local mount or not
LocalMount() bool
// ReplicationState indicates the state of cluster replication
ReplicationState() consts.ReplicationState
@ -63,6 +67,7 @@ type StaticSystemView struct {
CachingDisabledVal bool
Primary bool
EnableMlock bool
LocalMountVal bool
ReplicationStateVal consts.ReplicationState
}
@ -86,6 +91,10 @@ func (d StaticSystemView) CachingDisabled() bool {
return d.CachingDisabledVal
}
func (d StaticSystemView) LocalMount() bool {
return d.LocalMountVal
}
func (d StaticSystemView) ReplicationState() consts.ReplicationState {
return d.ReplicationStateVal
}

View file

@ -11,7 +11,7 @@ import (
type InmemHABackend struct {
physical.Backend
locks map[string]string
l sync.Mutex
l *sync.Mutex
cond *sync.Cond
logger log.Logger
}
@ -32,8 +32,9 @@ func NewInmemHA(_ map[string]string, logger log.Logger) (physical.Backend, error
Backend: be,
locks: make(map[string]string),
logger: logger,
l: new(sync.Mutex),
}
in.cond = sync.NewCond(&in.l)
in.cond = sync.NewCond(in.l)
return in, nil
}
@ -46,13 +47,14 @@ func NewTransactionalInmemHA(_ map[string]string, logger log.Logger) (physical.B
Backend: transInmem,
locks: make(map[string]string),
logger: logger,
l: new(sync.Mutex),
}
in := &TransactionalInmemHABackend{
InmemHABackend: inmemHA,
Transactional: transInmem.(physical.Transactional),
}
in.cond = sync.NewCond(&in.l)
in.cond = sync.NewCond(in.l)
return in, nil
}

View file

@ -88,7 +88,13 @@ func NewZooKeeperBackend(conf map[string]string, logger log.Logger) (physical.Ba
}
}
acl := []zk.ACL{{zk.PermAll, schema, owner}}
acl := []zk.ACL{
{
Perms: zk.PermAll,
Scheme: schema,
ID: owner,
},
}
// Authnetication info
var schemaAndUser string

View file

@ -364,10 +364,7 @@ func (c *Core) ClusterTLSConfig(ctx context.Context) (*tls.Config, error) {
PrivateKey: localSigner,
Leaf: parsedCert,
}, nil
}
return nil, nil
}
clientLookup := func(requestInfo *tls.CertificateRequestInfo) (*tls.Certificate, error) {

View file

@ -338,7 +338,6 @@ func testCluster_ForwardRequests(t *testing.T, c *TestClusterCore, rootToken, re
// We need to call Leader as that refreshes the connection info
isLeader, _, _, err := c.Leader()
if err != nil {
panic(err.Error())
t.Fatal(err)
}
if isLeader {

View file

@ -85,6 +85,10 @@ func (d dynamicSystemView) CachingDisabled() bool {
return d.core.cachingDisabled || (d.mountEntry != nil && d.mountEntry.Config.ForceNoCache)
}
func (d dynamicSystemView) LocalMount() bool {
return d.mountEntry != nil && d.mountEntry.Local
}
// Checks if this is a primary Vault instance. Caller should hold the stateLock
// in read mode.
func (d dynamicSystemView) ReplicationState() consts.ReplicationState {

View file

@ -1322,6 +1322,11 @@ func (i *IdentityStore) sanitizeAndUpsertGroup(group *identity.Group, memberGrou
}
func (i *IdentityStore) validateMemberGroupID(groupID string, memberGroupID string) error {
// Detect self loop
if groupID == memberGroupID {
return fmt.Errorf("member group ID %q is same as the ID of the group", groupID)
}
group, err := i.MemDBGroupByID(groupID, true)
if err != nil {
return err
@ -1333,11 +1338,6 @@ func (i *IdentityStore) validateMemberGroupID(groupID string, memberGroupID stri
return nil
}
// Detect self loop
if groupID == memberGroupID {
fmt.Errorf("member group ID %q is same as the ID of the group")
}
// If adding the memberGroupID to groupID creates a cycle, then groupID must
// be a hop in that loop. Start a DFS traversal from memberGroupID and see if
// it reaches back to groupID. If it does, then it's a loop.

View file

@ -5,6 +5,7 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
math "math"
"net"
"net/http"
"net/url"
@ -263,7 +264,11 @@ func (c *Core) refreshRequestForwardingConnection(ctx context.Context, clusterAd
grpc.WithInsecure(), // it's not, we handle it in the dialer
grpc.WithKeepaliveParams(keepalive.ClientParameters{
Time: 2 * HeartbeatInterval,
}))
}),
grpc.WithDefaultCallOptions(
grpc.MaxCallRecvMsgSize(math.MaxInt32),
grpc.MaxCallSendMsgSize(math.MaxInt32),
))
if err != nil {
cancelFunc()
c.logger.Error("core: err setting up forwarding rpc client", "error", err)

View file

@ -175,6 +175,10 @@ func (m *RollbackManager) attemptRollback(ctx context.Context, path string, rs *
if err == logical.ErrUnsupportedOperation {
err = nil
}
// If we failed due to read-only storage, we can't do anything; ignore
if err != nil && strings.Contains(err.Error(), logical.ErrReadOnly.Error()) {
err = nil
}
if err != nil {
m.logger.Error("rollback: error rolling back", "path", path, "error", err)
}

View file

@ -3,6 +3,7 @@ package plugin
import (
"bytes"
"context"
"io"
"net"
"net/rpc"
@ -10,6 +11,18 @@ import (
"google.golang.org/grpc"
)
// TestOptions allows specifying options that can affect the behavior of the
// test functions
type TestOptions struct {
//ServerStdout causes the given value to be used in place of a blank buffer
//for RPCServer's Stdout
ServerStdout io.ReadCloser
//ServerStderr causes the given value to be used in place of a blank buffer
//for RPCServer's Stderr
ServerStderr io.ReadCloser
}
// The testing file contains test helpers that you can use outside of
// this package for making it easier to test plugins themselves.
@ -61,12 +74,20 @@ func TestRPCConn(t testing.T) (*rpc.Client, *rpc.Server) {
// TestPluginRPCConn returns a plugin RPC client and server that are connected
// together and configured.
func TestPluginRPCConn(t testing.T, ps map[string]Plugin) (*RPCClient, *RPCServer) {
func TestPluginRPCConn(t testing.T, ps map[string]Plugin, opts *TestOptions) (*RPCClient, *RPCServer) {
// Create two net.Conns we can use to shuttle our control connection
clientConn, serverConn := TestConn(t)
// Start up the server
server := &RPCServer{Plugins: ps, Stdout: new(bytes.Buffer), Stderr: new(bytes.Buffer)}
if opts != nil {
if opts.ServerStdout != nil {
server.Stdout = opts.ServerStdout
}
if opts.ServerStderr != nil {
server.Stderr = opts.ServerStderr
}
}
go server.ServeConn(serverConn)
// Connect the client to the server

View file

@ -101,6 +101,9 @@ type Conn struct {
reconnectLatch chan struct{}
setWatchLimit int
setWatchCallback func([]*setWatchesRequest)
// Debug (for recurring re-auth hang)
debugCloseRecvLoop bool
debugReauthDone chan struct{}
logger Logger
logInfo bool // true if information messages are logged; false if only errors are logged
@ -301,9 +304,9 @@ func WithMaxBufferSize(maxBufferSize int) connOption {
// to a limit of 1mb. This option should be used for non-standard server setup
// where znode is bigger than default 1mb.
func WithMaxConnBufferSize(maxBufferSize int) connOption {
return func(c *Conn) {
c.buf = make([]byte, maxBufferSize)
}
return func(c *Conn) {
c.buf = make([]byte, maxBufferSize)
}
}
func (c *Conn) Close() {
@ -389,6 +392,17 @@ func (c *Conn) connect() error {
}
func (c *Conn) resendZkAuth(reauthReadyChan chan struct{}) {
shouldCancel := func() bool {
select {
case <-c.shouldQuit:
return true
case <-c.closeChan:
return true
default:
return false
}
}
c.credsMu.Lock()
defer c.credsMu.Unlock()
@ -400,6 +414,10 @@ func (c *Conn) resendZkAuth(reauthReadyChan chan struct{}) {
}
for _, cred := range c.creds {
if shouldCancel() {
c.logger.Printf("Cancel rer-submitting credentials")
return
}
resChan, err := c.sendRequest(
opSetAuth,
&setAuthRequest{Type: 0,
@ -415,7 +433,16 @@ func (c *Conn) resendZkAuth(reauthReadyChan chan struct{}) {
continue
}
res := <-resChan
var res response
select {
case res = <-resChan:
case <-c.closeChan:
c.logger.Printf("Recv closed, cancel re-submitting credentials")
return
case <-c.shouldQuit:
c.logger.Printf("Should quit, cancel re-submitting credentials")
return
}
if res.err != nil {
c.logger.Printf("Credential re-submit failed: %s", res.err)
// FIXME(prozlach): lets ignore errors for now
@ -476,6 +503,9 @@ func (c *Conn) loop() {
wg.Add(1)
go func() {
<-reauthChan
if c.debugCloseRecvLoop {
close(c.debugReauthDone)
}
err := c.sendLoop()
if err != nil || c.logInfo {
c.logger.Printf("Send loop terminated: err=%v", err)
@ -486,7 +516,12 @@ func (c *Conn) loop() {
wg.Add(1)
go func() {
err := c.recvLoop(c.conn)
var err error
if c.debugCloseRecvLoop {
err = errors.New("DEBUG: close recv loop")
} else {
err = c.recvLoop(c.conn)
}
if err != io.EOF || c.logInfo {
c.logger.Printf("Recv loop terminated: err=%v", err)
}

12
vendor/vendor.json vendored
View file

@ -1003,10 +1003,10 @@
"revisionTime": "2017-12-04T18:29:08Z"
},
{
"checksumSHA1": "y3op+t01flBlSBKlzUNqH5d4XHQ=",
"checksumSHA1": "7SheX5w6+xGsTMxPI3LiJx0iz7s=",
"path": "github.com/hashicorp/go-plugin",
"revision": "e53f54cbf51efde642d4711313e829a1ff0c236d",
"revisionTime": "2018-01-25T19:04:38Z"
"revision": "4b17561773d85e482ea040884ee3e288425d4174",
"revisionTime": "2018-02-06T18:30:35Z"
},
{
"checksumSHA1": "yzoWV7yrS/TvOrKy5ZrdUjsYaOA=",
@ -1495,10 +1495,10 @@
"revisionTime": "2017-01-28T01:21:29Z"
},
{
"checksumSHA1": "y33yd1uDZmV3VY4K/5FCGTeRtB8=",
"checksumSHA1": "ze1R6Lrk0kW0cX24ZdZD6ZpIDCo=",
"path": "github.com/samuel/go-zookeeper/zk",
"revision": "471cd4e61d7a78ece1791fa5faa0345dc8c7d5a5",
"revisionTime": "2017-11-17T18:40:27Z"
"revision": "c4fab1ac1bec58281ad0667dc3f0907a9476ac47",
"revisionTime": "2018-01-30T19:37:22Z"
},
{
"checksumSHA1": "eDQ6f1EsNf+frcRO/9XukSEchm8=",

View file

@ -10,8 +10,9 @@ description: |-
# Multi-Factor Authentication
~> **NOTE**: This page describes the legacy MFA system available in the OSS
edition of Vault. Vault Enterprise contains a significantly more complete and
flexible MFA system that can be used throughout Vault's API. See the [Vault
edition of Vault. This system is not supported by HashiCorp. Vault Enterprise
contains a fully-supported MFA system that is significantly more complete and
flexible and which can be used throughout Vault's API. See the [Vault
Enterprise MFA](/docs/enterprise/mfa/index.html) page for more information.
Several auth methods support multi-factor authentication (MFA). Once

View file

@ -117,7 +117,7 @@ This example show enabling high availability for the Etcd storage backend.
api_addr = "https://vault-leader.my-company.internal"
storage "etcd" {
ha_enabled = true
ha_enabled = "true"
...
}
```

View file

@ -478,10 +478,6 @@
<a href="/docs/auth/ldap.html">LDAP</a>
</li>
<li<%= sidebar_current("docs-auth-mfa") %>>
<a href="/docs/auth/mfa.html">MFA</a>
</li>
<li<%= sidebar_current("docs-auth-okta") %>>
<a href="/docs/auth/okta.html">Okta</a>
</li>
@ -508,6 +504,10 @@
<a href="/docs/auth/app-id.html">App ID <sup>DEPRECATED</sup></a>
</li>
<li<%= sidebar_current("docs-auth-mfa") %>>
<a href="/docs/auth/mfa.html">MFA <sup>LEGACY / UNSUPPORTED</sup></a>
</li>
</ul>
</li>