AWS upgrade role entries (#7025)

* upgrade aws roles

* test upgrade aws roles

* Initialize aws credential backend at mount time

* add a TODO

* create end-to-end test for builtin/credential/aws

* fix bug in initializer

* improve comments

* add Initialize() to logical.Backend

* use Initialize() in Core.enableCredentialInternal()

* use InitializeRequest to call Initialize()

* improve unit testing for framework.Backend

* call logical.Backend.Initialize() from all of the places that it needs to be called.

* implement backend.proto changes for logical.Backend.Initialize()

* persist current role storage version when upgrading aws roles

* format comments correctly

* improve comments

* use postUnseal funcs to initialize backends

* simplify test suite

* improve test suite

* simplify logic in aws role upgrade

* simplify aws credential initialization logic

* simplify logic in aws role upgrade

* use the core's activeContext for initialization

* refactor builtin/plugin/Backend

* use a goroutine to upgrade the aws roles

* misc improvements and cleanup

* do not run AWS role upgrade on DR Secondary

* always call logical.Backend.Initialize() when loading a plugin.

* improve comments

* on standbys and DR secondaries we do not want to run any kind of upgrade logic

* fix awsVersion struct

* clarify aws version upgrade

* make the upgrade logic for aws auth more explicit

* aws upgrade is now called from a switch

* fix fallthrough bug

* simplify logic

* simplify logic

* rename things

* introduce currentAwsVersion const to track aws version

* improve comments

* rearrange things once more

* conglomerate things into one function

* stub out aws auth initialize e2e test

* improve aws auth initialize e2e test

* finish aws auth initialize e2e test

* tinker with aws auth initialize e2e test

* tinker with aws auth initialize e2e test

* tinker with aws auth initialize e2e test

* fix typo in test suite

* simplify logic a tad

* rearrange assignment

* Fix a few lifecycle related issues in #7025 (#7075)

* Fix panic when plugin fails to load
This commit is contained in:
Mike Jarmy
2019-07-05 19:55:40 -04:00
committed by Brian Kassouf
parent 8b9e9ea1ec
commit c48159ea3a
21 changed files with 1135 additions and 342 deletions

View File

@@ -35,7 +35,7 @@ type backend struct {
configMutex sync.RWMutex
// Lock to make changes to role entries
roleMutex sync.RWMutex
roleMutex sync.Mutex
// Lock to make changes to the blacklist entries
blacklistMutex sync.RWMutex
@@ -81,6 +81,10 @@ type backend struct {
roleCache *cache.Cache
resolveArnToUniqueIDFunc func(context.Context, logical.Storage, string) (string, error)
// upgradeCancelFunc is used to cancel the context used in the upgrade
// function
upgradeCancelFunc context.CancelFunc
}
func Backend(conf *logical.BackendConfig) (*backend, error) {
@@ -134,8 +138,10 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
pathIdentityWhitelist(b),
pathTidyIdentityWhitelist(b),
},
Invalidate: b.invalidate,
BackendType: logical.TypeCredential,
Invalidate: b.invalidate,
InitializeFunc: b.initialize,
BackendType: logical.TypeCredential,
Clean: b.cleanup,
}
return b, nil
@@ -205,6 +211,12 @@ func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error
return nil
}
func (b *backend) cleanup(ctx context.Context) {
if b.upgradeCancelFunc != nil {
b.upgradeCancelFunc()
}
}
func (b *backend) invalidate(ctx context.Context, key string) {
switch {
case key == "config/client":

View File

@@ -0,0 +1,133 @@
package awsauth
import (
"context"
"testing"
"time"
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/api"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/vault"
)
func TestBackend_E2E_Initialize(t *testing.T) {
ctx := context.Background()
// Set up the cluster. This will trigger an Initialize(); we sleep briefly
// awaiting its completion.
cluster := setupAwsTestCluster(t, ctx)
defer cluster.Cleanup()
time.Sleep(time.Second)
core := cluster.Cores[0]
// Fetch the aws auth's path in storage. This is a uuid that is different
// every time we run the test
authUuids, err := core.UnderlyingStorage.List(ctx, "auth/")
if err != nil {
t.Fatal(err)
}
if len(authUuids) != 1 {
t.Fatalf("expected exactly one auth path")
}
awsPath := "auth/" + authUuids[0]
// Make sure that the upgrade happened, by fishing the 'config/version'
// entry out of storage. We can't use core.Client.Logical().Read() to do
// this, because 'config/version' hasn't been exposed as a path.
// TODO: should we expose 'config/version' as a path?
version, err := core.UnderlyingStorage.Get(ctx, awsPath+"config/version")
if err != nil {
t.Fatal(err)
}
if version == nil {
t.Fatalf("no config found")
}
// Nuke the version, so we can pretend that Initialize() has never been run
if err := core.UnderlyingStorage.Delete(ctx, awsPath+"config/version"); err != nil {
t.Fatal(err)
}
version, err = core.UnderlyingStorage.Get(ctx, awsPath+"config/version")
if err != nil {
t.Fatal(err)
}
if version != nil {
t.Fatalf("version found")
}
// Create a role
data := map[string]interface{}{
"auth_type": "ec2",
"policies": "default",
"bound_subnet_id": "subnet-abcdef"}
if _, err := core.Client.Logical().Write("auth/aws/role/test-role", data); err != nil {
t.Fatal(err)
}
role, err := core.Client.Logical().Read("auth/aws/role/test-role")
if err != nil {
t.Fatal(err)
}
if role == nil {
t.Fatalf("no role found")
}
// There should _still_ be no config version
version, err = core.UnderlyingStorage.Get(ctx, awsPath+"config/version")
if err != nil {
t.Fatal(err)
}
if version != nil {
t.Fatalf("version found")
}
// Seal, and then Unseal. This will once again trigger an Initialize(),
// only this time there will be a role present during the upgrade.
core.Seal(t)
cluster.UnsealCores(t)
time.Sleep(time.Second)
// Now the config version should be there again
version, err = core.UnderlyingStorage.Get(ctx, awsPath+"config/version")
if err != nil {
t.Fatal(err)
}
if version == nil {
t.Fatalf("no version found")
}
}
func setupAwsTestCluster(t *testing.T, ctx context.Context) *vault.TestCluster {
// create a cluster with the aws auth backend built-in
logger := logging.NewVaultLogger(hclog.Trace)
coreConfig := &vault.CoreConfig{
Logger: logger,
CredentialBackends: map[string]logical.Factory{
"aws": Factory,
},
}
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
NumCores: 1,
HandlerFunc: vaulthttp.Handler,
})
cluster.Start()
if len(cluster.Cores) != 1 {
t.Fatalf("expected exactly one core")
}
core := cluster.Cores[0]
vault.TestWaitActive(t, core.Core)
// load the auth plugin
if err := core.Client.Sys().EnableAuthWithOptions("aws", &api.EnableAuthOptions{
Type: "aws",
}); err != nil {
t.Fatal(err)
}
return cluster
}

View File

@@ -319,6 +319,119 @@ func (b *backend) setRole(ctx context.Context, s logical.Storage, roleName strin
return nil
}
// initialize is used to initialize the AWS roles
func (b *backend) initialize(ctx context.Context, req *logical.InitializationRequest) error {
// on standbys and DR secondaries we do not want to run any kind of upgrade logic
if b.System().ReplicationState().HasState(consts.ReplicationPerformanceStandby | consts.ReplicationDRSecondary) {
return nil
}
// Initialize only if we are either:
// (1) A local mount.
// (2) Are _NOT_ a replicated performance secondary
if b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary) {
s := req.Storage
logger := b.Logger().Named("initialize")
logger.Debug("starting initialization")
var upgradeCtx context.Context
upgradeCtx, b.upgradeCancelFunc = context.WithCancel(context.Background())
go func() {
// The vault will become unsealed while this goroutine is running,
// so we could see some role requests block until the lock is
// released. However we'd rather see those requests block (and
// potentially start timing out) than allow a non-upgraded role to
// be fetched.
b.roleMutex.Lock()
defer b.roleMutex.Unlock()
upgraded, err := b.upgrade(upgradeCtx, s)
if err != nil {
logger.Error("error running initialization", "error", err)
return
}
if upgraded {
logger.Info("an upgrade was performed during initialization")
}
}()
}
return nil
}
// awsVersion stores info about the the latest aws version that we have
// upgraded to.
type awsVersion struct {
Version int `json:"version"`
}
// currentAwsVersion stores the latest version that we have upgraded to.
// Note that this is tracked independently from currentRoleStorageVersion.
const currentAwsVersion = 1
// upgrade does an upgrade, if necessary
func (b *backend) upgrade(ctx context.Context, s logical.Storage) (bool, error) {
entry, err := s.Get(ctx, "config/version")
if err != nil {
return false, err
}
var version awsVersion
if entry != nil {
err = entry.DecodeJSON(&version)
if err != nil {
return false, err
}
}
upgraded := version.Version < currentAwsVersion
switch version.Version {
case 0:
// Read all the role names.
roleNames, err := s.List(ctx, "role/")
if err != nil {
return false, err
}
// Upgrade the roles as necessary.
for _, roleName := range roleNames {
// make sure the context hasn't been canceled
if ctx.Err() != nil {
return false, err
}
_, err := b.roleInternal(ctx, s, roleName)
if err != nil {
return false, err
}
}
fallthrough
case currentAwsVersion:
version.Version = currentAwsVersion
default:
return false, fmt.Errorf("unrecognized role version: %d", version.Version)
}
// save the current version
if upgraded {
entry, err = logical.StorageEntryJSON("config/version", &version)
if err != nil {
return false, err
}
err = s.Put(ctx, entry)
if err != nil {
return false, err
}
}
return upgraded, nil
}
// If needed, updates the role entry and returns a bool indicating if it was updated
// (and thus needs to be persisted)
func (b *backend) upgradeRole(ctx context.Context, s logical.Storage, roleEntry *awsRoleEntry) (bool, error) {

View File

@@ -809,6 +809,183 @@ func TestRoleEntryUpgradeV(t *testing.T) {
}
}
func TestRoleInitialize(t *testing.T) {
config := logical.TestBackendConfig()
storage := &logical.InmemStorage{}
config.StorageView = storage
b, err := Backend(config)
if err != nil {
t.Fatal(err)
}
ctx := context.Background()
err = b.Setup(ctx, config)
if err != nil {
t.Fatal(err)
}
// create some role entries, some of which will need to be upgraded
type testData struct {
name string
entry *awsRoleEntry
}
before := []testData{
{
name: "role1",
entry: &awsRoleEntry{
BoundIamRoleARNs: []string{"arn:aws:iam::000000000001:role/my_role_prefix"},
BoundIamInstanceProfileARNs: []string{"arn:aws:iam::000000000001:instance-profile/my_profile-prefix"},
Version: 1,
},
},
{
name: "role2",
entry: &awsRoleEntry{
BoundIamRoleARNs: []string{"arn:aws:iam::000000000002:role/my_role_prefix"},
BoundIamInstanceProfileARNs: []string{"arn:aws:iam::000000000002:instance-profile/my_profile-prefix"},
Version: 2,
},
},
{
name: "role3",
entry: &awsRoleEntry{
BoundIamRoleARNs: []string{"arn:aws:iam::000000000003:role/my_role_prefix"},
BoundIamInstanceProfileARNs: []string{"arn:aws:iam::000000000003:instance-profile/my_profile-prefix"},
Version: currentRoleStorageVersion,
},
},
}
// put the entries in storage
for _, role := range before {
err = b.setRole(ctx, storage, role.name, role.entry)
if err != nil {
t.Fatal(err)
}
}
// upgrade all the entries
upgraded, err := b.upgrade(ctx, storage)
if err != nil {
t.Fatal(err)
}
if !upgraded {
t.Fatalf("expected upgrade")
}
// read the entries from storage
after := make([]testData, 0)
names, err := storage.List(ctx, "role/")
if err != nil {
t.Fatal(err)
}
for _, name := range names {
entry, err := b.role(ctx, storage, name)
if err != nil {
t.Fatal(err)
}
after = append(after, testData{name: name, entry: entry})
}
// make sure each entry is at the current version
expected := []testData{
{
name: "role1",
entry: &awsRoleEntry{
BoundIamRoleARNs: []string{"arn:aws:iam::000000000001:role/my_role_prefix"},
BoundIamInstanceProfileARNs: []string{"arn:aws:iam::000000000001:instance-profile/my_profile-prefix"},
Version: currentRoleStorageVersion,
},
},
{
name: "role2",
entry: &awsRoleEntry{
BoundIamRoleARNs: []string{"arn:aws:iam::000000000002:role/my_role_prefix"},
BoundIamInstanceProfileARNs: []string{"arn:aws:iam::000000000002:instance-profile/my_profile-prefix"},
Version: currentRoleStorageVersion,
},
},
{
name: "role3",
entry: &awsRoleEntry{
BoundIamRoleARNs: []string{"arn:aws:iam::000000000003:role/my_role_prefix"},
BoundIamInstanceProfileARNs: []string{"arn:aws:iam::000000000003:instance-profile/my_profile-prefix"},
Version: currentRoleStorageVersion,
},
},
}
if diff := deep.Equal(expected, after); diff != nil {
t.Fatal(diff)
}
// run it again -- nothing will happen
upgraded, err = b.upgrade(ctx, storage)
if err != nil {
t.Fatal(err)
}
if upgraded {
t.Fatalf("expected no upgrade")
}
// make sure saved role version is correct
entry, err := storage.Get(ctx, "config/version")
if err != nil {
t.Fatal(err)
}
var version awsVersion
err = entry.DecodeJSON(&version)
if err != nil {
t.Fatal(err)
}
if version.Version != currentAwsVersion {
t.Fatalf("expected version %d, got %d", currentAwsVersion, version.Version)
}
// stomp on the saved version
version.Version = 0
e2, err := logical.StorageEntryJSON("config/version", version)
if err != nil {
t.Fatal(err)
}
err = storage.Put(ctx, e2)
if err != nil {
t.Fatal(err)
}
// run it again -- now an upgrade will happen
upgraded, err = b.upgrade(ctx, storage)
if err != nil {
t.Fatal(err)
}
if !upgraded {
t.Fatalf("expected upgrade")
}
}
func TestAwsVersion(t *testing.T) {
before := awsVersion{
Version: 42,
}
entry, err := logical.StorageEntryJSON("config/version", &before)
if err != nil {
t.Fatal(err)
}
var after awsVersion
err = entry.DecodeJSON(&after)
if err != nil {
t.Fatal(err)
}
if diff := deep.Equal(before, after); diff != nil {
t.Fatal(diff)
}
}
func resolveArnToFakeUniqueId(ctx context.Context, s logical.Storage, arn string) (string, error) {
return "FakeUniqueId1", nil
}

View File

