mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-01 02:57:59 +00:00 
			
		
		
		
	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
					Mike Jarmy
				
			
				
					committed by
					
						 Brian Kassouf
						Brian Kassouf
					
				
			
			
				
	
			
			
			 Brian Kassouf
						Brian Kassouf
					
				
			
						parent
						
							8b9e9ea1ec
						
					
				
				
					commit
					c48159ea3a
				
			| @@ -35,7 +35,7 @@ type backend struct { | |||||||
| 	configMutex sync.RWMutex | 	configMutex sync.RWMutex | ||||||
|  |  | ||||||
| 	// Lock to make changes to role entries | 	// Lock to make changes to role entries | ||||||
| 	roleMutex sync.RWMutex | 	roleMutex sync.Mutex | ||||||
|  |  | ||||||
| 	// Lock to make changes to the blacklist entries | 	// Lock to make changes to the blacklist entries | ||||||
| 	blacklistMutex sync.RWMutex | 	blacklistMutex sync.RWMutex | ||||||
| @@ -81,6 +81,10 @@ type backend struct { | |||||||
| 	roleCache *cache.Cache | 	roleCache *cache.Cache | ||||||
|  |  | ||||||
| 	resolveArnToUniqueIDFunc func(context.Context, logical.Storage, string) (string, error) | 	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) { | func Backend(conf *logical.BackendConfig) (*backend, error) { | ||||||
| @@ -134,8 +138,10 @@ func Backend(conf *logical.BackendConfig) (*backend, error) { | |||||||
| 			pathIdentityWhitelist(b), | 			pathIdentityWhitelist(b), | ||||||
| 			pathTidyIdentityWhitelist(b), | 			pathTidyIdentityWhitelist(b), | ||||||
| 		}, | 		}, | ||||||
| 		Invalidate:  b.invalidate, | 		Invalidate:     b.invalidate, | ||||||
| 		BackendType: logical.TypeCredential, | 		InitializeFunc: b.initialize, | ||||||
|  | 		BackendType:    logical.TypeCredential, | ||||||
|  | 		Clean:          b.cleanup, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return b, nil | 	return b, nil | ||||||
| @@ -205,6 +211,12 @@ func (b *backend) periodicFunc(ctx context.Context, req *logical.Request) error | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (b *backend) cleanup(ctx context.Context) { | ||||||
|  | 	if b.upgradeCancelFunc != nil { | ||||||
|  | 		b.upgradeCancelFunc() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func (b *backend) invalidate(ctx context.Context, key string) { | func (b *backend) invalidate(ctx context.Context, key string) { | ||||||
| 	switch { | 	switch { | ||||||
| 	case key == "config/client": | 	case key == "config/client": | ||||||
|   | |||||||
							
								
								
									
										133
									
								
								builtin/credential/aws/backend_e2e_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								builtin/credential/aws/backend_e2e_test.go
									
									
									
									
									
										Normal 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 | ||||||
|  | } | ||||||
| @@ -319,6 +319,119 @@ func (b *backend) setRole(ctx context.Context, s logical.Storage, roleName strin | |||||||
| 	return nil | 	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 | // If needed, updates the role entry and returns a bool indicating if it was updated | ||||||
| // (and thus needs to be persisted) | // (and thus needs to be persisted) | ||||||
| func (b *backend) upgradeRole(ctx context.Context, s logical.Storage, roleEntry *awsRoleEntry) (bool, error) { | func (b *backend) upgradeRole(ctx context.Context, s logical.Storage, roleEntry *awsRoleEntry) (bool, error) { | ||||||
|   | |||||||
| @@ -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) { | func resolveArnToFakeUniqueId(ctx context.Context, s logical.Storage, arn string) (string, error) { | ||||||
| 	return "FakeUniqueId1", nil | 	return "FakeUniqueId1", nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -91,13 +91,8 @@ type PluginBackend struct { | |||||||
| 	loaded bool | 	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 | // 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"] | 	pluginName := b.config.Config["plugin_name"] | ||||||
| 	pluginType, err := consts.ParsePluginType(b.config.Config["plugin_type"]) | 	pluginType, err := consts.ParsePluginType(b.config.Config["plugin_type"]) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -134,11 +129,14 @@ func (b *PluginBackend) startBackend(ctx context.Context) error { | |||||||
| 	b.Backend = nb | 	b.Backend = nb | ||||||
| 	b.loaded = true | 	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. | // lazyLoad lazy-loads the backend before running a method | ||||||
| func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) { | func (b *PluginBackend) lazyLoadBackend(ctx context.Context, storage logical.Storage, methodWrapper func() error) error { | ||||||
| 	b.RLock() | 	b.RLock() | ||||||
| 	canary := b.canary | 	canary := b.canary | ||||||
|  |  | ||||||
| @@ -149,17 +147,19 @@ func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request) | |||||||
| 		b.Lock() | 		b.Lock() | ||||||
| 		// Check once more after lock swap | 		// Check once more after lock swap | ||||||
| 		if !b.loaded { | 		if !b.loaded { | ||||||
| 			err := b.startBackend(ctx) | 			err := b.startBackend(ctx, storage) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				b.Unlock() | 				b.Unlock() | ||||||
| 				return nil, err | 				return err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		b.Unlock() | 		b.Unlock() | ||||||
| 		b.RLock() | 		b.RLock() | ||||||
| 	} | 	} | ||||||
| 	resp, err := b.Backend.HandleRequest(ctx, req) |  | ||||||
|  | 	err := methodWrapper() | ||||||
| 	b.RUnlock() | 	b.RUnlock() | ||||||
|  |  | ||||||
| 	// Need to compare string value for case were err comes from plugin RPC | 	// Need to compare string value for case were err comes from plugin RPC | ||||||
| 	// and is returned as plugin.BasicError type. | 	// and is returned as plugin.BasicError type. | ||||||
| 	if err != nil && | 	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 | 		// Reload plugin if it's an rpc.ErrShutdown | ||||||
| 		b.Lock() | 		b.Lock() | ||||||
| 		if b.canary == canary { | 		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 { | 			if err != nil { | ||||||
| 				b.Unlock() | 				b.Unlock() | ||||||
| 				return nil, err | 				return err | ||||||
| 			} | 			} | ||||||
| 			b.canary, err = uuid.GenerateUUID() | 			b.canary, err = uuid.GenerateUUID() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				b.Unlock() | 				b.Unlock() | ||||||
| 				return nil, err | 				return err | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		b.Unlock() | 		b.Unlock() | ||||||
|  |  | ||||||
| 		// Try request once more | 		// Try once more | ||||||
| 		b.RLock() | 		b.RLock() | ||||||
| 		defer b.RUnlock() | 		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. | // HandleRequest 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) { | func (b *PluginBackend) HandleRequest(ctx context.Context, req *logical.Request) (resp *logical.Response, err error) { | ||||||
| 	b.RLock() |  | ||||||
| 	canary := b.canary |  | ||||||
|  |  | ||||||
| 	// Lazy-load backend | 	err = b.lazyLoadBackend(ctx, req.Storage, func() error { | ||||||
| 	if !b.loaded { | 		var merr error | ||||||
| 		// Upgrade lock | 		resp, merr = b.Backend.HandleRequest(ctx, req) | ||||||
| 		b.RUnlock() | 		return merr | ||||||
| 		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() |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	checkFound, exists, err := b.Backend.HandleExistenceCheck(ctx, req) | 	return | ||||||
| 	b.RUnlock() | } | ||||||
| 	if err != nil && |  | ||||||
| 		(err.Error() == rpc.ErrShutdown.Error() || err == bplugin.ErrPluginShutdown) { | // HandleExistenceCheck is a thin wrapper implementation of HandleExistenceCheck that includes automatic plugin reload. | ||||||
| 		// Reload plugin if it's an rpc.ErrShutdown | func (b *PluginBackend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (checkFound bool, exists bool, err error) { | ||||||
| 		b.Lock() |  | ||||||
| 		if b.canary == canary { | 	err = b.lazyLoadBackend(ctx, req.Storage, func() error { | ||||||
| 			err := b.reloadBackend(ctx) | 		var merr error | ||||||
| 			if err != nil { | 		checkFound, exists, merr = b.Backend.HandleExistenceCheck(ctx, req) | ||||||
| 				b.Unlock() | 		return merr | ||||||
| 				return false, false, err | 	}) | ||||||
| 			} |  | ||||||
| 			b.canary, err = uuid.GenerateUUID() | 	return | ||||||
| 			if err != nil { | } | ||||||
| 				b.Unlock() |  | ||||||
| 				return false, false, err | // Initialize is a thin wrapper implementation of Initialize that includes automatic plugin reload. | ||||||
| 			} | func (b *PluginBackend) Initialize(ctx context.Context, req *logical.InitializationRequest) error { | ||||||
| 		} |  | ||||||
| 		b.Unlock() | 	// This method is only ever called just after mounting, so we know that the | ||||||
|  | 	// call to lazyLoadBackend() will call startBackend().  Since | ||||||
| 		// Try request once more | 	// startBackend() calls Initialize() on the underlying logical.Backend, the | ||||||
| 		b.RLock() | 	// method wrapper that we pass in here is a no-op | ||||||
| 		defer b.RUnlock() | 	return b.lazyLoadBackend(ctx, req.Storage, func() error { | ||||||
| 		return b.Backend.HandleExistenceCheck(ctx, req) | 		return nil | ||||||
| 	} | 	}) | ||||||
| 	return checkFound, exists, err |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -49,6 +49,10 @@ type Backend struct { | |||||||
| 	// and ease specifying callbacks for revocation, renewal, etc. | 	// and ease specifying callbacks for revocation, renewal, etc. | ||||||
| 	Secrets []*Secret | 	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 | 	// PeriodicFunc is the callback, which if set, will be invoked when the | ||||||
| 	// periodic timer of RollbackManager ticks. This can be used by | 	// periodic timer of RollbackManager ticks. This can be used by | ||||||
| 	// backends to do anything it wishes to do periodically. | 	// 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. | // InvalidateFunc is the callback for backend key invalidation. | ||||||
| type InvalidateFunc func(context.Context, string) | 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. | // HandleExistenceCheck is the logical.Backend implementation. | ||||||
| func (b *Backend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (checkFound bool, exists bool, err error) { | func (b *Backend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (checkFound bool, exists bool, err error) { | ||||||
| 	b.once.Do(b.init) | 	b.once.Do(b.init) | ||||||
|   | |||||||
| @@ -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") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -38,6 +38,10 @@ func (b BackendType) String() string { | |||||||
| // allows for a "procfs" like interaction, as internal state can be exposed by | // allows for a "procfs" like interaction, as internal state can be exposed by | ||||||
| // acting like a logical backend and being mounted. | // acting like a logical backend and being mounted. | ||||||
| type Backend interface { | 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. | 	// HandleRequest is used to handle a request and generate a response. | ||||||
| 	// The backends must check the operation type and handle appropriately. | 	// The backends must check the operation type and handle appropriately. | ||||||
| 	HandleRequest(context.Context, *Request) (*Response, error) | 	HandleRequest(context.Context, *Request) (*Response, error) | ||||||
|   | |||||||
| @@ -303,3 +303,11 @@ const ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| type MFACreds map[string][]string | 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 | ||||||
|  | } | ||||||
|   | |||||||
| @@ -7,6 +7,8 @@ import ( | |||||||
| 	"sync/atomic" | 	"sync/atomic" | ||||||
|  |  | ||||||
| 	"google.golang.org/grpc" | 	"google.golang.org/grpc" | ||||||
|  | 	"google.golang.org/grpc/codes" | ||||||
|  | 	"google.golang.org/grpc/status" | ||||||
|  |  | ||||||
| 	log "github.com/hashicorp/go-hclog" | 	log "github.com/hashicorp/go-hclog" | ||||||
| 	plugin "github.com/hashicorp/go-plugin" | 	plugin "github.com/hashicorp/go-plugin" | ||||||
| @@ -44,6 +46,38 @@ type backendGRPCPluginClient struct { | |||||||
| 	doneCtx    context.Context | 	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) { | func (b *backendGRPCPluginClient) HandleRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) { | ||||||
| 	if b.metadataMode { | 	if b.metadataMode { | ||||||
| 		return nil, ErrClientInMetadataMode | 		return nil, ErrClientInMetadataMode | ||||||
|   | |||||||
| @@ -84,6 +84,22 @@ func (b *backendGRPCPluginServer) HandleRequest(ctx context.Context, args *pb.Ha | |||||||
| 	}, nil | 	}, 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) { | func (b *backendGRPCPluginServer) SpecialPaths(ctx context.Context, args *pb.Empty) (*pb.SpecialPathsReply, error) { | ||||||
| 	paths := b.backend.SpecialPaths() | 	paths := b.backend.SpecialPaths() | ||||||
| 	if paths == nil { | 	if paths == nil { | ||||||
|   | |||||||
| @@ -137,6 +137,16 @@ func TestGRPCBackendPlugin_Setup(t *testing.T) { | |||||||
| 	defer cleanup() | 	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()) { | func testGRPCBackend(t *testing.T) (logical.Backend, func()) { | ||||||
| 	// Create a mock provider | 	// Create a mock provider | ||||||
| 	pluginMap := map[string]gplugin.Plugin{ | 	pluginMap := map[string]gplugin.Plugin{ | ||||||
|   | |||||||
| @@ -19,6 +19,15 @@ type backendTracingMiddleware struct { | |||||||
| // Validate the backendTracingMiddle object satisfies the backend interface | // Validate the backendTracingMiddle object satisfies the backend interface | ||||||
| var _ logical.Backend = &backendTracingMiddleware{} | 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) { | func (b *backendTracingMiddleware) HandleRequest(ctx context.Context, req *logical.Request) (resp *logical.Response, err error) { | ||||||
| 	defer func(then time.Time) { | 	defer func(then time.Time) { | ||||||
| 		b.logger.Trace("handle request", "path", req.Path, "status", "finished", "err", err, "took", time.Since(then)) | 		b.logger.Trace("handle request", "path", req.Path, "status", "finished", "err", err, "took", time.Since(then)) | ||||||
|   | |||||||
| @@ -10,8 +10,6 @@ import ( | |||||||
| 	timestamp "github.com/golang/protobuf/ptypes/timestamp" | 	timestamp "github.com/golang/protobuf/ptypes/timestamp" | ||||||
| 	logical "github.com/hashicorp/vault/sdk/logical" | 	logical "github.com/hashicorp/vault/sdk/logical" | ||||||
| 	grpc "google.golang.org/grpc" | 	grpc "google.golang.org/grpc" | ||||||
| 	codes "google.golang.org/grpc/codes" |  | ||||||
| 	status "google.golang.org/grpc/status" |  | ||||||
| 	math "math" | 	math "math" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -1372,6 +1370,78 @@ func (m *HandleRequestReply) GetErr() *ProtoError { | |||||||
| 	return nil | 	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. | // SpecialPathsReply is the reply for SpecialPaths method. | ||||||
| type SpecialPathsReply struct { | type SpecialPathsReply struct { | ||||||
| 	Paths                *Paths   `sentinel:"" protobuf:"bytes,1,opt,name=paths,proto3" json:"paths,omitempty"` | 	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 (m *SpecialPathsReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*SpecialPathsReply) ProtoMessage()    {} | func (*SpecialPathsReply) ProtoMessage()    {} | ||||||
| func (*SpecialPathsReply) Descriptor() ([]byte, []int) { | func (*SpecialPathsReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{14} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{16} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *SpecialPathsReply) XXX_Unmarshal(b []byte) error { | 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 (m *HandleExistenceCheckArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*HandleExistenceCheckArgs) ProtoMessage()    {} | func (*HandleExistenceCheckArgs) ProtoMessage()    {} | ||||||
| func (*HandleExistenceCheckArgs) Descriptor() ([]byte, []int) { | func (*HandleExistenceCheckArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{15} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{17} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *HandleExistenceCheckArgs) XXX_Unmarshal(b []byte) error { | 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 (m *HandleExistenceCheckReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*HandleExistenceCheckReply) ProtoMessage()    {} | func (*HandleExistenceCheckReply) ProtoMessage()    {} | ||||||
| func (*HandleExistenceCheckReply) Descriptor() ([]byte, []int) { | func (*HandleExistenceCheckReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{16} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{18} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *HandleExistenceCheckReply) XXX_Unmarshal(b []byte) error { | 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 (m *SetupArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*SetupArgs) ProtoMessage()    {} | func (*SetupArgs) ProtoMessage()    {} | ||||||
| func (*SetupArgs) Descriptor() ([]byte, []int) { | func (*SetupArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{17} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{19} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *SetupArgs) XXX_Unmarshal(b []byte) error { | 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 (m *SetupReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*SetupReply) ProtoMessage()    {} | func (*SetupReply) ProtoMessage()    {} | ||||||
| func (*SetupReply) Descriptor() ([]byte, []int) { | func (*SetupReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{18} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{20} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *SetupReply) XXX_Unmarshal(b []byte) error { | 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 (m *TypeReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*TypeReply) ProtoMessage()    {} | func (*TypeReply) ProtoMessage()    {} | ||||||
| func (*TypeReply) Descriptor() ([]byte, []int) { | func (*TypeReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{19} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{21} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *TypeReply) XXX_Unmarshal(b []byte) error { | 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 (m *InvalidateKeyArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*InvalidateKeyArgs) ProtoMessage()    {} | func (*InvalidateKeyArgs) ProtoMessage()    {} | ||||||
| func (*InvalidateKeyArgs) Descriptor() ([]byte, []int) { | func (*InvalidateKeyArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{20} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{22} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *InvalidateKeyArgs) XXX_Unmarshal(b []byte) error { | 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 (m *StorageEntry) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageEntry) ProtoMessage()    {} | func (*StorageEntry) ProtoMessage()    {} | ||||||
| func (*StorageEntry) Descriptor() ([]byte, []int) { | func (*StorageEntry) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{21} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{23} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageEntry) XXX_Unmarshal(b []byte) error { | 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 (m *StorageListArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageListArgs) ProtoMessage()    {} | func (*StorageListArgs) ProtoMessage()    {} | ||||||
| func (*StorageListArgs) Descriptor() ([]byte, []int) { | func (*StorageListArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{22} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{24} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageListArgs) XXX_Unmarshal(b []byte) error { | 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 (m *StorageListReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageListReply) ProtoMessage()    {} | func (*StorageListReply) ProtoMessage()    {} | ||||||
| func (*StorageListReply) Descriptor() ([]byte, []int) { | func (*StorageListReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{23} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{25} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageListReply) XXX_Unmarshal(b []byte) error { | 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 (m *StorageGetArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageGetArgs) ProtoMessage()    {} | func (*StorageGetArgs) ProtoMessage()    {} | ||||||
| func (*StorageGetArgs) Descriptor() ([]byte, []int) { | func (*StorageGetArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{24} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{26} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageGetArgs) XXX_Unmarshal(b []byte) error { | 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 (m *StorageGetReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageGetReply) ProtoMessage()    {} | func (*StorageGetReply) ProtoMessage()    {} | ||||||
| func (*StorageGetReply) Descriptor() ([]byte, []int) { | func (*StorageGetReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{25} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{27} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageGetReply) XXX_Unmarshal(b []byte) error { | 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 (m *StoragePutArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StoragePutArgs) ProtoMessage()    {} | func (*StoragePutArgs) ProtoMessage()    {} | ||||||
| func (*StoragePutArgs) Descriptor() ([]byte, []int) { | func (*StoragePutArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{26} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{28} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StoragePutArgs) XXX_Unmarshal(b []byte) error { | 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 (m *StoragePutReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StoragePutReply) ProtoMessage()    {} | func (*StoragePutReply) ProtoMessage()    {} | ||||||
| func (*StoragePutReply) Descriptor() ([]byte, []int) { | func (*StoragePutReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{27} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{29} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StoragePutReply) XXX_Unmarshal(b []byte) error { | 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 (m *StorageDeleteArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageDeleteArgs) ProtoMessage()    {} | func (*StorageDeleteArgs) ProtoMessage()    {} | ||||||
| func (*StorageDeleteArgs) Descriptor() ([]byte, []int) { | func (*StorageDeleteArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{28} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{30} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageDeleteArgs) XXX_Unmarshal(b []byte) error { | 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 (m *StorageDeleteReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*StorageDeleteReply) ProtoMessage()    {} | func (*StorageDeleteReply) ProtoMessage()    {} | ||||||
| func (*StorageDeleteReply) Descriptor() ([]byte, []int) { | func (*StorageDeleteReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{29} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{31} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *StorageDeleteReply) XXX_Unmarshal(b []byte) error { | 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 (m *TTLReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*TTLReply) ProtoMessage()    {} | func (*TTLReply) ProtoMessage()    {} | ||||||
| func (*TTLReply) Descriptor() ([]byte, []int) { | func (*TTLReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{30} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{32} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *TTLReply) XXX_Unmarshal(b []byte) error { | 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 (m *SudoPrivilegeArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*SudoPrivilegeArgs) ProtoMessage()    {} | func (*SudoPrivilegeArgs) ProtoMessage()    {} | ||||||
| func (*SudoPrivilegeArgs) Descriptor() ([]byte, []int) { | func (*SudoPrivilegeArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{31} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{33} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *SudoPrivilegeArgs) XXX_Unmarshal(b []byte) error { | 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 (m *SudoPrivilegeReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*SudoPrivilegeReply) ProtoMessage()    {} | func (*SudoPrivilegeReply) ProtoMessage()    {} | ||||||
| func (*SudoPrivilegeReply) Descriptor() ([]byte, []int) { | func (*SudoPrivilegeReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{32} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{34} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *SudoPrivilegeReply) XXX_Unmarshal(b []byte) error { | 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 (m *TaintedReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*TaintedReply) ProtoMessage()    {} | func (*TaintedReply) ProtoMessage()    {} | ||||||
| func (*TaintedReply) Descriptor() ([]byte, []int) { | func (*TaintedReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{33} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{35} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *TaintedReply) XXX_Unmarshal(b []byte) error { | 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 (m *CachingDisabledReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*CachingDisabledReply) ProtoMessage()    {} | func (*CachingDisabledReply) ProtoMessage()    {} | ||||||
| func (*CachingDisabledReply) Descriptor() ([]byte, []int) { | func (*CachingDisabledReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{34} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{36} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *CachingDisabledReply) XXX_Unmarshal(b []byte) error { | 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 (m *ReplicationStateReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*ReplicationStateReply) ProtoMessage()    {} | func (*ReplicationStateReply) ProtoMessage()    {} | ||||||
| func (*ReplicationStateReply) Descriptor() ([]byte, []int) { | func (*ReplicationStateReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{35} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{37} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *ReplicationStateReply) XXX_Unmarshal(b []byte) error { | 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 (m *ResponseWrapDataArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*ResponseWrapDataArgs) ProtoMessage()    {} | func (*ResponseWrapDataArgs) ProtoMessage()    {} | ||||||
| func (*ResponseWrapDataArgs) Descriptor() ([]byte, []int) { | func (*ResponseWrapDataArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{36} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{38} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *ResponseWrapDataArgs) XXX_Unmarshal(b []byte) error { | 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 (m *ResponseWrapDataReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*ResponseWrapDataReply) ProtoMessage()    {} | func (*ResponseWrapDataReply) ProtoMessage()    {} | ||||||
| func (*ResponseWrapDataReply) Descriptor() ([]byte, []int) { | func (*ResponseWrapDataReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{37} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{39} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *ResponseWrapDataReply) XXX_Unmarshal(b []byte) error { | 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 (m *MlockEnabledReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*MlockEnabledReply) ProtoMessage()    {} | func (*MlockEnabledReply) ProtoMessage()    {} | ||||||
| func (*MlockEnabledReply) Descriptor() ([]byte, []int) { | func (*MlockEnabledReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{38} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{40} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *MlockEnabledReply) XXX_Unmarshal(b []byte) error { | 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 (m *LocalMountReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*LocalMountReply) ProtoMessage()    {} | func (*LocalMountReply) ProtoMessage()    {} | ||||||
| func (*LocalMountReply) Descriptor() ([]byte, []int) { | func (*LocalMountReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{39} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{41} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *LocalMountReply) XXX_Unmarshal(b []byte) error { | 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 (m *EntityInfoArgs) String() string { return proto.CompactTextString(m) } | ||||||
| func (*EntityInfoArgs) ProtoMessage()    {} | func (*EntityInfoArgs) ProtoMessage()    {} | ||||||
| func (*EntityInfoArgs) Descriptor() ([]byte, []int) { | func (*EntityInfoArgs) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{40} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{42} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *EntityInfoArgs) XXX_Unmarshal(b []byte) error { | 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 (m *EntityInfoReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*EntityInfoReply) ProtoMessage()    {} | func (*EntityInfoReply) ProtoMessage()    {} | ||||||
| func (*EntityInfoReply) Descriptor() ([]byte, []int) { | func (*EntityInfoReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{41} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{43} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *EntityInfoReply) XXX_Unmarshal(b []byte) error { | 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 (m *PluginEnvReply) String() string { return proto.CompactTextString(m) } | ||||||
| func (*PluginEnvReply) ProtoMessage()    {} | func (*PluginEnvReply) ProtoMessage()    {} | ||||||
| func (*PluginEnvReply) Descriptor() ([]byte, []int) { | func (*PluginEnvReply) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{42} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{44} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *PluginEnvReply) XXX_Unmarshal(b []byte) error { | 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 (m *Connection) String() string { return proto.CompactTextString(m) } | ||||||
| func (*Connection) ProtoMessage()    {} | func (*Connection) ProtoMessage()    {} | ||||||
| func (*Connection) Descriptor() ([]byte, []int) { | func (*Connection) Descriptor() ([]byte, []int) { | ||||||
| 	return fileDescriptor_4dbf1dfe0c11846b, []int{43} | 	return fileDescriptor_4dbf1dfe0c11846b, []int{45} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (m *Connection) XXX_Unmarshal(b []byte) error { | func (m *Connection) XXX_Unmarshal(b []byte) error { | ||||||
| @@ -2688,6 +2758,8 @@ func init() { | |||||||
| 	proto.RegisterType((*RequestWrapInfo)(nil), "pb.RequestWrapInfo") | 	proto.RegisterType((*RequestWrapInfo)(nil), "pb.RequestWrapInfo") | ||||||
| 	proto.RegisterType((*HandleRequestArgs)(nil), "pb.HandleRequestArgs") | 	proto.RegisterType((*HandleRequestArgs)(nil), "pb.HandleRequestArgs") | ||||||
| 	proto.RegisterType((*HandleRequestReply)(nil), "pb.HandleRequestReply") | 	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((*SpecialPathsReply)(nil), "pb.SpecialPathsReply") | ||||||
| 	proto.RegisterType((*HandleExistenceCheckArgs)(nil), "pb.HandleExistenceCheckArgs") | 	proto.RegisterType((*HandleExistenceCheckArgs)(nil), "pb.HandleExistenceCheckArgs") | ||||||
| 	proto.RegisterType((*HandleExistenceCheckReply)(nil), "pb.HandleExistenceCheckReply") | 	proto.RegisterType((*HandleExistenceCheckReply)(nil), "pb.HandleExistenceCheckReply") | ||||||
| @@ -2724,165 +2796,167 @@ func init() { | |||||||
| func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) } | func init() { proto.RegisterFile("sdk/plugin/pb/backend.proto", fileDescriptor_4dbf1dfe0c11846b) } | ||||||
|  |  | ||||||
| var fileDescriptor_4dbf1dfe0c11846b = []byte{ | var fileDescriptor_4dbf1dfe0c11846b = []byte{ | ||||||
| 	// 2519 bytes of a gzipped FileDescriptorProto | 	// 2556 bytes of a gzipped FileDescriptorProto | ||||||
| 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdb, 0x72, 0x1b, 0xc7, | 	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x73, 0xe3, 0xc6, | ||||||
| 	0xd1, 0x2e, 0x00, 0xc4, 0xa9, 0x71, 0x22, 0x46, 0xb4, 0xfe, 0x15, 0x24, 0xff, 0x82, 0xd7, 0x91, | 	0x11, 0x2e, 0x92, 0xe2, 0xab, 0xf9, 0x9e, 0x95, 0x37, 0x58, 0xee, 0x3a, 0x2b, 0xc3, 0xd9, 0x35, | ||||||
| 	0x0c, 0x33, 0x36, 0x68, 0xd1, 0x71, 0x2c, 0x27, 0x65, 0xa7, 0x68, 0x8a, 0x96, 0x19, 0x93, 0x36, | 	0xad, 0xd8, 0x94, 0x57, 0x1b, 0xc7, 0xeb, 0xa4, 0xec, 0x94, 0xac, 0x95, 0xd7, 0x8a, 0x25, 0x5b, | ||||||
| 	0x6b, 0x09, 0xc7, 0x39, 0x55, 0xc1, 0x83, 0xdd, 0x21, 0xb8, 0xc5, 0xc5, 0xee, 0x66, 0x76, 0x96, | 	0x05, 0xd1, 0x71, 0x5e, 0x55, 0xf4, 0x10, 0x18, 0x51, 0x28, 0x81, 0x00, 0x32, 0x18, 0x68, 0xc5, | ||||||
| 	0x22, 0xae, 0xf2, 0x16, 0x79, 0x8d, 0xdc, 0xe6, 0x2e, 0x77, 0x29, 0x57, 0xee, 0xf3, 0x0a, 0xb9, | 	0x5c, 0xf2, 0x2f, 0xf2, 0x0f, 0x72, 0xce, 0x35, 0xb7, 0xdc, 0x52, 0xae, 0xdc, 0xf3, 0x17, 0xf2, | ||||||
| 	0xcc, 0x33, 0xa4, 0xa6, 0x67, 0xf6, 0x04, 0x80, 0x96, 0x5c, 0xe5, 0xdc, 0xcd, 0x74, 0xf7, 0x9c, | 	0x3b, 0x52, 0xd3, 0x33, 0x78, 0x91, 0x94, 0x1f, 0x55, 0xce, 0x6d, 0xa6, 0xbb, 0xe7, 0xd5, 0xf3, | ||||||
| 	0x7a, 0xbe, 0xfe, 0xba, 0x67, 0x17, 0xee, 0x47, 0xce, 0xd5, 0x5e, 0xe8, 0xc5, 0x73, 0xd7, 0xdf, | 	0xf5, 0xd7, 0x3d, 0x00, 0xdc, 0x8f, 0x9c, 0xab, 0xbd, 0xd0, 0x8b, 0xe7, 0xae, 0xbf, 0x17, 0xce, | ||||||
| 	0x0b, 0x67, 0x7b, 0x33, 0x6a, 0x5f, 0x31, 0xdf, 0x19, 0x87, 0x3c, 0x10, 0x01, 0x29, 0x87, 0xb3, | 	0xf6, 0x66, 0xd4, 0xbe, 0x62, 0xbe, 0x33, 0x0e, 0x79, 0x20, 0x02, 0x52, 0x0e, 0x67, 0xc3, 0x87, | ||||||
| 	0xc1, 0xc3, 0x79, 0x10, 0xcc, 0x3d, 0xb6, 0x87, 0x92, 0x59, 0x7c, 0xb1, 0x27, 0xdc, 0x05, 0x8b, | 	0xf3, 0x20, 0x98, 0x7b, 0x6c, 0x0f, 0x25, 0xb3, 0xf8, 0x62, 0x4f, 0xb8, 0x0b, 0x16, 0x09, 0xba, | ||||||
| 	0x04, 0x5d, 0x84, 0xca, 0x68, 0x30, 0x90, 0x33, 0x78, 0xc1, 0xdc, 0xb5, 0xa9, 0xb7, 0xe7, 0x3a, | 	0x08, 0x95, 0xd1, 0x70, 0x28, 0x67, 0xf0, 0x82, 0xb9, 0x6b, 0x53, 0x6f, 0xcf, 0x75, 0x98, 0x2f, | ||||||
| 	0xcc, 0x17, 0xae, 0x58, 0x6a, 0x9d, 0x91, 0xd7, 0xa9, 0x55, 0x94, 0xc6, 0xac, 0x43, 0xf5, 0x68, | 	0x5c, 0xb1, 0xd4, 0x3a, 0x23, 0xaf, 0x53, 0xab, 0x28, 0x8d, 0x59, 0x87, 0xea, 0xd1, 0x22, 0x14, | ||||||
| 	0x11, 0x8a, 0xa5, 0x39, 0x84, 0xda, 0xe7, 0x8c, 0x3a, 0x8c, 0x93, 0xbb, 0x50, 0xbb, 0xc4, 0x96, | 	0x4b, 0x73, 0x07, 0x6a, 0x9f, 0x30, 0xea, 0x30, 0x4e, 0xee, 0x42, 0xed, 0x12, 0x5b, 0x46, 0x69, | ||||||
| 	0x51, 0x1a, 0x56, 0x46, 0x4d, 0x4b, 0xf7, 0xcc, 0x3f, 0x00, 0x9c, 0xc9, 0x31, 0x47, 0x9c, 0x07, | 	0xa7, 0x32, 0x6a, 0x5a, 0xba, 0x67, 0xfe, 0x01, 0xe0, 0x4c, 0x8e, 0x39, 0xe2, 0x3c, 0xe0, 0xe4, | ||||||
| 	0x9c, 0xdc, 0x83, 0x06, 0xe3, 0x7c, 0x2a, 0x96, 0x21, 0x33, 0x4a, 0xc3, 0xd2, 0xa8, 0x63, 0xd5, | 	0x1e, 0x34, 0x18, 0xe7, 0x53, 0xb1, 0x0c, 0x99, 0x51, 0xda, 0x29, 0x8d, 0x3a, 0x56, 0x9d, 0x71, | ||||||
| 	0x19, 0xe7, 0x93, 0x65, 0xc8, 0xc8, 0xff, 0x81, 0x6c, 0x4e, 0x17, 0xd1, 0xdc, 0x28, 0x0f, 0x4b, | 	0x3e, 0x59, 0x86, 0x8c, 0xfc, 0x08, 0x64, 0x73, 0xba, 0x88, 0xe6, 0x46, 0x79, 0xa7, 0x24, 0x67, | ||||||
| 	0x72, 0x06, 0xc6, 0xf9, 0x69, 0x34, 0x4f, 0xc6, 0xd8, 0x81, 0xc3, 0x8c, 0xca, 0xb0, 0x34, 0xaa, | 	0x60, 0x9c, 0x9f, 0x46, 0xf3, 0x64, 0x8c, 0x1d, 0x38, 0xcc, 0xa8, 0xec, 0x94, 0x46, 0x15, 0x1c, | ||||||
| 	0xe0, 0x98, 0xc3, 0xc0, 0x61, 0xe6, 0x5f, 0x4a, 0x50, 0x3d, 0xa3, 0xe2, 0x32, 0x22, 0x04, 0xb6, | 	0x73, 0x18, 0x38, 0xcc, 0xfc, 0x6b, 0x09, 0xaa, 0x67, 0x54, 0x5c, 0x46, 0x84, 0xc0, 0x16, 0x0f, | ||||||
| 	0x78, 0x10, 0x08, 0xbd, 0x38, 0xb6, 0xc9, 0x08, 0x7a, 0xb1, 0x4f, 0x63, 0x71, 0x29, 0x4f, 0x65, | 	0x02, 0xa1, 0x17, 0xc7, 0x36, 0x19, 0x41, 0x2f, 0xf6, 0x69, 0x2c, 0x2e, 0xe5, 0xa9, 0x6c, 0x2a, | ||||||
| 	0x53, 0xc1, 0x1c, 0xa3, 0x8c, 0xea, 0x55, 0x31, 0x79, 0x13, 0x3a, 0x5e, 0x60, 0x53, 0x6f, 0x1a, | 	0x98, 0x63, 0x94, 0x51, 0xbd, 0x2a, 0x26, 0xaf, 0x43, 0xc7, 0x0b, 0x6c, 0xea, 0x4d, 0x23, 0x11, | ||||||
| 	0x89, 0x80, 0xd3, 0xb9, 0x5c, 0x47, 0xda, 0xb5, 0x51, 0x78, 0xae, 0x64, 0x64, 0x17, 0xfa, 0x11, | 	0x70, 0x3a, 0x97, 0xeb, 0x48, 0xbb, 0x36, 0x0a, 0xcf, 0x95, 0x8c, 0xec, 0xc2, 0x20, 0x62, 0xd4, | ||||||
| 	0xa3, 0xde, 0xf4, 0x05, 0xa7, 0x61, 0x6a, 0xb8, 0xa5, 0x26, 0x94, 0x8a, 0x6f, 0x38, 0x0d, 0xb5, | 	0x9b, 0xbe, 0xe4, 0x34, 0x4c, 0x0d, 0xb7, 0xd4, 0x84, 0x52, 0xf1, 0x25, 0xa7, 0xa1, 0xb6, 0x35, | ||||||
| 	0xad, 0xf9, 0xf7, 0x1a, 0xd4, 0x2d, 0xf6, 0xa7, 0x98, 0x45, 0x82, 0x74, 0xa1, 0xec, 0x3a, 0x78, | 	0xff, 0x59, 0x83, 0xba, 0xc5, 0xfe, 0x14, 0xb3, 0x48, 0x90, 0x2e, 0x94, 0x5d, 0x07, 0x4f, 0xdb, | ||||||
| 	0xda, 0xa6, 0x55, 0x76, 0x1d, 0x32, 0x06, 0x62, 0xb1, 0xd0, 0x93, 0x4b, 0xbb, 0x81, 0x7f, 0xe8, | 	0xb4, 0xca, 0xae, 0x43, 0xc6, 0x40, 0x2c, 0x16, 0x7a, 0x72, 0x69, 0x37, 0xf0, 0x0f, 0xbd, 0x38, | ||||||
| 	0xc5, 0x91, 0x60, 0x5c, 0x9f, 0x79, 0x83, 0x86, 0x3c, 0x80, 0x66, 0x10, 0x32, 0x8e, 0x32, 0x74, | 	0x12, 0x8c, 0xeb, 0x33, 0x6f, 0xd0, 0x90, 0x07, 0xd0, 0x0c, 0x42, 0xc6, 0x51, 0x86, 0x0e, 0x68, | ||||||
| 	0x40, 0xd3, 0xca, 0x04, 0xf2, 0xe0, 0x21, 0x15, 0x97, 0xc6, 0x16, 0x2a, 0xb0, 0x2d, 0x65, 0x0e, | 	0x5a, 0x99, 0x40, 0x1e, 0x3c, 0xa4, 0xe2, 0xd2, 0xd8, 0x42, 0x05, 0xb6, 0xa5, 0xcc, 0xa1, 0x82, | ||||||
| 	0x15, 0xd4, 0xa8, 0x2a, 0x99, 0x6c, 0x13, 0x13, 0x6a, 0x11, 0xb3, 0x39, 0x13, 0x46, 0x6d, 0x58, | 	0x1a, 0x55, 0x25, 0x93, 0x6d, 0x62, 0x42, 0x2d, 0x62, 0x36, 0x67, 0xc2, 0xa8, 0xed, 0x94, 0x46, | ||||||
| 	0x1a, 0xb5, 0xf6, 0x61, 0x1c, 0xce, 0xc6, 0xe7, 0x28, 0xb1, 0xb4, 0x86, 0x3c, 0x80, 0x2d, 0xe9, | 	0xad, 0x7d, 0x18, 0x87, 0xb3, 0xf1, 0x39, 0x4a, 0x2c, 0xad, 0x21, 0x0f, 0x60, 0x4b, 0xfa, 0xc5, | ||||||
| 	0x17, 0xa3, 0x8e, 0x16, 0x0d, 0x69, 0x71, 0x10, 0x8b, 0x4b, 0x0b, 0xa5, 0x64, 0x1f, 0xea, 0xea, | 	0xa8, 0xa3, 0x45, 0x43, 0x5a, 0x1c, 0xc4, 0xe2, 0xd2, 0x42, 0x29, 0xd9, 0x87, 0xba, 0xba, 0xd3, | ||||||
| 	0x4e, 0x23, 0xa3, 0x31, 0xac, 0x8c, 0x5a, 0xfb, 0x86, 0x34, 0xd0, 0xa7, 0x1c, 0x2b, 0x18, 0x44, | 	0xc8, 0x68, 0xec, 0x54, 0x46, 0xad, 0x7d, 0x43, 0x1a, 0xe8, 0x53, 0x8e, 0x15, 0x0c, 0xa2, 0x23, | ||||||
| 	0x47, 0xbe, 0xe0, 0x4b, 0x2b, 0x31, 0x24, 0x6f, 0x40, 0xdb, 0xf6, 0x5c, 0xe6, 0x8b, 0xa9, 0x08, | 	0x5f, 0xf0, 0xa5, 0x95, 0x18, 0x92, 0xd7, 0xa0, 0x6d, 0x7b, 0x2e, 0xf3, 0xc5, 0x54, 0x04, 0x57, | ||||||
| 	0xae, 0x98, 0x6f, 0x34, 0x71, 0x47, 0x2d, 0x25, 0x9b, 0x48, 0x11, 0xd9, 0x87, 0xd7, 0xf2, 0x26, | 	0xcc, 0x37, 0x9a, 0xb8, 0xa3, 0x96, 0x92, 0x4d, 0xa4, 0x88, 0xec, 0xc3, 0x2b, 0x79, 0x93, 0x29, | ||||||
| 	0x53, 0x6a, 0xdb, 0x2c, 0x8a, 0x02, 0x6e, 0x00, 0xda, 0xde, 0xc9, 0xd9, 0x1e, 0x68, 0x95, 0x9c, | 	0xb5, 0x6d, 0x16, 0x45, 0x01, 0x37, 0x00, 0x6d, 0xef, 0xe4, 0x6c, 0x0f, 0xb4, 0x4a, 0x4e, 0xeb, | ||||||
| 	0xd6, 0x71, 0xa3, 0xd0, 0xa3, 0xcb, 0xa9, 0x4f, 0x17, 0xcc, 0x68, 0xa9, 0x69, 0xb5, 0xec, 0x4b, | 	0xb8, 0x51, 0xe8, 0xd1, 0xe5, 0xd4, 0xa7, 0x0b, 0x66, 0xb4, 0xd4, 0xb4, 0x5a, 0xf6, 0x19, 0x5d, | ||||||
| 	0xba, 0x60, 0xe4, 0x21, 0xb4, 0x16, 0x41, 0xec, 0x8b, 0x69, 0x18, 0xb8, 0xbe, 0x30, 0xda, 0x68, | 	0x30, 0xf2, 0x10, 0x5a, 0x8b, 0x20, 0xf6, 0xc5, 0x34, 0x0c, 0x5c, 0x5f, 0x18, 0x6d, 0xb4, 0x00, | ||||||
| 	0x01, 0x28, 0x3a, 0x93, 0x12, 0xf2, 0x3a, 0xa8, 0x9e, 0x02, 0x63, 0x47, 0xf9, 0x15, 0x25, 0x08, | 	0x14, 0x9d, 0x49, 0x09, 0x79, 0x15, 0x54, 0x4f, 0x81, 0xb1, 0xa3, 0xfc, 0x8a, 0x12, 0x84, 0xe3, | ||||||
| 	0xc7, 0x47, 0xd0, 0x55, 0xea, 0x74, 0x3f, 0x5d, 0x34, 0xe9, 0xa0, 0x34, 0xdd, 0xc9, 0x7b, 0xd0, | 	0x23, 0xe8, 0x2a, 0x75, 0xba, 0x9f, 0x2e, 0x9a, 0x74, 0x50, 0x9a, 0xee, 0xe4, 0x1d, 0x68, 0x22, | ||||||
| 	0x44, 0x3c, 0xb8, 0xfe, 0x45, 0x60, 0xf4, 0xd0, 0x6f, 0x77, 0x72, 0x6e, 0x91, 0x98, 0x38, 0xf6, | 	0x1e, 0x5c, 0xff, 0x22, 0x30, 0x7a, 0xe8, 0xb7, 0x3b, 0x39, 0xb7, 0x48, 0x4c, 0x1c, 0xfb, 0x17, | ||||||
| 	0x2f, 0x02, 0xab, 0xf1, 0x42, 0xb7, 0xc8, 0xc7, 0x70, 0xbf, 0x70, 0x5e, 0xce, 0x16, 0xd4, 0xf5, | 	0x81, 0xd5, 0x78, 0xa9, 0x5b, 0xe4, 0x03, 0xb8, 0x5f, 0x38, 0x2f, 0x67, 0x0b, 0xea, 0xfa, 0xae, | ||||||
| 	0x5d, 0x7f, 0x3e, 0x8d, 0x23, 0x16, 0x19, 0xdb, 0x88, 0x70, 0x23, 0x77, 0x6a, 0x2b, 0x31, 0xf8, | 	0x3f, 0x9f, 0xc6, 0x11, 0x8b, 0x8c, 0x3e, 0x22, 0xdc, 0xc8, 0x9d, 0xda, 0x4a, 0x0c, 0xbe, 0x88, | ||||||
| 	0x3a, 0x62, 0x11, 0xb9, 0x0f, 0x4d, 0x15, 0xa4, 0x53, 0xd7, 0x31, 0xfa, 0xb8, 0xa5, 0x86, 0x12, | 	0x58, 0x44, 0xee, 0x43, 0x53, 0x05, 0xe9, 0xd4, 0x75, 0x8c, 0x01, 0x6e, 0xa9, 0xa1, 0x04, 0xc7, | ||||||
| 	0x1c, 0x3b, 0xe4, 0x2d, 0xe8, 0x85, 0x81, 0xe7, 0xda, 0xcb, 0x69, 0x70, 0xcd, 0x38, 0x77, 0x1d, | 	0x0e, 0x79, 0x03, 0x7a, 0x61, 0xe0, 0xb9, 0xf6, 0x72, 0x1a, 0x5c, 0x33, 0xce, 0x5d, 0x87, 0x19, | ||||||
| 	0x66, 0x90, 0x61, 0x69, 0xd4, 0xb0, 0xba, 0x4a, 0xfc, 0x95, 0x96, 0x6e, 0x0a, 0x8d, 0x3b, 0x68, | 	0x64, 0xa7, 0x34, 0x6a, 0x58, 0x5d, 0x25, 0xfe, 0x5c, 0x4b, 0x37, 0x85, 0xc6, 0x1d, 0x34, 0x5c, | ||||||
| 	0xb8, 0x16, 0x1a, 0x63, 0x00, 0x3b, 0xf0, 0x7d, 0x66, 0x23, 0xfc, 0x76, 0xf0, 0x84, 0x5d, 0x79, | 	0x0b, 0x8d, 0x31, 0x80, 0x1d, 0xf8, 0x3e, 0xb3, 0x11, 0x7e, 0xdb, 0x78, 0xc2, 0xae, 0x3c, 0xe1, | ||||||
| 	0xc2, 0xc3, 0x54, 0x6a, 0xe5, 0x2c, 0x06, 0x9f, 0x41, 0x3b, 0x0f, 0x05, 0xb2, 0x0d, 0x95, 0x2b, | 	0x61, 0x2a, 0xb5, 0x72, 0x16, 0xc3, 0x8f, 0xa1, 0x9d, 0x87, 0x02, 0xe9, 0x43, 0xe5, 0x8a, 0x2d, | ||||||
| 	0xb6, 0xd4, 0xf0, 0x97, 0x4d, 0x32, 0x84, 0xea, 0x35, 0xf5, 0x62, 0x86, 0x90, 0xd7, 0x40, 0x54, | 	0x35, 0xfc, 0x65, 0x93, 0xec, 0x40, 0xf5, 0x9a, 0x7a, 0x31, 0x43, 0xc8, 0x6b, 0x20, 0xaa, 0x21, | ||||||
| 	0x43, 0x2c, 0xa5, 0xf8, 0x45, 0xf9, 0x69, 0xc9, 0xfc, 0x77, 0x15, 0xb6, 0x24, 0xf8, 0xc8, 0x07, | 	0x96, 0x52, 0xfc, 0xa2, 0xfc, 0xac, 0x64, 0xfe, 0xb7, 0x0a, 0x5b, 0x12, 0x7c, 0xe4, 0x5d, 0xe8, | ||||||
| 	0xd0, 0xf1, 0x18, 0x8d, 0xd8, 0x34, 0x08, 0xe5, 0x02, 0x11, 0x4e, 0xd5, 0xda, 0xdf, 0x96, 0xc3, | 	0x78, 0x8c, 0x46, 0x6c, 0x1a, 0x84, 0x72, 0x81, 0x08, 0xa7, 0x6a, 0xed, 0xf7, 0xe5, 0xb0, 0x13, | ||||||
| 	0x4e, 0xa4, 0xe2, 0x2b, 0x25, 0xb7, 0xda, 0x5e, 0xae, 0x27, 0x43, 0xda, 0xf5, 0x05, 0xe3, 0x3e, | 	0xa9, 0xf8, 0x5c, 0xc9, 0xad, 0xb6, 0x97, 0xeb, 0xc9, 0x90, 0x76, 0x7d, 0xc1, 0xb8, 0x4f, 0xbd, | ||||||
| 	0xf5, 0xa6, 0x18, 0x0c, 0x2a, 0xc0, 0xda, 0x89, 0xf0, 0x99, 0x0c, 0x8a, 0x55, 0x1c, 0x55, 0xd6, | 	0x29, 0x06, 0x83, 0x0a, 0xb0, 0x76, 0x22, 0x7c, 0x2e, 0x83, 0x62, 0x15, 0x47, 0x95, 0x75, 0x1c, | ||||||
| 	0x71, 0x34, 0x80, 0x06, 0xfa, 0xce, 0x65, 0x91, 0x0e, 0xf6, 0xb4, 0x4f, 0xf6, 0xa1, 0xb1, 0x60, | 	0x0d, 0xa1, 0x81, 0xbe, 0x73, 0x59, 0xa4, 0x83, 0x3d, 0xed, 0x93, 0x7d, 0x68, 0x2c, 0x98, 0xa0, | ||||||
| 	0x82, 0xea, 0x58, 0x93, 0x21, 0x71, 0x37, 0x89, 0x99, 0xf1, 0xa9, 0x56, 0xa8, 0x80, 0x48, 0xed, | 	0x3a, 0xd6, 0x64, 0x48, 0xdc, 0x4d, 0x62, 0x66, 0x7c, 0xaa, 0x15, 0x2a, 0x20, 0x52, 0xbb, 0xb5, | ||||||
| 	0xd6, 0x22, 0xa2, 0xb6, 0x1e, 0x11, 0x03, 0x68, 0xa4, 0xa0, 0xab, 0xab, 0x1b, 0x4e, 0xfa, 0x92, | 	0x88, 0xa8, 0xad, 0x47, 0xc4, 0x10, 0x1a, 0x29, 0xe8, 0xea, 0xea, 0x86, 0x93, 0xbe, 0xa4, 0xd9, | ||||||
| 	0x66, 0x43, 0xc6, 0xdd, 0xc0, 0x31, 0x1a, 0x08, 0x14, 0xdd, 0x93, 0x24, 0xe9, 0xc7, 0x0b, 0x05, | 	0x90, 0x71, 0x37, 0x70, 0x8c, 0x06, 0x02, 0x45, 0xf7, 0x24, 0x49, 0xfa, 0xf1, 0x42, 0x41, 0xa8, | ||||||
| 	0xa1, 0xa6, 0x22, 0x49, 0x3f, 0x5e, 0xac, 0x23, 0x06, 0x56, 0x10, 0xf3, 0x13, 0xa8, 0x52, 0xcf, | 	0xa9, 0x48, 0xd2, 0x8f, 0x17, 0xeb, 0x88, 0x81, 0x15, 0xc4, 0xfc, 0x04, 0xaa, 0xd4, 0x73, 0x69, | ||||||
| 	0xa5, 0x11, 0x86, 0x90, 0xbc, 0x59, 0xcd, 0xf7, 0xe3, 0x03, 0x29, 0xb5, 0x94, 0x92, 0xbc, 0x0f, | 	0x84, 0x21, 0x24, 0x6f, 0x56, 0xf3, 0xfd, 0xf8, 0x40, 0x4a, 0x2d, 0xa5, 0x24, 0x4f, 0xa1, 0x33, | ||||||
| 	0x9d, 0x39, 0x0f, 0xe2, 0x70, 0x8a, 0x5d, 0x16, 0x19, 0x6d, 0x3c, 0xed, 0xaa, 0x75, 0x1b, 0x8d, | 	0xe7, 0x41, 0x1c, 0x4e, 0xb1, 0xcb, 0x22, 0xa3, 0x8d, 0xa7, 0x5d, 0xb5, 0x6e, 0xa3, 0xd1, 0x81, | ||||||
| 	0x0e, 0x94, 0x8d, 0x8c, 0xc0, 0x59, 0x10, 0xfb, 0xce, 0xd4, 0x76, 0x1d, 0x1e, 0x19, 0x1d, 0x74, | 	0xb2, 0x91, 0x11, 0x38, 0x0b, 0x62, 0xdf, 0x99, 0xda, 0xae, 0xc3, 0x23, 0xa3, 0x83, 0xce, 0x03, | ||||||
| 	0x1e, 0xa0, 0xe8, 0x50, 0x4a, 0x64, 0x88, 0xa9, 0x10, 0x48, 0x1d, 0xdc, 0x45, 0x9b, 0x0e, 0x4a, | 	0x14, 0x1d, 0x4a, 0x89, 0x0c, 0x31, 0x15, 0x02, 0xa9, 0x83, 0xbb, 0x68, 0xd3, 0x41, 0xe9, 0x59, | ||||||
| 	0xcf, 0x12, 0x2f, 0xff, 0x14, 0xfa, 0x49, 0x62, 0xca, 0x2c, 0x7b, 0x68, 0xb9, 0x9d, 0x28, 0x52, | 	0xe2, 0xe5, 0x9f, 0xc2, 0x20, 0x49, 0x4c, 0x99, 0x65, 0x0f, 0x2d, 0xfb, 0x89, 0x22, 0x35, 0x1e, | ||||||
| 	0xe3, 0x11, 0x6c, 0xb3, 0x1b, 0x49, 0xa1, 0xae, 0x98, 0x2e, 0xe8, 0xcd, 0x54, 0x08, 0x4f, 0x87, | 	0x41, 0x9f, 0xdd, 0x48, 0x0a, 0x75, 0xc5, 0x74, 0x41, 0x6f, 0xa6, 0x42, 0x78, 0x3a, 0xa4, 0xba, | ||||||
| 	0x54, 0x37, 0x91, 0x9f, 0xd2, 0x9b, 0x89, 0xf0, 0x64, 0xfc, 0xab, 0xd5, 0x31, 0xfe, 0xfb, 0x98, | 	0x89, 0xfc, 0x94, 0xde, 0x4c, 0x84, 0x27, 0xe3, 0x5f, 0xad, 0x8e, 0xf1, 0x3f, 0xc0, 0x64, 0xd4, | ||||||
| 	0x8c, 0x9a, 0x28, 0xc1, 0xf8, 0xdf, 0x85, 0xbe, 0x1f, 0x4c, 0x1d, 0x76, 0x41, 0x63, 0x4f, 0xa8, | 	0x44, 0x09, 0xc6, 0xff, 0x2e, 0x0c, 0xfc, 0x60, 0xea, 0xb0, 0x0b, 0x1a, 0x7b, 0x42, 0xad, 0xbb, | ||||||
| 	0x75, 0x97, 0x3a, 0x98, 0x7a, 0x7e, 0xf0, 0x4c, 0xc9, 0x71, 0xd9, 0xe5, 0xe0, 0x97, 0xd0, 0x29, | 	0xd4, 0xc1, 0xd4, 0xf3, 0x83, 0xe7, 0x4a, 0x8e, 0xcb, 0x2e, 0x87, 0xbf, 0x84, 0x4e, 0xe1, 0xba, | ||||||
| 	0x5c, 0xf7, 0x06, 0xd0, 0xef, 0xe4, 0x41, 0xdf, 0xcc, 0x03, 0xfd, 0x9f, 0x5b, 0x00, 0x78, 0xef, | 	0x37, 0x80, 0x7e, 0x3b, 0x0f, 0xfa, 0x66, 0x1e, 0xe8, 0xff, 0xde, 0x02, 0xc0, 0x7b, 0x57, 0x43, | ||||||
| 	0x6a, 0xe8, 0x6a, 0xb6, 0xc8, 0x83, 0xa1, 0xbc, 0x01, 0x0c, 0x94, 0x33, 0x5f, 0x68, 0xe0, 0xea, | 	0x57, 0xb3, 0x45, 0x1e, 0x0c, 0xe5, 0x0d, 0x60, 0xa0, 0x9c, 0xf9, 0x42, 0x03, 0x57, 0xf7, 0xbe, | ||||||
| 	0xde, 0xf7, 0x62, 0x36, 0xc9, 0x17, 0xd5, 0x5c, 0xbe, 0x78, 0x07, 0xb6, 0x24, 0x3e, 0x8d, 0x5a, | 	0x11, 0xb3, 0x49, 0xbe, 0xa8, 0xe6, 0xf2, 0xc5, 0x5b, 0xb0, 0x25, 0xf1, 0x69, 0xd4, 0x32, 0x5a, | ||||||
| 	0x46, 0xeb, 0xd9, 0x8e, 0x10, 0xc9, 0x0a, 0xc5, 0x68, 0xb5, 0x16, 0x34, 0xf5, 0xf5, 0xa0, 0xc9, | 	0xcf, 0x76, 0x84, 0x48, 0x56, 0x28, 0x46, 0xab, 0xb5, 0xa0, 0xa9, 0xaf, 0x07, 0x4d, 0x1e, 0x8d, | ||||||
| 	0xa3, 0xb1, 0x51, 0x44, 0xe3, 0x9b, 0xd0, 0xb1, 0x39, 0xc3, 0xdc, 0x35, 0x95, 0xc5, 0x88, 0x46, | 	0x8d, 0x22, 0x1a, 0x5f, 0x87, 0x8e, 0xcd, 0x19, 0xe6, 0xae, 0xa9, 0x2c, 0x46, 0x34, 0x5a, 0xdb, | ||||||
| 	0x6b, 0x3b, 0x11, 0x4e, 0xdc, 0x05, 0x93, 0xfe, 0x93, 0x17, 0x07, 0xa8, 0x92, 0xcd, 0x8d, 0xf7, | 	0x89, 0x70, 0xe2, 0x2e, 0x98, 0xf4, 0x9f, 0xbc, 0x38, 0x40, 0x95, 0x6c, 0x6e, 0xbc, 0xd7, 0xd6, | ||||||
| 	0xda, 0xda, 0x78, 0xaf, 0x58, 0x09, 0x78, 0x4c, 0x33, 0x3e, 0xb6, 0x73, 0x51, 0xd3, 0x29, 0x44, | 	0xc6, 0x7b, 0xc5, 0x4a, 0xc0, 0x63, 0x9a, 0xf1, 0xb1, 0x9d, 0x8b, 0x9a, 0x4e, 0x21, 0x6a, 0x0a, | ||||||
| 	0x4d, 0x21, 0x34, 0xba, 0x2b, 0xa1, 0xb1, 0x82, 0xdf, 0xde, 0x1a, 0x7e, 0xdf, 0x80, 0xb6, 0x74, | 	0xa1, 0xd1, 0x5d, 0x09, 0x8d, 0x15, 0xfc, 0xf6, 0xd6, 0xf0, 0xfb, 0x1a, 0xb4, 0xa5, 0x03, 0xa2, | ||||||
| 	0x40, 0x14, 0x52, 0x9b, 0xc9, 0x09, 0xb6, 0x95, 0x23, 0x52, 0xd9, 0xb1, 0x83, 0xd1, 0x1e, 0xcf, | 	0x90, 0xda, 0x4c, 0x4e, 0xd0, 0x57, 0x8e, 0x48, 0x65, 0xc7, 0x0e, 0x46, 0x7b, 0x3c, 0x9b, 0x2d, | ||||||
| 	0x66, 0xcb, 0xcb, 0xc0, 0x63, 0x19, 0x61, 0xb7, 0x52, 0xd9, 0xb1, 0x23, 0xf7, 0x8b, 0x08, 0x24, | 	0x2f, 0x03, 0x8f, 0x65, 0x84, 0xdd, 0x4a, 0x65, 0xc7, 0x8e, 0xdc, 0x2f, 0x22, 0x90, 0x20, 0x02, | ||||||
| 	0x88, 0x40, 0x6c, 0x0f, 0x3e, 0x84, 0x66, 0xea, 0xf5, 0x1f, 0x04, 0xa6, 0xbf, 0x96, 0xa0, 0x9d, | 	0xb1, 0x3d, 0x7c, 0x0f, 0x9a, 0xa9, 0xd7, 0xbf, 0x17, 0x98, 0xfe, 0x5e, 0x82, 0x76, 0x9e, 0x14, | ||||||
| 	0x27, 0x45, 0x39, 0x78, 0x32, 0x39, 0xc1, 0xc1, 0x15, 0x4b, 0x36, 0x65, 0x39, 0xc1, 0x99, 0xcf, | 	0xe5, 0xe0, 0xc9, 0xe4, 0x04, 0x07, 0x57, 0x2c, 0xd9, 0x94, 0xe5, 0x04, 0x67, 0x3e, 0x7b, 0x49, | ||||||
| 	0x5e, 0xd0, 0x99, 0xa7, 0x26, 0x68, 0x58, 0x99, 0x40, 0x6a, 0x5d, 0xdf, 0xe6, 0x6c, 0x91, 0xa0, | 	0x67, 0x9e, 0x9a, 0xa0, 0x61, 0x65, 0x02, 0xa9, 0x75, 0x7d, 0x9b, 0xb3, 0x45, 0x82, 0xaa, 0x8a, | ||||||
| 	0xaa, 0x62, 0x65, 0x02, 0xf2, 0x11, 0x80, 0x1b, 0x45, 0x31, 0x53, 0x37, 0xb7, 0x85, 0x94, 0x31, | 	0x95, 0x09, 0xc8, 0xfb, 0x00, 0x6e, 0x14, 0xc5, 0x4c, 0xdd, 0xdc, 0x16, 0x52, 0xc6, 0x70, 0xac, | ||||||
| 	0x18, 0xab, 0x1a, 0x73, 0x9c, 0xd4, 0x98, 0xe3, 0x49, 0x52, 0x63, 0x5a, 0x4d, 0xb4, 0xc6, 0x2b, | 	0x6a, 0xcc, 0x71, 0x52, 0x63, 0x8e, 0x27, 0x49, 0x8d, 0x69, 0x35, 0xd1, 0x1a, 0xaf, 0xf4, 0x2e, | ||||||
| 	0xbd, 0x0b, 0x35, 0x79, 0x41, 0x93, 0x13, 0x44, 0x5e, 0xc5, 0xd2, 0x3d, 0xf3, 0xcf, 0x50, 0x53, | 	0xd4, 0xe4, 0x05, 0x4d, 0x4e, 0x10, 0x79, 0x15, 0x4b, 0xf7, 0xcc, 0xbf, 0x40, 0x4d, 0x55, 0x21, | ||||||
| 	0x55, 0xc8, 0xff, 0x94, 0xe8, 0xef, 0x41, 0x43, 0xcd, 0xed, 0x3a, 0x3a, 0x56, 0xea, 0xd8, 0x3f, | 	0xff, 0x57, 0xa2, 0xbf, 0x07, 0x0d, 0x35, 0xb7, 0xeb, 0xe8, 0x58, 0xa9, 0x63, 0xff, 0xd8, 0x31, | ||||||
| 	0x76, 0xcc, 0xef, 0xca, 0xd0, 0xb0, 0x58, 0x14, 0x06, 0x7e, 0xc4, 0x72, 0x55, 0x52, 0xe9, 0xa5, | 	0xbf, 0x2e, 0x43, 0xc3, 0x62, 0x51, 0x18, 0xf8, 0x11, 0xcb, 0x55, 0x49, 0xa5, 0x6f, 0xad, 0x92, | ||||||
| 	0x55, 0x52, 0x79, 0x63, 0x95, 0x94, 0xd4, 0x5e, 0x95, 0x5c, 0xed, 0x35, 0x80, 0x06, 0x67, 0x8e, | 	0xca, 0x1b, 0xab, 0xa4, 0xa4, 0xf6, 0xaa, 0xe4, 0x6a, 0xaf, 0x21, 0x34, 0x38, 0x73, 0x5c, 0xce, | ||||||
| 	0xcb, 0x99, 0x2d, 0x74, 0x9d, 0x96, 0xf6, 0xa5, 0xee, 0x05, 0xe5, 0x32, 0xbd, 0x47, 0x98, 0x43, | 	0x6c, 0xa1, 0xeb, 0xb4, 0xb4, 0x2f, 0x75, 0x2f, 0x29, 0x97, 0xe9, 0x3d, 0xc2, 0x1c, 0xd2, 0xb4, | ||||||
| 	0x9a, 0x56, 0xda, 0x27, 0x4f, 0xf2, 0xc5, 0x85, 0x2a, 0xdb, 0x76, 0x54, 0x71, 0xa1, 0xb6, 0xbb, | 	0xd2, 0x3e, 0x79, 0x92, 0x2f, 0x2e, 0x54, 0xd9, 0xb6, 0xad, 0x8a, 0x0b, 0xb5, 0xdd, 0x0d, 0xd5, | ||||||
| 	0xa1, 0xba, 0x78, 0x3f, 0x2b, 0xd2, 0xea, 0x18, 0xcd, 0xf7, 0xf2, 0x03, 0x36, 0x57, 0x69, 0x3f, | 	0xc5, 0xd3, 0xac, 0x48, 0xab, 0x63, 0x34, 0xdf, 0xcb, 0x0f, 0xd8, 0x5c, 0xa5, 0xfd, 0x60, 0x39, | ||||||
| 	0x5a, 0xce, 0xfe, 0xae, 0x0c, 0xdb, 0xab, 0x7b, 0xdb, 0x80, 0xc0, 0x1d, 0xa8, 0xaa, 0xdc, 0xa7, | 	0xfb, 0xeb, 0x32, 0xf4, 0x57, 0xf7, 0xb6, 0x01, 0x81, 0xdb, 0x50, 0x55, 0xb9, 0x4f, 0xc3, 0x57, | ||||||
| 	0xe1, 0x2b, 0xd6, 0xb2, 0x5e, 0x65, 0x85, 0xe8, 0x7e, 0xb5, 0x4a, 0x1a, 0x2f, 0x87, 0x5e, 0x91, | 	0xac, 0x65, 0xbd, 0xca, 0x0a, 0xd1, 0xfd, 0x6a, 0x95, 0x34, 0xbe, 0x1d, 0x7a, 0x45, 0x42, 0x79, | ||||||
| 	0x50, 0xde, 0x86, 0x6d, 0xe9, 0xa2, 0x90, 0x39, 0x59, 0x3d, 0xa7, 0x18, 0xb0, 0xa7, 0xe5, 0x69, | 	0x13, 0xfa, 0xd2, 0x45, 0x21, 0x73, 0xb2, 0x7a, 0x4e, 0x31, 0x60, 0x4f, 0xcb, 0xd3, 0x8a, 0x6e, | ||||||
| 	0x45, 0xb7, 0x0b, 0xfd, 0xc4, 0x34, 0xe3, 0x86, 0x5a, 0xc1, 0xf6, 0x28, 0xa1, 0x88, 0xbb, 0x50, | 	0x17, 0x06, 0x89, 0x69, 0xc6, 0x0d, 0xb5, 0x82, 0xed, 0x51, 0x42, 0x11, 0x77, 0xa1, 0x76, 0x11, | ||||||
| 	0xbb, 0x08, 0xf8, 0x82, 0x0a, 0x4d, 0x82, 0xba, 0x57, 0x20, 0x39, 0x64, 0xdb, 0x86, 0xc2, 0x64, | 	0xf0, 0x05, 0x15, 0x9a, 0x04, 0x75, 0xaf, 0x40, 0x72, 0xc8, 0xb6, 0x0d, 0x85, 0xc9, 0x44, 0x28, | ||||||
| 	0x22, 0x94, 0x6f, 0x16, 0x49, 0x3e, 0xe9, 0x7b, 0x02, 0x59, 0xb0, 0x61, 0x35, 0x92, 0x77, 0x84, | 	0xdf, 0x2c, 0x92, 0x7c, 0xd2, 0xf7, 0x04, 0xb2, 0x60, 0xc3, 0x6a, 0x24, 0xef, 0x08, 0xf3, 0xb7, | ||||||
| 	0xf9, 0x5b, 0xe8, 0xad, 0x94, 0x90, 0x1b, 0x1c, 0x99, 0x2d, 0x5f, 0x2e, 0x2c, 0x5f, 0x98, 0xb9, | 	0xd0, 0x5b, 0x29, 0x21, 0x37, 0x38, 0x32, 0x5b, 0xbe, 0x5c, 0x58, 0xbe, 0x30, 0x73, 0x65, 0x65, | ||||||
| 	0xb2, 0x32, 0xf3, 0xef, 0xa0, 0xff, 0x39, 0xf5, 0x1d, 0x8f, 0xe9, 0xf9, 0x0f, 0xf8, 0x3c, 0x92, | 	0xe6, 0xdf, 0xc1, 0xe0, 0x13, 0xea, 0x3b, 0x1e, 0xd3, 0xf3, 0x1f, 0xf0, 0x79, 0x24, 0x93, 0xa1, | ||||||
| 	0xc9, 0x50, 0xbf, 0x68, 0xa6, 0x3a, 0xfb, 0x74, 0xac, 0xa6, 0x96, 0x1c, 0x3b, 0xe4, 0x11, 0xd4, | 	0x7e, 0xd1, 0x4c, 0x75, 0xf6, 0xe9, 0x58, 0x4d, 0x2d, 0x39, 0x76, 0xc8, 0x23, 0xa8, 0x73, 0x65, | ||||||
| 	0xb9, 0xb2, 0xd6, 0x00, 0x68, 0xe5, 0x6a, 0x5c, 0x2b, 0xd1, 0x99, 0xdf, 0x02, 0x29, 0x4c, 0x2d, | 	0xad, 0x01, 0xd0, 0xca, 0xd5, 0xb8, 0x56, 0xa2, 0x33, 0xbf, 0x02, 0x52, 0x98, 0x5a, 0x3e, 0x66, | ||||||
| 	0x1f, 0x33, 0x4b, 0x32, 0x92, 0xe8, 0x57, 0xa0, 0xd0, 0x51, 0xd5, 0xce, 0x63, 0xd2, 0x4a, 0xb5, | 	0x96, 0x64, 0x24, 0xd1, 0xaf, 0x40, 0xa1, 0xa3, 0xaa, 0x9d, 0xc7, 0xa4, 0x95, 0x6a, 0xc9, 0x0e, | ||||||
| 	0x64, 0x08, 0x15, 0xc6, 0xb9, 0x5e, 0x02, 0x8b, 0xcc, 0xec, 0xe9, 0x68, 0x49, 0x95, 0xf9, 0x33, | 	0x54, 0x18, 0xe7, 0x7a, 0x09, 0x2c, 0x32, 0xb3, 0xa7, 0xa3, 0x25, 0x55, 0x66, 0x1f, 0xba, 0xc7, | ||||||
| 	0xe8, 0x9f, 0x87, 0xcc, 0x76, 0xa9, 0x87, 0xcf, 0x3e, 0xb5, 0xc0, 0x43, 0xa8, 0x4a, 0x27, 0x27, | 	0xbe, 0x2b, 0x5c, 0xea, 0xb9, 0x7f, 0x66, 0x72, 0xe7, 0xe6, 0x53, 0xe8, 0x65, 0x12, 0xb5, 0xa0, | ||||||
| 	0x84, 0xd1, 0xc4, 0x81, 0xa8, 0x56, 0x72, 0xf3, 0x5b, 0x30, 0xd4, 0xbe, 0x8e, 0x6e, 0xdc, 0x48, | 	0x9e, 0xa6, 0x74, 0xfb, 0x34, 0x3f, 0x83, 0xc1, 0x79, 0xc8, 0x6c, 0x97, 0x7a, 0xf8, 0x7a, 0x54, | ||||||
| 	0x30, 0xdf, 0x66, 0x87, 0x97, 0xcc, 0xbe, 0xfa, 0x11, 0x4f, 0x7e, 0x0d, 0xf7, 0x36, 0xad, 0x90, | 	0xc3, 0x1e, 0x42, 0x55, 0xde, 0x55, 0xc2, 0x3b, 0x4d, 0x1c, 0x88, 0x6a, 0x25, 0x37, 0xbf, 0x02, | ||||||
| 	0xec, 0xaf, 0x65, 0xcb, 0xde, 0xf4, 0x42, 0xe6, 0x0e, 0x5c, 0xa3, 0x61, 0x01, 0x8a, 0x3e, 0x93, | 	0x43, 0x1d, 0xef, 0xe8, 0xc6, 0x8d, 0x04, 0xf3, 0x6d, 0x76, 0x78, 0xc9, 0xec, 0xab, 0x1f, 0xd0, | ||||||
| 	0x12, 0x79, 0x8f, 0x4c, 0x8e, 0x8b, 0x34, 0x1f, 0xeb, 0x5e, 0xe2, 0x8f, 0xca, 0xed, 0xfe, 0xf8, | 	0x81, 0xd7, 0x70, 0x6f, 0xd3, 0x0a, 0xc9, 0xfe, 0x5a, 0xb6, 0xec, 0x4d, 0x2f, 0x64, 0x0a, 0xc2, | ||||||
| 	0x5b, 0x09, 0x9a, 0xe7, 0x4c, 0xc4, 0x21, 0x9e, 0xe5, 0x3e, 0x34, 0x67, 0x3c, 0xb8, 0x62, 0x3c, | 	0x35, 0x1a, 0x16, 0xa0, 0xe8, 0x63, 0x29, 0x91, 0x70, 0x60, 0x72, 0x5c, 0xa4, 0x69, 0x5d, 0xf7, | ||||||
| 	0x3b, 0x4a, 0x43, 0x09, 0x8e, 0x1d, 0xf2, 0x04, 0x6a, 0x87, 0x81, 0x7f, 0xe1, 0xce, 0xf1, 0x11, | 	0x12, 0x7f, 0x54, 0x6e, 0xf7, 0xc7, 0x3f, 0x4a, 0xd0, 0x3c, 0x67, 0x22, 0x0e, 0xf1, 0x2c, 0xf7, | ||||||
| 	0xac, 0x89, 0x21, 0x1d, 0x3b, 0x56, 0x3a, 0x45, 0x0c, 0xda, 0x90, 0x0c, 0xa1, 0xa5, 0x3f, 0x29, | 	0xa1, 0x39, 0xe3, 0xc1, 0x15, 0xe3, 0xd9, 0x51, 0x1a, 0x4a, 0x70, 0xec, 0x90, 0x27, 0x50, 0x3b, | ||||||
| 	0x7c, 0xfd, 0xf5, 0xf1, 0xb3, 0xa4, 0x3a, 0xce, 0x89, 0x06, 0x1f, 0x41, 0x2b, 0x37, 0xf0, 0x07, | 	0x0c, 0xfc, 0x0b, 0x77, 0x8e, 0x6f, 0x69, 0xcd, 0x2f, 0xe9, 0xd8, 0xb1, 0xd2, 0x29, 0x7e, 0xd1, | ||||||
| 	0xa5, 0xaa, 0xff, 0x07, 0xc0, 0xd5, 0x95, 0x8f, 0xb6, 0xd5, 0x51, 0xf5, 0x48, 0x79, 0xb4, 0x87, | 	0x86, 0x64, 0x07, 0x5a, 0xfa, 0xcb, 0xc4, 0x17, 0x5f, 0x1c, 0x3f, 0x4f, 0x8a, 0xec, 0x9c, 0x68, | ||||||
| 	0xd0, 0x94, 0x85, 0x98, 0x52, 0x27, 0x49, 0xb2, 0x94, 0x25, 0x49, 0xf3, 0x11, 0xf4, 0x8f, 0xfd, | 	0xf8, 0x3e, 0xb4, 0x72, 0x03, 0xbf, 0x57, 0xc6, 0xfb, 0x31, 0x00, 0xae, 0xae, 0x7c, 0xd4, 0xcf, | ||||||
| 	0x6b, 0xea, 0xb9, 0x0e, 0x15, 0xec, 0x0b, 0xb6, 0x44, 0x17, 0xac, 0xed, 0xc0, 0x3c, 0x87, 0xb6, | 	0xae, 0xbe, 0xa9, 0x8e, 0xf6, 0x10, 0x9a, 0xb2, 0x9e, 0x53, 0xea, 0x24, 0xd7, 0x96, 0xb2, 0x5c, | ||||||
| 	0x7e, 0x95, 0xbf, 0xd2, 0x1e, 0xdb, 0x7a, 0x8f, 0xdf, 0x1f, 0x44, 0x6f, 0x43, 0x4f, 0x4f, 0x7a, | 	0x6b, 0x3e, 0x82, 0xc1, 0xb1, 0x7f, 0x4d, 0x3d, 0xd7, 0xa1, 0x82, 0x7d, 0xca, 0x96, 0xe8, 0x82, | ||||||
| 	0xe2, 0xea, 0x10, 0x92, 0x35, 0x06, 0x67, 0x17, 0xee, 0x8d, 0x9e, 0x5a, 0xf7, 0xcc, 0xa7, 0xb0, | 	0xb5, 0x1d, 0x98, 0xe7, 0xd0, 0xd6, 0x8f, 0xfb, 0xef, 0xb4, 0xc7, 0xb6, 0xde, 0xe3, 0x37, 0xc7, | ||||||
| 	0x9d, 0x33, 0x4d, 0x8f, 0x73, 0xc5, 0x96, 0x51, 0xf2, 0xb5, 0x42, 0xb6, 0x13, 0x0f, 0x94, 0x33, | 	0xe2, 0x9b, 0xd0, 0xd3, 0x93, 0x9e, 0xb8, 0x3a, 0x12, 0x65, 0xa9, 0xc2, 0xd9, 0x85, 0x7b, 0xa3, | ||||||
| 	0x0f, 0x98, 0xd0, 0xd5, 0x23, 0x9f, 0x33, 0x71, 0xcb, 0xe9, 0xbe, 0x48, 0x37, 0xf2, 0x9c, 0xe9, | 	0xa7, 0xd6, 0x3d, 0xf3, 0x19, 0xf4, 0x73, 0xa6, 0xe9, 0x71, 0xae, 0xd8, 0x32, 0x4a, 0x3e, 0x7a, | ||||||
| 	0xc9, 0x1f, 0x43, 0x95, 0xc9, 0x93, 0xe6, 0xf3, 0x67, 0xde, 0x03, 0x96, 0x52, 0x6f, 0x58, 0xf0, | 	0xc8, 0x76, 0xe2, 0x81, 0x72, 0xe6, 0x01, 0x13, 0xba, 0x7a, 0xe4, 0x0b, 0x26, 0x6e, 0x39, 0xdd, | ||||||
| 	0x69, 0xba, 0xe0, 0x59, 0xac, 0x16, 0x7c, 0xc5, 0xb9, 0xcc, 0x37, 0xd3, 0x6d, 0x9c, 0xc5, 0xe2, | 	0xa7, 0xe9, 0x46, 0x5e, 0x30, 0x3d, 0xf9, 0x63, 0xa8, 0x32, 0x79, 0xd2, 0x7c, 0x1a, 0xce, 0x7b, | ||||||
| 	0xb6, 0x1b, 0x7d, 0x04, 0x7d, 0x6d, 0xf4, 0x8c, 0x79, 0x4c, 0xb0, 0x5b, 0x8e, 0xf4, 0x18, 0x48, | 	0xc0, 0x52, 0xea, 0x0d, 0x0b, 0x3e, 0x4b, 0x17, 0x3c, 0x8b, 0xd5, 0x82, 0xdf, 0x71, 0x2e, 0xf3, | ||||||
| 	0xc1, 0xec, 0xb6, 0xe9, 0x1e, 0x40, 0x63, 0x32, 0x39, 0x49, 0xb5, 0x45, 0x6e, 0x34, 0x3f, 0x86, | 	0xf5, 0x74, 0x1b, 0x67, 0xb1, 0xb8, 0xed, 0x46, 0x1f, 0xc1, 0x40, 0x1b, 0x3d, 0x67, 0x1e, 0x13, | ||||||
| 	0xfe, 0x79, 0xec, 0x04, 0x67, 0xdc, 0xbd, 0x76, 0x3d, 0x36, 0x57, 0x8b, 0x25, 0xc5, 0x6f, 0x29, | 	0xec, 0x96, 0x23, 0x3d, 0x06, 0x52, 0x30, 0xbb, 0x6d, 0xba, 0x07, 0xd0, 0x98, 0x4c, 0x4e, 0x52, | ||||||
| 	0x57, 0xfc, 0x6e, 0xcc, 0x46, 0xe6, 0x08, 0x48, 0x61, 0x78, 0x7a, 0x6f, 0x51, 0xec, 0x04, 0x3a, | 	0x6d, 0x91, 0x62, 0xcd, 0x0f, 0x60, 0x70, 0x1e, 0x3b, 0xc1, 0x19, 0x77, 0xaf, 0x5d, 0x8f, 0xcd, | ||||||
| 	0x84, 0xb1, 0x6d, 0x8e, 0xa0, 0x3d, 0xa1, 0xb2, 0xd8, 0x70, 0x94, 0x8d, 0x01, 0x75, 0xa1, 0xfa, | 	0xd5, 0x62, 0x49, 0x0d, 0x5d, 0xca, 0xd5, 0xd0, 0x1b, 0x93, 0x9a, 0x39, 0x02, 0x52, 0x18, 0x9e, | ||||||
| 	0xda, 0x2c, 0xe9, 0x9a, 0xfb, 0xb0, 0x73, 0x48, 0xed, 0x4b, 0xd7, 0x9f, 0x3f, 0x73, 0x23, 0x59, | 	0xde, 0x5b, 0x14, 0x3b, 0x81, 0x0e, 0x61, 0x6c, 0x9b, 0x23, 0x68, 0x4f, 0xa8, 0xac, 0x59, 0x1c, | ||||||
| 	0x6d, 0xe9, 0x11, 0x03, 0x68, 0x38, 0x5a, 0xa0, 0x87, 0xa4, 0x7d, 0xf3, 0x5d, 0x78, 0x2d, 0xf7, | 	0x65, 0x63, 0x40, 0x5d, 0xa8, 0xbe, 0x36, 0x4b, 0xba, 0xe6, 0x3e, 0x6c, 0x1f, 0x52, 0xfb, 0xd2, | ||||||
| 	0x49, 0xe8, 0x5c, 0xd0, 0xc4, 0x1f, 0x3b, 0x50, 0x8d, 0x64, 0x0f, 0x47, 0x54, 0x2d, 0xd5, 0x31, | 	0xf5, 0xe7, 0xcf, 0xdd, 0x48, 0x16, 0x6d, 0x7a, 0xc4, 0x10, 0x1a, 0x8e, 0x16, 0xe8, 0x21, 0x69, | ||||||
| 	0xbf, 0x84, 0x9d, 0x7c, 0x02, 0x96, 0xb5, 0x4f, 0x72, 0x70, 0xac, 0x4a, 0x4a, 0xb9, 0xaa, 0x44, | 	0xdf, 0x7c, 0x1b, 0x5e, 0xc9, 0x7d, 0x59, 0x3a, 0x17, 0x34, 0xf1, 0xc7, 0x36, 0x54, 0x23, 0xd9, | ||||||
| 	0xfb, 0xac, 0x9c, 0xe5, 0x93, 0x6d, 0xa8, 0xfc, 0xfa, 0x9b, 0x89, 0x06, 0xbb, 0x6c, 0x9a, 0x7f, | 	0xc3, 0x11, 0x55, 0x4b, 0x75, 0xcc, 0xcf, 0x60, 0x3b, 0x9f, 0xc7, 0x65, 0x09, 0x95, 0x1c, 0x1c, | ||||||
| 	0x94, 0xcb, 0x17, 0xe7, 0x53, 0xcb, 0x17, 0x4a, 0x93, 0xd2, 0x2b, 0x95, 0x26, 0xeb, 0x78, 0x7b, | 	0x8b, 0x9b, 0x52, 0xae, 0xb8, 0xd1, 0x3e, 0x2b, 0x67, 0x69, 0xa9, 0x0f, 0x95, 0x5f, 0x7f, 0x39, | ||||||
| 	0x17, 0xfa, 0xa7, 0x5e, 0x60, 0x5f, 0x1d, 0xf9, 0x39, 0x6f, 0x18, 0x50, 0x67, 0x7e, 0xde, 0x19, | 	0xd1, 0x60, 0x97, 0x4d, 0xf3, 0x8f, 0x72, 0xf9, 0xe2, 0x7c, 0x6a, 0xf9, 0x42, 0x85, 0x53, 0xfa, | ||||||
| 	0x49, 0xd7, 0x7c, 0x0b, 0x7a, 0x27, 0x81, 0x4d, 0xbd, 0xd3, 0x20, 0xf6, 0x45, 0xea, 0x05, 0xfc, | 	0x4e, 0x15, 0xce, 0x3a, 0xde, 0xde, 0x86, 0xc1, 0xa9, 0x17, 0xd8, 0x57, 0x47, 0x7e, 0xce, 0x1b, | ||||||
| 	0x46, 0xa7, 0x4d, 0x55, 0xc7, 0x7c, 0x17, 0xba, 0x3a, 0x45, 0xfb, 0x17, 0x41, 0xc2, 0x8c, 0x59, | 	0x06, 0xd4, 0x99, 0x9f, 0x77, 0x46, 0xd2, 0x35, 0xdf, 0x80, 0xde, 0x49, 0x60, 0x53, 0xef, 0x34, | ||||||
| 	0x32, 0x2f, 0x15, 0x0b, 0x7d, 0xf3, 0x04, 0x7a, 0x99, 0xb9, 0x9a, 0xf7, 0x2d, 0xa8, 0x29, 0xb5, | 	0x88, 0x7d, 0x91, 0x7a, 0x01, 0x3f, 0xf5, 0x69, 0x53, 0xd5, 0x31, 0xdf, 0x86, 0xae, 0xce, 0xf4, | ||||||
| 	0x3e, 0x5b, 0x2f, 0x7d, 0xe9, 0x2a, 0x4b, 0x4b, 0xab, 0x37, 0x1c, 0x6a, 0x01, 0xdd, 0x33, 0xfc, | 	0xfe, 0x45, 0x90, 0x30, 0x63, 0x56, 0x13, 0x94, 0x8a, 0xef, 0x05, 0xf3, 0x04, 0x7a, 0x99, 0xb9, | ||||||
| 	0x56, 0x7a, 0xe4, 0x5f, 0xab, 0xc9, 0x8e, 0x81, 0xa8, 0xaf, 0xa7, 0x53, 0xe6, 0x5f, 0xbb, 0x3c, | 	0x9a, 0xf7, 0x0d, 0xa8, 0x29, 0xb5, 0x3e, 0x5b, 0x2f, 0x7d, 0x30, 0x2b, 0x4b, 0x4b, 0xab, 0x37, | ||||||
| 	0xf0, 0xb1, 0xb8, 0x2e, 0xe9, 0x12, 0x26, 0x99, 0x38, 0x1d, 0x94, 0x58, 0x58, 0xfd, 0x70, 0x55, | 	0x1c, 0x6a, 0x01, 0xdd, 0x33, 0xfc, 0xe4, 0x7a, 0xe4, 0x5f, 0xab, 0xc9, 0x8e, 0x81, 0xa8, 0x8f, | ||||||
| 	0xb4, 0xd1, 0x87, 0x90, 0x7d, 0x89, 0x91, 0xa9, 0x86, 0xb3, 0x45, 0x20, 0xd8, 0x94, 0x3a, 0x4e, | 	0xb0, 0x53, 0xe6, 0x5f, 0xbb, 0x3c, 0xf0, 0xb1, 0x46, 0x2f, 0xe9, 0x4a, 0x28, 0x99, 0x38, 0x1d, | ||||||
| 	0x12, 0x2d, 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x53, 0x86, 0xfa, 0xa7, 0x8a, 0xc0, 0xc9, | 	0x94, 0x58, 0x58, 0x83, 0x70, 0x55, 0xb4, 0xd1, 0x87, 0x90, 0x7d, 0xd0, 0x91, 0xa9, 0x86, 0xb3, | ||||||
| 	0x27, 0xd0, 0x29, 0xa4, 0x6b, 0xf2, 0x1a, 0x96, 0x75, 0xab, 0xc5, 0xc1, 0xe0, 0xee, 0x9a, 0x58, | 	0x45, 0x20, 0xd8, 0x94, 0x3a, 0x4e, 0x12, 0x2d, 0xa0, 0x44, 0x07, 0x8e, 0xc3, 0xf7, 0xff, 0x56, | ||||||
| 	0x9d, 0xeb, 0x3d, 0x68, 0xe7, 0x93, 0x31, 0xc1, 0xc4, 0x8b, 0xdf, 0x85, 0x07, 0x38, 0xd3, 0x7a, | 	0x81, 0xfa, 0x47, 0x8a, 0xc0, 0xc9, 0x87, 0xd0, 0x29, 0x64, 0x7d, 0xf2, 0x0a, 0x56, 0x87, 0xab, | ||||||
| 	0xa6, 0x3e, 0x87, 0x9d, 0x4d, 0x69, 0x92, 0x3c, 0xc8, 0x56, 0x58, 0x4f, 0xd1, 0x83, 0xd7, 0x6f, | 	0x35, 0xc6, 0xf0, 0xee, 0x9a, 0x58, 0x9d, 0xeb, 0x1d, 0x68, 0xe7, 0x93, 0x31, 0xc1, 0xc4, 0x8b, | ||||||
| 	0xd3, 0x26, 0xe9, 0xb5, 0x7e, 0xe8, 0x31, 0xea, 0xc7, 0x61, 0x7e, 0x07, 0x59, 0x93, 0x3c, 0x81, | 	0x9f, 0x97, 0x87, 0x38, 0xd3, 0x7a, 0xa6, 0x3e, 0x87, 0xed, 0x4d, 0x69, 0x92, 0x3c, 0xc8, 0x56, | ||||||
| 	0x4e, 0x21, 0x51, 0xa8, 0x73, 0xae, 0xe5, 0x8e, 0xfc, 0x90, 0xc7, 0x50, 0xc5, 0xe4, 0x44, 0x3a, | 	0x58, 0x4f, 0xd1, 0xc3, 0x57, 0x6f, 0xd3, 0x26, 0xe9, 0xb5, 0x7e, 0xe8, 0x31, 0xea, 0xc7, 0x61, | ||||||
| 	0x85, 0x2c, 0x39, 0xe8, 0xa6, 0x5d, 0xb5, 0xf6, 0x10, 0xb6, 0xf0, 0x6b, 0x41, 0x6e, 0x61, 0x1c, | 	0x7e, 0x07, 0x59, 0x93, 0x3c, 0x81, 0x4e, 0x21, 0x51, 0xa8, 0x73, 0xae, 0xe5, 0x8e, 0xfc, 0x90, | ||||||
| 	0x91, 0x66, 0xae, 0xfd, 0x7f, 0x95, 0xa0, 0x9e, 0x7c, 0x41, 0x7e, 0x02, 0x5b, 0x32, 0x07, 0x90, | 	0xc7, 0x50, 0xc5, 0xe4, 0x44, 0x3a, 0x85, 0x2c, 0x39, 0xec, 0xa6, 0x5d, 0xb5, 0xf6, 0xbb, 0x00, | ||||||
| 	0x3b, 0x39, 0x1a, 0x4d, 0xf2, 0xc7, 0x60, 0x67, 0x45, 0xa8, 0x16, 0x18, 0x43, 0xe5, 0x39, 0x13, | 	0x59, 0x11, 0x43, 0x88, 0x9a, 0x37, 0x5f, 0xe6, 0x0c, 0xef, 0x14, 0x65, 0x49, 0xa1, 0xb3, 0x85, | ||||||
| 	0x84, 0xe4, 0x94, 0x3a, 0x19, 0x0c, 0xee, 0x14, 0x65, 0xa9, 0xfd, 0x59, 0x5c, 0xb4, 0xd7, 0x5c, | 	0xdf, 0x2a, 0x72, 0xfb, 0xc5, 0x85, 0xd2, 0x84, 0xb7, 0xff, 0x9f, 0x12, 0xd4, 0x93, 0xef, 0xd7, | ||||||
| 	0x5e, 0xb0, 0x4f, 0x59, 0xfa, 0x43, 0xa8, 0x29, 0x96, 0x55, 0x4e, 0x59, 0xe3, 0x67, 0x75, 0xf9, | 	0x4f, 0x60, 0x4b, 0xa6, 0x0e, 0x72, 0x27, 0xc7, 0xbe, 0x49, 0xda, 0x19, 0x6e, 0xaf, 0x08, 0xd5, | ||||||
| 	0xeb, 0x7c, 0xbc, 0xff, 0x8f, 0x2d, 0x80, 0xf3, 0x65, 0x24, 0xd8, 0xe2, 0x37, 0x2e, 0x7b, 0x41, | 	0x02, 0x63, 0xa8, 0xbc, 0x60, 0x42, 0x6d, 0xa8, 0x98, 0x43, 0x86, 0x77, 0x8a, 0xb2, 0xd4, 0xfe, | ||||||
| 	0x76, 0xa1, 0xa7, 0xbf, 0x89, 0xe0, 0x53, 0x4d, 0xb2, 0x49, 0xce, 0x27, 0x58, 0xf0, 0xa5, 0x64, | 	0x2c, 0x2e, 0xda, 0xeb, 0x14, 0x50, 0xb0, 0x4f, 0xc9, 0xfd, 0x3d, 0xa8, 0x29, 0x72, 0x56, 0xbe, | ||||||
| 	0xfd, 0x18, 0x5a, 0xa7, 0xf4, 0xe6, 0xe5, 0x76, 0x9f, 0x40, 0xa7, 0xc0, 0xc1, 0x7a, 0x8b, 0xab, | 	0x5c, 0xa3, 0x75, 0x85, 0x99, 0x75, 0x1a, 0xdf, 0xff, 0xd7, 0x16, 0xc0, 0xf9, 0x32, 0x12, 0x6c, | ||||||
| 	0xac, 0xae, 0xb7, 0xb8, 0xce, 0xd6, 0x8f, 0xa1, 0xae, 0x99, 0x39, 0xbf, 0x06, 0xe6, 0xb0, 0x02, | 	0xf1, 0x1b, 0x97, 0xbd, 0x24, 0xbb, 0xd0, 0xd3, 0x5f, 0x64, 0xf0, 0xa1, 0x28, 0x49, 0x28, 0xe7, | ||||||
| 	0x63, 0xff, 0x1c, 0x7a, 0x2b, 0xbc, 0x9c, 0xb7, 0xc7, 0xcf, 0x21, 0x1b, 0x79, 0xfb, 0xa9, 0x7c, | 	0x13, 0x2c, 0x37, 0x53, 0x8e, 0x7f, 0x0c, 0xad, 0x53, 0x7a, 0xf3, 0xed, 0x76, 0x1f, 0x42, 0xa7, | ||||||
| 	0xed, 0x14, 0xb9, 0x39, 0x3f, 0x50, 0xbf, 0xbc, 0x36, 0x91, 0xf7, 0xf3, 0xe2, 0x3b, 0x09, 0x9f, | 	0x40, 0xdd, 0x7a, 0x8b, 0xab, 0xc9, 0x40, 0x6f, 0x71, 0x9d, 0xe4, 0x1f, 0x43, 0x5d, 0x13, 0x7a, | ||||||
| 	0xa8, 0xc6, 0x2a, 0x7d, 0x26, 0xe4, 0x3d, 0xb8, 0xb7, 0x49, 0x93, 0x86, 0x60, 0x9e, 0x41, 0xd7, | 	0x7e, 0x0d, 0x4c, 0x7d, 0x05, 0xa2, 0xff, 0x39, 0xf4, 0x56, 0xe8, 0x3c, 0x6f, 0x8f, 0x1f, 0x63, | ||||||
| 	0x42, 0x70, 0x9d, 0x5e, 0xdf, 0x01, 0xc8, 0x48, 0x34, 0x6f, 0x8f, 0xf0, 0x58, 0xe5, 0xd7, 0x0f, | 	0x36, 0xd2, 0xfd, 0x33, 0xf9, 0xd6, 0x2a, 0x52, 0x7a, 0x7e, 0xa0, 0x7e, 0xf7, 0x6d, 0xe2, 0xfc, | ||||||
| 	0x00, 0x32, 0x6a, 0x54, 0xa8, 0x2a, 0x32, 0xab, 0x1a, 0xb6, 0x4a, 0x9f, 0xbb, 0xd0, 0x4c, 0xe9, | 	0x17, 0xc5, 0x57, 0x1a, 0x3e, 0x90, 0x8d, 0x55, 0xd6, 0x4d, 0x38, 0x7f, 0x78, 0x6f, 0x93, 0x26, | ||||||
| 	0x2c, 0xbf, 0x06, 0x4e, 0x50, 0x64, 0xc7, 0x4f, 0x77, 0x7f, 0x3f, 0x9a, 0xbb, 0xe2, 0x32, 0x9e, | 	0x8d, 0xdc, 0x3c, 0xf1, 0xae, 0x45, 0xee, 0x3a, 0x2b, 0xbf, 0x05, 0x90, 0x71, 0x6f, 0xde, 0x1e, | ||||||
| 	0x8d, 0xed, 0x60, 0xb1, 0x77, 0x49, 0xa3, 0x4b, 0xd7, 0x0e, 0x78, 0xb8, 0x77, 0x2d, 0xc1, 0xb4, | 	0xe1, 0xb1, 0x4a, 0xcb, 0xef, 0x02, 0x64, 0x8c, 0xaa, 0x50, 0x55, 0x24, 0x64, 0x35, 0x6c, 0x95, | ||||||
| 	0x57, 0xf8, 0xc1, 0x35, 0xab, 0xe1, 0x43, 0xef, 0xfd, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0xbd, | 	0x75, 0x77, 0xa1, 0x99, 0xb2, 0x60, 0x7e, 0x0d, 0x9c, 0xa0, 0x48, 0xaa, 0x1f, 0xed, 0xfe, 0x7e, | ||||||
| 	0xc6, 0x6e, 0xfa, 0xf8, 0x1a, 0x00, 0x00, | 	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. | // 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 | 	// broker_id to create a connection back to Vault for use with the Storage | ||||||
| 	// and SystemView clients. | 	// and SystemView clients. | ||||||
| 	Setup(ctx context.Context, in *SetupArgs, opts ...grpc.CallOption) (*SetupReply, error) | 	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 returns the BackendType for the particular backend | ||||||
| 	Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeReply, error) | 	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 | 	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) { | func (c *backendClient) Type(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*TypeReply, error) { | ||||||
| 	out := new(TypeReply) | 	out := new(TypeReply) | ||||||
| 	err := c.cc.Invoke(ctx, "/pb.Backend/Type", in, out, opts...) | 	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 | 	// broker_id to create a connection back to Vault for use with the Storage | ||||||
| 	// and SystemView clients. | 	// and SystemView clients. | ||||||
| 	Setup(context.Context, *SetupArgs) (*SetupReply, error) | 	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 returns the BackendType for the particular backend | ||||||
| 	Type(context.Context, *Empty) (*TypeReply, error) | 	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) { | func RegisterBackendServer(s *grpc.Server, srv BackendServer) { | ||||||
| 	s.RegisterService(&_Backend_serviceDesc, srv) | 	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) | 	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) { | func _Backend_Type_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { | ||||||
| 	in := new(Empty) | 	in := new(Empty) | ||||||
| 	if err := dec(in); err != nil { | 	if err := dec(in); err != nil { | ||||||
| @@ -3222,6 +3303,10 @@ var _Backend_serviceDesc = grpc.ServiceDesc{ | |||||||
| 			MethodName: "Setup", | 			MethodName: "Setup", | ||||||
| 			Handler:    _Backend_Setup_Handler, | 			Handler:    _Backend_Setup_Handler, | ||||||
| 		}, | 		}, | ||||||
|  | 		{ | ||||||
|  | 			MethodName: "Initialize", | ||||||
|  | 			Handler:    _Backend_Initialize_Handler, | ||||||
|  | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			MethodName: "Type", | 			MethodName: "Type", | ||||||
| 			Handler:    _Backend_Type_Handler, | 			Handler:    _Backend_Type_Handler, | ||||||
| @@ -3293,23 +3378,6 @@ type StorageServer interface { | |||||||
| 	Delete(context.Context, *StorageDeleteArgs) (*StorageDeleteReply, error) | 	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) { | func RegisterStorageServer(s *grpc.Server, srv StorageServer) { | ||||||
| 	s.RegisterService(&_Storage_serviceDesc, srv) | 	s.RegisterService(&_Storage_serviceDesc, srv) | ||||||
| } | } | ||||||
| @@ -3600,44 +3668,6 @@ type SystemViewServer interface { | |||||||
| 	PluginEnv(context.Context, *Empty) (*PluginEnvReply, error) | 	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) { | func RegisterSystemViewServer(s *grpc.Server, srv SystemViewServer) { | ||||||
| 	s.RegisterService(&_SystemView_serviceDesc, srv) | 	s.RegisterService(&_SystemView_serviceDesc, srv) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -355,6 +355,15 @@ message HandleRequestReply { | |||||||
| 	ProtoError err = 2; | 	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. | // SpecialPathsReply is the reply for SpecialPaths method. | ||||||
| message SpecialPathsReply { | message SpecialPathsReply { | ||||||
| 	Paths paths = 1; | 	Paths paths = 1; | ||||||
| @@ -434,6 +443,10 @@ service Backend { | |||||||
| 	// and SystemView clients. | 	// and SystemView clients. | ||||||
| 	rpc Setup(SetupArgs) returns (SetupReply); | 	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 |    	// Type returns the BackendType for the particular backend | ||||||
| 	rpc Type(Empty) returns (TypeReply); | 	rpc Type(Empty) returns (TypeReply); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -185,6 +185,17 @@ func (c *Core) enableCredentialInternal(ctx context.Context, entry *MountEntry, | |||||||
| 		return err | 		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() { | 	if c.logger.IsInfo() { | ||||||
| 		c.logger.Info("enabled credential backend", "path", entry.Path, "type", entry.Type) | 		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 | 		// Populate cache | ||||||
| 		NamespaceByID(ctx, entry.NamespaceID, c) | 		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 { | 	if persistNeeded { | ||||||
|   | |||||||
| @@ -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") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -511,6 +511,17 @@ func (c *Core) mountInternal(ctx context.Context, entry *MountEntry, updateStora | |||||||
| 		return err | 		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() { | 	if c.logger.IsInfo() { | ||||||
| 		c.logger.Info("successful mount", "namespace", entry.Namespace().Path, "path", entry.Path, "type", entry.Type) | 		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 | 			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() { | 		if c.logger.IsInfo() { | ||||||
| 			c.logger.Info("successfully mounted backend", "type", entry.Type, "path", entry.Path) | 			c.logger.Info("successfully mounted backend", "type", entry.Type, "path", entry.Path) | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -735,3 +735,72 @@ func TestSingletonMountTableFunc(t *testing.T) { | |||||||
| 		t.Fatal("unexpected entry type for auth") | 		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") | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package vault | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -103,7 +104,7 @@ func (n *NoopBackend) Logger() log.Logger { | |||||||
| 	return log.NewNullLogger() | 	return log.NewNullLogger() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (n *NoopBackend) Initialize(ctx context.Context) error { | func (n *NoopBackend) Initialize(ctx context.Context, req *logical.InitializationRequest) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -113,3 +114,29 @@ func (n *NoopBackend) Type() logical.BackendType { | |||||||
| 	} | 	} | ||||||
| 	return n.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 | ||||||
|  | } | ||||||
|   | |||||||
| @@ -717,8 +717,7 @@ func (n *rawHTTP) Cleanup(ctx context.Context) { | |||||||
| 	// noop | 	// noop | ||||||
| } | } | ||||||
|  |  | ||||||
| func (n *rawHTTP) Initialize(ctx context.Context) error { | func (n *rawHTTP) Initialize(ctx context.Context, req *logical.InitializationRequest) error { | ||||||
| 	// noop |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user