More porting from rep (#2388)
* More porting from rep * Address review feedback
This commit is contained in:
parent
0c39b613c8
commit
c81582fea0
|
@ -17,20 +17,10 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
|
|||
}
|
||||
|
||||
func Backend(conf *logical.BackendConfig) (*framework.Backend, error) {
|
||||
// Initialize the salt
|
||||
salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
|
||||
HashFunc: salt.SHA1Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var b backend
|
||||
b.Salt = salt
|
||||
b.MapAppId = &framework.PolicyMap{
|
||||
PathMap: framework.PathMap{
|
||||
Name: "app-id",
|
||||
Salt: salt,
|
||||
Schema: map[string]*framework.FieldSchema{
|
||||
"display_name": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
|
@ -48,7 +38,6 @@ func Backend(conf *logical.BackendConfig) (*framework.Backend, error) {
|
|||
|
||||
b.MapUserId = &framework.PathMap{
|
||||
Name: "user-id",
|
||||
Salt: salt,
|
||||
Schema: map[string]*framework.FieldSchema{
|
||||
"cidr_block": &framework.FieldSchema{
|
||||
Type: framework.TypeString,
|
||||
|
@ -81,17 +70,11 @@ func Backend(conf *logical.BackendConfig) (*framework.Backend, error) {
|
|||
),
|
||||
|
||||
AuthRenew: b.pathLoginRenew,
|
||||
|
||||
Init: b.initialize,
|
||||
}
|
||||
|
||||
// Since the salt is new in 0.2, we need to handle this by migrating
|
||||
// any existing keys to use the salt. We can deprecate this eventually,
|
||||
// but for now we want a smooth upgrade experience by automatically
|
||||
// upgrading to use salting.
|
||||
if salt.DidGenerate() {
|
||||
if err := b.upgradeToSalted(conf.StorageView); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
b.view = conf.StorageView
|
||||
|
||||
return b.Backend, nil
|
||||
}
|
||||
|
@ -100,10 +83,36 @@ type backend struct {
|
|||
*framework.Backend
|
||||
|
||||
Salt *salt.Salt
|
||||
view logical.Storage
|
||||
MapAppId *framework.PolicyMap
|
||||
MapUserId *framework.PathMap
|
||||
}
|
||||
|
||||
func (b *backend) initialize() error {
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA1Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Salt = salt
|
||||
|
||||
b.MapAppId.Salt = salt
|
||||
b.MapUserId.Salt = salt
|
||||
|
||||
// Since the salt is new in 0.2, we need to handle this by migrating
|
||||
// any existing keys to use the salt. We can deprecate this eventually,
|
||||
// but for now we want a smooth upgrade experience by automatically
|
||||
// upgrading to use salting.
|
||||
if salt.DidGenerate() {
|
||||
if err := b.upgradeToSalted(b.view); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// upgradeToSalted is used to upgrade the non-salted keys prior to
|
||||
// Vault 0.2 to be salted. This is done on mount time and is only
|
||||
// done once. It can be deprecated eventually, but should be around
|
||||
|
|
|
@ -72,6 +72,10 @@ func TestBackend_upgradeToSalted(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
err = backend.Initialize()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Check the keys have been upgraded
|
||||
out, err := inm.Get("struct/map/app-id/foo")
|
||||
|
|
|
@ -17,6 +17,9 @@ type backend struct {
|
|||
// by this backend.
|
||||
salt *salt.Salt
|
||||
|
||||
// The view to use when creating the salt
|
||||
view logical.Storage
|
||||
|
||||
// Guard to clean-up the expired SecretID entries
|
||||
tidySecretIDCASGuard uint32
|
||||
|
||||
|
@ -57,18 +60,9 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
|
|||
}
|
||||
|
||||
func Backend(conf *logical.BackendConfig) (*backend, error) {
|
||||
// Initialize the salt
|
||||
salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create a backend object
|
||||
b := &backend{
|
||||
// Set the salt object for the backend
|
||||
salt: salt,
|
||||
view: conf.StorageView,
|
||||
|
||||
// Create the map of locks to modify the registered roles
|
||||
roleLocksMap: make(map[string]*sync.RWMutex, 257),
|
||||
|
@ -83,6 +77,8 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
secretIDAccessorLocksMap: make(map[string]*sync.RWMutex, 257),
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
// Create 256 locks each for managing RoleID and SecretIDs. This will avoid
|
||||
// a superfluous number of locks directly proportional to the number of RoleID
|
||||
// and SecretIDs. These locks can be accessed by indexing based on the first two
|
||||
|
@ -129,10 +125,22 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
pathTidySecretID(b),
|
||||
},
|
||||
),
|
||||
Init: b.initialize,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *backend) initialize() error {
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.salt = salt
|
||||
return nil
|
||||
}
|
||||
|
||||
// periodicFunc of the backend will be invoked once a minute by the RollbackManager.
|
||||
// RoleRole backend utilizes this function to delete expired SecretID entries.
|
||||
// This could mean that the SecretID may live in the backend upto 1 min after its
|
||||
|
|
|
@ -21,5 +21,9 @@ func createBackendWithStorage(t *testing.T) (*backend, logical.Storage) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = b.Initialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return b, config.StorageView
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ type backend struct {
|
|||
*framework.Backend
|
||||
Salt *salt.Salt
|
||||
|
||||
// Used during initialization to set the salt
|
||||
view logical.Storage
|
||||
|
||||
// Lock to make changes to any of the backend's configuration endpoints.
|
||||
configMutex sync.RWMutex
|
||||
|
||||
|
@ -59,18 +62,11 @@ type backend struct {
|
|||
}
|
||||
|
||||
func Backend(conf *logical.BackendConfig) (*backend, error) {
|
||||
salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b := &backend{
|
||||
// Setting the periodic func to be run once in an hour.
|
||||
// If there is a real need, this can be made configurable.
|
||||
tidyCooldownPeriod: time.Hour,
|
||||
Salt: salt,
|
||||
view: conf.StorageView,
|
||||
EC2ClientsMap: make(map[string]map[string]*ec2.EC2),
|
||||
IAMClientsMap: make(map[string]map[string]*iam.IAM),
|
||||
}
|
||||
|
@ -83,6 +79,9 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
Unauthenticated: []string{
|
||||
"login",
|
||||
},
|
||||
LocalStorage: []string{
|
||||
"whitelist/identity/",
|
||||
},
|
||||
},
|
||||
Paths: []*framework.Path{
|
||||
pathLogin(b),
|
||||
|
@ -104,11 +103,26 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
pathIdentityWhitelist(b),
|
||||
pathTidyIdentityWhitelist(b),
|
||||
},
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
|
||||
Init: b.initialize,
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *backend) initialize() error {
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Salt = salt
|
||||
return nil
|
||||
}
|
||||
|
||||
// periodicFunc performs the tasks that the backend wishes to do periodically.
|
||||
// Currently this will be triggered once in a minute by the RollbackManager.
|
||||
//
|
||||
|
@ -169,6 +183,16 @@ func (b *backend) periodicFunc(req *logical.Request) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/client":
|
||||
b.configMutex.Lock()
|
||||
defer b.configMutex.Unlock()
|
||||
b.flushCachedEC2Clients()
|
||||
b.flushCachedIAMClients()
|
||||
}
|
||||
}
|
||||
|
||||
const backendHelp = `
|
||||
aws-ec2 auth backend takes in PKCS#7 signature of an AWS EC2 instance and a client
|
||||
created nonce to authenticates the EC2 instance with Vault.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cert
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
|
@ -13,7 +14,7 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
|
|||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
return b, b.populateCRLs(conf.StorageView)
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func Backend() *backend {
|
||||
|
@ -36,9 +37,10 @@ func Backend() *backend {
|
|||
}),
|
||||
|
||||
AuthRenew: b.pathLoginRenew,
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
|
||||
b.crls = map[string]CRLInfo{}
|
||||
b.crlUpdateMutex = &sync.RWMutex{}
|
||||
|
||||
return &b
|
||||
|
@ -52,6 +54,15 @@ type backend struct {
|
|||
crlUpdateMutex *sync.RWMutex
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch {
|
||||
case strings.HasPrefix(key, "crls/"):
|
||||
b.crlUpdateMutex.Lock()
|
||||
defer b.crlUpdateMutex.Unlock()
|
||||
b.crls = nil
|
||||
}
|
||||
}
|
||||
|
||||
const backendHelp = `
|
||||
The "cert" credential provider allows authentication using
|
||||
TLS client certificates. A client connects to Vault and uses
|
||||
|
|
|
@ -45,6 +45,12 @@ func (b *backend) populateCRLs(storage logical.Storage) error {
|
|||
b.crlUpdateMutex.Lock()
|
||||
defer b.crlUpdateMutex.Unlock()
|
||||
|
||||
if b.crls != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b.crls = map[string]CRLInfo{}
|
||||
|
||||
keys, err := storage.List("crls/")
|
||||
if err != nil {
|
||||
return fmt.Errorf("error listing CRLs: %v", err)
|
||||
|
@ -56,6 +62,7 @@ func (b *backend) populateCRLs(storage logical.Storage) error {
|
|||
for _, key := range keys {
|
||||
entry, err := storage.Get("crls/" + key)
|
||||
if err != nil {
|
||||
b.crls = nil
|
||||
return fmt.Errorf("error loading CRL %s: %v", key, err)
|
||||
}
|
||||
if entry == nil {
|
||||
|
@ -64,6 +71,7 @@ func (b *backend) populateCRLs(storage logical.Storage) error {
|
|||
var crlInfo CRLInfo
|
||||
err = entry.DecodeJSON(&crlInfo)
|
||||
if err != nil {
|
||||
b.crls = nil
|
||||
return fmt.Errorf("error decoding CRL %s: %v", key, err)
|
||||
}
|
||||
b.crls[key] = crlInfo
|
||||
|
@ -121,6 +129,10 @@ func (b *backend) pathCRLDelete(
|
|||
return logical.ErrorResponse(`"name" parameter cannot be empty`), nil
|
||||
}
|
||||
|
||||
if err := b.populateCRLs(req.Storage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.crlUpdateMutex.Lock()
|
||||
defer b.crlUpdateMutex.Unlock()
|
||||
|
||||
|
@ -131,8 +143,7 @@ func (b *backend) pathCRLDelete(
|
|||
)), nil
|
||||
}
|
||||
|
||||
err := req.Storage.Delete("crls/" + name)
|
||||
if err != nil {
|
||||
if err := req.Storage.Delete("crls/" + name); err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"error deleting crl %s: %v", name, err),
|
||||
), nil
|
||||
|
@ -150,6 +161,10 @@ func (b *backend) pathCRLRead(
|
|||
return logical.ErrorResponse(`"name" parameter must be set`), nil
|
||||
}
|
||||
|
||||
if err := b.populateCRLs(req.Storage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.crlUpdateMutex.RLock()
|
||||
defer b.crlUpdateMutex.RUnlock()
|
||||
|
||||
|
@ -185,6 +200,10 @@ func (b *backend) pathCRLWrite(
|
|||
return logical.ErrorResponse("parsed CRL is nil"), nil
|
||||
}
|
||||
|
||||
if err := b.populateCRLs(req.Storage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.crlUpdateMutex.Lock()
|
||||
defer b.crlUpdateMutex.Unlock()
|
||||
|
||||
|
|
|
@ -17,6 +17,12 @@ func Backend() *backend {
|
|||
b.Backend = &framework.Backend{
|
||||
Help: strings.TrimSpace(backendHelp),
|
||||
|
||||
PathsSpecial: &logical.Paths{
|
||||
LocalStorage: []string{
|
||||
framework.WALPrefix,
|
||||
},
|
||||
},
|
||||
|
||||
Paths: []*framework.Path{
|
||||
pathConfigRoot(),
|
||||
pathConfigLease(&b),
|
||||
|
|
|
@ -31,6 +31,8 @@ func Backend() *backend {
|
|||
secretCreds(&b),
|
||||
},
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
|
||||
Clean: func() {
|
||||
b.ResetDB(nil)
|
||||
},
|
||||
|
@ -107,6 +109,13 @@ func (b *backend) ResetDB(newSession *gocql.Session) {
|
|||
b.session = newSession
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/connection":
|
||||
b.ResetDB(nil)
|
||||
}
|
||||
}
|
||||
|
||||
const backendHelp = `
|
||||
The Cassandra backend dynamically generates database users.
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ func Backend() *framework.Backend {
|
|||
},
|
||||
|
||||
Clean: b.ResetSession,
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
|
||||
return b.Backend
|
||||
|
@ -97,6 +99,13 @@ func (b *backend) ResetSession() {
|
|||
b.session = nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/connection":
|
||||
b.ResetSession()
|
||||
}
|
||||
}
|
||||
|
||||
// LeaseConfig returns the lease configuration
|
||||
func (b *backend) LeaseConfig(s logical.Storage) (*configLease, error) {
|
||||
entry, err := s.Get("config/lease")
|
||||
|
|
|
@ -32,6 +32,8 @@ func Backend() *backend {
|
|||
secretCreds(&b),
|
||||
},
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
|
||||
Clean: b.ResetDB,
|
||||
}
|
||||
|
||||
|
@ -112,6 +114,13 @@ func (b *backend) ResetDB() {
|
|||
b.db = nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/connection":
|
||||
b.ResetDB()
|
||||
}
|
||||
}
|
||||
|
||||
// LeaseConfig returns the lease configuration
|
||||
func (b *backend) LeaseConfig(s logical.Storage) (*configLease, error) {
|
||||
entry, err := s.Get("config/lease")
|
||||
|
|
|
@ -32,6 +32,8 @@ func Backend() *backend {
|
|||
secretCreds(&b),
|
||||
},
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
|
||||
Clean: b.ResetDB,
|
||||
}
|
||||
|
||||
|
@ -105,6 +107,13 @@ func (b *backend) ResetDB() {
|
|||
b.db = nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/connection":
|
||||
b.ResetDB()
|
||||
}
|
||||
}
|
||||
|
||||
// Lease returns the lease information
|
||||
func (b *backend) Lease(s logical.Storage) (*configLease, error) {
|
||||
entry, err := s.Get("config/lease")
|
||||
|
|
|
@ -29,6 +29,12 @@ func Backend() *backend {
|
|||
"crl/pem",
|
||||
"crl",
|
||||
},
|
||||
|
||||
LocalStorage: []string{
|
||||
"revoked/",
|
||||
"crl",
|
||||
"certs/",
|
||||
},
|
||||
},
|
||||
|
||||
Paths: []*framework.Path{
|
||||
|
|
|
@ -34,6 +34,8 @@ func Backend(conf *logical.BackendConfig) *backend {
|
|||
},
|
||||
|
||||
Clean: b.ResetDB,
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
|
||||
b.logger = conf.Logger
|
||||
|
@ -126,6 +128,13 @@ func (b *backend) ResetDB() {
|
|||
b.db = nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/connection":
|
||||
b.ResetDB()
|
||||
}
|
||||
}
|
||||
|
||||
// Lease returns the lease information
|
||||
func (b *backend) Lease(s logical.Storage) (*configLease, error) {
|
||||
entry, err := s.Get("config/lease")
|
||||
|
|
|
@ -35,6 +35,8 @@ func Backend() *backend {
|
|||
},
|
||||
|
||||
Clean: b.resetClient,
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
|
||||
return &b
|
||||
|
@ -99,6 +101,13 @@ func (b *backend) resetClient() {
|
|||
b.client = nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case "config/connection":
|
||||
b.resetClient()
|
||||
}
|
||||
}
|
||||
|
||||
// Lease returns the lease information
|
||||
func (b *backend) Lease(s logical.Storage) (*configLease, error) {
|
||||
entry, err := s.Get("config/lease")
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
type backend struct {
|
||||
*framework.Backend
|
||||
view logical.Storage
|
||||
salt *salt.Salt
|
||||
}
|
||||
|
||||
|
@ -22,15 +23,8 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
|
|||
}
|
||||
|
||||
func Backend(conf *logical.BackendConfig) (*backend, error) {
|
||||
salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var b backend
|
||||
b.salt = salt
|
||||
b.view = conf.StorageView
|
||||
b.Backend = &framework.Backend{
|
||||
Help: strings.TrimSpace(backendHelp),
|
||||
|
||||
|
@ -38,6 +32,10 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
Unauthenticated: []string{
|
||||
"verify",
|
||||
},
|
||||
|
||||
LocalStorage: []string{
|
||||
"otp/",
|
||||
},
|
||||
},
|
||||
|
||||
Paths: []*framework.Path{
|
||||
|
@ -54,10 +52,23 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
secretDynamicKey(&b),
|
||||
secretOTP(&b),
|
||||
},
|
||||
|
||||
Init: b.Initialize,
|
||||
}
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
func (b *backend) Initialize() error {
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.salt = salt
|
||||
return nil
|
||||
}
|
||||
|
||||
const backendHelp = `
|
||||
The SSH backend generates credentials allowing clients to establish SSH
|
||||
connections to remote hosts.
|
||||
|
|
|
@ -73,6 +73,10 @@ func TestBackend_allowed_users(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = b.Initialize()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
roleData := map[string]interface{}{
|
||||
"key_type": "otp",
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package transit
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/helper/keysutil"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
|
@ -39,6 +41,8 @@ func Backend(conf *logical.BackendConfig) *backend {
|
|||
},
|
||||
|
||||
Secrets: []*framework.Secret{},
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
|
||||
b.lm = keysutil.NewLockManager(conf.System.CachingDisabled())
|
||||
|
@ -50,3 +54,14 @@ type backend struct {
|
|||
*framework.Backend
|
||||
lm *keysutil.LockManager
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
if b.Logger().IsTrace() {
|
||||
b.Logger().Trace("transit: invalidating key", "key", key)
|
||||
}
|
||||
switch {
|
||||
case strings.HasPrefix(key, "policy/"):
|
||||
name := strings.TrimPrefix(key, "policy/")
|
||||
b.lm.InvalidatePolicy(name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,13 @@ type MountCommand struct {
|
|||
|
||||
func (c *MountCommand) Run(args []string) int {
|
||||
var description, path, defaultLeaseTTL, maxLeaseTTL string
|
||||
var local bool
|
||||
flags := c.Meta.FlagSet("mount", meta.FlagSetDefault)
|
||||
flags.StringVar(&description, "description", "", "")
|
||||
flags.StringVar(&path, "path", "", "")
|
||||
flags.StringVar(&defaultLeaseTTL, "default-lease-ttl", "", "")
|
||||
flags.StringVar(&maxLeaseTTL, "max-lease-ttl", "", "")
|
||||
flags.BoolVar(&local, "local", false, "")
|
||||
flags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := flags.Parse(args); err != nil {
|
||||
return 1
|
||||
|
@ -54,6 +56,7 @@ func (c *MountCommand) Run(args []string) int {
|
|||
DefaultLeaseTTL: defaultLeaseTTL,
|
||||
MaxLeaseTTL: maxLeaseTTL,
|
||||
},
|
||||
Local: local,
|
||||
}
|
||||
|
||||
if err := client.Sys().Mount(path, mountInfo); err != nil {
|
||||
|
@ -102,6 +105,10 @@ Mount Options:
|
|||
the previously set value. Set to '0' to
|
||||
explicitly set it to use the global default.
|
||||
|
||||
-local Mark the mount as a local mount. Local mounts
|
||||
are not replicated nor (if a secondary)
|
||||
removed by replication.
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func (c *MountsCommand) Run(args []string) int {
|
|||
}
|
||||
sort.Strings(paths)
|
||||
|
||||
columns := []string{"Path | Type | Default TTL | Max TTL | Description"}
|
||||
columns := []string{"Path | Type | Default TTL | Max TTL | Replication Behavior | Description"}
|
||||
for _, path := range paths {
|
||||
mount := mounts[path]
|
||||
defTTL := "system"
|
||||
|
@ -63,8 +63,12 @@ func (c *MountsCommand) Run(args []string) int {
|
|||
case mount.Config.MaxLeaseTTL != 0:
|
||||
maxTTL = strconv.Itoa(mount.Config.MaxLeaseTTL)
|
||||
}
|
||||
replicatedBehavior := "replicated"
|
||||
if mount.Local {
|
||||
replicatedBehavior = "local"
|
||||
}
|
||||
columns = append(columns, fmt.Sprintf(
|
||||
"%s | %s | %s | %s | %s", path, mount.Type, defTTL, maxTTL, mount.Description))
|
||||
"%s | %s | %s | %s | %s | %s", path, mount.Type, defTTL, maxTTL, replicatedBehavior, mount.Description))
|
||||
}
|
||||
|
||||
c.Ui.Output(columnize.SimpleFormat(columns))
|
||||
|
|
|
@ -61,7 +61,7 @@ type ServerCommand struct {
|
|||
}
|
||||
|
||||
func (c *ServerCommand) Run(args []string) int {
|
||||
var dev, verifyOnly, devHA bool
|
||||
var dev, verifyOnly, devHA, devTransactional bool
|
||||
var configPath []string
|
||||
var logLevel, devRootTokenID, devListenAddress string
|
||||
flags := c.Meta.FlagSet("server", meta.FlagSetDefault)
|
||||
|
@ -70,7 +70,8 @@ func (c *ServerCommand) Run(args []string) int {
|
|||
flags.StringVar(&devListenAddress, "dev-listen-address", "", "")
|
||||
flags.StringVar(&logLevel, "log-level", "info", "")
|
||||
flags.BoolVar(&verifyOnly, "verify-only", false, "")
|
||||
flags.BoolVar(&devHA, "dev-ha", false, "")
|
||||
flags.BoolVar(&devHA, "ha", false, "")
|
||||
flags.BoolVar(&devTransactional, "transactional", false, "")
|
||||
flags.Usage = func() { c.Ui.Output(c.Help()) }
|
||||
flags.Var((*sliceflag.StringFlag)(&configPath), "config", "config")
|
||||
if err := flags.Parse(args); err != nil {
|
||||
|
@ -122,7 +123,7 @@ func (c *ServerCommand) Run(args []string) int {
|
|||
devListenAddress = os.Getenv("VAULT_DEV_LISTEN_ADDRESS")
|
||||
}
|
||||
|
||||
if devHA {
|
||||
if devHA || devTransactional {
|
||||
dev = true
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,7 @@ func (c *ServerCommand) Run(args []string) int {
|
|||
// Load the configuration
|
||||
var config *server.Config
|
||||
if dev {
|
||||
config = server.DevConfig(devHA)
|
||||
config = server.DevConfig(devHA, devTransactional)
|
||||
if devListenAddress != "" {
|
||||
config.Listeners[0].Config["address"] = devListenAddress
|
||||
}
|
||||
|
@ -235,6 +236,9 @@ func (c *ServerCommand) Run(args []string) int {
|
|||
ClusterName: config.ClusterName,
|
||||
CacheSize: config.CacheSize,
|
||||
}
|
||||
if dev {
|
||||
coreConfig.DevToken = devRootTokenID
|
||||
}
|
||||
|
||||
var disableClustering bool
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ type Config struct {
|
|||
}
|
||||
|
||||
// DevConfig is a Config that is used for dev mode of Vault.
|
||||
func DevConfig(ha bool) *Config {
|
||||
func DevConfig(ha, transactional bool) *Config {
|
||||
ret := &Config{
|
||||
DisableCache: false,
|
||||
DisableMlock: true,
|
||||
|
@ -63,7 +63,12 @@ func DevConfig(ha bool) *Config {
|
|||
DefaultLeaseTTL: 32 * 24 * time.Hour,
|
||||
}
|
||||
|
||||
if ha {
|
||||
switch {
|
||||
case ha && transactional:
|
||||
ret.Backend.Type = "inmem_transactional_ha"
|
||||
case !ha && transactional:
|
||||
ret.Backend.Type = "inmem_transactional"
|
||||
case ha && !transactional:
|
||||
ret.Backend.Type = "inmem_ha"
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ func TestServer_CommonHA(t *testing.T) {
|
|||
args := []string{"-config", tmpfile.Name(), "-verify-only", "true"}
|
||||
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
t.Fatalf("bad: %d\n\n%s\n\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String())
|
||||
}
|
||||
|
||||
if !strings.Contains(ui.OutputWriter.String(), "(HA available)") {
|
||||
|
@ -61,7 +61,7 @@ func TestServer_GoodSeparateHA(t *testing.T) {
|
|||
args := []string{"-config", tmpfile.Name(), "-verify-only", "true"}
|
||||
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
t.Fatalf("bad: %d\n\n%s\n\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String())
|
||||
}
|
||||
|
||||
if !strings.Contains(ui.OutputWriter.String(), "HA Backend:") {
|
||||
|
|
|
@ -71,6 +71,15 @@ func (lm *LockManager) CacheActive() bool {
|
|||
return lm.cache != nil
|
||||
}
|
||||
|
||||
func (lm *LockManager) InvalidatePolicy(name string) {
|
||||
// Check if it's in our cache. If so, return right away.
|
||||
if lm.CacheActive() {
|
||||
lm.cacheMutex.Lock()
|
||||
defer lm.cacheMutex.Unlock()
|
||||
delete(lm.cache, name)
|
||||
}
|
||||
}
|
||||
|
||||
func (lm *LockManager) policyLock(name string, lockType bool) *sync.RWMutex {
|
||||
lm.locksMutex.RLock()
|
||||
lock := lm.locks[name]
|
||||
|
|
|
@ -16,6 +16,12 @@ func CubbyholeBackendFactory(conf *logical.BackendConfig) (logical.Backend, erro
|
|||
b.Backend = &framework.Backend{
|
||||
Help: strings.TrimSpace(cubbyholeHelp),
|
||||
|
||||
PathsSpecial: &logical.Paths{
|
||||
LocalStorage: []string{
|
||||
"*",
|
||||
},
|
||||
},
|
||||
|
||||
Paths: []*framework.Path{
|
||||
&framework.Path{
|
||||
Pattern: ".*",
|
||||
|
|
|
@ -12,9 +12,13 @@ import (
|
|||
|
||||
func TestCubbyholeBackend_RootPaths(t *testing.T) {
|
||||
b := testCubbyholeBackend()
|
||||
root := b.SpecialPaths()
|
||||
if root != nil {
|
||||
t.Fatalf("unexpected: %v", root)
|
||||
expected := []string{
|
||||
"*",
|
||||
}
|
||||
|
||||
actual := b.SpecialPaths().LocalStorage
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/helper/consts"
|
||||
"github.com/hashicorp/vault/helper/duration"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
|
@ -39,12 +40,14 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) (logical.Backen
|
|||
"audit",
|
||||
"audit/*",
|
||||
"raw/*",
|
||||
"replication/primary/secondary-token",
|
||||
"rotate",
|
||||
"config/auditing/*",
|
||||
},
|
||||
|
||||
Unauthenticated: []string{
|
||||
"wrapping/pubkey",
|
||||
"replication/status",
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -226,6 +229,11 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) (logical.Backen
|
|||
Type: framework.TypeMap,
|
||||
Description: strings.TrimSpace(sysHelp["mount_config"][0]),
|
||||
},
|
||||
"local": &framework.FieldSchema{
|
||||
Type: framework.TypeBool,
|
||||
Default: false,
|
||||
Description: strings.TrimSpace(sysHelp["mount_local"][0]),
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
|
@ -377,6 +385,11 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) (logical.Backen
|
|||
Type: framework.TypeString,
|
||||
Description: strings.TrimSpace(sysHelp["auth_desc"][0]),
|
||||
},
|
||||
"local": &framework.FieldSchema{
|
||||
Type: framework.TypeBool,
|
||||
Default: false,
|
||||
Description: strings.TrimSpace(sysHelp["mount_local"][0]),
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
|
@ -495,6 +508,11 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) (logical.Backen
|
|||
Type: framework.TypeMap,
|
||||
Description: strings.TrimSpace(sysHelp["audit_opts"][0]),
|
||||
},
|
||||
"local": &framework.FieldSchema{
|
||||
Type: framework.TypeBool,
|
||||
Default: false,
|
||||
Description: strings.TrimSpace(sysHelp["mount_local"][0]),
|
||||
},
|
||||
},
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
|
@ -657,6 +675,10 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) (logical.Backen
|
|||
},
|
||||
}
|
||||
|
||||
b.Backend.Paths = append(b.Backend.Paths, b.replicationPaths()...)
|
||||
|
||||
b.Backend.Invalidate = b.invalidate
|
||||
|
||||
return b.Backend.Setup(config)
|
||||
}
|
||||
|
||||
|
@ -668,6 +690,20 @@ type SystemBackend struct {
|
|||
Backend *framework.Backend
|
||||
}
|
||||
|
||||
func (b *SystemBackend) invalidate(key string) {
|
||||
if b.Core.logger.IsTrace() {
|
||||
b.Core.logger.Trace("sys: invaliding key", "key", key)
|
||||
}
|
||||
switch {
|
||||
case strings.HasPrefix(key, policySubPath):
|
||||
b.Core.stateLock.RLock()
|
||||
defer b.Core.stateLock.RUnlock()
|
||||
if b.Core.policyStore != nil {
|
||||
b.Core.policyStore.invalidate(strings.TrimPrefix(key, policySubPath))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handleAuditedHeaderUpdate creates or overwrites a header entry
|
||||
func (b *SystemBackend) handleAuditedHeaderUpdate(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
header := d.Get("header").(string)
|
||||
|
@ -869,6 +905,7 @@ func (b *SystemBackend) handleMountTable(
|
|||
"default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()),
|
||||
"max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()),
|
||||
},
|
||||
"local": entry.Local,
|
||||
}
|
||||
|
||||
resp.Data[entry.Path] = info
|
||||
|
@ -880,6 +917,15 @@ func (b *SystemBackend) handleMountTable(
|
|||
// handleMount is used to mount a new path
|
||||
func (b *SystemBackend) handleMount(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
|
||||
local := data.Get("local").(bool)
|
||||
if !local && repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot add a non-local mount to a replication secondary"), nil
|
||||
}
|
||||
|
||||
// Get all the options
|
||||
path := data.Get("path").(string)
|
||||
logicalType := data.Get("type").(string)
|
||||
|
@ -954,6 +1000,7 @@ func (b *SystemBackend) handleMount(
|
|||
Type: logicalType,
|
||||
Description: description,
|
||||
Config: config,
|
||||
Local: local,
|
||||
}
|
||||
|
||||
// Attempt mount
|
||||
|
@ -979,6 +1026,10 @@ func handleError(
|
|||
// handleUnmount is used to unmount a path
|
||||
func (b *SystemBackend) handleUnmount(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
|
||||
suffix := strings.TrimPrefix(req.Path, "mounts/")
|
||||
if len(suffix) == 0 {
|
||||
return logical.ErrorResponse("path cannot be blank"), logical.ErrInvalidRequest
|
||||
|
@ -986,6 +1037,11 @@ func (b *SystemBackend) handleUnmount(
|
|||
|
||||
suffix = sanitizeMountPath(suffix)
|
||||
|
||||
entry := b.Core.router.MatchingMountEntry(suffix)
|
||||
if entry != nil && !entry.Local && repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot unmount a non-local mount on a replication secondary"), nil
|
||||
}
|
||||
|
||||
// Attempt unmount
|
||||
if existed, err := b.Core.unmount(suffix); existed && err != nil {
|
||||
b.Backend.Logger().Error("sys: unmount failed", "path", suffix, "error", err)
|
||||
|
@ -998,6 +1054,10 @@ func (b *SystemBackend) handleUnmount(
|
|||
// handleRemount is used to remount a path
|
||||
func (b *SystemBackend) handleRemount(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
|
||||
// Get the paths
|
||||
fromPath := data.Get("from").(string)
|
||||
toPath := data.Get("to").(string)
|
||||
|
@ -1010,6 +1070,11 @@ func (b *SystemBackend) handleRemount(
|
|||
fromPath = sanitizeMountPath(fromPath)
|
||||
toPath = sanitizeMountPath(toPath)
|
||||
|
||||
entry := b.Core.router.MatchingMountEntry(fromPath)
|
||||
if entry != nil && !entry.Local && repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot remount a non-local mount on a replication secondary"), nil
|
||||
}
|
||||
|
||||
// Attempt remount
|
||||
if err := b.Core.remount(fromPath, toPath); err != nil {
|
||||
b.Backend.Logger().Error("sys: remount failed", "from_path", fromPath, "to_path", toPath, "error", err)
|
||||
|
@ -1095,6 +1160,10 @@ func (b *SystemBackend) handleMountTuneWrite(
|
|||
// handleTuneWriteCommon is used to set config settings on a path
|
||||
func (b *SystemBackend) handleTuneWriteCommon(
|
||||
path string, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
|
||||
path = sanitizeMountPath(path)
|
||||
|
||||
// Prevent protected paths from being changed
|
||||
|
@ -1110,6 +1179,9 @@ func (b *SystemBackend) handleTuneWriteCommon(
|
|||
b.Backend.Logger().Error("sys: tune failed: no mount entry found", "path", path)
|
||||
return handleError(fmt.Errorf("sys: tune of path '%s' failed: no mount entry found", path))
|
||||
}
|
||||
if mountEntry != nil && !mountEntry.Local && repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot tune a non-local mount on a replication secondary"), nil
|
||||
}
|
||||
|
||||
var lock *sync.RWMutex
|
||||
switch {
|
||||
|
@ -1249,6 +1321,7 @@ func (b *SystemBackend) handleAuthTable(
|
|||
"default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()),
|
||||
"max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()),
|
||||
},
|
||||
"local": entry.Local,
|
||||
}
|
||||
resp.Data[entry.Path] = info
|
||||
}
|
||||
|
@ -1258,6 +1331,15 @@ func (b *SystemBackend) handleAuthTable(
|
|||
// handleEnableAuth is used to enable a new credential backend
|
||||
func (b *SystemBackend) handleEnableAuth(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
|
||||
local := data.Get("local").(bool)
|
||||
if !local && repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot add a non-local mount to a replication secondary"), nil
|
||||
}
|
||||
|
||||
// Get all the options
|
||||
path := data.Get("path").(string)
|
||||
logicalType := data.Get("type").(string)
|
||||
|
@ -1277,6 +1359,7 @@ func (b *SystemBackend) handleEnableAuth(
|
|||
Path: path,
|
||||
Type: logicalType,
|
||||
Description: description,
|
||||
Local: local,
|
||||
}
|
||||
|
||||
// Attempt enabling
|
||||
|
@ -1391,6 +1474,7 @@ func (b *SystemBackend) handleAuditTable(
|
|||
"type": entry.Type,
|
||||
"description": entry.Description,
|
||||
"options": entry.Options,
|
||||
"local": entry.Local,
|
||||
}
|
||||
resp.Data[entry.Path] = info
|
||||
}
|
||||
|
@ -1424,6 +1508,15 @@ func (b *SystemBackend) handleAuditHash(
|
|||
// handleEnableAudit is used to enable a new audit backend
|
||||
func (b *SystemBackend) handleEnableAudit(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
|
||||
local := data.Get("local").(bool)
|
||||
if !local && repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot add a non-local mount to a replication secondary"), nil
|
||||
}
|
||||
|
||||
// Get all the options
|
||||
path := data.Get("path").(string)
|
||||
backendType := data.Get("type").(string)
|
||||
|
@ -1447,6 +1540,7 @@ func (b *SystemBackend) handleEnableAudit(
|
|||
Type: backendType,
|
||||
Description: description,
|
||||
Options: optionMap,
|
||||
Local: local,
|
||||
}
|
||||
|
||||
// Attempt enabling
|
||||
|
@ -1562,6 +1656,13 @@ func (b *SystemBackend) handleKeyStatus(
|
|||
// handleRotate is used to trigger a key rotation
|
||||
func (b *SystemBackend) handleRotate(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
b.Core.clusterParamsLock.RLock()
|
||||
repState := b.Core.replicationState
|
||||
b.Core.clusterParamsLock.RUnlock()
|
||||
if repState == consts.ReplicationSecondary {
|
||||
return logical.ErrorResponse("cannot rotate on a replication secondary"), nil
|
||||
}
|
||||
|
||||
// Rotate to the new term
|
||||
newTerm, err := b.Core.barrier.Rotate()
|
||||
if err != nil {
|
||||
|
@ -1584,6 +1685,17 @@ func (b *SystemBackend) handleRotate(
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Write to the canary path, which will force a synchronous truing during
|
||||
// replication
|
||||
if err := b.Core.barrier.Put(&Entry{
|
||||
Key: coreKeyringCanaryPath,
|
||||
Value: []byte(fmt.Sprintf("new-rotation-term-%d", newTerm)),
|
||||
}); err != nil {
|
||||
b.Core.logger.Error("core: error saving keyring canary", "error", err)
|
||||
return nil, fmt.Errorf("failed to save keyring canary: %v", err)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -1950,6 +2062,11 @@ west coast.
|
|||
and max_lease_ttl.`,
|
||||
},
|
||||
|
||||
"mount_local": {
|
||||
`Mark the mount as a local mount, which is not replicated
|
||||
and is unaffected by replication.`,
|
||||
},
|
||||
|
||||
"tune_default_lease_ttl": {
|
||||
`The default lease TTL for this mount.`,
|
||||
},
|
||||
|
|
|
@ -21,6 +21,7 @@ func TestSystemBackend_RootPaths(t *testing.T) {
|
|||
"audit",
|
||||
"audit/*",
|
||||
"raw/*",
|
||||
"replication/*",
|
||||
"rotate",
|
||||
"config/auditing/*",
|
||||
}
|
||||
|
@ -50,6 +51,7 @@ func TestSystemBackend_mounts(t *testing.T) {
|
|||
"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
|
||||
"max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
|
||||
},
|
||||
"local": false,
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"type": "system",
|
||||
|
@ -58,6 +60,7 @@ func TestSystemBackend_mounts(t *testing.T) {
|
|||
"default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
|
||||
"max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
|
||||
},
|
||||
"local": false,
|
||||
},
|
||||
"cubbyhole/": map[string]interface{}{
|
||||
"description": "per-token private secret storage",
|
||||
|
@ -66,6 +69,7 @@ func TestSystemBackend_mounts(t *testing.T) {
|
|||
"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
|
||||
"max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
|
||||
},
|
||||
"local": false,
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(resp.Data, exp) {
|
||||
|
@ -580,6 +584,7 @@ func TestSystemBackend_authTable(t *testing.T) {
|
|||
"default_lease_ttl": int64(0),
|
||||
"max_lease_ttl": int64(0),
|
||||
},
|
||||
"local": false,
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(resp.Data, exp) {
|
||||
|
@ -843,6 +848,7 @@ func TestSystemBackend_auditTable(t *testing.T) {
|
|||
req.Data["options"] = map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}
|
||||
req.Data["local"] = true
|
||||
b.HandleRequest(req)
|
||||
|
||||
req = logical.TestRequest(t, logical.ReadOperation, "audit")
|
||||
|
@ -859,6 +865,7 @@ func TestSystemBackend_auditTable(t *testing.T) {
|
|||
"options": map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
"local": true,
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(resp.Data, exp) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<ul class="nav">
|
||||
<li<%= sidebar_current("docs-internals-architecture") %>>
|
||||
<a href="/docs/internals/architecture.html">Architecture</a>
|
||||
</li>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-internals-ha") %>>
|
||||
<a href="/docs/internals/high-availability.html">High Availability</a>
|
||||
|
@ -19,15 +19,15 @@
|
|||
|
||||
<li<%= sidebar_current("docs-internals-security") %>>
|
||||
<a href="/docs/internals/security.html">Security Model</a>
|
||||
</li>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-internals-telemetry") %>>
|
||||
<a href="/docs/internals/telemetry.html">Telemetry</a>
|
||||
</li>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-internals-token") %>>
|
||||
<a href="/docs/internals/token.html">Token Authentication</a>
|
||||
</li>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-internals-rotation") %>>
|
||||
<a href="/docs/internals/rotation.html">Key Rotation</a>
|
||||
|
|
Loading…
Reference in New Issue