@@ -91,13 +91,8 @@ type PluginBackend struct {
loaded bool
}
func (b *PluginBackend) reloadBackend(ctx context.Context) error {
b.Logger().Debug("reloading plugin backend", "plugin", b.config.Config["plugin_name"])
return b.startBackend(ctx)
}
// startBackend starts a plugin backend
func (b *PluginBackend) startBackend(ctx context.Context) error {
func (b *PluginBackend) startBackend(ctx context.Context, storage logical.Storage) error {
pluginName := b.config.Config["plugin_name"]
pluginType, err := consts.ParsePluginType(b.config.Config["plugin_type"])
if err != nil {
@@ -134,11 +129,14 @@ func (b *PluginBackend) startBackend(ctx context.Context) error {
b.Backend = nb
b.loaded = true
return nil
// call Initialize() explicitly here.
return b.Backend.Initialize(ctx, &logical.InitializationRequest{
Storage: storage,
})
}
// HandleRequest is a thin wrapper implementation of HandleRequest that includes automatic plugin reload.
func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) {
// lazyLoad lazy-loads the backend before running a method
func (b *PluginBackend) lazyLoadBackend(ctx context.Context, storage logical.Storage, methodWrapper func() error) error {
b.RLock()
canary := b.canary
@@ -149,17 +147,19 @@ func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request)
b.Lock()
// Check once more after lock swap
if !b.loaded {
err := b.startBackend(ctx)
err := b.startBackend(ctx, storage)
if err != nil {
b.Unlock()
return nil, err
return err
}
}
b.Unlock()
b.RLock()
}
resp, err := b.Backend.HandleRequest(ctx, req)
err := methodWrapper()
b.RUnlock()
// Need to compare string value for case were err comes from plugin RPC
// and is returned as plugin.BasicError type.
if err != nil &&
@@ -167,73 +167,60 @@ func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request)
// Reload plugin if it's an rpc.ErrShutdown
b.Lock()
if b.canary == canary {
err := b.reloadBackend(ctx)
b.Logger().Debug("reloading plugin backend", "plugin", b.config.Config["plugin_name"])
err := b.startBackend(ctx, storage)
if err != nil {
b.Unlock()
return nil, err
return err
}
b.canary, err = uuid.GenerateUUID()
if err != nil {
b.Unlock()
return nil, err
return err
}
}
b.Unlock()
// Try request once more
// Try once more
b.RLock()
defer b.RUnlock()
return b.Backend.HandleRequest(ctx, req)
return methodWrapper()
}
return resp, err
return err
}
// HandleExistenceCheck is a thin wrapper implementation of HandleRequest that includes automatic plugin reload.
func (b *PluginBackend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (bool, bool, error) {
b.RLock()
canary := b.canary
// HandleRequest is a thin wrapper implementation of HandleRequest that includes automatic plugin reload.
func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request) (resp *logical.Response, err error) {
// Lazy-load backend
if !b.loaded {
// Upgrade lock
b.RUnlock()
b.Lock()
// Check once more after lock swap
if !b.loaded {
err := b.startBackend(ctx)
if err != nil {
b.Unlock()
return false, false, err
}
}
b.Unlock()
b.RLock()
}
err = b.lazyLoadBackend(ctx, req.Storage, func() error {
var merr error
resp, merr = b.Backend.HandleRequest(ctx, req)
return merr
})
checkFound, exists, err := b.Backend.HandleExistenceCheck(ctx, req)
b.RUnlock()
if err != nil &&
(err.Error() == rpc.ErrShutdown.Error() || err == bplugin.ErrPluginShutdown) {
// Reload plugin if it's an rpc.ErrShutdown
b.Lock()
if b.canary == canary {
err := b.reloadBackend(ctx)
if err != nil {
b.Unlock()
return false, false, err
}
b.canary, err = uuid.GenerateUUID()
if err != nil {
b.Unlock()
return false, false, err
}
}
b.Unlock()
// Try request once more
b.RLock()
defer b.RUnlock()
return b.Backend.HandleExistenceCheck(ctx, req)
}
return checkFound, exists, err
return
}
// HandleExistenceCheck is a thin wrapper implementation of HandleExistenceCheck that includes automatic plugin reload.
func (b *PluginBackend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (checkFound bool, exists bool, err error) {
err = b.lazyLoadBackend(ctx, req.Storage, func() error {
var merr error
checkFound, exists, merr = b.Backend.HandleExistenceCheck(ctx, req)
return merr
})
return
}
// Initialize is a thin wrapper implementation of Initialize that includes automatic plugin reload.
func (b *PluginBackend) Initialize(ctx context.Context, req *logical.InitializationRequest) error {
// This method is only ever called just after mounting, so we know that the
// call to lazyLoadBackend() will call startBackend(). Since
// startBackend() calls Initialize() on the underlying logical.Backend, the
// method wrapper that we pass in here is a no-op
return b.lazyLoadBackend(ctx, req.Storage, func() error {
return nil
})
}

View File

@@ -49,6 +49,10 @@ type Backend struct {
// and ease specifying callbacks for revocation, renewal, etc.
Secrets []*Secret
// InitializeFunc is the callback, which if set, will be invoked via
// Initialize() just after a plugin has been mounted.
InitializeFunc InitializeFunc
// PeriodicFunc is the callback, which if set, will be invoked when the
// periodic timer of RollbackManager ticks. This can be used by
// backends to do anything it wishes to do periodically.
@@ -108,6 +112,18 @@ type CleanupFunc func(context.Context)
// InvalidateFunc is the callback for backend key invalidation.
type InvalidateFunc func(context.Context, string)
// InitializeFunc is the callback, which if set, will be invoked via
// Initialize() just after a plugin has been mounted.
type InitializeFunc func(context.Context, *logical.InitializationRequest) error
// Initialize is the logical.Backend implementation.
func (b *Backend) Initialize(ctx context.Context, req *logical.InitializationRequest) error {
if b.InitializeFunc != nil {
return b.InitializeFunc(ctx, req)
}
return nil
}
// HandleExistenceCheck is the logical.Backend implementation.
func (b *Backend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (checkFound bool, exists bool, err error) {
b.once.Do(b.init)

View File

@@ -642,3 +642,18 @@ func TestFieldSchemaDefaultOrZero(t *testing.T) {
}
}
}
func TestInitializeBackend(t *testing.T) {
var inited bool
backend := &Backend{InitializeFunc: func(context.Context, *logical.InitializationRequest) error {
inited = true
return nil
}}
backend.Initialize(nil, &logical.InitializationRequest{Storage: nil})
if !inited {
t.Fatal("backend should be open")
}
}

View File

@@ -38,6 +38,10 @@ func (b BackendType) String() string {
// allows for a "procfs" like interaction, as internal state can be exposed by
// acting like a logical backend and being mounted.
type Backend interface {
// Initialize is used to initialize a plugin after it has been mounted.
Initialize(context.Context, *InitializationRequest) error
// HandleRequest is used to handle a request and generate a response.
// The backends must check the operation type and handle appropriately.
HandleRequest(context.Context, *Request) (*Response, error)

View File

@@ -303,3 +303,11 @@ const (
)
type MFACreds map[string][]string
// InitializationRequest stores the parameters and context of an Initialize()
// call being made to a logical.Backend.
type InitializationRequest struct {
// Storage can be used to durably store and retrieve state.
Storage Storage
}

View File

@@ -7,6 +7,8 @@ import (
"sync/atomic"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
log "github.com/hashicorp/go-hclog"
plugin "github.com/hashicorp/go-plugin"
@@ -44,6 +46,38 @@ type backendGRPCPluginClient struct {
doneCtx context.Context
}
func (b *backendGRPCPluginClient) Initialize(ctx context.Context, _ *logical.InitializationRequest) error {
if b.metadataMode {
return nil
}
ctx, cancel := context.WithCancel(ctx)
quitCh := pluginutil.CtxCancelIfCanceled(cancel, b.doneCtx)
defer close(quitCh)
defer cancel()
reply, err := b.client.Initialize(ctx, &pb.InitializeArgs{}, largeMsgGRPCCallOpts...)
if err != nil {
if b.doneCtx.Err() != nil {
return ErrPluginShutdown
}
// If the plugin doesn't have Initialize implemented we should not fail
// the initalize call; otherwise this could halt startup of vault.
grpcStatus, ok := status.FromError(err)
if ok && grpcStatus.Code() == codes.Unimplemented {
return nil
}
return err
}
if reply.Err != nil {
return pb.ProtoErrToErr(reply.Err)
}
return nil
}
func (b *backendGRPCPluginClient) HandleRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) {
if b.metadataMode {
return nil, ErrClientInMetadataMode

View File

@@ -84,6 +84,22 @@ func (b *backendGRPCPluginServer) HandleRequest(ctx context.Context, args *pb.Ha
}, nil
}
func (b *backendGRPCPluginServer) Initialize(ctx context.Context, _ *pb.InitializeArgs) (*pb.InitializeReply, error) {
if pluginutil.InMetadataMode() {
return &pb.InitializeReply{}, ErrServerInMetadataMode
}
req := &logical.InitializationRequest{
Storage: newGRPCStorageClient(b.brokeredClient),
}
respErr := b.backend.Initialize(ctx, req)
return &pb.InitializeReply{
Err: pb.ErrToProtoErr(respErr),
}, nil
}
func (b *backendGRPCPluginServer) SpecialPaths(ctx context.Context, args *pb.Empty) (*pb.SpecialPathsReply, error) {
paths := b.backend.SpecialPaths()
if paths == nil {

View File

@@ -137,6 +137,16 @@ func TestGRPCBackendPlugin_Setup(t *testing.T) {
defer cleanup()
}
func TestGRPCBackendPlugin_Initialize(t *testing.T) {
b, cleanup := testGRPCBackend(t)
defer cleanup()
err := b.Initialize(context.Background(), &logical.InitializationRequest{})
if err != nil {
t.Fatal(err)
}
}
func testGRPCBackend(t *testing.T) (logical.Backend, func()) {
// Create a mock provider
pluginMap := map[string]gplugin.Plugin{

View File

@@ -19,6 +19,15 @@ type backendTracingMiddleware struct {
// Validate the backendTracingMiddle object satisfies the backend interface
var _ logical.Backend = &backendTracingMiddleware{}
func (b *backendTracingMiddleware) Initialize(ctx context.Context, req *logical.InitializationRequest) (err error) {
defer func(then time.Time) {
b.logger.Trace("initialize", "status", "finished", "err", err, "took", time.Since(then))
}(time.Now())
b.logger.Trace("initialize", "status", "started")
return b.next.Initialize(ctx, req)
}
func (b *backendTracingMiddleware) HandleRequest(ctx context.Context, req *logical.Request) (resp *logical.Response, err error) {
defer func(then time.Time) {
b.logger.Trace("handle request", "path", req.Path, "status", "finished", "err", err, "took", time.Since(then))

View File

@@ -10,8 +10,6 @@ import (
timestamp "github.com/golang/protobuf/ptypes/timestamp"
logical "github.com/hashicorp/vault/sdk/logical"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
math "math"
)
@@ -1372,6 +1370,78 @@ func (m *HandleRequestReply) GetErr() *ProtoError {
return nil
}
// InitializeArgs is the args for Initialize method.
type InitializeArgs struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *InitializeArgs) Reset() { *m = InitializeArgs{} }
func (m *InitializeArgs) String() string { return proto.CompactTextString(m) }
func (*InitializeArgs) ProtoMessage() {}
func (*InitializeArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{14}
}
func (m *InitializeArgs) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InitializeArgs.Unmarshal(m, b)
}
func (m *InitializeArgs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InitializeArgs.Marshal(b, m, deterministic)
}
func (m *InitializeArgs) XXX_Merge(src proto.Message) {
xxx_messageInfo_InitializeArgs.Merge(m, src)
}
func (m *InitializeArgs) XXX_Size() int {
return xxx_messageInfo_InitializeArgs.Size(m)
}
func (m *InitializeArgs) XXX_DiscardUnknown() {
xxx_messageInfo_InitializeArgs.DiscardUnknown(m)
}
var xxx_messageInfo_InitializeArgs proto.InternalMessageInfo
// InitializeReply is the reply for Initialize method.
type InitializeReply struct {
Err *ProtoError `sentinel:"" protobuf:"bytes,1,opt,name=err,proto3" json:"err,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *InitializeReply) Reset() { *m = InitializeReply{} }
func (m *InitializeReply) String() string { return proto.CompactTextString(m) }
func (*InitializeReply) ProtoMessage() {}
func (*InitializeReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{15}
}
func (m *InitializeReply) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_InitializeReply.Unmarshal(m, b)
}
func (m *InitializeReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_InitializeReply.Marshal(b, m, deterministic)
}
func (m *InitializeReply) XXX_Merge(src proto.Message) {
xxx_messageInfo_InitializeReply.Merge(m, src)
}
func (m *InitializeReply) XXX_Size() int {
return xxx_messageInfo_InitializeReply.Size(m)
}
func (m *InitializeReply) XXX_DiscardUnknown() {
xxx_messageInfo_InitializeReply.DiscardUnknown(m)
}
var xxx_messageInfo_InitializeReply proto.InternalMessageInfo
func (m *InitializeReply) GetErr() *ProtoError {
if m != nil {
return m.Err
}
return nil
}
// SpecialPathsReply is the reply for SpecialPaths method.
type SpecialPathsReply struct {
Paths *Paths `sentinel:"" protobuf:"bytes,1,opt,name=paths,proto3" json:"paths,omitempty"`
@@ -1384,7 +1454,7 @@ func (m *SpecialPathsReply) Reset() { *m = SpecialPathsReply{} }
func (m *SpecialPathsReply) String() string { return proto.CompactTextString(m) }
func (*SpecialPathsReply) ProtoMessage() {}
func (*SpecialPathsReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{14}
return fileDescriptor_4dbf1dfe0c11846b, []int{16}
}
func (m *SpecialPathsReply) XXX_Unmarshal(b []byte) error {
@@ -1425,7 +1495,7 @@ func (m *HandleExistenceCheckArgs) Reset() { *m = HandleExistenceCheckAr
func (m *HandleExistenceCheckArgs) String() string { return proto.CompactTextString(m) }
func (*HandleExistenceCheckArgs) ProtoMessage() {}
func (*HandleExistenceCheckArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{15}
return fileDescriptor_4dbf1dfe0c11846b, []int{17}
}
func (m *HandleExistenceCheckArgs) XXX_Unmarshal(b []byte) error {
@@ -1474,7 +1544,7 @@ func (m *HandleExistenceCheckReply) Reset() { *m = HandleExistenceCheckR
func (m *HandleExistenceCheckReply) String() string { return proto.CompactTextString(m) }
func (*HandleExistenceCheckReply) ProtoMessage() {}
func (*HandleExistenceCheckReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{16}
return fileDescriptor_4dbf1dfe0c11846b, []int{18}
}
func (m *HandleExistenceCheckReply) XXX_Unmarshal(b []byte) error {
@@ -1530,7 +1600,7 @@ func (m *SetupArgs) Reset() { *m = SetupArgs{} }
func (m *SetupArgs) String() string { return proto.CompactTextString(m) }
func (*SetupArgs) ProtoMessage() {}
func (*SetupArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{17}
return fileDescriptor_4dbf1dfe0c11846b, []int{19}
}
func (m *SetupArgs) XXX_Unmarshal(b []byte) error {
@@ -1584,7 +1654,7 @@ func (m *SetupReply) Reset() { *m = SetupReply{} }
func (m *SetupReply) String() string { return proto.CompactTextString(m) }
func (*SetupReply) ProtoMessage() {}
func (*SetupReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{18}
return fileDescriptor_4dbf1dfe0c11846b, []int{20}
}
func (m *SetupReply) XXX_Unmarshal(b []byte) error {
@@ -1624,7 +1694,7 @@ func (m *TypeReply) Reset() { *m = TypeReply{} }
func (m *TypeReply) String() string { return proto.CompactTextString(m) }
func (*TypeReply) ProtoMessage() {}
func (*TypeReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{19}
return fileDescriptor_4dbf1dfe0c11846b, []int{21}
}
func (m *TypeReply) XXX_Unmarshal(b []byte) error {
@@ -1663,7 +1733,7 @@ func (m *InvalidateKeyArgs) Reset() { *m = InvalidateKeyArgs{} }
func (m *InvalidateKeyArgs) String() string { return proto.CompactTextString(m) }
func (*InvalidateKeyArgs) ProtoMessage() {}
func (*InvalidateKeyArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{20}
return fileDescriptor_4dbf1dfe0c11846b, []int{22}
}
func (m *InvalidateKeyArgs) XXX_Unmarshal(b []byte) error {
@@ -1704,7 +1774,7 @@ func (m *StorageEntry) Reset() { *m = StorageEntry{} }
func (m *StorageEntry) String() string { return proto.CompactTextString(m) }
func (*StorageEntry) ProtoMessage() {}
func (*StorageEntry) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{21}
return fileDescriptor_4dbf1dfe0c11846b, []int{23}
}
func (m *StorageEntry) XXX_Unmarshal(b []byte) error {
@@ -1757,7 +1827,7 @@ func (m *StorageListArgs) Reset() { *m = StorageListArgs{} }
func (m *StorageListArgs) String() string { return proto.CompactTextString(m) }
func (*StorageListArgs) ProtoMessage() {}
func (*StorageListArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{22}
return fileDescriptor_4dbf1dfe0c11846b, []int{24}
}
func (m *StorageListArgs) XXX_Unmarshal(b []byte) error {
@@ -1797,7 +1867,7 @@ func (m *StorageListReply) Reset() { *m = StorageListReply{} }
func (m *StorageListReply) String() string { return proto.CompactTextString(m) }
func (*StorageListReply) ProtoMessage() {}
func (*StorageListReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{23}
return fileDescriptor_4dbf1dfe0c11846b, []int{25}
}
func (m *StorageListReply) XXX_Unmarshal(b []byte) error {
@@ -1843,7 +1913,7 @@ func (m *StorageGetArgs) Reset() { *m = StorageGetArgs{} }
func (m *StorageGetArgs) String() string { return proto.CompactTextString(m) }
func (*StorageGetArgs) ProtoMessage() {}
func (*StorageGetArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{24}
return fileDescriptor_4dbf1dfe0c11846b, []int{26}
}
func (m *StorageGetArgs) XXX_Unmarshal(b []byte) error {
@@ -1883,7 +1953,7 @@ func (m *StorageGetReply) Reset() { *m = StorageGetReply{} }
func (m *StorageGetReply) String() string { return proto.CompactTextString(m) }
func (*StorageGetReply) ProtoMessage() {}
func (*StorageGetReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{25}
return fileDescriptor_4dbf1dfe0c11846b, []int{27}
}
func (m *StorageGetReply) XXX_Unmarshal(b []byte) error {
@@ -1929,7 +1999,7 @@ func (m *StoragePutArgs) Reset() { *m = StoragePutArgs{} }
func (m *StoragePutArgs) String() string { return proto.CompactTextString(m) }
func (*StoragePutArgs) ProtoMessage() {}
func (*StoragePutArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{26}
return fileDescriptor_4dbf1dfe0c11846b, []int{28}
}
func (m *StoragePutArgs) XXX_Unmarshal(b []byte) error {
@@ -1968,7 +2038,7 @@ func (m *StoragePutReply) Reset() { *m = StoragePutReply{} }
func (m *StoragePutReply) String() string { return proto.CompactTextString(m) }
func (*StoragePutReply) ProtoMessage() {}
func (*StoragePutReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{27}
return fileDescriptor_4dbf1dfe0c11846b, []int{29}
}
func (m *StoragePutReply) XXX_Unmarshal(b []byte) error {
@@ -2007,7 +2077,7 @@ func (m *StorageDeleteArgs) Reset() { *m = StorageDeleteArgs{} }
func (m *StorageDeleteArgs) String() string { return proto.CompactTextString(m) }
func (*StorageDeleteArgs) ProtoMessage() {}
func (*StorageDeleteArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{28}
return fileDescriptor_4dbf1dfe0c11846b, []int{30}
}
func (m *StorageDeleteArgs) XXX_Unmarshal(b []byte) error {
@@ -2046,7 +2116,7 @@ func (m *StorageDeleteReply) Reset() { *m = StorageDeleteReply{} }
func (m *StorageDeleteReply) String() string { return proto.CompactTextString(m) }
func (*StorageDeleteReply) ProtoMessage() {}
func (*StorageDeleteReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{29}
return fileDescriptor_4dbf1dfe0c11846b, []int{31}
}
func (m *StorageDeleteReply) XXX_Unmarshal(b []byte) error {
@@ -2085,7 +2155,7 @@ func (m *TTLReply) Reset() { *m = TTLReply{} }
func (m *TTLReply) String() string { return proto.CompactTextString(m) }
func (*TTLReply) ProtoMessage() {}
func (*TTLReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{30}
return fileDescriptor_4dbf1dfe0c11846b, []int{32}
}
func (m *TTLReply) XXX_Unmarshal(b []byte) error {
@@ -2125,7 +2195,7 @@ func (m *SudoPrivilegeArgs) Reset() { *m = SudoPrivilegeArgs{} }
func (m *SudoPrivilegeArgs) String() string { return proto.CompactTextString(m) }
func (*SudoPrivilegeArgs) ProtoMessage() {}
func (*SudoPrivilegeArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{31}
return fileDescriptor_4dbf1dfe0c11846b, []int{33}
}
func (m *SudoPrivilegeArgs) XXX_Unmarshal(b []byte) error {
@@ -2171,7 +2241,7 @@ func (m *SudoPrivilegeReply) Reset() { *m = SudoPrivilegeReply{} }
func (m *SudoPrivilegeReply) String() string { return proto.CompactTextString(m) }
func (*SudoPrivilegeReply) ProtoMessage() {}
func (*SudoPrivilegeReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{32}
return fileDescriptor_4dbf1dfe0c11846b, []int{34}
}
func (m *SudoPrivilegeReply) XXX_Unmarshal(b []byte) error {
@@ -2210,7 +2280,7 @@ func (m *TaintedReply) Reset() { *m = TaintedReply{} }
func (m *TaintedReply) String() string { return proto.CompactTextString(m) }
func (*TaintedReply) ProtoMessage() {}
func (*TaintedReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{33}
return fileDescriptor_4dbf1dfe0c11846b, []int{35}
}
func (m *TaintedReply) XXX_Unmarshal(b []byte) error {
@@ -2249,7 +2319,7 @@ func (m *CachingDisabledReply) Reset() { *m = CachingDisabledReply{} }
func (m *CachingDisabledReply) String() string { return proto.CompactTextString(m) }
func (*CachingDisabledReply) ProtoMessage() {}
func (*CachingDisabledReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{34}
return fileDescriptor_4dbf1dfe0c11846b, []int{36}
}
func (m *CachingDisabledReply) XXX_Unmarshal(b []byte) error {
@@ -2288,7 +2358,7 @@ func (m *ReplicationStateReply) Reset() { *m = ReplicationStateReply{} }
func (m *ReplicationStateReply) String() string { return proto.CompactTextString(m) }
func (*ReplicationStateReply) ProtoMessage() {}
func (*ReplicationStateReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{35}
return fileDescriptor_4dbf1dfe0c11846b, []int{37}
}
func (m *ReplicationStateReply) XXX_Unmarshal(b []byte) error {
@@ -2329,7 +2399,7 @@ func (m *ResponseWrapDataArgs) Reset() { *m = ResponseWrapDataArgs{} }
func (m *ResponseWrapDataArgs) String() string { return proto.CompactTextString(m) }
func (*ResponseWrapDataArgs) ProtoMessage() {}
func (*ResponseWrapDataArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{36}
return fileDescriptor_4dbf1dfe0c11846b, []int{38}
}
func (m *ResponseWrapDataArgs) XXX_Unmarshal(b []byte) error {
@@ -2383,7 +2453,7 @@ func (m *ResponseWrapDataReply) Reset() { *m = ResponseWrapDataReply{} }
func (m *ResponseWrapDataReply) String() string { return proto.CompactTextString(m) }
func (*ResponseWrapDataReply) ProtoMessage() {}
func (*ResponseWrapDataReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{37}
return fileDescriptor_4dbf1dfe0c11846b, []int{39}
}
func (m *ResponseWrapDataReply) XXX_Unmarshal(b []byte) error {
@@ -2429,7 +2499,7 @@ func (m *MlockEnabledReply) Reset() { *m = MlockEnabledReply{} }
func (m *MlockEnabledReply) String() string { return proto.CompactTextString(m) }
func (*MlockEnabledReply) ProtoMessage() {}
func (*MlockEnabledReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{38}
return fileDescriptor_4dbf1dfe0c11846b, []int{40}
}
func (m *MlockEnabledReply) XXX_Unmarshal(b []byte) error {
@@ -2468,7 +2538,7 @@ func (m *LocalMountReply) Reset() { *m = LocalMountReply{} }
func (m *LocalMountReply) String() string { return proto.CompactTextString(m) }
func (*LocalMountReply) ProtoMessage() {}
func (*LocalMountReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{39}
return fileDescriptor_4dbf1dfe0c11846b, []int{41}
}
func (m *LocalMountReply) XXX_Unmarshal(b []byte) error {
@@ -2507,7 +2577,7 @@ func (m *EntityInfoArgs) Reset() { *m = EntityInfoArgs{} }
func (m *EntityInfoArgs) String() string { return proto.CompactTextString(m) }
func (*EntityInfoArgs) ProtoMessage() {}
func (*EntityInfoArgs) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{40}
return fileDescriptor_4dbf1dfe0c11846b, []int{42}
}
func (m *EntityInfoArgs) XXX_Unmarshal(b []byte) error {
@@ -2547,7 +2617,7 @@ func (m *EntityInfoReply) Reset() { *m = EntityInfoReply{} }
func (m *EntityInfoReply) String() string { return proto.CompactTextString(m) }
func (*EntityInfoReply) ProtoMessage() {}
func (*EntityInfoReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{41}
return fileDescriptor_4dbf1dfe0c11846b, []int{43}
}
func (m *EntityInfoReply) XXX_Unmarshal(b []byte) error {
@@ -2594,7 +2664,7 @@ func (m *PluginEnvReply) Reset() { *m = PluginEnvReply{} }
func (m *PluginEnvReply) String() string { return proto.CompactTextString(m) }
func (*PluginEnvReply) ProtoMessage() {}
func (*PluginEnvReply) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{42}
return fileDescriptor_4dbf1dfe0c11846b, []int{44}
}
func (m *PluginEnvReply) XXX_Unmarshal(b []byte) error {
@@ -2641,7 +2711,7 @@ func (m *Connection) Reset() { *m = Connection{} }
func (m *Connection) String() string { return proto.CompactTextString(m) }
func (*Connection) ProtoMessage() {}
func (*Connection) Descriptor() ([]byte, []int) {
return fileDescriptor_4dbf1dfe0c11846b, []int{43}
return fileDescriptor_4dbf1dfe0c11846b, []int{45}
}
func (m *Connection) XXX_Unmarshal(b []byte) error {
@@ -2688,6 +2758,8 @@ func init() {
proto.RegisterType((*RequestWrapInfo)(nil), "pb.RequestWrapInfo")
proto.RegisterType((*HandleRequestArgs)(nil), "pb.HandleRequestArgs")
proto.RegisterType((*HandleRequestReply)(nil), "pb.HandleRequestReply")
proto.RegisterType((*InitializeArgs)(nil), "pb.InitializeArgs")
proto.RegisterType((*InitializeReply)(nil), "pb.InitializeReply")
proto.RegisterType((*SpecialPathsReply)(nil), "pb.SpecialPathsReply")
proto.RegisterType((*HandleExistenceCheckArgs)(nil), "pb.HandleExistenceCheckArgs")
proto.RegisterType((*HandleExistenceCheckReply)(nil), "pb.HandleExistenceCheckReply")
@@ -2724,165 +2796,167 @@ func init() {
func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) }
var fileDescriptor_4dbf1dfe0c11846b = []byte{
// 2519 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdb, 0x72, 0x1b, 0xc7,
0xd1, 0x2e, 0x00, 0xc4, 0xa9, 0x71, 0x22, 0x46, 0xb4, 0xfe, 0x15, 0x24, 0xff, 0x82, 0xd7, 0x91,
0x0c, 0x33, 0x36, 0x68, 0xd1, 0x71, 0x2c, 0x27, 0x65, 0xa7, 0x68, 0x8a, 0x96, 0x19, 0x93, 0x36,
0x6b, 0x09, 0xc7, 0x39, 0x55, 0xc1, 0x83, 0xdd, 0x21, 0xb8, 0xc5, 0xc5, 0xee, 0x66, 0x76, 0x96,
0x22, 0xae, 0xf2, 0x16, 0x79, 0x8d, 0xdc, 0xe6, 0x2e, 0x77, 0x29, 0x57, 0xee, 0xf3, 0x0a, 0xb9,
0xcc, 0x33, 0xa4, 0xa6, 0x67, 0xf6, 0x04, 0x80, 0x96, 0x5c, 0xe5, 0xdc, 0xcd, 0x74, 0xf7, 0x9c,
0x7a, 0xbe, 0xfe, 0xba, 0x67, 0x17, 0xee, 0x47, 0xce, 0xd5, 0x5e, 0xe8, 0xc5, 0x73, 0xd7, 0xdf,
0x0b, 0x67, 0x7b, 0x33, 0x6a, 0x5f, 0x31, 0xdf, 0x19, 0x87, 0x3c, 0x10, 0x01, 0x29, 0x87, 0xb3,
0xc1, 0xc3, 0x79, 0x10, 0xcc, 0x3d, 0xb6, 0x87, 0x92, 0x59, 0x7c, 0xb1, 0x27, 0xdc, 0x05, 0x8b,
0x04, 0x5d, 0x84, 0xca, 0x68, 0x30, 0x90, 0x33, 0x78, 0xc1, 0xdc, 0xb5, 0xa9, 0xb7, 0xe7, 0x3a,
0xcc, 0x17, 0xae, 0x58, 0x6a, 0x9d, 0x91, 0xd7, 0xa9, 0x55, 0x94, 0xc6, 0xac, 0x43, 0xf5, 0x68,
0x11, 0x8a, 0xa5, 0x39, 0x84, 0xda, 0xe7, 0x8c, 0x3a, 0x8c, 0x93, 0xbb, 0x50, 0xbb, 0xc4, 0x96,
0x51, 0x1a, 0x56, 0x46, 0x4d, 0x4b, 0xf7, 0xcc, 0x3f, 0x00, 0x9c, 0xc9, 0x31, 0x47, 0x9c, 0x07,
0x9c, 0xdc, 0x83, 0x06, 0xe3, 0x7c, 0x2a, 0x96, 0x21, 0x33, 0x4a, 0xc3, 0xd2, 0xa8, 0x63, 0xd5,
0x19, 0xe7, 0x93, 0x65, 0xc8, 0xc8, 0xff, 0x81, 0x6c, 0x4e, 0x17, 0xd1, 0xdc, 0x28, 0x0f, 0x4b,
0x72, 0x06, 0xc6, 0xf9, 0x69, 0x34, 0x4f, 0xc6, 0xd8, 0x81, 0xc3, 0x8c, 0xca, 0xb0, 0x34, 0xaa,
0xe0, 0x98, 0xc3, 0xc0, 0x61, 0xe6, 0x5f, 0x4a, 0x50, 0x3d, 0xa3, 0xe2, 0x32, 0x22, 0x04, 0xb6,
0x78, 0x10, 0x08, 0xbd, 0x38, 0xb6, 0xc9, 0x08, 0x7a, 0xb1, 0x4f, 0x63, 0x71, 0x29, 0x4f, 0x65,
0x53, 0xc1, 0x1c, 0xa3, 0x8c, 0xea, 0x55, 0x31, 0x79, 0x13, 0x3a, 0x5e, 0x60, 0x53, 0x6f, 0x1a,
0x89, 0x80, 0xd3, 0xb9, 0x5c, 0x47, 0xda, 0xb5, 0x51, 0x78, 0xae, 0x64, 0x64, 0x17, 0xfa, 0x11,
0xa3, 0xde, 0xf4, 0x05, 0xa7, 0x61, 0x6a, 0xb8, 0xa5, 0x26, 0x94, 0x8a, 0x6f, 0x38, 0x0d, 0xb5,
0xad, 0xf9, 0xf7, 0x1a, 0xd4, 0x2d, 0xf6, 0xa7, 0x98, 0x45, 0x82, 0x74, 0xa1, 0xec, 0x3a, 0x78,
0xda, 0xa6, 0x55, 0x76, 0x1d, 0x32, 0x06, 0x62, 0xb1, 0xd0, 0x93, 0x4b, 0xbb, 0x81, 0x7f, 0xe8,
0xc5, 0x91, 0x60, 0x5c, 0x9f, 0x79, 0x83, 0x86, 0x3c, 0x80, 0x66, 0x10, 0x32, 0x8e, 0x32, 0x74,
0x40, 0xd3, 0xca, 0x04, 0xf2, 0xe0, 0x21, 0x15, 0x97, 0xc6, 0x16, 0x2a, 0xb0, 0x2d, 0x65, 0x0e,
0x15, 0xd4, 0xa8, 0x2a, 0x99, 0x6c, 0x13, 0x13, 0x6a, 0x11, 0xb3, 0x39, 0x13, 0x46, 0x6d, 0x58,
0x1a, 0xb5, 0xf6, 0x61, 0x1c, 0xce, 0xc6, 0xe7, 0x28, 0xb1, 0xb4, 0x86, 0x3c, 0x80, 0x2d, 0xe9,
0x17, 0xa3, 0x8e, 0x16, 0x0d, 0x69, 0x71, 0x10, 0x8b, 0x4b, 0x0b, 0xa5, 0x64, 0x1f, 0xea, 0xea,
0x4e, 0x23, 0xa3, 0x31, 0xac, 0x8c, 0x5a, 0xfb, 0x86, 0x34, 0xd0, 0xa7, 0x1c, 0x2b, 0x18, 0x44,
0x47, 0xbe, 0xe0, 0x4b, 0x2b, 0x31, 0x24, 0x6f, 0x40, 0xdb, 0xf6, 0x5c, 0xe6, 0x8b, 0xa9, 0x08,
0xae, 0x98, 0x6f, 0x34, 0x71, 0x47, 0x2d, 0x25, 0x9b, 0x48, 0x11, 0xd9, 0x87, 0xd7, 0xf2, 0x26,
0x53, 0x6a, 0xdb, 0x2c, 0x8a, 0x02, 0x6e, 0x00, 0xda, 0xde, 0xc9, 0xd9, 0x1e, 0x68, 0x95, 0x9c,
0xd6, 0x71, 0xa3, 0xd0, 0xa3, 0xcb, 0xa9, 0x4f, 0x17, 0xcc, 0x68, 0xa9, 0x69, 0xb5, 0xec, 0x4b,
0xba, 0x60, 0xe4, 0x21, 0xb4, 0x16, 0x41, 0xec, 0x8b, 0x69, 0x18, 0xb8, 0xbe, 0x30, 0xda, 0x68,
0x01, 0x28, 0x3a, 0x93, 0x12, 0xf2, 0x3a, 0xa8, 0x9e, 0x02, 0x63, 0x47, 0xf9, 0x15, 0x25, 0x08,
0xc7, 0x47, 0xd0, 0x55, 0xea, 0x74, 0x3f, 0x5d, 0x34, 0xe9, 0xa0, 0x34, 0xdd, 0xc9, 0x7b, 0xd0,
0x44, 0x3c, 0xb8, 0xfe, 0x45, 0x60, 0xf4, 0xd0, 0x6f, 0x77, 0x72, 0x6e, 0x91, 0x98, 0x38, 0xf6,
0x2f, 0x02, 0xab, 0xf1, 0x42, 0xb7, 0xc8, 0xc7, 0x70, 0xbf, 0x70, 0x5e, 0xce, 0x16, 0xd4, 0xf5,
0x5d, 0x7f, 0x3e, 0x8d, 0x23, 0x16, 0x19, 0xdb, 0x88, 0x70, 0x23, 0x77, 0x6a, 0x2b, 0x31, 0xf8,
0x3a, 0x62, 0x11, 0xb9, 0x0f, 0x4d, 0x15, 0xa4, 0x53, 0xd7, 0x31, 0xfa, 0xb8, 0xa5, 0x86, 0x12,
0x1c, 0x3b, 0xe4, 0x2d, 0xe8, 0x85, 0x81, 0xe7, 0xda, 0xcb, 0x69, 0x70, 0xcd, 0x38, 0x77, 0x1d,
0x66, 0x90, 0x61, 0x69, 0xd4, 0xb0, 0xba, 0x4a, 0xfc, 0x95, 0x96, 0x6e, 0x0a, 0x8d, 0x3b, 0x68,
0xb8, 0x16, 0x1a, 0x63, 0x00, 0x3b, 0xf0, 0x7d, 0x66, 0x23, 0xfc, 0x76, 0xf0, 0x84, 0x5d, 0x79,
0xc2, 0xc3, 0x54, 0x6a, 0xe5, 0x2c, 0x06, 0x9f, 0x41, 0x3b, 0x0f, 0x05, 0xb2, 0x0d, 0x95, 0x2b,
0xb6, 0xd4, 0xf0, 0x97, 0x4d, 0x32, 0x84, 0xea, 0x35, 0xf5, 0x62, 0x86, 0x90, 0xd7, 0x40, 0x54,
0x43, 0x2c, 0xa5, 0xf8, 0x45, 0xf9, 0x69, 0xc9, 0xfc, 0x77, 0x15, 0xb6, 0x24, 0xf8, 0xc8, 0x07,
0xd0, 0xf1, 0x18, 0x8d, 0xd8, 0x34, 0x08, 0xe5, 0x02, 0x11, 0x4e, 0xd5, 0xda, 0xdf, 0x96, 0xc3,
0x4e, 0xa4, 0xe2, 0x2b, 0x25, 0xb7, 0xda, 0x5e, 0xae, 0x27, 0x43, 0xda, 0xf5, 0x05, 0xe3, 0x3e,
0xf5, 0xa6, 0x18, 0x0c, 0x2a, 0xc0, 0xda, 0x89, 0xf0, 0x99, 0x0c, 0x8a, 0x55, 0x1c, 0x55, 0xd6,
0x71, 0x34, 0x80, 0x06, 0xfa, 0xce, 0x65, 0x91, 0x0e, 0xf6, 0xb4, 0x4f, 0xf6, 0xa1, 0xb1, 0x60,
0x82, 0xea, 0x58, 0x93, 0x21, 0x71, 0x37, 0x89, 0x99, 0xf1, 0xa9, 0x56, 0xa8, 0x80, 0x48, 0xed,
0xd6, 0x22, 0xa2, 0xb6, 0x1e, 0x11, 0x03, 0x68, 0xa4, 0xa0, 0xab, 0xab, 0x1b, 0x4e, 0xfa, 0x92,
0x66, 0x43, 0xc6, 0xdd, 0xc0, 0x31, 0x1a, 0x08, 0x14, 0xdd, 0x93, 0x24, 0xe9, 0xc7, 0x0b, 0x05,
0xa1, 0xa6, 0x22, 0x49, 0x3f, 0x5e, 0xac, 0x23, 0x06, 0x56, 0x10, 0xf3, 0x13, 0xa8, 0x52, 0xcf,
0xa5, 0x11, 0x86, 0x90, 0xbc, 0x59, 0xcd, 0xf7, 0xe3, 0x03, 0x29, 0xb5, 0x94, 0x92, 0xbc, 0x0f,
0x9d, 0x39, 0x0f, 0xe2, 0x70, 0x8a, 0x5d, 0x16, 0x19, 0x6d, 0x3c, 0xed, 0xaa, 0x75, 0x1b, 0x8d,
0x0e, 0x94, 0x8d, 0x8c, 0xc0, 0x59, 0x10, 0xfb, 0xce, 0xd4, 0x76, 0x1d, 0x1e, 0x19, 0x1d, 0x74,
0x1e, 0xa0, 0xe8, 0x50, 0x4a, 0x64, 0x88, 0xa9, 0x10, 0x48, 0x1d, 0xdc, 0x45, 0x9b, 0x0e, 0x4a,
0xcf, 0x12, 0x2f, 0xff, 0x14, 0xfa, 0x49, 0x62, 0xca, 0x2c, 0x7b, 0x68, 0xb9, 0x9d, 0x28, 0x52,
0xe3, 0x11, 0x6c, 0xb3, 0x1b, 0x49, 0xa1, 0xae, 0x98, 0x2e, 0xe8, 0xcd, 0x54, 0x08, 0x4f, 0x87,
0x54, 0x37, 0x91, 0x9f, 0xd2, 0x9b, 0x89, 0xf0, 0x64, 0xfc, 0xab, 0xd5, 0x31, 0xfe, 0xfb, 0x98,
0x8c, 0x9a, 0x28, 0xc1, 0xf8, 0xdf, 0x85, 0xbe, 0x1f, 0x4c, 0x1d, 0x76, 0x41, 0x63, 0x4f, 0xa8,
0x75, 0x97, 0x3a, 0x98, 0x7a, 0x7e, 0xf0, 0x4c, 0xc9, 0x71, 0xd9, 0xe5, 0xe0, 0x97, 0xd0, 0x29,
0x5c, 0xf7, 0x06, 0xd0, 0xef, 0xe4, 0x41, 0xdf, 0xcc, 0x03, 0xfd, 0x9f, 0x5b, 0x00, 0x78, 0xef,
0x6a, 0xe8, 0x6a, 0xb6, 0xc8, 0x83, 0xa1, 0xbc, 0x01, 0x0c, 0x94, 0x33, 0x5f, 0x68, 0xe0, 0xea,
0xde, 0xf7, 0x62, 0x36, 0xc9, 0x17, 0xd5, 0x5c, 0xbe, 0x78, 0x07, 0xb6, 0x24, 0x3e, 0x8d, 0x5a,
0x46, 0xeb, 0xd9, 0x8e, 0x10, 0xc9, 0x0a, 0xc5, 0x68, 0xb5, 0x16, 0x34, 0xf5, 0xf5, 0xa0, 0xc9,
0xa3, 0xb1, 0x51, 0x44, 0xe3, 0x9b, 0xd0, 0xb1, 0x39, 0xc3, 0xdc, 0x35, 0x95, 0xc5, 0x88, 0x46,
0x6b, 0x3b, 0x11, 0x4e, 0xdc, 0x05, 0x93, 0xfe, 0x93, 0x17, 0x07, 0xa8, 0x92, 0xcd, 0x8d, 0xf7,
0xda, 0xda, 0x78, 0xaf, 0x58, 0x09, 0x78, 0x4c, 0x33, 0x3e, 0xb6, 0x73, 0x51, 0xd3, 0x29, 0x44,
0x4d, 0x21, 0x34, 0xba, 0x2b, 0xa1, 0xb1, 0x82, 0xdf, 0xde, 0x1a, 0x7e, 0xdf, 0x80, 0xb6, 0x74,
0x40, 0x14, 0x52, 0x9b, 0xc9, 0x09, 0xb6, 0x95, 0x23, 0x52, 0xd9, 0xb1, 0x83, 0xd1, 0x1e, 0xcf,
0x66, 0xcb, 0xcb, 0xc0, 0x63, 0x19, 0x61, 0xb7, 0x52, 0xd9, 0xb1, 0x23, 0xf7, 0x8b, 0x08, 0x24,
0x88, 0x40, 0x6c, 0x0f, 0x3e, 0x84, 0x66, 0xea, 0xf5, 0x1f, 0x04, 0xa6, 0xbf, 0x96, 0xa0, 0x9d,
0x27, 0x45, 0x39, 0x78, 0x32, 0x39, 0xc1, 0xc1, 0x15, 0x4b, 0x36, 0x65, 0x39, 0xc1, 0x99, 0xcf,
0x5e, 0xd0, 0x99, 0xa7, 0x26, 0x68, 0x58, 0x99, 0x40, 0x6a, 0x5d, 0xdf, 0xe6, 0x6c, 0x91, 0xa0,
0xaa, 0x62, 0x65, 0x02, 0xf2, 0x11, 0x80, 0x1b, 0x45, 0x31, 0x53, 0x37, 0xb7, 0x85, 0x94, 0x31,
0x18, 0xab, 0x1a, 0x73, 0x9c, 0xd4, 0x98, 0xe3, 0x49, 0x52, 0x63, 0x5a, 0x4d, 0xb4, 0xc6, 0x2b,
0xbd, 0x0b, 0x35, 0x79, 0x41, 0x93, 0x13, 0x44, 0x5e, 0xc5, 0xd2, 0x3d, 0xf3, 0xcf, 0x50, 0x53,
0x55, 0xc8, 0xff, 0x94, 0xe8, 0xef, 0x41, 0x43, 0xcd, 0xed, 0x3a, 0x3a, 0x56, 0xea, 0xd8, 0x3f,
0x76, 0xcc, 0xef, 0xca, 0xd0, 0xb0, 0x58, 0x14, 0x06, 0x7e, 0xc4, 0x72, 0x55, 0x52, 0xe9, 0xa5,
0x55, 0x52, 0x79, 0x63, 0x95, 0x94, 0xd4, 0x5e, 0x95, 0x5c, 0xed, 0x35, 0x80, 0x06, 0x67, 0x8e,
0xcb, 0x99, 0x2d, 0x74, 0x9d, 0x96, 0xf6, 0xa5, 0xee, 0x05, 0xe5, 0x32, 0xbd, 0x47, 0x98, 0x43,
0x9a, 0x56, 0xda, 0x27, 0x4f, 0xf2, 0xc5, 0x85, 0x2a, 0xdb, 0x76, 0x54, 0x71, 0xa1, 0xb6, 0xbb,
0xa1, 0xba, 0x78, 0x3f, 0x2b, 0xd2, 0xea, 0x18, 0xcd, 0xf7, 0xf2, 0x03, 0x36, 0x57, 0x69, 0x3f,
0x5a, 0xce, 0xfe, 0xae, 0x0c, 0xdb, 0xab, 0x7b, 0xdb, 0x80, 0xc0, 0x1d, 0xa8, 0xaa, 0xdc, 0xa7,
0xe1, 0x2b, 0xd6, 0xb2, 0x5e, 0x65, 0x85, 0xe8, 0x7e, 0xb5, 0x4a, 0x1a, 0x2f, 0x87, 0x5e, 0x91,
0x50, 0xde, 0x86, 0x6d, 0xe9, 0xa2, 0x90, 0x39, 0x59, 0x3d, 0xa7, 0x18, 0xb0, 0xa7, 0xe5, 0x69,
0x45, 0xb7, 0x0b, 0xfd, 0xc4, 0x34, 0xe3, 0x86, 0x5a, 0xc1, 0xf6, 0x28, 0xa1, 0x88, 0xbb, 0x50,
0xbb, 0x08, 0xf8, 0x82, 0x0a, 0x4d, 0x82, 0xba, 0x57, 0x20, 0x39, 0x64, 0xdb, 0x86, 0xc2, 0x64,
0x22, 0x94, 0x6f, 0x16, 0x49, 0x3e, 0xe9, 0x7b, 0x02, 0x59, 0xb0, 0x61, 0x35, 0x92, 0x77, 0x84,
0xf9, 0x5b, 0xe8, 0xad, 0x94, 0x90, 0x1b, 0x1c, 0x99, 0x2d, 0x5f, 0x2e, 0x2c, 0x5f, 0x98, 0xb9,
0xb2, 0x32, 0xf3, 0xef, 0xa0, 0xff, 0x39, 0xf5, 0x1d, 0x8f, 0xe9, 0xf9, 0x0f, 0xf8, 0x3c, 0x92,
0xc9, 0x50, 0xbf, 0x68, 0xa6, 0x3a, 0xfb, 0x74, 0xac, 0xa6, 0x96, 0x1c, 0x3b, 0xe4, 0x11, 0xd4,
0xb9, 0xb2, 0xd6, 0x00, 0x68, 0xe5, 0x6a, 0x5c, 0x2b, 0xd1, 0x99, 0xdf, 0x02, 0x29, 0x4c, 0x2d,
0x1f, 0x33, 0x4b, 0x32, 0x92, 0xe8, 0x57, 0xa0, 0xd0, 0x51, 0xd5, 0xce, 0x63, 0xd2, 0x4a, 0xb5,
0x64, 0x08, 0x15, 0xc6, 0xb9, 0x5e, 0x02, 0x8b, 0xcc, 0xec, 0xe9, 0x68, 0x49, 0x95, 0xf9, 0x33,
0xe8, 0x9f, 0x87, 0xcc, 0x76, 0xa9, 0x87, 0xcf, 0x3e, 0xb5, 0xc0, 0x43, 0xa8, 0x4a, 0x27, 0x27,
0x84, 0xd1, 0xc4, 0x81, 0xa8, 0x56, 0x72, 0xf3, 0x5b, 0x30, 0xd4, 0xbe, 0x8e, 0x6e, 0xdc, 0x48,
0x30, 0xdf, 0x66, 0x87, 0x97, 0xcc, 0xbe, 0xfa, 0x11, 0x4f, 0x7e, 0x0d, 0xf7, 0x36, 0xad, 0x90,
0xec, 0xaf, 0x65, 0xcb, 0xde, 0xf4, 0x42, 0xe6, 0x0e, 0x5c, 0xa3, 0x61, 0x01, 0x8a, 0x3e, 0x93,
0x12, 0x79, 0x8f, 0x4c, 0x8e, 0x8b, 0x34, 0x1f, 0xeb, 0x5e, 0xe2, 0x8f, 0xca, 0xed, 0xfe, 0xf8,
0x5b, 0x09, 0x9a, 0xe7, 0x4c, 0xc4, 0x21, 0x9e, 0xe5, 0x3e, 0x34, 0x67, 0x3c, 0xb8, 0x62, 0x3c,
0x3b, 0x4a, 0x43, 0x09, 0x8e, 0x1d, 0xf2, 0x04, 0x6a, 0x87, 0x81, 0x7f, 0xe1, 0xce, 0xf1, 0x11,
0xac, 0x89, 0x21, 0x1d, 0x3b, 0x56, 0x3a, 0x45, 0x0c, 0xda, 0x90, 0x0c, 0xa1, 0xa5, 0x3f, 0x29,
0x7c, 0xfd, 0xf5, 0xf1, 0xb3, 0xa4, 0x3a, 0xce, 0x89, 0x06, 0x1f, 0x41, 0x2b, 0x37, 0xf0, 0x07,
0xa5, 0xaa, 0xff, 0x07, 0xc0, 0xd5, 0x95, 0x8f, 0xb6, 0xd5, 0x51, 0xf5, 0x48, 0x79, 0xb4, 0x87,
0xd0, 0x94, 0x85, 0x98, 0x52, 0x27, 0x49, 0xb2, 0x94, 0x25, 0x49, 0xf3, 0x11, 0xf4, 0x8f, 0xfd,
0x6b, 0xea, 0xb9, 0x0e, 0x15, 0xec, 0x0b, 0xb6, 0x44, 0x17, 0xac, 0xed, 0xc0, 0x3c, 0x87, 0xb6,
0x7e, 0x95, 0xbf, 0xd2, 0x1e, 0xdb, 0x7a, 0x8f, 0xdf, 0x1f, 0x44, 0x6f, 0x43, 0x4f, 0x4f, 0x7a,
0xe2, 0xea, 0x10, 0x92, 0x35, 0x06, 0x67, 0x17, 0xee, 0x8d, 0x9e, 0x5a, 0xf7, 0xcc, 0xa7, 0xb0,
0x9d, 0x33, 0x4d, 0x8f, 0x73, 0xc5, 0x96, 0x51, 0xf2, 0xb5, 0x42, 0xb6, 0x13, 0x0f, 0x94, 0x33,
0x0f, 0x98, 0xd0, 0xd5, 0x23, 0x9f, 0x33, 0x71, 0xcb, 0xe9, 0xbe, 0x48, 0x37, 0xf2, 0x9c, 0xe9,
0xc9, 0x1f, 0x43, 0x95, 0xc9, 0x93, 0xe6, 0xf3, 0x67, 0xde, 0x03, 0x96, 0x52, 0x6f, 0x58, 0xf0,
0x69, 0xba, 0xe0, 0x59, 0xac, 0x16, 0x7c, 0xc5, 0xb9, 0xcc, 0x37, 0xd3, 0x6d, 0x9c, 0xc5, 0xe2,
0xb6, 0x1b, 0x7d, 0x04, 0x7d, 0x6d, 0xf4, 0x8c, 0x79, 0x4c, 0xb0, 0x5b, 0x8e, 0xf4, 0x18, 0x48,
0xc1, 0xec, 0xb6, 0xe9, 0x1e, 0x40, 0x63, 0x32, 0x39, 0x49, 0xb5, 0x45, 0x6e, 0x34, 0x3f, 0x86,
0xfe, 0x79, 0xec, 0x04, 0x67, 0xdc, 0xbd, 0x76, 0x3d, 0x36, 0x57, 0x8b, 0x25, 0xc5, 0x6f, 0x29,
0x57, 0xfc, 0x6e, 0xcc, 0x46, 0xe6, 0x08, 0x48, 0x61, 0x78, 0x7a, 0x6f, 0x51, 0xec, 0x04, 0x3a,
0x84, 0xb1, 0x6d, 0x8e, 0xa0, 0x3d, 0xa1, 0xb2, 0xd8, 0x70, 0x94, 0x8d, 0x01, 0x75, 0xa1, 0xfa,
0xda, 0x2c, 0xe9, 0x9a, 0xfb, 0xb0, 0x73, 0x48, 0xed, 0x4b, 0xd7, 0x9f, 0x3f, 0x73, 0x23, 0x59,
0x6d, 0xe9, 0x11, 0x03, 0x68, 0x38, 0x5a, 0xa0, 0x87, 0xa4, 0x7d, 0xf3, 0x5d, 0x78, 0x2d, 0xf7,
0x49, 0xe8, 0x5c, 0xd0, 0xc4, 0x1f, 0x3b, 0x50, 0x8d, 0x64, 0x0f, 0x47, 0x54, 0x2d, 0xd5, 0x31,
0xbf, 0x84, 0x9d, 0x7c, 0x02, 0x96, 0xb5, 0x4f, 0x72, 0x70, 0xac, 0x4a, 0x4a, 0xb9, 0xaa, 0x44,
0xfb, 0xac, 0x9c, 0xe5, 0x93, 0x6d, 0xa8, 0xfc, 0xfa, 0x9b, 0x89, 0x06, 0xbb, 0x6c, 0x9a, 0x7f,
0x94, 0xcb, 0x17, 0xe7, 0x53, 0xcb, 0x17, 0x4a, 0x93, 0xd2, 0x2b, 0x95, 0x26, 0xeb, 0x78, 0x7b,
0x17, 0xfa, 0xa7, 0x5e, 0x60, 0x5f, 0x1d, 0xf9, 0x39, 0x6f, 0x18, 0x50, 0x67, 0x7e, 0xde, 0x19,
0x49, 0xd7, 0x7c, 0x0b, 0x7a, 0x27, 0x81, 0x4d, 0xbd, 0xd3, 0x20, 0xf6, 0x45, 0xea, 0x05, 0xfc,
0x46, 0xa7, 0x4d, 0x55, 0xc7, 0x7c, 0x17, 0xba, 0x3a, 0x45, 0xfb, 0x17, 0x41, 0xc2, 0x8c, 0x59,
0x32, 0x2f, 0x15, 0x0b, 0x7d, 0xf3, 0x04, 0x7a, 0x99, 0xb9, 0x9a, 0xf7, 0x2d, 0xa8, 0x29, 0xb5,
0x3e, 0x5b, 0x2f, 0x7d, 0xe9, 0x2a, 0x4b, 0x4b, 0xab, 0x37, 0x1c, 0x6a, 0x01, 0xdd, 0x33, 0xfc,
0x56, 0x7a, 0xe4, 0x5f, 0xab, 0xc9, 0x8e, 0x81, 0xa8, 0xaf, 0xa7, 0x53, 0xe6, 0x5f, 0xbb, 0x3c,
0xf0, 0xb1, 0xb8, 0x2e, 0xe9, 0x12, 0x26, 0x99, 0x38, 0x1d, 0x94, 0x58, 0x58, 0xfd, 0x70, 0x55,
0xb4, 0xd1, 0x87, 0x90, 0x7d, 0x89, 0x91, 0xa9, 0x86, 0xb3, 0x45, 0x20, 0xd8, 0x94, 0x3a, 0x4e,
0x12, 0x2d, 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x53, 0x86, 0xfa, 0xa7, 0x8a, 0xc0, 0xc9,
0x27, 0xd0, 0x29, 0xa4, 0x6b, 0xf2, 0x1a, 0x96, 0x75, 0xab, 0xc5, 0xc1, 0xe0, 0xee, 0x9a, 0x58,
0x9d, 0xeb, 0x3d, 0x68, 0xe7, 0x93, 0x31, 0xc1, 0xc4, 0x8b, 0xdf, 0x85, 0x07, 0x38, 0xd3, 0x7a,
0xa6, 0x3e, 0x87, 0x9d, 0x4d, 0x69, 0x92, 0x3c, 0xc8, 0x56, 0x58, 0x4f, 0xd1, 0x83, 0xd7, 0x6f,
0xd3, 0x26, 0xe9, 0xb5, 0x7e, 0xe8, 0x31, 0xea, 0xc7, 0x61, 0x7e, 0x07, 0x59, 0x93, 0x3c, 0x81,
0x4e, 0x21, 0x51, 0xa8, 0x73, 0xae, 0xe5, 0x8e, 0xfc, 0x90, 0xc7, 0x50, 0xc5, 0xe4, 0x44, 0x3a,
0x85, 0x2c, 0x39, 0xe8, 0xa6, 0x5d, 0xb5, 0xf6, 0x10, 0xb6, 0xf0, 0x6b, 0x41, 0x6e, 0x61, 0x1c,
0x91, 0x66, 0xae, 0xfd, 0x7f, 0x95, 0xa0, 0x9e, 0x7c, 0x41, 0x7e, 0x02, 0x5b, 0x32, 0x07, 0x90,
0x3b, 0x39, 0x1a, 0x4d, 0xf2, 0xc7, 0x60, 0x67, 0x45, 0xa8, 0x16, 0x18, 0x43, 0xe5, 0x39, 0x13,
0x84, 0xe4, 0x94, 0x3a, 0x19, 0x0c, 0xee, 0x14, 0x65, 0xa9, 0xfd, 0x59, 0x5c, 0xb4, 0xd7, 0x5c,
0x5e, 0xb0, 0x4f, 0x59, 0xfa, 0x43, 0xa8, 0x29, 0x96, 0x55, 0x4e, 0x59, 0xe3, 0x67, 0x75, 0xf9,
0xeb, 0x7c, 0xbc, 0xff, 0x8f, 0x2d, 0x80, 0xf3, 0x65, 0x24, 0xd8, 0xe2, 0x37, 0x2e, 0x7b, 0x41,
0x76, 0xa1, 0xa7, 0xbf, 0x89, 0xe0, 0x53, 0x4d, 0xb2, 0x49, 0xce, 0x27, 0x58, 0xf0, 0xa5, 0x64,
0xfd, 0x18, 0x5a, 0xa7, 0xf4, 0xe6, 0xe5, 0x76, 0x9f, 0x40, 0xa7, 0xc0, 0xc1, 0x7a, 0x8b, 0xab,
0xac, 0xae, 0xb7, 0xb8, 0xce, 0xd6, 0x8f, 0xa1, 0xae, 0x99, 0x39, 0xbf, 0x06, 0xe6, 0xb0, 0x02,
0x63, 0xff, 0x1c, 0x7a, 0x2b, 0xbc, 0x9c, 0xb7, 0xc7, 0xcf, 0x21, 0x1b, 0x79, 0xfb, 0xa9, 0x7c,
0xed, 0x14, 0xb9, 0x39, 0x3f, 0x50, 0xbf, 0xbc, 0x36, 0x91, 0xf7, 0xf3, 0xe2, 0x3b, 0x09, 0x9f,
0xa8, 0xc6, 0x2a, 0x7d, 0x26, 0xe4, 0x3d, 0xb8, 0xb7, 0x49, 0x93, 0x86, 0x60, 0x9e, 0x41, 0xd7,
0x42, 0x70, 0x9d, 0x5e, 0xdf, 0x01, 0xc8, 0x48, 0x34, 0x6f, 0x8f, 0xf0, 0x58, 0xe5, 0xd7, 0x0f,
0x00, 0x32, 0x6a, 0x54, 0xa8, 0x2a, 0x32, 0xab, 0x1a, 0xb6, 0x4a, 0x9f, 0xbb, 0xd0, 0x4c, 0xe9,
0x2c, 0xbf, 0x06, 0x4e, 0x50, 0x64, 0xc7, 0x4f, 0x77, 0x7f, 0x3f, 0x9a, 0xbb, 0xe2, 0x32, 0x9e,
0x8d, 0xed, 0x60, 0xb1, 0x77, 0x49, 0xa3, 0x4b, 0xd7, 0x0e, 0x78, 0xb8, 0x77, 0x2d, 0xc1, 0xb4,
0x57, 0xf8, 0xc1, 0x35, 0xab, 0xe1, 0x43, 0xef, 0xfd, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xbd,
0xc6, 0x6e, 0xfa, 0xf8, 0x1a, 0x00, 0x00,
// 2556 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x73, 0xe3, 0xc6,
0x11, 0x2e, 0x92, 0xe2, 0xab, 0xf9, 0x9e, 0x95, 0x37, 0x58, 0xee, 0x3a, 0x2b, 0xc3, 0xd9, 0x35,
0xad, 0xd8, 0x94, 0x57, 0x1b, 0xc7, 0xeb, 0xa4, 0xec, 0x94, 0xac, 0x95, 0xd7, 0x8a, 0x25, 0x5b,
0x05, 0xd1, 0x71, 0x5e, 0x55, 0xf4, 0x10, 0x18, 0x51, 0x28, 0x81, 0x00, 0x32, 0x18, 0x68, 0xc5,
0x5c, 0xf2, 0x2f, 0xf2, 0x0f, 0x72, 0xce, 0x35, 0xb7, 0xdc, 0x52, 0xae, 0xdc, 0xf3, 0x17, 0xf2,
0x3b, 0x52, 0xd3, 0x33, 0x78, 0x91, 0x94, 0x1f, 0x55, 0xce, 0x6d, 0xa6, 0xbb, 0xe7, 0xd5, 0xf3,
0xf5, 0xd7, 0x3d, 0x00, 0xdc, 0x8f, 0x9c, 0xab, 0xbd, 0xd0, 0x8b, 0xe7, 0xae, 0xbf, 0x17, 0xce,
0xf6, 0x66, 0xd4, 0xbe, 0x62, 0xbe, 0x33, 0x0e, 0x79, 0x20, 0x02, 0x52, 0x0e, 0x67, 0xc3, 0x87,
0xf3, 0x20, 0x98, 0x7b, 0x6c, 0x0f, 0x25, 0xb3, 0xf8, 0x62, 0x4f, 0xb8, 0x0b, 0x16, 0x09, 0xba,
0x08, 0x95, 0xd1, 0x70, 0x28, 0x67, 0xf0, 0x82, 0xb9, 0x6b, 0x53, 0x6f, 0xcf, 0x75, 0x98, 0x2f,
0x5c, 0xb1, 0xd4, 0x3a, 0x23, 0xaf, 0x53, 0xab, 0x28, 0x8d, 0x59, 0x87, 0xea, 0xd1, 0x22, 0x14,
0x4b, 0x73, 0x07, 0x6a, 0x9f, 0x30, 0xea, 0x30, 0x4e, 0xee, 0x42, 0xed, 0x12, 0x5b, 0x46, 0x69,
0xa7, 0x32, 0x6a, 0x5a, 0xba, 0x67, 0xfe, 0x01, 0xe0, 0x4c, 0x8e, 0x39, 0xe2, 0x3c, 0xe0, 0xe4,
0x1e, 0x34, 0x18, 0xe7, 0x53, 0xb1, 0x0c, 0x99, 0x51, 0xda, 0x29, 0x8d, 0x3a, 0x56, 0x9d, 0x71,
0x3e, 0x59, 0x86, 0x8c, 0xfc, 0x08, 0x64, 0x73, 0xba, 0x88, 0xe6, 0x46, 0x79, 0xa7, 0x24, 0x67,
0x60, 0x9c, 0x9f, 0x46, 0xf3, 0x64, 0x8c, 0x1d, 0x38, 0xcc, 0xa8, 0xec, 0x94, 0x46, 0x15, 0x1c,
0x73, 0x18, 0x38, 0xcc, 0xfc, 0x6b, 0x09, 0xaa, 0x67, 0x54, 0x5c, 0x46, 0x84, 0xc0, 0x16, 0x0f,
0x02, 0xa1, 0x17, 0xc7, 0x36, 0x19, 0x41, 0x2f, 0xf6, 0x69, 0x2c, 0x2e, 0xe5, 0xa9, 0x6c, 0x2a,
0x98, 0x63, 0x94, 0x51, 0xbd, 0x2a, 0x26, 0xaf, 0x43, 0xc7, 0x0b, 0x6c, 0xea, 0x4d, 0x23, 0x11,
0x70, 0x3a, 0x97, 0xeb, 0x48, 0xbb, 0x36, 0x0a, 0xcf, 0x95, 0x8c, 0xec, 0xc2, 0x20, 0x62, 0xd4,
0x9b, 0xbe, 0xe4, 0x34, 0x4c, 0x0d, 0xb7, 0xd4, 0x84, 0x52, 0xf1, 0x25, 0xa7, 0xa1, 0xb6, 0x35,
0xff, 0x59, 0x83, 0xba, 0xc5, 0xfe, 0x14, 0xb3, 0x48, 0x90, 0x2e, 0x94, 0x5d, 0x07, 0x4f, 0xdb,
0xb4, 0xca, 0xae, 0x43, 0xc6, 0x40, 0x2c, 0x16, 0x7a, 0x72, 0x69, 0x37, 0xf0, 0x0f, 0xbd, 0x38,
0x12, 0x8c, 0xeb, 0x33, 0x6f, 0xd0, 0x90, 0x07, 0xd0, 0x0c, 0x42, 0xc6, 0x51, 0x86, 0x0e, 0x68,
0x5a, 0x99, 0x40, 0x1e, 0x3c, 0xa4, 0xe2, 0xd2, 0xd8, 0x42, 0x05, 0xb6, 0xa5, 0xcc, 0xa1, 0x82,
0x1a, 0x55, 0x25, 0x93, 0x6d, 0x62, 0x42, 0x2d, 0x62, 0x36, 0x67, 0xc2, 0xa8, 0xed, 0x94, 0x46,
0xad, 0x7d, 0x18, 0x87, 0xb3, 0xf1, 0x39, 0x4a, 0x2c, 0xad, 0x21, 0x0f, 0x60, 0x4b, 0xfa, 0xc5,
0xa8, 0xa3, 0x45, 0x43, 0x5a, 0x1c, 0xc4, 0xe2, 0xd2, 0x42, 0x29, 0xd9, 0x87, 0xba, 0xba, 0xd3,
0xc8, 0x68, 0xec, 0x54, 0x46, 0xad, 0x7d, 0x43, 0x1a, 0xe8, 0x53, 0x8e, 0x15, 0x0c, 0xa2, 0x23,
0x5f, 0xf0, 0xa5, 0x95, 0x18, 0x92, 0xd7, 0xa0, 0x6d, 0x7b, 0x2e, 0xf3, 0xc5, 0x54, 0x04, 0x57,
0xcc, 0x37, 0x9a, 0xb8, 0xa3, 0x96, 0x92, 0x4d, 0xa4, 0x88, 0xec, 0xc3, 0x2b, 0x79, 0x93, 0x29,
0xb5, 0x6d, 0x16, 0x45, 0x01, 0x37, 0x00, 0x6d, 0xef, 0xe4, 0x6c, 0x0f, 0xb4, 0x4a, 0x4e, 0xeb,
0xb8, 0x51, 0xe8, 0xd1, 0xe5, 0xd4, 0xa7, 0x0b, 0x66, 0xb4, 0xd4, 0xb4, 0x5a, 0xf6, 0x19, 0x5d,
0x30, 0xf2, 0x10, 0x5a, 0x8b, 0x20, 0xf6, 0xc5, 0x34, 0x0c, 0x5c, 0x5f, 0x18, 0x6d, 0xb4, 0x00,
0x14, 0x9d, 0x49, 0x09, 0x79, 0x15, 0x54, 0x4f, 0x81, 0xb1, 0xa3, 0xfc, 0x8a, 0x12, 0x84, 0xe3,
0x23, 0xe8, 0x2a, 0x75, 0xba, 0x9f, 0x2e, 0x9a, 0x74, 0x50, 0x9a, 0xee, 0xe4, 0x1d, 0x68, 0x22,
0x1e, 0x5c, 0xff, 0x22, 0x30, 0x7a, 0xe8, 0xb7, 0x3b, 0x39, 0xb7, 0x48, 0x4c, 0x1c, 0xfb, 0x17,
0x81, 0xd5, 0x78, 0xa9, 0x5b, 0xe4, 0x03, 0xb8, 0x5f, 0x38, 0x2f, 0x67, 0x0b, 0xea, 0xfa, 0xae,
0x3f, 0x9f, 0xc6, 0x11, 0x8b, 0x8c, 0x3e, 0x22, 0xdc, 0xc8, 0x9d, 0xda, 0x4a, 0x0c, 0xbe, 0x88,
0x58, 0x44, 0xee, 0x43, 0x53, 0x05, 0xe9, 0xd4, 0x75, 0x8c, 0x01, 0x6e, 0xa9, 0xa1, 0x04, 0xc7,
0x0e, 0x79, 0x03, 0x7a, 0x61, 0xe0, 0xb9, 0xf6, 0x72, 0x1a, 0x5c, 0x33, 0xce, 0x5d, 0x87, 0x19,
0x64, 0xa7, 0x34, 0x6a, 0x58, 0x5d, 0x25, 0xfe, 0x5c, 0x4b, 0x37, 0x85, 0xc6, 0x1d, 0x34, 0x5c,
0x0b, 0x8d, 0x31, 0x80, 0x1d, 0xf8, 0x3e, 0xb3, 0x11, 0x7e, 0xdb, 0x78, 0xc2, 0xae, 0x3c, 0xe1,
0x61, 0x2a, 0xb5, 0x72, 0x16, 0xc3, 0x8f, 0xa1, 0x9d, 0x87, 0x02, 0xe9, 0x43, 0xe5, 0x8a, 0x2d,
0x35, 0xfc, 0x65, 0x93, 0xec, 0x40, 0xf5, 0x9a, 0x7a, 0x31, 0x43, 0xc8, 0x6b, 0x20, 0xaa, 0x21,
0x96, 0x52, 0xfc, 0xa2, 0xfc, 0xac, 0x64, 0xfe, 0xb7, 0x0a, 0x5b, 0x12, 0x7c, 0xe4, 0x5d, 0xe8,
0x78, 0x8c, 0x46, 0x6c, 0x1a, 0x84, 0x72, 0x81, 0x08, 0xa7, 0x6a, 0xed, 0xf7, 0xe5, 0xb0, 0x13,
0xa9, 0xf8, 0x5c, 0xc9, 0xad, 0xb6, 0x97, 0xeb, 0xc9, 0x90, 0x76, 0x7d, 0xc1, 0xb8, 0x4f, 0xbd,
0x29, 0x06, 0x83, 0x0a, 0xb0, 0x76, 0x22, 0x7c, 0x2e, 0x83, 0x62, 0x15, 0x47, 0x95, 0x75, 0x1c,
0x0d, 0xa1, 0x81, 0xbe, 0x73, 0x59, 0xa4, 0x83, 0x3d, 0xed, 0x93, 0x7d, 0x68, 0x2c, 0x98, 0xa0,
0x3a, 0xd6, 0x64, 0x48, 0xdc, 0x4d, 0x62, 0x66, 0x7c, 0xaa, 0x15, 0x2a, 0x20, 0x52, 0xbb, 0xb5,
0x88, 0xa8, 0xad, 0x47, 0xc4, 0x10, 0x1a, 0x29, 0xe8, 0xea, 0xea, 0x86, 0x93, 0xbe, 0xa4, 0xd9,
0x90, 0x71, 0x37, 0x70, 0x8c, 0x06, 0x02, 0x45, 0xf7, 0x24, 0x49, 0xfa, 0xf1, 0x42, 0x41, 0xa8,
0xa9, 0x48, 0xd2, 0x8f, 0x17, 0xeb, 0x88, 0x81, 0x15, 0xc4, 0xfc, 0x04, 0xaa, 0xd4, 0x73, 0x69,
0x84, 0x21, 0x24, 0x6f, 0x56, 0xf3, 0xfd, 0xf8, 0x40, 0x4a, 0x2d, 0xa5, 0x24, 0x4f, 0xa1, 0x33,
0xe7, 0x41, 0x1c, 0x4e, 0xb1, 0xcb, 0x22, 0xa3, 0x8d, 0xa7, 0x5d, 0xb5, 0x6e, 0xa3, 0xd1, 0x81,
0xb2, 0x91, 0x11, 0x38, 0x0b, 0x62, 0xdf, 0x99, 0xda, 0xae, 0xc3, 0x23, 0xa3, 0x83, 0xce, 0x03,
0x14, 0x1d, 0x4a, 0x89, 0x0c, 0x31, 0x15, 0x02, 0xa9, 0x83, 0xbb, 0x68, 0xd3, 0x41, 0xe9, 0x59,
0xe2, 0xe5, 0x9f, 0xc2, 0x20, 0x49, 0x4c, 0x99, 0x65, 0x0f, 0x2d, 0xfb, 0x89, 0x22, 0x35, 0x1e,
0x41, 0x9f, 0xdd, 0x48, 0x0a, 0x75, 0xc5, 0x74, 0x41, 0x6f, 0xa6, 0x42, 0x78, 0x3a, 0xa4, 0xba,
0x89, 0xfc, 0x94, 0xde, 0x4c, 0x84, 0x27, 0xe3, 0x5f, 0xad, 0x8e, 0xf1, 0x3f, 0xc0, 0x64, 0xd4,
0x44, 0x09, 0xc6, 0xff, 0x2e, 0x0c, 0xfc, 0x60, 0xea, 0xb0, 0x0b, 0x1a, 0x7b, 0x42, 0xad, 0xbb,
0xd4, 0xc1, 0xd4, 0xf3, 0x83, 0xe7, 0x4a, 0x8e, 0xcb, 0x2e, 0x87, 0xbf, 0x84, 0x4e, 0xe1, 0xba,
0x37, 0x80, 0x7e, 0x3b, 0x0f, 0xfa, 0x66, 0x1e, 0xe8, 0xff, 0xde, 0x02, 0xc0, 0x7b, 0x57, 0x43,
0x57, 0xb3, 0x45, 0x1e, 0x0c, 0xe5, 0x0d, 0x60, 0xa0, 0x9c, 0xf9, 0x42, 0x03, 0x57, 0xf7, 0xbe,
0x11, 0xb3, 0x49, 0xbe, 0xa8, 0xe6, 0xf2, 0xc5, 0x5b, 0xb0, 0x25, 0xf1, 0x69, 0xd4, 0x32, 0x5a,
0xcf, 0x76, 0x84, 0x48, 0x56, 0x28, 0x46, 0xab, 0xb5, 0xa0, 0xa9, 0xaf, 0x07, 0x4d, 0x1e, 0x8d,
0x8d, 0x22, 0x1a, 0x5f, 0x87, 0x8e, 0xcd, 0x19, 0xe6, 0xae, 0xa9, 0x2c, 0x46, 0x34, 0x5a, 0xdb,
0x89, 0x70, 0xe2, 0x2e, 0x98, 0xf4, 0x9f, 0xbc, 0x38, 0x40, 0x95, 0x6c, 0x6e, 0xbc, 0xd7, 0xd6,
0xc6, 0x7b, 0xc5, 0x4a, 0xc0, 0x63, 0x9a, 0xf1, 0xb1, 0x9d, 0x8b, 0x9a, 0x4e, 0x21, 0x6a, 0x0a,
0xa1, 0xd1, 0x5d, 0x09, 0x8d, 0x15, 0xfc, 0xf6, 0xd6, 0xf0, 0xfb, 0x1a, 0xb4, 0xa5, 0x03, 0xa2,
0x90, 0xda, 0x4c, 0x4e, 0xd0, 0x57, 0x8e, 0x48, 0x65, 0xc7, 0x0e, 0x46, 0x7b, 0x3c, 0x9b, 0x2d,
0x2f, 0x03, 0x8f, 0x65, 0x84, 0xdd, 0x4a, 0x65, 0xc7, 0x8e, 0xdc, 0x2f, 0x22, 0x90, 0x20, 0x02,
0xb1, 0x3d, 0x7c, 0x0f, 0x9a, 0xa9, 0xd7, 0xbf, 0x17, 0x98, 0xfe, 0x5e, 0x82, 0x76, 0x9e, 0x14,
0xe5, 0xe0, 0xc9, 0xe4, 0x04, 0x07, 0x57, 0x2c, 0xd9, 0x94, 0xe5, 0x04, 0x67, 0x3e, 0x7b, 0x49,
0x67, 0x9e, 0x9a, 0xa0, 0x61, 0x65, 0x02, 0xa9, 0x75, 0x7d, 0x9b, 0xb3, 0x45, 0x82, 0xaa, 0x8a,
0x95, 0x09, 0xc8, 0xfb, 0x00, 0x6e, 0x14, 0xc5, 0x4c, 0xdd, 0xdc, 0x16, 0x52, 0xc6, 0x70, 0xac,
0x6a, 0xcc, 0x71, 0x52, 0x63, 0x8e, 0x27, 0x49, 0x8d, 0x69, 0x35, 0xd1, 0x1a, 0xaf, 0xf4, 0x2e,
0xd4, 0xe4, 0x05, 0x4d, 0x4e, 0x10, 0x79, 0x15, 0x4b, 0xf7, 0xcc, 0xbf, 0x40, 0x4d, 0x55, 0x21,
0xff, 0x57, 0xa2, 0xbf, 0x07, 0x0d, 0x35, 0xb7, 0xeb, 0xe8, 0x58, 0xa9, 0x63, 0xff, 0xd8, 0x31,
0xbf, 0x2e, 0x43, 0xc3, 0x62, 0x51, 0x18, 0xf8, 0x11, 0xcb, 0x55, 0x49, 0xa5, 0x6f, 0xad, 0x92,
0xca, 0x1b, 0xab, 0xa4, 0xa4, 0xf6, 0xaa, 0xe4, 0x6a, 0xaf, 0x21, 0x34, 0x38, 0x73, 0x5c, 0xce,
0x6c, 0xa1, 0xeb, 0xb4, 0xb4, 0x2f, 0x75, 0x2f, 0x29, 0x97, 0xe9, 0x3d, 0xc2, 0x1c, 0xd2, 0xb4,
0xd2, 0x3e, 0x79, 0x92, 0x2f, 0x2e, 0x54, 0xd9, 0xb6, 0xad, 0x8a, 0x0b, 0xb5, 0xdd, 0x0d, 0xd5,
0xc5, 0xd3, 0xac, 0x48, 0xab, 0x63, 0x34, 0xdf, 0xcb, 0x0f, 0xd8, 0x5c, 0xa5, 0xfd, 0x60, 0x39,
0xfb, 0xeb, 0x32, 0xf4, 0x57, 0xf7, 0xb6, 0x01, 0x81, 0xdb, 0x50, 0x55, 0xb9, 0x4f, 0xc3, 0x57,
0xac, 0x65, 0xbd, 0xca, 0x0a, 0xd1, 0xfd, 0x6a, 0x95, 0x34, 0xbe, 0x1d, 0x7a, 0x45, 0x42, 0x79,
0x13, 0xfa, 0xd2, 0x45, 0x21, 0x73, 0xb2, 0x7a, 0x4e, 0x31, 0x60, 0x4f, 0xcb, 0xd3, 0x8a, 0x6e,
0x17, 0x06, 0x89, 0x69, 0xc6, 0x0d, 0xb5, 0x82, 0xed, 0x51, 0x42, 0x11, 0x77, 0xa1, 0x76, 0x11,
0xf0, 0x05, 0x15, 0x9a, 0x04, 0x75, 0xaf, 0x40, 0x72, 0xc8, 0xb6, 0x0d, 0x85, 0xc9, 0x44, 0x28,
0xdf, 0x2c, 0x92, 0x7c, 0xd2, 0xf7, 0x04, 0xb2, 0x60, 0xc3, 0x6a, 0x24, 0xef, 0x08, 0xf3, 0xb7,
0xd0, 0x5b, 0x29, 0x21, 0x37, 0x38, 0x32, 0x5b, 0xbe, 0x5c, 0x58, 0xbe, 0x30, 0x73, 0x65, 0x65,
0xe6, 0xdf, 0xc1, 0xe0, 0x13, 0xea, 0x3b, 0x1e, 0xd3, 0xf3, 0x1f, 0xf0, 0x79, 0x24, 0x93, 0xa1,
0x7e, 0xd1, 0x4c, 0x75, 0xf6, 0xe9, 0x58, 0x4d, 0x2d, 0x39, 0x76, 0xc8, 0x23, 0xa8, 0x73, 0x65,
0xad, 0x01, 0xd0, 0xca, 0xd5, 0xb8, 0x56, 0xa2, 0x33, 0xbf, 0x02, 0x52, 0x98, 0x5a, 0x3e, 0x66,
0x96, 0x64, 0x24, 0xd1, 0xaf, 0x40, 0xa1, 0xa3, 0xaa, 0x9d, 0xc7, 0xa4, 0x95, 0x6a, 0xc9, 0x0e,
0x54, 0x18, 0xe7, 0x7a, 0x09, 0x2c, 0x32, 0xb3, 0xa7, 0xa3, 0x25, 0x55, 0x66, 0x1f, 0xba, 0xc7,
0xbe, 0x2b, 0x5c, 0xea, 0xb9, 0x7f, 0x66, 0x72, 0xe7, 0xe6, 0x53, 0xe8, 0x65, 0x12, 0xb5, 0xa0,
0x9e, 0xa6, 0x74, 0xfb, 0x34, 0x3f, 0x83, 0xc1, 0x79, 0xc8, 0x6c, 0x97, 0x7a, 0xf8, 0x7a, 0x54,
0xc3, 0x1e, 0x42, 0x55, 0xde, 0x55, 0xc2, 0x3b, 0x4d, 0x1c, 0x88, 0x6a, 0x25, 0x37, 0xbf, 0x02,
0x43, 0x1d, 0xef, 0xe8, 0xc6, 0x8d, 0x04, 0xf3, 0x6d, 0x76, 0x78, 0xc9, 0xec, 0xab, 0x1f, 0xd0,
0x81, 0xd7, 0x70, 0x6f, 0xd3, 0x0a, 0xc9, 0xfe, 0x5a, 0xb6, 0xec, 0x4d, 0x2f, 0x64, 0x0a, 0xc2,
0x35, 0x1a, 0x16, 0xa0, 0xe8, 0x63, 0x29, 0x91, 0x70, 0x60, 0x72, 0x5c, 0xa4, 0x69, 0x5d, 0xf7,
0x12, 0x7f, 0x54, 0x6e, 0xf7, 0xc7, 0x3f, 0x4a, 0xd0, 0x3c, 0x67, 0x22, 0x0e, 0xf1, 0x2c, 0xf7,
0xa1, 0x39, 0xe3, 0xc1, 0x15, 0xe3, 0xd9, 0x51, 0x1a, 0x4a, 0x70, 0xec, 0x90, 0x27, 0x50, 0x3b,
0x0c, 0xfc, 0x0b, 0x77, 0x8e, 0x6f, 0x69, 0xcd, 0x2f, 0xe9, 0xd8, 0xb1, 0xd2, 0x29, 0x7e, 0xd1,
0x86, 0x64, 0x07, 0x5a, 0xfa, 0xcb, 0xc4, 0x17, 0x5f, 0x1c, 0x3f, 0x4f, 0x8a, 0xec, 0x9c, 0x68,
0xf8, 0x3e, 0xb4, 0x72, 0x03, 0xbf, 0x57, 0xc6, 0xfb, 0x31, 0x00, 0xae, 0xae, 0x7c, 0xd4, 0xcf,
0xae, 0xbe, 0xa9, 0x8e, 0xf6, 0x10, 0x9a, 0xb2, 0x9e, 0x53, 0xea, 0x24, 0xd7, 0x96, 0xb2, 0x5c,
0x6b, 0x3e, 0x82, 0xc1, 0xb1, 0x7f, 0x4d, 0x3d, 0xd7, 0xa1, 0x82, 0x7d, 0xca, 0x96, 0xe8, 0x82,
0xb5, 0x1d, 0x98, 0xe7, 0xd0, 0xd6, 0x8f, 0xfb, 0xef, 0xb4, 0xc7, 0xb6, 0xde, 0xe3, 0x37, 0xc7,
0xe2, 0x9b, 0xd0, 0xd3, 0x93, 0x9e, 0xb8, 0x3a, 0x12, 0x65, 0xa9, 0xc2, 0xd9, 0x85, 0x7b, 0xa3,
0xa7, 0xd6, 0x3d, 0xf3, 0x19, 0xf4, 0x73, 0xa6, 0xe9, 0x71, 0xae, 0xd8, 0x32, 0x4a, 0x3e, 0x7a,
0xc8, 0x76, 0xe2, 0x81, 0x72, 0xe6, 0x01, 0x13, 0xba, 0x7a, 0xe4, 0x0b, 0x26, 0x6e, 0x39, 0xdd,
0xa7, 0xe9, 0x46, 0x5e, 0x30, 0x3d, 0xf9, 0x63, 0xa8, 0x32, 0x79, 0xd2, 0x7c, 0x1a, 0xce, 0x7b,
0xc0, 0x52, 0xea, 0x0d, 0x0b, 0x3e, 0x4b, 0x17, 0x3c, 0x8b, 0xd5, 0x82, 0xdf, 0x71, 0x2e, 0xf3,
0xf5, 0x74, 0x1b, 0x67, 0xb1, 0xb8, 0xed, 0x46, 0x1f, 0xc1, 0x40, 0x1b, 0x3d, 0x67, 0x1e, 0x13,
0xec, 0x96, 0x23, 0x3d, 0x06, 0x52, 0x30, 0xbb, 0x6d, 0xba, 0x07, 0xd0, 0x98, 0x4c, 0x4e, 0x52,
0x6d, 0x91, 0x62, 0xcd, 0x0f, 0x60, 0x70, 0x1e, 0x3b, 0xc1, 0x19, 0x77, 0xaf, 0x5d, 0x8f, 0xcd,
0xd5, 0x62, 0x49, 0x0d, 0x5d, 0xca, 0xd5, 0xd0, 0x1b, 0x93, 0x9a, 0x39, 0x02, 0x52, 0x18, 0x9e,
0xde, 0x5b, 0x14, 0x3b, 0x81, 0x0e, 0x61, 0x6c, 0x9b, 0x23, 0x68, 0x4f, 0xa8, 0xac, 0x59, 0x1c,
0x65, 0x63, 0x40, 0x5d, 0xa8, 0xbe, 0x36, 0x4b, 0xba, 0xe6, 0x3e, 0x6c, 0x1f, 0x52, 0xfb, 0xd2,
0xf5, 0xe7, 0xcf, 0xdd, 0x48, 0x16, 0x6d, 0x7a, 0xc4, 0x10, 0x1a, 0x8e, 0x16, 0xe8, 0x21, 0x69,
0xdf, 0x7c, 0x1b, 0x5e, 0xc9, 0x7d, 0x59, 0x3a, 0x17, 0x34, 0xf1, 0xc7, 0x36, 0x54, 0x23, 0xd9,
0xc3, 0x11, 0x55, 0x4b, 0x75, 0xcc, 0xcf, 0x60, 0x3b, 0x9f, 0xc7, 0x65, 0x09, 0x95, 0x1c, 0x1c,
0x8b, 0x9b, 0x52, 0xae, 0xb8, 0xd1, 0x3e, 0x2b, 0x67, 0x69, 0xa9, 0x0f, 0x95, 0x5f, 0x7f, 0x39,
0xd1, 0x60, 0x97, 0x4d, 0xf3, 0x8f, 0x72, 0xf9, 0xe2, 0x7c, 0x6a, 0xf9, 0x42, 0x85, 0x53, 0xfa,
0x4e, 0x15, 0xce, 0x3a, 0xde, 0xde, 0x86, 0xc1, 0xa9, 0x17, 0xd8, 0x57, 0x47, 0x7e, 0xce, 0x1b,
0x06, 0xd4, 0x99, 0x9f, 0x77, 0x46, 0xd2, 0x35, 0xdf, 0x80, 0xde, 0x49, 0x60, 0x53, 0xef, 0x34,
0x88, 0x7d, 0x91, 0x7a, 0x01, 0x3f, 0xf5, 0x69, 0x53, 0xd5, 0x31, 0xdf, 0x86, 0xae, 0xce, 0xf4,
0xfe, 0x45, 0x90, 0x30, 0x63, 0x56, 0x13, 0x94, 0x8a, 0xef, 0x05, 0xf3, 0x04, 0x7a, 0x99, 0xb9,
0x9a, 0xf7, 0x0d, 0xa8, 0x29, 0xb5, 0x3e, 0x5b, 0x2f, 0x7d, 0x30, 0x2b, 0x4b, 0x4b, 0xab, 0x37,
0x1c, 0x6a, 0x01, 0xdd, 0x33, 0xfc, 0xe4, 0x7a, 0xe4, 0x5f, 0xab, 0xc9, 0x8e, 0x81, 0xa8, 0x8f,
0xb0, 0x53, 0xe6, 0x5f, 0xbb, 0x3c, 0xf0, 0xb1, 0x46, 0x2f, 0xe9, 0x4a, 0x28, 0x99, 0x38, 0x1d,
0x94, 0x58, 0x58, 0x83, 0x70, 0x55, 0xb4, 0xd1, 0x87, 0x90, 0x7d, 0xd0, 0x91, 0xa9, 0x86, 0xb3,
0x45, 0x20, 0xd8, 0x94, 0x3a, 0x4e, 0x12, 0x2d, 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x56,
0x81, 0xfa, 0x47, 0x8a, 0xc0, 0xc9, 0x87, 0xd0, 0x29, 0x64, 0x7d, 0xf2, 0x0a, 0x56, 0x87, 0xab,
0x35, 0xc6, 0xf0, 0xee, 0x9a, 0x58, 0x9d, 0xeb, 0x1d, 0x68, 0xe7, 0x93, 0x31, 0xc1, 0xc4, 0x8b,
0x9f, 0x97, 0x87, 0x38, 0xd3, 0x7a, 0xa6, 0x3e, 0x87, 0xed, 0x4d, 0x69, 0x92, 0x3c, 0xc8, 0x56,
0x58, 0x4f, 0xd1, 0xc3, 0x57, 0x6f, 0xd3, 0x26, 0xe9, 0xb5, 0x7e, 0xe8, 0x31, 0xea, 0xc7, 0x61,
0x7e, 0x07, 0x59, 0x93, 0x3c, 0x81, 0x4e, 0x21, 0x51, 0xa8, 0x73, 0xae, 0xe5, 0x8e, 0xfc, 0x90,
0xc7, 0x50, 0xc5, 0xe4, 0x44, 0x3a, 0x85, 0x2c, 0x39, 0xec, 0xa6, 0x5d, 0xb5, 0xf6, 0xbb, 0x00,
0x59, 0x11, 0x43, 0x88, 0x9a, 0x37, 0x5f, 0xe6, 0x0c, 0xef, 0x14, 0x65, 0x49, 0xa1, 0xb3, 0x85,
0xdf, 0x2a, 0x72, 0xfb, 0xc5, 0x85, 0xd2, 0x84, 0xb7, 0xff, 0x9f, 0x12, 0xd4, 0x93, 0xef, 0xd7,
0x4f, 0x60, 0x4b, 0xa6, 0x0e, 0x72, 0x27, 0xc7, 0xbe, 0x49, 0xda, 0x19, 0x6e, 0xaf, 0x08, 0xd5,
0x02, 0x63, 0xa8, 0xbc, 0x60, 0x42, 0x6d, 0xa8, 0x98, 0x43, 0x86, 0x77, 0x8a, 0xb2, 0xd4, 0xfe,
0x2c, 0x2e, 0xda, 0xeb, 0x14, 0x50, 0xb0, 0x4f, 0xc9, 0xfd, 0x3d, 0xa8, 0x29, 0x72, 0x56, 0xbe,
0x5c, 0xa3, 0x75, 0x85, 0x99, 0x75, 0x1a, 0xdf, 0xff, 0xd7, 0x16, 0xc0, 0xf9, 0x32, 0x12, 0x6c,
0xf1, 0x1b, 0x97, 0xbd, 0x24, 0xbb, 0xd0, 0xd3, 0x5f, 0x64, 0xf0, 0xa1, 0x28, 0x49, 0x28, 0xe7,
0x13, 0x2c, 0x37, 0x53, 0x8e, 0x7f, 0x0c, 0xad, 0x53, 0x7a, 0xf3, 0xed, 0x76, 0x1f, 0x42, 0xa7,
0x40, 0xdd, 0x7a, 0x8b, 0xab, 0xc9, 0x40, 0x6f, 0x71, 0x9d, 0xe4, 0x1f, 0x43, 0x5d, 0x13, 0x7a,
0x7e, 0x0d, 0x4c, 0x7d, 0x05, 0xa2, 0xff, 0x39, 0xf4, 0x56, 0xe8, 0x3c, 0x6f, 0x8f, 0x1f, 0x63,
0x36, 0xd2, 0xfd, 0x33, 0xf9, 0xd6, 0x2a, 0x52, 0x7a, 0x7e, 0xa0, 0x7e, 0xf7, 0x6d, 0xe2, 0xfc,
0x17, 0xc5, 0x57, 0x1a, 0x3e, 0x90, 0x8d, 0x55, 0xd6, 0x4d, 0x38, 0x7f, 0x78, 0x6f, 0x93, 0x26,
0x8d, 0xdc, 0x3c, 0xf1, 0xae, 0x45, 0xee, 0x3a, 0x2b, 0xbf, 0x05, 0x90, 0x71, 0x6f, 0xde, 0x1e,
0xe1, 0xb1, 0x4a, 0xcb, 0xef, 0x02, 0x64, 0x8c, 0xaa, 0x50, 0x55, 0x24, 0x64, 0x35, 0x6c, 0x95,
0x75, 0x77, 0xa1, 0x99, 0xb2, 0x60, 0x7e, 0x0d, 0x9c, 0xa0, 0x48, 0xaa, 0x1f, 0xed, 0xfe, 0x7e,
0x34, 0x77, 0xc5, 0x65, 0x3c, 0x1b, 0xdb, 0xc1, 0x62, 0xef, 0x92, 0x46, 0x97, 0xae, 0x1d, 0xf0,
0x70, 0xef, 0x5a, 0x82, 0x69, 0xaf, 0xf0, 0x7b, 0x6d, 0x56, 0xc3, 0x67, 0xe6, 0xd3, 0xff, 0x05,
0x00, 0x00, 0xff, 0xff, 0xc4, 0xd7, 0xaa, 0x59, 0x76, 0x1b, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -2927,6 +3001,9 @@ type BackendClient interface {
// broker_id to create a connection back to Vault for use with the Storage
// and SystemView clients.
Setup(ctx context.Context, in *SetupArgs, opts ...grpc.CallOption) (*SetupReply, error)
// Initialize is invoked just after mounting a backend to allow it to
// handle any initialization tasks that need to be performed.
Initialize(ctx context.Context, in *InitializeArgs, opts ...grpc.CallOption) (*InitializeReply, error)
// Type returns the BackendType for the particular backend
Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeReply, error)
}
@@ -2993,6 +3070,15 @@ func (c *backendClient) Setup(ctx context.Context, in *SetupArgs, opts ...grpc.C
return out, nil
}
func (c *backendClient) Initialize(ctx context.Context, in *InitializeArgs, opts ...grpc.CallOption) (*InitializeReply, error) {
out := new(InitializeReply)
err := c.cc.Invoke(ctx, "/pb.Backend/Initialize", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *backendClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeReply, error) {
out := new(TypeReply)
err := c.cc.Invoke(ctx, "/pb.Backend/Type", in, out, opts...)
@@ -3034,36 +3120,13 @@ type BackendServer interface {
// broker_id to create a connection back to Vault for use with the Storage
// and SystemView clients.
Setup(context.Context, *SetupArgs) (*SetupReply, error)
// Initialize is invoked just after mounting a backend to allow it to
// handle any initialization tasks that need to be performed.
Initialize(context.Context, *InitializeArgs) (*InitializeReply, error)
// Type returns the BackendType for the particular backend
Type(context.Context, *Empty) (*TypeReply, error)
}
// UnimplementedBackendServer can be embedded to have forward compatible implementations.
type UnimplementedBackendServer struct {
}
func (*UnimplementedBackendServer) HandleRequest(ctx context.Context, req *HandleRequestArgs) (*HandleRequestReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method HandleRequest not implemented")
}
func (*UnimplementedBackendServer) SpecialPaths(ctx context.Context, req *Empty) (*SpecialPathsReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SpecialPaths not implemented")
}
func (*UnimplementedBackendServer) HandleExistenceCheck(ctx context.Context, req *HandleExistenceCheckArgs) (*HandleExistenceCheckReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method HandleExistenceCheck not implemented")
}
func (*UnimplementedBackendServer) Cleanup(ctx context.Context, req *Empty) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method Cleanup not implemented")
}
func (*UnimplementedBackendServer) InvalidateKey(ctx context.Context, req *InvalidateKeyArgs) (*Empty, error) {
return nil, status.Errorf(codes.Unimplemented, "method InvalidateKey not implemented")
}
func (*UnimplementedBackendServer) Setup(ctx context.Context, req *SetupArgs) (*SetupReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Setup not implemented")
}
func (*UnimplementedBackendServer) Type(ctx context.Context, req *Empty) (*TypeReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Type not implemented")
}
func RegisterBackendServer(s *grpc.Server, srv BackendServer) {
s.RegisterService(&_Backend_serviceDesc, srv)
}
@@ -3176,6 +3239,24 @@ func _Backend_Setup_Handler(srv interface{}, ctx context.Context, dec func(inter
return interceptor(ctx, in, info, handler)
}
func _Backend_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(InitializeArgs)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BackendServer).Initialize(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/pb.Backend/Initialize",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BackendServer).Initialize(ctx, req.(*InitializeArgs))
}
return interceptor(ctx, in, info, handler)
}
func _Backend_Type_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Empty)
if err := dec(in); err != nil {
@@ -3222,6 +3303,10 @@ var _Backend_serviceDesc = grpc.ServiceDesc{
MethodName: "Setup",
Handler: _Backend_Setup_Handler,
},
{
MethodName: "Initialize",
Handler: _Backend_Initialize_Handler,
},
{
MethodName: "Type",
Handler: _Backend_Type_Handler,
@@ -3293,23 +3378,6 @@ type StorageServer interface {
Delete(context.Context, *StorageDeleteArgs) (*StorageDeleteReply, error)
}
// UnimplementedStorageServer can be embedded to have forward compatible implementations.
type UnimplementedStorageServer struct {
}
func (*UnimplementedStorageServer) List(ctx context.Context, req *StorageListArgs) (*StorageListReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method List not implemented")
}
func (*UnimplementedStorageServer) Get(ctx context.Context, req *StorageGetArgs) (*StorageGetReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
}
func (*UnimplementedStorageServer) Put(ctx context.Context, req *StoragePutArgs) (*StoragePutReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Put not implemented")
}
func (*UnimplementedStorageServer) Delete(ctx context.Context, req *StorageDeleteArgs) (*StorageDeleteReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented")
}
func RegisterStorageServer(s *grpc.Server, srv StorageServer) {
s.RegisterService(&_Storage_serviceDesc, srv)
}
@@ -3600,44 +3668,6 @@ type SystemViewServer interface {
PluginEnv(context.Context, *Empty) (*PluginEnvReply, error)
}
// UnimplementedSystemViewServer can be embedded to have forward compatible implementations.
type UnimplementedSystemViewServer struct {
}
func (*UnimplementedSystemViewServer) DefaultLeaseTTL(ctx context.Context, req *Empty) (*TTLReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method DefaultLeaseTTL not implemented")
}
func (*UnimplementedSystemViewServer) MaxLeaseTTL(ctx context.Context, req *Empty) (*TTLReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method MaxLeaseTTL not implemented")
}
func (*UnimplementedSystemViewServer) SudoPrivilege(ctx context.Context, req *SudoPrivilegeArgs) (*SudoPrivilegeReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SudoPrivilege not implemented")
}
func (*UnimplementedSystemViewServer) Tainted(ctx context.Context, req *Empty) (*TaintedReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Tainted not implemented")
}
func (*UnimplementedSystemViewServer) CachingDisabled(ctx context.Context, req *Empty) (*CachingDisabledReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CachingDisabled not implemented")
}
func (*UnimplementedSystemViewServer) ReplicationState(ctx context.Context, req *Empty) (*ReplicationStateReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method ReplicationState not implemented")
}
func (*UnimplementedSystemViewServer) ResponseWrapData(ctx context.Context, req *ResponseWrapDataArgs) (*ResponseWrapDataReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method ResponseWrapData not implemented")
}
func (*UnimplementedSystemViewServer) MlockEnabled(ctx context.Context, req *Empty) (*MlockEnabledReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method MlockEnabled not implemented")
}
func (*UnimplementedSystemViewServer) LocalMount(ctx context.Context, req *Empty) (*LocalMountReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method LocalMount not implemented")
}
func (*UnimplementedSystemViewServer) EntityInfo(ctx context.Context, req *EntityInfoArgs) (*EntityInfoReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method EntityInfo not implemented")
}
func (*UnimplementedSystemViewServer) PluginEnv(ctx context.Context, req *Empty) (*PluginEnvReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PluginEnv not implemented")
}
func RegisterSystemViewServer(s *grpc.Server, srv SystemViewServer) {
s.RegisterService(&_SystemView_serviceDesc, srv)
}

View File

@@ -355,6 +355,15 @@ message HandleRequestReply {
ProtoError err = 2;
}
// InitializeArgs is the args for Initialize method.
message InitializeArgs {
}
// InitializeReply is the reply for Initialize method.
message InitializeReply {
ProtoError err = 1;
}
// SpecialPathsReply is the reply for SpecialPaths method.
message SpecialPathsReply {
Paths paths = 1;
@@ -434,6 +443,10 @@ service Backend {
// and SystemView clients.
rpc Setup(SetupArgs) returns (SetupReply);
// Initialize is invoked just after mounting a backend to allow it to
// handle any initialization tasks that need to be performed.
rpc Initialize(InitializeArgs) returns (InitializeReply);
// Type returns the BackendType for the particular backend
rpc Type(Empty) returns (TypeReply);
}

View File

@@ -185,6 +185,17 @@ func (c *Core) enableCredentialInternal(ctx context.Context, entry *MountEntry,
return err
}
if !nilMount {
// restore the original readOnlyErr, so we can write to the view in
// Initialize() if necessary
view.setReadOnlyErr(origViewReadOnlyErr)
// initialize, using the core's active context.
err := backend.Initialize(c.activeContext, &logical.InitializationRequest{Storage: view})
if err != nil {
return err
}
}
if c.logger.IsInfo() {
c.logger.Info("enabled credential backend", "path", entry.Path, "type", entry.Type)
}
@@ -678,6 +689,21 @@ func (c *Core) setupCredentials(ctx context.Context) error {
// Populate cache
NamespaceByID(ctx, entry.NamespaceID, c)
// Initialize
if !nilMount {
c.postUnsealFuncs = append(c.postUnsealFuncs, func() {
if backend == nil {
c.logger.Error("skipping initialization on nil backend", "path", entry.Path)
return
}
err := backend.Initialize(ctx, &logical.InitializationRequest{Storage: view})
if err != nil {
c.logger.Error("failed to initialize auth entry", "path", entry.Path, "error", err)
}
})
}
}
if persistNeeded {

View File

@@ -424,3 +424,72 @@ func verifyDefaultAuthTable(t *testing.T, table *MountTable) {
}
}
}
func TestCore_CredentialInitialize(t *testing.T) {
{
backend := &InitializableBackend{
&NoopBackend{
BackendType: logical.TypeCredential,
}, false}
c, _, _ := TestCoreUnsealed(t)
c.credentialBackends["initable"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
return backend, nil
}
me := &MountEntry{
Table: credentialTableType,
Path: "foo/",
Type: "initable",
}
err := c.enableCredential(namespace.RootContext(nil), me)
if err != nil {
t.Fatalf("err: %v", err)
}
if !backend.isInitialized {
t.Fatal("backend is not initialized")
}
}
{
backend := &InitializableBackend{
&NoopBackend{
BackendType: logical.TypeCredential,
}, false}
c, _, _ := TestCoreUnsealed(t)
c.credentialBackends["initable"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
return backend, nil
}
c.auth = &MountTable{
Type: credentialTableType,
Entries: []*MountEntry{
&MountEntry{
Table: credentialTableType,
Path: "foo/",
Type: "initable",
UUID: "abcd",
Accessor: "initable-abcd",
BackendAwareUUID: "abcde",
NamespaceID: namespace.RootNamespaceID,
namespace: namespace.RootNamespace,
},
},
}
err := c.setupCredentials(context.Background())
if err != nil {
t.Fatal(err)
}
// run the postUnseal funcs, so that the backend will be inited
for _, f := range c.postUnsealFuncs {
f()
}
if !backend.isInitialized {
t.Fatal("backend is not initialized")
}
}
}

View File

@@ -511,6 +511,17 @@ func (c *Core) mountInternal(ctx context.Context, entry *MountEntry, updateStora
return err
}
if !nilMount {
// restore the original readOnlyErr, so we can write to the view in
// Initialize() if necessary
view.setReadOnlyErr(origReadOnlyErr)
// initialize, using the core's active context.
err := backend.Initialize(c.activeContext, &logical.InitializationRequest{Storage: view})
if err != nil {
return err
}
}
if c.logger.IsInfo() {
c.logger.Info("successful mount", "namespace", entry.Namespace().Path, "path", entry.Path, "type", entry.Type)
}
@@ -1131,6 +1142,21 @@ func (c *Core) setupMounts(ctx context.Context) error {
return errLoadMountsFailed
}
// Initialize
if !nilMount {
c.postUnsealFuncs = append(c.postUnsealFuncs, func() {
if backend == nil {
c.logger.Error("skipping initialization on nil backend", "path", entry.Path)
return
}
err := backend.Initialize(ctx, &logical.InitializationRequest{Storage: view})
if err != nil {
c.logger.Error("failed to initialize mount entry", "path", entry.Path, "error", err)
}
})
}
if c.logger.IsInfo() {
c.logger.Info("successfully mounted backend", "type", entry.Type, "path", entry.Path)
}

View File

@@ -735,3 +735,72 @@ func TestSingletonMountTableFunc(t *testing.T) {
t.Fatal("unexpected entry type for auth")
}
}
func TestCore_MountInitialize(t *testing.T) {
{
backend := &InitializableBackend{
&NoopBackend{
BackendType: logical.TypeLogical,
}, false}
c, _, _ := TestCoreUnsealed(t)
c.logicalBackends["initable"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
return backend, nil
}
// Mount the noop backend
me := &MountEntry{
Table: mountTableType,
Path: "foo/",
Type: "initable",
}
if err := c.mount(namespace.RootContext(nil), me); err != nil {
t.Fatalf("err: %v", err)
}
if !backend.isInitialized {
t.Fatal("backend is not initialized")
}
}
{
backend := &InitializableBackend{
&NoopBackend{
BackendType: logical.TypeLogical,
}, false}
c, _, _ := TestCoreUnsealed(t)
c.logicalBackends["initable"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
return backend, nil
}
c.mounts = &MountTable{
Type: mountTableType,
Entries: []*MountEntry{
&MountEntry{
Table: mountTableType,
Path: "foo/",
Type: "initable",
UUID: "abcd",
Accessor: "initable-abcd",
BackendAwareUUID: "abcde",
NamespaceID: namespace.RootNamespaceID,
namespace: namespace.RootNamespace,
},
},
}
err := c.setupMounts(namespace.RootContext(nil))
if err != nil {
t.Fatal(err)
}
// run the postUnseal funcs, so that the backend will be inited
for _, f := range c.postUnsealFuncs {
f()
}
if !backend.isInitialized {
t.Fatal("backend is not initialized")
}
}
}

View File

@@ -2,6 +2,7 @@ package vault
import (
"context"
"errors"
"fmt"
"sync"
"time"
@@ -103,7 +104,7 @@ func (n *NoopBackend) Logger() log.Logger {
return log.NewNullLogger()
}
func (n *NoopBackend) Initialize(ctx context.Context) error {
func (n *NoopBackend) Initialize(ctx context.Context, req *logical.InitializationRequest) error {
return nil
}
@@ -113,3 +114,29 @@ func (n *NoopBackend) Type() logical.BackendType {
}
return n.BackendType
}
// InitializableBackend is a backend that knows whether it has been initialized
// properly.
type InitializableBackend struct {
*NoopBackend
isInitialized bool
}
func (b *InitializableBackend) Initialize(ctx context.Context, req *logical.InitializationRequest) error {
if b.isInitialized {
return errors.New("already initialized")
}
// do a dummy write, to prove that the storage is not readonly
entry := &logical.StorageEntry{
Key: "initialize/zork",
Value: []byte("quux"),
}
err := req.Storage.Put(ctx, entry)
if err != nil {
return err
}
b.isInitialized = true
return nil
}

View File

@@ -717,8 +717,7 @@ func (n *rawHTTP) Cleanup(ctx context.Context) {
// noop
}
func (n *rawHTTP) Initialize(ctx context.Context) error {
// noop
func (n *rawHTTP) Initialize(ctx context.Context, req *logical.InitializationRequest) error {
return nil
}