diff --git a/Makefile b/Makefile index 6521eb60..d6d27988 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ COMMIT := $(shell git rev-parse --short HEAD) TAG := "$(shell git rev-list --tags --max-count=1)" VERSION := "$(shell git describe --tags ${TAG})-next" BUILD_DIR=dist -PROTON_COMMIT := "95140abe54e3c27f0bf4f06bc780a289f41aadf1" +PROTON_COMMIT := "17305c2660e06ff9c82c1b6130799a703e4e543b" .PHONY: all build clean test tidy vet proto setup format generate diff --git a/api/handler/v1beta1/activity.go b/api/handler/v1beta1/activity.go index d1de13ce..0b2a962c 100644 --- a/api/handler/v1beta1/activity.go +++ b/api/handler/v1beta1/activity.go @@ -66,7 +66,7 @@ func (s *GRPCServer) ListActivities(ctx context.Context, req *guardianv1beta1.Li } func (s *GRPCServer) ImportActivities(ctx context.Context, req *guardianv1beta1.ImportActivitiesRequest) (*guardianv1beta1.ImportActivitiesResponse, error) { - filter := domain.ImportActivitiesFilter{ + filter := domain.ListActivitiesFilter{ ProviderID: req.GetProviderId(), ResourceIDs: req.GetResourceIds(), AccountIDs: req.GetAccountIds(), diff --git a/api/handler/v1beta1/appeal.go b/api/handler/v1beta1/appeal.go index 03e793d2..7439e31b 100644 --- a/api/handler/v1beta1/appeal.go +++ b/api/handler/v1beta1/appeal.go @@ -7,6 +7,7 @@ import ( guardianv1beta1 "github.com/raystack/guardian/api/proto/raystack/guardian/v1beta1" "github.com/raystack/guardian/core/appeal" "github.com/raystack/guardian/domain" + "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -35,24 +36,36 @@ func (s *GRPCServer) ListUserAppeals(ctx context.Context, req *guardianv1beta1.L if req.GetResourceTypes() != nil { filters.ResourceTypes = req.GetResourceTypes() } + if req.GetAccountTypes() != nil { + filters.AccountTypes = req.GetAccountTypes() + } if req.GetResourceUrns() != nil { filters.ResourceURNs = req.GetResourceUrns() } if req.GetOrderBy() != nil { filters.OrderBy = req.GetOrderBy() } - appeals, err := s.listAppeals(ctx, filters) + if req.GetQ() != "" { + filters.Q = req.GetQ() + } + filters.Offset = int(req.GetOffset()) + filters.Size = int(req.GetSize()) + + appeals, total, err := s.listAppeals(ctx, filters) if err != nil { return nil, err } return &guardianv1beta1.ListUserAppealsResponse{ Appeals: appeals, + Total: int32(total), }, nil } func (s *GRPCServer) ListAppeals(ctx context.Context, req *guardianv1beta1.ListAppealsRequest) (*guardianv1beta1.ListAppealsResponse, error) { filters := &domain.ListAppealsFilter{ + Q: req.GetQ(), + AccountTypes: req.GetAccountTypes(), AccountID: req.GetAccountId(), Statuses: req.GetStatuses(), Role: req.GetRole(), @@ -60,15 +73,18 @@ func (s *GRPCServer) ListAppeals(ctx context.Context, req *guardianv1beta1.ListA ProviderURNs: req.GetProviderUrns(), ResourceTypes: req.GetResourceTypes(), ResourceURNs: req.GetResourceUrns(), + Size: int(req.GetSize()), + Offset: int(req.GetOffset()), OrderBy: req.GetOrderBy(), } - appeals, err := s.listAppeals(ctx, filters) + appeals, total, err := s.listAppeals(ctx, filters) if err != nil { return nil, err } return &guardianv1beta1.ListAppealsResponse{ Appeals: appeals, + Total: int32(total), }, nil } @@ -106,6 +122,7 @@ func (s *GRPCServer) CreateAppeal(ctx context.Context, req *guardianv1beta1.Crea func (s *GRPCServer) GetAppeal(ctx context.Context, req *guardianv1beta1.GetAppealRequest) (*guardianv1beta1.GetAppealResponse, error) { id := req.GetId() + a, err := s.appealService.GetByID(ctx, id) if err != nil { if errors.As(err, new(appeal.InvalidError)) || errors.Is(err, appeal.ErrAppealIDEmptyParam) { @@ -113,6 +130,7 @@ func (s *GRPCServer) GetAppeal(ctx context.Context, req *guardianv1beta1.GetAppe } return nil, status.Errorf(codes.Internal, "failed to retrieve appeal: %v", err) } + if a == nil { return nil, status.Errorf(codes.NotFound, "appeal not found: %v", id) } @@ -129,11 +147,13 @@ func (s *GRPCServer) GetAppeal(ctx context.Context, req *guardianv1beta1.GetAppe func (s *GRPCServer) CancelAppeal(ctx context.Context, req *guardianv1beta1.CancelAppealRequest) (*guardianv1beta1.CancelAppealResponse, error) { id := req.GetId() + a, err := s.appealService.Cancel(ctx, id) if err != nil { if errors.As(err, new(appeal.InvalidError)) || errors.Is(err, appeal.ErrAppealIDEmptyParam) { return nil, status.Errorf(codes.InvalidArgument, err.Error()) } + switch err { case appeal.ErrAppealNotFound: return nil, status.Errorf(codes.NotFound, "appeal not found: %v", id) @@ -157,20 +177,40 @@ func (s *GRPCServer) CancelAppeal(ctx context.Context, req *guardianv1beta1.Canc }, nil } -func (s *GRPCServer) listAppeals(ctx context.Context, filters *domain.ListAppealsFilter) ([]*guardianv1beta1.Appeal, error) { - appeals, err := s.appealService.Find(ctx, filters) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get appeal list: %s", err) +func (s *GRPCServer) listAppeals(ctx context.Context, filters *domain.ListAppealsFilter) ([]*guardianv1beta1.Appeal, int64, error) { + eg, ctx := errgroup.WithContext(ctx) + var appeals []*domain.Appeal + var total int64 + + eg.Go(func() error { + appealRecords, err := s.appealService.Find(ctx, filters) + if err != nil { + return status.Errorf(codes.Internal, "failed to get appeal list: %s", err) + } + appeals = appealRecords + return nil + }) + eg.Go(func() error { + totalRecord, err := s.appealService.GetAppealsTotalCount(ctx, filters) + if err != nil { + return status.Errorf(codes.Internal, "failed to get appeal total count: %s", err) + } + total = totalRecord + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, 0, err } appealProtos := []*guardianv1beta1.Appeal{} for _, a := range appeals { appealProto, err := s.adapter.ToAppealProto(a) if err != nil { - return nil, status.Errorf(codes.Internal, "failed to parse appeal: %s", err) + return nil, 0, status.Errorf(codes.Internal, "failed to parse appeal: %s", err) } appealProtos = append(appealProtos, appealProto) } - return appealProtos, nil + return appealProtos, total, nil } diff --git a/api/handler/v1beta1/appeal_test.go b/api/handler/v1beta1/appeal_test.go index 21fb9284..1489b447 100644 --- a/api/handler/v1beta1/appeal_test.go +++ b/api/handler/v1beta1/appeal_test.go @@ -3,6 +3,7 @@ package v1beta1_test import ( "context" "errors" + "fmt" "time" "github.com/google/uuid" @@ -32,6 +33,8 @@ func (s *GrpcHandlersSuite) TestListUserAppeals() { ResourceTypes: []string{"test-resource-type"}, ResourceURNs: []string{"test-resource-urn"}, OrderBy: []string{"test-order"}, + AccountTypes: []string{"test-account-type"}, + Q: "test", } expectedAppeals := []*domain.Appeal{ { @@ -116,9 +119,12 @@ func (s *GrpcHandlersSuite) TestListUserAppeals() { UpdatedAt: timestamppb.New(timeNow), }, }, + Total: 1, } - s.appealService.EXPECT().Find(mock.AnythingOfType("*context.valueCtx"), expectedFilters). + s.appealService.EXPECT().Find(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). Return(expectedAppeals, nil).Once() + s.appealService.EXPECT().GetAppealsTotalCount(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListUserAppealsRequest{ Statuses: []string{"active", "pending"}, @@ -128,6 +134,8 @@ func (s *GrpcHandlersSuite) TestListUserAppeals() { ResourceTypes: []string{"test-resource-type"}, ResourceUrns: []string{"test-resource-urn"}, OrderBy: []string{"test-order"}, + AccountTypes: []string{"test-account-type"}, + Q: "test", } ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, expectedUser) res, err := s.grpcServer.ListUserAppeals(ctx, req) @@ -155,13 +163,16 @@ func (s *GrpcHandlersSuite) TestListUserAppeals() { s.setup() expectedError := errors.New("random error") - s.appealService.EXPECT().Find(mock.AnythingOfType("*context.valueCtx"), mock.Anything). + s.appealService.EXPECT().Find(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(nil, expectedError).Once() + s.appealService.EXPECT().GetAppealsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(0), nil).Once() req := &guardianv1beta1.ListUserAppealsRequest{} ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, "test-user") res, err := s.grpcServer.ListUserAppeals(ctx, req) + fmt.Println(status.Code(err)) s.Equal(codes.Internal, status.Code(err)) s.Nil(res) s.appealService.AssertExpectations(s.T()) @@ -177,8 +188,10 @@ func (s *GrpcHandlersSuite) TestListUserAppeals() { }, }, } - s.appealService.EXPECT().Find(mock.AnythingOfType("*context.valueCtx"), mock.Anything). + s.appealService.EXPECT().Find(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(invalidAppeals, nil).Once() + s.appealService.EXPECT().GetAppealsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListUserAppealsRequest{} ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, "test-user") @@ -287,9 +300,12 @@ func (s *GrpcHandlersSuite) TestListAppeals() { UpdatedAt: timestamppb.New(timeNow), }, }, + Total: 1, } - s.appealService.EXPECT().Find(mock.AnythingOfType("*context.emptyCtx"), expectedFilters). + s.appealService.EXPECT().Find(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). Return(expectedAppeals, nil).Once() + s.appealService.EXPECT().GetAppealsTotalCount(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListAppealsRequest{ AccountId: expectedUser, @@ -312,8 +328,10 @@ func (s *GrpcHandlersSuite) TestListAppeals() { s.setup() expectedError := errors.New("random error") - s.appealService.EXPECT().Find(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + s.appealService.EXPECT().Find(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(nil, expectedError).Once() + s.appealService.EXPECT().GetAppealsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(0), nil).Once() req := &guardianv1beta1.ListAppealsRequest{} res, err := s.grpcServer.ListAppeals(context.Background(), req) @@ -333,8 +351,10 @@ func (s *GrpcHandlersSuite) TestListAppeals() { }, }, } - s.appealService.EXPECT().Find(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + s.appealService.EXPECT().Find(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(invalidAppeals, nil).Once() + s.appealService.EXPECT().GetAppealsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListAppealsRequest{} res, err := s.grpcServer.ListAppeals(context.Background(), req) diff --git a/api/handler/v1beta1/approval.go b/api/handler/v1beta1/approval.go index 986a8c31..963ed9c3 100644 --- a/api/handler/v1beta1/approval.go +++ b/api/handler/v1beta1/approval.go @@ -7,6 +7,7 @@ import ( guardianv1beta1 "github.com/raystack/guardian/api/proto/raystack/guardian/v1beta1" "github.com/raystack/guardian/core/appeal" "github.com/raystack/guardian/domain" + "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -17,8 +18,11 @@ func (s *GRPCServer) ListUserApprovals(ctx context.Context, req *guardianv1beta1 return nil, status.Error(codes.Unauthenticated, err.Error()) } - approvals, err := s.listApprovals(ctx, &domain.ListApprovalsFilter{ + approvals, total, err := s.listApprovals(ctx, &domain.ListApprovalsFilter{ + Q: req.GetQ(), AccountID: req.GetAccountId(), + AccountTypes: req.GetAccountTypes(), + ResourceTypes: req.GetResourceTypes(), CreatedBy: user, Statuses: req.GetStatuses(), OrderBy: req.GetOrderBy(), @@ -32,12 +36,16 @@ func (s *GRPCServer) ListUserApprovals(ctx context.Context, req *guardianv1beta1 return &guardianv1beta1.ListUserApprovalsResponse{ Approvals: approvals, + Total: int32(total), }, nil } func (s *GRPCServer) ListApprovals(ctx context.Context, req *guardianv1beta1.ListApprovalsRequest) (*guardianv1beta1.ListApprovalsResponse, error) { - approvals, err := s.listApprovals(ctx, &domain.ListApprovalsFilter{ + approvals, total, err := s.listApprovals(ctx, &domain.ListApprovalsFilter{ + Q: req.GetQ(), AccountID: req.GetAccountId(), + AccountTypes: req.GetAccountTypes(), + ResourceTypes: req.GetResourceTypes(), CreatedBy: req.GetCreatedBy(), Statuses: req.GetStatuses(), OrderBy: req.GetOrderBy(), @@ -51,6 +59,7 @@ func (s *GRPCServer) ListApprovals(ctx context.Context, req *guardianv1beta1.Lis return &guardianv1beta1.ListApprovalsResponse{ Approvals: approvals, + Total: int32(total), }, nil } @@ -150,20 +159,41 @@ func (s *GRPCServer) DeleteApprover(ctx context.Context, req *guardianv1beta1.De }, nil } -func (s *GRPCServer) listApprovals(ctx context.Context, filters *domain.ListApprovalsFilter) ([]*guardianv1beta1.Approval, error) { - approvals, err := s.approvalService.ListApprovals(ctx, filters) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get approval list: %s", err) +func (s *GRPCServer) listApprovals(ctx context.Context, filters *domain.ListApprovalsFilter) ([]*guardianv1beta1.Approval, int64, error) { + eg, ctx := errgroup.WithContext(ctx) + var approvals []*domain.Approval + var total int64 + + eg.Go(func() error { + approvalRecords, err := s.approvalService.ListApprovals(ctx, filters) + if err != nil { + return status.Errorf(codes.Internal, "failed to get approval list: %s", err) + } + approvals = approvalRecords + return nil + }) + + eg.Go(func() error { + totalRecord, err := s.approvalService.GetApprovalsTotalCount(ctx, filters) + if err != nil { + return status.Errorf(codes.Internal, "failed to get approval list: %v", err) + } + total = totalRecord + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, 0, err } approvalProtos := []*guardianv1beta1.Approval{} for _, a := range approvals { approvalProto, err := s.adapter.ToApprovalProto(a) if err != nil { - return nil, status.Errorf(codes.Internal, "failed to parse approval: %v: %s", a.ID, err) + return nil, 0, status.Errorf(codes.Internal, "failed to parse approval: %v: %s", a.ID, err) } approvalProtos = append(approvalProtos, approvalProto) } - return approvalProtos, nil + return approvalProtos, total, nil } diff --git a/api/handler/v1beta1/approval_test.go b/api/handler/v1beta1/approval_test.go index de5d5b3e..3c56b122 100644 --- a/api/handler/v1beta1/approval_test.go +++ b/api/handler/v1beta1/approval_test.go @@ -107,9 +107,12 @@ func (s *GrpcHandlersSuite) TestListUserApprovals() { }, }, }, + Total: 1, } - s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.valueCtx"), expectedFilters). + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). Return(expectedApprovals, nil).Once() + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListUserApprovalsRequest{ AccountId: "test-account-id", @@ -138,12 +141,32 @@ func (s *GrpcHandlersSuite) TestListUserApprovals() { s.approvalService.AssertExpectations(s.T()) }) - s.Run("should return internal error if approval service returns an error", func() { + s.Run("should return internal error if approvalService.ListApprovals returns an error", func() { s.setup() expectedError := errors.New("random error") - s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.valueCtx"), mock.Anything). + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(nil, expectedError).Once() + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(0), nil).Once() + + req := &guardianv1beta1.ListUserApprovalsRequest{} + ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, "test-user") + res, err := s.grpcServer.ListUserApprovals(ctx, req) + + s.Equal(codes.Internal, status.Code(err)) + s.Nil(res) + s.approvalService.AssertExpectations(s.T()) + }) + + s.Run("should return internal error if approvalService.GetApprovalsTotalCount returns an error", func() { + s.setup() + + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return([]*domain.Approval{}, nil).Once() + expectedError := errors.New("random error") + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(0), expectedError).Once() req := &guardianv1beta1.ListUserApprovalsRequest{} ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, "test-user") @@ -166,8 +189,10 @@ func (s *GrpcHandlersSuite) TestListUserApprovals() { }, }, } - s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.valueCtx"), mock.Anything). + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(invalidApprovals, nil).Once() + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListUserApprovalsRequest{} ctx := context.WithValue(context.Background(), authEmailTestContextKey{}, "test-user") @@ -268,9 +293,12 @@ func (s *GrpcHandlersSuite) TestListApprovals() { }, }, }, + Total: 1, } - s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.emptyCtx"), expectedFilters). + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). Return(expectedApprovals, nil).Once() + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), expectedFilters). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListApprovalsRequest{ AccountId: "test-account-id", @@ -289,8 +317,10 @@ func (s *GrpcHandlersSuite) TestListApprovals() { s.setup() expectedError := errors.New("random error") - s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(nil, expectedError).Once() + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(0), nil).Once() req := &guardianv1beta1.ListApprovalsRequest{} res, err := s.grpcServer.ListApprovals(context.Background(), req) @@ -312,8 +342,10 @@ func (s *GrpcHandlersSuite) TestListApprovals() { }, }, } - s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + s.approvalService.EXPECT().ListApprovals(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). Return(invalidApprovals, nil).Once() + s.approvalService.EXPECT().GetApprovalsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.Anything). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListApprovalsRequest{} res, err := s.grpcServer.ListApprovals(context.Background(), req) diff --git a/api/handler/v1beta1/grant.go b/api/handler/v1beta1/grant.go index 180fb7bb..73a91a19 100644 --- a/api/handler/v1beta1/grant.go +++ b/api/handler/v1beta1/grant.go @@ -8,12 +8,14 @@ import ( "github.com/raystack/guardian/core/grant" "github.com/raystack/guardian/core/provider" "github.com/raystack/guardian/domain" + "golang.org/x/sync/errgroup" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func (s *GRPCServer) ListGrants(ctx context.Context, req *guardianv1beta1.ListGrantsRequest) (*guardianv1beta1.ListGrantsResponse, error) { filter := domain.ListGrantsFilter{ + Q: req.GetQ(), Statuses: req.GetStatuses(), AccountIDs: req.GetAccountIds(), AccountTypes: req.GetAccountTypes(), @@ -26,14 +28,17 @@ func (s *GRPCServer) ListGrants(ctx context.Context, req *guardianv1beta1.ListGr CreatedBy: req.GetCreatedBy(), Owner: req.GetOwner(), OrderBy: req.GetOrderBy(), + Size: int(req.GetSize()), + Offset: int(req.GetOffset()), } - grants, err := s.listGrants(ctx, filter) + grants, total, err := s.listGrants(ctx, filter) if err != nil { return nil, err } return &guardianv1beta1.ListGrantsResponse{ Grants: grants, + Total: int32(total), }, nil } @@ -54,15 +59,18 @@ func (s *GRPCServer) ListUserGrants(ctx context.Context, req *guardianv1beta1.Li ResourceTypes: req.GetResourceTypes(), ResourceURNs: req.GetResourceUrns(), OrderBy: req.GetOrderBy(), + Size: int(req.GetSize()), + Offset: int(req.GetOffset()), Owner: user, } - grants, err := s.listGrants(ctx, filter) + grants, total, err := s.listGrants(ctx, filter) if err != nil { return nil, err } return &guardianv1beta1.ListUserGrantsResponse{ Grants: grants, + Total: int32(total), }, nil } @@ -167,22 +175,42 @@ func (s *GRPCServer) RevokeGrants(ctx context.Context, req *guardianv1beta1.Revo }, nil } -func (s *GRPCServer) listGrants(ctx context.Context, filter domain.ListGrantsFilter) ([]*guardianv1beta1.Grant, error) { - grants, err := s.grantService.List(ctx, filter) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to list grants: %v", err) +func (s *GRPCServer) listGrants(ctx context.Context, filter domain.ListGrantsFilter) ([]*guardianv1beta1.Grant, int64, error) { + eg, ctx := errgroup.WithContext(ctx) + var grants []domain.Grant + var total int64 + + eg.Go(func() error { + grantRecords, err := s.grantService.List(ctx, filter) + if err != nil { + return status.Errorf(codes.Internal, "failed to get grant list: %s", err) + } + grants = grantRecords + return nil + }) + eg.Go(func() error { + totalRecord, err := s.grantService.GetGrantsTotalCount(ctx, filter) + if err != nil { + return status.Errorf(codes.Internal, "failed to get grant total count: %s", err) + } + total = totalRecord + return nil + }) + + if err := eg.Wait(); err != nil { + return nil, 0, err } var grantProtos []*guardianv1beta1.Grant for i, a := range grants { grantProto, err := s.adapter.ToGrantProto(&grants[i]) if err != nil { - return nil, status.Errorf(codes.Internal, "failed to parse grant %q: %v", a.ID, err) + return nil, 0, status.Errorf(codes.Internal, "failed to parse grant %q: %v", a.ID, err) } grantProtos = append(grantProtos, grantProto) } - return grantProtos, nil + return grantProtos, total, nil } func (s *GRPCServer) ImportGrantsFromProvider(ctx context.Context, req *guardianv1beta1.ImportGrantsFromProviderRequest) (*guardianv1beta1.ImportGrantsFromProviderResponse, error) { diff --git a/api/handler/v1beta1/grant_test.go b/api/handler/v1beta1/grant_test.go index 655184fb..50355f67 100644 --- a/api/handler/v1beta1/grant_test.go +++ b/api/handler/v1beta1/grant_test.go @@ -66,6 +66,7 @@ func (s *GrpcHandlersSuite) TestListGrants() { }, }, }, + Total: 1, } expectedFilter := domain.ListGrantsFilter{ Statuses: []string{"test-status"}, @@ -74,8 +75,11 @@ func (s *GrpcHandlersSuite) TestListGrants() { ResourceIDs: []string{"test-resource-id"}, } s.grantService.EXPECT(). - List(mock.AnythingOfType("*context.emptyCtx"), expectedFilter). + List(mock.AnythingOfType("*context.cancelCtx"), expectedFilter). Return(dummyGrants, nil).Once() + s.grantService.EXPECT(). + GetGrantsTotalCount(mock.AnythingOfType("*context.cancelCtx"), expectedFilter). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListGrantsRequest{ Statuses: expectedFilter.Statuses, @@ -95,8 +99,11 @@ func (s *GrpcHandlersSuite) TestListGrants() { expectedError := errors.New("unexpected error") s.grantService.EXPECT(). - List(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). + List(mock.AnythingOfType("*context.cancelCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). Return(nil, expectedError).Once() + s.grantService.EXPECT(). + GetGrantsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). + Return(int64(0), nil).Once() req := &guardianv1beta1.ListGrantsRequest{} res, err := s.grpcServer.ListGrants(context.Background(), req) @@ -119,9 +126,11 @@ func (s *GrpcHandlersSuite) TestListGrants() { }, } s.grantService.EXPECT(). - List(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). + List(mock.AnythingOfType("*context.cancelCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). Return(expectedGrants, nil).Once() - + s.grantService.EXPECT(). + GetGrantsTotalCount(mock.AnythingOfType("*context.cancelCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). + Return(int64(1), nil).Once() req := &guardianv1beta1.ListGrantsRequest{} res, err := s.grpcServer.ListGrants(context.Background(), req) diff --git a/api/handler/v1beta1/grpc.go b/api/handler/v1beta1/grpc.go index f3bf2e9b..441cac40 100644 --- a/api/handler/v1beta1/grpc.go +++ b/api/handler/v1beta1/grpc.go @@ -54,7 +54,7 @@ type resourceService interface { type activityService interface { GetOne(context.Context, string) (*domain.Activity, error) Find(context.Context, domain.ListProviderActivitiesFilter) ([]*domain.Activity, error) - Import(context.Context, domain.ImportActivitiesFilter) ([]*domain.Activity, error) + Import(context.Context, domain.ListActivitiesFilter) ([]*domain.Activity, error) } //go:generate mockery --name=providerService --exported --with-expecter @@ -83,6 +83,7 @@ type policyService interface { //go:generate mockery --name=appealService --exported --with-expecter type appealService interface { + GetAppealsTotalCount(context.Context, *domain.ListAppealsFilter) (int64, error) GetByID(context.Context, string) (*domain.Appeal, error) Find(context.Context, *domain.ListAppealsFilter) ([]*domain.Appeal, error) Create(context.Context, []*domain.Appeal, ...appeal.CreateAppealOption) error @@ -95,11 +96,13 @@ type appealService interface { //go:generate mockery --name=approvalService --exported --with-expecter type approvalService interface { ListApprovals(context.Context, *domain.ListApprovalsFilter) ([]*domain.Approval, error) + GetApprovalsTotalCount(context.Context, *domain.ListApprovalsFilter) (int64, error) BulkInsert(context.Context, []*domain.Approval) error } //go:generate mockery --name=grantService --exported --with-expecter type grantService interface { + GetGrantsTotalCount(context.Context, domain.ListGrantsFilter) (int64, error) List(context.Context, domain.ListGrantsFilter) ([]domain.Grant, error) GetByID(context.Context, string) (*domain.Grant, error) Update(context.Context, *domain.Grant) error diff --git a/api/handler/v1beta1/mocks/activityService.go b/api/handler/v1beta1/mocks/activityService.go index 19568c5e..e9cbb7a2 100644 --- a/api/handler/v1beta1/mocks/activityService.go +++ b/api/handler/v1beta1/mocks/activityService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -133,15 +133,15 @@ func (_c *ActivityService_GetOne_Call) RunAndReturn(run func(context.Context, st } // Import provides a mock function with given fields: _a0, _a1 -func (_m *ActivityService) Import(_a0 context.Context, _a1 domain.ImportActivitiesFilter) ([]*domain.Activity, error) { +func (_m *ActivityService) Import(_a0 context.Context, _a1 domain.ListActivitiesFilter) ([]*domain.Activity, error) { ret := _m.Called(_a0, _a1) var r0 []*domain.Activity var r1 error - if rf, ok := ret.Get(0).(func(context.Context, domain.ImportActivitiesFilter) ([]*domain.Activity, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, domain.ListActivitiesFilter) ([]*domain.Activity, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, domain.ImportActivitiesFilter) []*domain.Activity); ok { + if rf, ok := ret.Get(0).(func(context.Context, domain.ListActivitiesFilter) []*domain.Activity); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -149,7 +149,7 @@ func (_m *ActivityService) Import(_a0 context.Context, _a1 domain.ImportActiviti } } - if rf, ok := ret.Get(1).(func(context.Context, domain.ImportActivitiesFilter) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, domain.ListActivitiesFilter) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -165,14 +165,14 @@ type ActivityService_Import_Call struct { // Import is a helper method to define mock.On call // - _a0 context.Context -// - _a1 domain.ImportActivitiesFilter +// - _a1 domain.ListActivitiesFilter func (_e *ActivityService_Expecter) Import(_a0 interface{}, _a1 interface{}) *ActivityService_Import_Call { return &ActivityService_Import_Call{Call: _e.mock.On("Import", _a0, _a1)} } -func (_c *ActivityService_Import_Call) Run(run func(_a0 context.Context, _a1 domain.ImportActivitiesFilter)) *ActivityService_Import_Call { +func (_c *ActivityService_Import_Call) Run(run func(_a0 context.Context, _a1 domain.ListActivitiesFilter)) *ActivityService_Import_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(domain.ImportActivitiesFilter)) + run(args[0].(context.Context), args[1].(domain.ListActivitiesFilter)) }) return _c } @@ -182,7 +182,7 @@ func (_c *ActivityService_Import_Call) Return(_a0 []*domain.Activity, _a1 error) return _c } -func (_c *ActivityService_Import_Call) RunAndReturn(run func(context.Context, domain.ImportActivitiesFilter) ([]*domain.Activity, error)) *ActivityService_Import_Call { +func (_c *ActivityService_Import_Call) RunAndReturn(run func(context.Context, domain.ListActivitiesFilter) ([]*domain.Activity, error)) *ActivityService_Import_Call { _c.Call.Return(run) return _c } diff --git a/api/handler/v1beta1/mocks/appealService.go b/api/handler/v1beta1/mocks/appealService.go index 787b1af8..bdc3d56c 100644 --- a/api/handler/v1beta1/mocks/appealService.go +++ b/api/handler/v1beta1/mocks/appealService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -307,6 +307,59 @@ func (_c *AppealService_Find_Call) RunAndReturn(run func(context.Context, *domai return _c } +// GetAppealsTotalCount provides a mock function with given fields: _a0, _a1 +func (_m *AppealService) GetAppealsTotalCount(_a0 context.Context, _a1 *domain.ListAppealsFilter) (int64, error) { + ret := _m.Called(_a0, _a1) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListAppealsFilter) (int64, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListAppealsFilter) int64); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, *domain.ListAppealsFilter) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// AppealService_GetAppealsTotalCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAppealsTotalCount' +type AppealService_GetAppealsTotalCount_Call struct { + *mock.Call +} + +// GetAppealsTotalCount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *domain.ListAppealsFilter +func (_e *AppealService_Expecter) GetAppealsTotalCount(_a0 interface{}, _a1 interface{}) *AppealService_GetAppealsTotalCount_Call { + return &AppealService_GetAppealsTotalCount_Call{Call: _e.mock.On("GetAppealsTotalCount", _a0, _a1)} +} + +func (_c *AppealService_GetAppealsTotalCount_Call) Run(run func(_a0 context.Context, _a1 *domain.ListAppealsFilter)) *AppealService_GetAppealsTotalCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*domain.ListAppealsFilter)) + }) + return _c +} + +func (_c *AppealService_GetAppealsTotalCount_Call) Return(_a0 int64, _a1 error) *AppealService_GetAppealsTotalCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *AppealService_GetAppealsTotalCount_Call) RunAndReturn(run func(context.Context, *domain.ListAppealsFilter) (int64, error)) *AppealService_GetAppealsTotalCount_Call { + _c.Call.Return(run) + return _c +} + // GetByID provides a mock function with given fields: _a0, _a1 func (_m *AppealService) GetByID(_a0 context.Context, _a1 string) (*domain.Appeal, error) { ret := _m.Called(_a0, _a1) diff --git a/api/handler/v1beta1/mocks/approvalService.go b/api/handler/v1beta1/mocks/approvalService.go index 31b8ea9a..221ec63f 100644 --- a/api/handler/v1beta1/mocks/approvalService.go +++ b/api/handler/v1beta1/mocks/approvalService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -65,6 +65,59 @@ func (_c *ApprovalService_BulkInsert_Call) RunAndReturn(run func(context.Context return _c } +// GetApprovalsTotalCount provides a mock function with given fields: _a0, _a1 +func (_m *ApprovalService) GetApprovalsTotalCount(_a0 context.Context, _a1 *domain.ListApprovalsFilter) (int64, error) { + ret := _m.Called(_a0, _a1) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListApprovalsFilter) (int64, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListApprovalsFilter) int64); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, *domain.ListApprovalsFilter) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ApprovalService_GetApprovalsTotalCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetApprovalsTotalCount' +type ApprovalService_GetApprovalsTotalCount_Call struct { + *mock.Call +} + +// GetApprovalsTotalCount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *domain.ListApprovalsFilter +func (_e *ApprovalService_Expecter) GetApprovalsTotalCount(_a0 interface{}, _a1 interface{}) *ApprovalService_GetApprovalsTotalCount_Call { + return &ApprovalService_GetApprovalsTotalCount_Call{Call: _e.mock.On("GetApprovalsTotalCount", _a0, _a1)} +} + +func (_c *ApprovalService_GetApprovalsTotalCount_Call) Run(run func(_a0 context.Context, _a1 *domain.ListApprovalsFilter)) *ApprovalService_GetApprovalsTotalCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*domain.ListApprovalsFilter)) + }) + return _c +} + +func (_c *ApprovalService_GetApprovalsTotalCount_Call) Return(_a0 int64, _a1 error) *ApprovalService_GetApprovalsTotalCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ApprovalService_GetApprovalsTotalCount_Call) RunAndReturn(run func(context.Context, *domain.ListApprovalsFilter) (int64, error)) *ApprovalService_GetApprovalsTotalCount_Call { + _c.Call.Return(run) + return _c +} + // ListApprovals provides a mock function with given fields: _a0, _a1 func (_m *ApprovalService) ListApprovals(_a0 context.Context, _a1 *domain.ListApprovalsFilter) ([]*domain.Approval, error) { ret := _m.Called(_a0, _a1) diff --git a/api/handler/v1beta1/mocks/grantService.go b/api/handler/v1beta1/mocks/grantService.go index 155e1f23..6b312b42 100644 --- a/api/handler/v1beta1/mocks/grantService.go +++ b/api/handler/v1beta1/mocks/grantService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -136,6 +136,59 @@ func (_c *GrantService_GetByID_Call) RunAndReturn(run func(context.Context, stri return _c } +// GetGrantsTotalCount provides a mock function with given fields: _a0, _a1 +func (_m *GrantService) GetGrantsTotalCount(_a0 context.Context, _a1 domain.ListGrantsFilter) (int64, error) { + ret := _m.Called(_a0, _a1) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, domain.ListGrantsFilter) (int64, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, domain.ListGrantsFilter) int64); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, domain.ListGrantsFilter) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GrantService_GetGrantsTotalCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGrantsTotalCount' +type GrantService_GetGrantsTotalCount_Call struct { + *mock.Call +} + +// GetGrantsTotalCount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.ListGrantsFilter +func (_e *GrantService_Expecter) GetGrantsTotalCount(_a0 interface{}, _a1 interface{}) *GrantService_GetGrantsTotalCount_Call { + return &GrantService_GetGrantsTotalCount_Call{Call: _e.mock.On("GetGrantsTotalCount", _a0, _a1)} +} + +func (_c *GrantService_GetGrantsTotalCount_Call) Run(run func(_a0 context.Context, _a1 domain.ListGrantsFilter)) *GrantService_GetGrantsTotalCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.ListGrantsFilter)) + }) + return _c +} + +func (_c *GrantService_GetGrantsTotalCount_Call) Return(_a0 int64, _a1 error) *GrantService_GetGrantsTotalCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GrantService_GetGrantsTotalCount_Call) RunAndReturn(run func(context.Context, domain.ListGrantsFilter) (int64, error)) *GrantService_GetGrantsTotalCount_Call { + _c.Call.Return(run) + return _c +} + // ImportFromProvider provides a mock function with given fields: ctx, criteria func (_m *GrantService) ImportFromProvider(ctx context.Context, criteria grant.ImportFromProviderCriteria) ([]*domain.Grant, error) { ret := _m.Called(ctx, criteria) diff --git a/api/handler/v1beta1/mocks/namespaceService.go b/api/handler/v1beta1/mocks/namespaceService.go index ffc6a165..e758def2 100644 --- a/api/handler/v1beta1/mocks/namespaceService.go +++ b/api/handler/v1beta1/mocks/namespaceService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/api/handler/v1beta1/mocks/policyService.go b/api/handler/v1beta1/mocks/policyService.go index 3c448398..2d95a7c4 100644 --- a/api/handler/v1beta1/mocks/policyService.go +++ b/api/handler/v1beta1/mocks/policyService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/api/handler/v1beta1/mocks/providerActivityService.go b/api/handler/v1beta1/mocks/providerActivityService.go deleted file mode 100644 index 5551f14c..00000000 --- a/api/handler/v1beta1/mocks/providerActivityService.go +++ /dev/null @@ -1,164 +0,0 @@ -// Code generated by mockery v2.10.0. DO NOT EDIT. - -package mocks - -import ( - context "context" - - domain "github.com/raystack/guardian/domain" - mock "github.com/stretchr/testify/mock" -) - -// ProviderActivityService is an autogenerated mock type for the providerActivityService type -type ProviderActivityService struct { - mock.Mock -} - -type ProviderActivityService_Expecter struct { - mock *mock.Mock -} - -func (_m *ProviderActivityService) EXPECT() *ProviderActivityService_Expecter { - return &ProviderActivityService_Expecter{mock: &_m.Mock} -} - -// Find provides a mock function with given fields: _a0, _a1 -func (_m *ProviderActivityService) Find(_a0 context.Context, _a1 domain.ListProviderActivitiesFilter) ([]*domain.Activity, error) { - ret := _m.Called(_a0, _a1) - - var r0 []*domain.Activity - if rf, ok := ret.Get(0).(func(context.Context, domain.ListProviderActivitiesFilter) []*domain.Activity); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*domain.Activity) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, domain.ListProviderActivitiesFilter) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProviderActivityService_Find_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Find' -type ProviderActivityService_Find_Call struct { - *mock.Call -} - -// Find is a helper method to define mock.On call -// - _a0 context.Context -// - _a1 domain.ListProviderActivitiesFilter -func (_e *ProviderActivityService_Expecter) Find(_a0 interface{}, _a1 interface{}) *ProviderActivityService_Find_Call { - return &ProviderActivityService_Find_Call{Call: _e.mock.On("Find", _a0, _a1)} -} - -func (_c *ProviderActivityService_Find_Call) Run(run func(_a0 context.Context, _a1 domain.ListProviderActivitiesFilter)) *ProviderActivityService_Find_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(domain.ListProviderActivitiesFilter)) - }) - return _c -} - -func (_c *ProviderActivityService_Find_Call) Return(_a0 []*domain.Activity, _a1 error) *ProviderActivityService_Find_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -// GetOne provides a mock function with given fields: _a0, _a1 -func (_m *ProviderActivityService) GetOne(_a0 context.Context, _a1 string) (*domain.Activity, error) { - ret := _m.Called(_a0, _a1) - - var r0 *domain.Activity - if rf, ok := ret.Get(0).(func(context.Context, string) *domain.Activity); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*domain.Activity) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProviderActivityService_GetOne_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOne' -type ProviderActivityService_GetOne_Call struct { - *mock.Call -} - -// GetOne is a helper method to define mock.On call -// - _a0 context.Context -// - _a1 string -func (_e *ProviderActivityService_Expecter) GetOne(_a0 interface{}, _a1 interface{}) *ProviderActivityService_GetOne_Call { - return &ProviderActivityService_GetOne_Call{Call: _e.mock.On("GetOne", _a0, _a1)} -} - -func (_c *ProviderActivityService_GetOne_Call) Run(run func(_a0 context.Context, _a1 string)) *ProviderActivityService_GetOne_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string)) - }) - return _c -} - -func (_c *ProviderActivityService_GetOne_Call) Return(_a0 *domain.Activity, _a1 error) *ProviderActivityService_GetOne_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -// Import provides a mock function with given fields: _a0, _a1 -func (_m *ProviderActivityService) Import(_a0 context.Context, _a1 domain.ImportActivitiesFilter) ([]*domain.Activity, error) { - ret := _m.Called(_a0, _a1) - - var r0 []*domain.Activity - if rf, ok := ret.Get(0).(func(context.Context, domain.ImportActivitiesFilter) []*domain.Activity); ok { - r0 = rf(_a0, _a1) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*domain.Activity) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(context.Context, domain.ImportActivitiesFilter) error); ok { - r1 = rf(_a0, _a1) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ProviderActivityService_Import_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Import' -type ProviderActivityService_Import_Call struct { - *mock.Call -} - -// Import is a helper method to define mock.On call -// - _a0 context.Context -// - _a1 domain.ImportActivitiesFilter -func (_e *ProviderActivityService_Expecter) Import(_a0 interface{}, _a1 interface{}) *ProviderActivityService_Import_Call { - return &ProviderActivityService_Import_Call{Call: _e.mock.On("Import", _a0, _a1)} -} - -func (_c *ProviderActivityService_Import_Call) Run(run func(_a0 context.Context, _a1 domain.ImportActivitiesFilter)) *ProviderActivityService_Import_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(domain.ImportActivitiesFilter)) - }) - return _c -} - -func (_c *ProviderActivityService_Import_Call) Return(_a0 []*domain.Activity, _a1 error) *ProviderActivityService_Import_Call { - _c.Call.Return(_a0, _a1) - return _c -} diff --git a/api/handler/v1beta1/mocks/providerService.go b/api/handler/v1beta1/mocks/providerService.go index 815624ca..30848e0c 100644 --- a/api/handler/v1beta1/mocks/providerService.go +++ b/api/handler/v1beta1/mocks/providerService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/api/handler/v1beta1/mocks/resourceService.go b/api/handler/v1beta1/mocks/resourceService.go index 785f8a4c..79bbf8fb 100644 --- a/api/handler/v1beta1/mocks/resourceService.go +++ b/api/handler/v1beta1/mocks/resourceService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/api/proto/raystack/guardian/v1beta1/guardian.pb.go b/api/proto/raystack/guardian/v1beta1/guardian.pb.go index 7b6cc8e4..d9749228 100644 --- a/api/proto/raystack/guardian/v1beta1/guardian.pb.go +++ b/api/proto/raystack/guardian/v1beta1/guardian.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 +// protoc-gen-go v1.30.0 // protoc (unknown) // source: raystack/guardian/v1beta1/guardian.proto @@ -2096,6 +2096,10 @@ type ListUserAppealsRequest struct { ResourceTypes []string `protobuf:"bytes,5,rep,name=resource_types,json=resourceTypes,proto3" json:"resource_types,omitempty"` ResourceUrns []string `protobuf:"bytes,6,rep,name=resource_urns,json=resourceUrns,proto3" json:"resource_urns,omitempty"` OrderBy []string `protobuf:"bytes,7,rep,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` + Size uint32 `protobuf:"varint,8,opt,name=size,proto3" json:"size,omitempty"` + Offset uint32 `protobuf:"varint,9,opt,name=offset,proto3" json:"offset,omitempty"` + Q string `protobuf:"bytes,10,opt,name=q,proto3" json:"q,omitempty"` + AccountTypes []string `protobuf:"bytes,11,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"` } func (x *ListUserAppealsRequest) Reset() { @@ -2179,12 +2183,41 @@ func (x *ListUserAppealsRequest) GetOrderBy() []string { return nil } +func (x *ListUserAppealsRequest) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListUserAppealsRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListUserAppealsRequest) GetQ() string { + if x != nil { + return x.Q + } + return "" +} + +func (x *ListUserAppealsRequest) GetAccountTypes() []string { + if x != nil { + return x.AccountTypes + } + return nil +} + type ListUserAppealsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Appeals []*Appeal `protobuf:"bytes,1,rep,name=appeals,proto3" json:"appeals,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListUserAppealsResponse) Reset() { @@ -2226,6 +2259,13 @@ func (x *ListUserAppealsResponse) GetAppeals() []*Appeal { return nil } +func (x *ListUserAppealsResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + type ListAppealsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2240,6 +2280,10 @@ type ListAppealsRequest struct { ResourceUrns []string `protobuf:"bytes,7,rep,name=resource_urns,json=resourceUrns,proto3" json:"resource_urns,omitempty"` OrderBy []string `protobuf:"bytes,8,rep,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` CreatedBy string `protobuf:"bytes,9,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` + Size uint32 `protobuf:"varint,10,opt,name=size,proto3" json:"size,omitempty"` + Offset uint32 `protobuf:"varint,11,opt,name=offset,proto3" json:"offset,omitempty"` + Q string `protobuf:"bytes,12,opt,name=q,proto3" json:"q,omitempty"` + AccountTypes []string `protobuf:"bytes,13,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"` } func (x *ListAppealsRequest) Reset() { @@ -2337,12 +2381,41 @@ func (x *ListAppealsRequest) GetCreatedBy() string { return "" } +func (x *ListAppealsRequest) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListAppealsRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListAppealsRequest) GetQ() string { + if x != nil { + return x.Q + } + return "" +} + +func (x *ListAppealsRequest) GetAccountTypes() []string { + if x != nil { + return x.AccountTypes + } + return nil +} + type ListAppealsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Appeals []*Appeal `protobuf:"bytes,1,rep,name=appeals,proto3" json:"appeals,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListAppealsResponse) Reset() { @@ -2384,6 +2457,13 @@ func (x *ListAppealsResponse) GetAppeals() []*Appeal { return nil } +func (x *ListAppealsResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + type GetAppealRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2937,6 +3017,9 @@ type ListUserApprovalsRequest struct { Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` Offset uint32 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"` AppealStatuses []string `protobuf:"bytes,7,rep,name=appeal_statuses,json=appealStatuses,proto3" json:"appeal_statuses,omitempty"` + Q string `protobuf:"bytes,8,opt,name=q,proto3" json:"q,omitempty"` + AccountTypes []string `protobuf:"bytes,9,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"` + ResourceTypes []string `protobuf:"bytes,10,rep,name=resource_types,json=resourceTypes,proto3" json:"resource_types,omitempty"` } func (x *ListUserApprovalsRequest) Reset() { @@ -3013,12 +3096,34 @@ func (x *ListUserApprovalsRequest) GetAppealStatuses() []string { return nil } +func (x *ListUserApprovalsRequest) GetQ() string { + if x != nil { + return x.Q + } + return "" +} + +func (x *ListUserApprovalsRequest) GetAccountTypes() []string { + if x != nil { + return x.AccountTypes + } + return nil +} + +func (x *ListUserApprovalsRequest) GetResourceTypes() []string { + if x != nil { + return x.ResourceTypes + } + return nil +} + type ListUserApprovalsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Approvals []*Approval `protobuf:"bytes,1,rep,name=approvals,proto3" json:"approvals,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListUserApprovalsResponse) Reset() { @@ -3060,6 +3165,13 @@ func (x *ListUserApprovalsResponse) GetApprovals() []*Approval { return nil } +func (x *ListUserApprovalsResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + type ListApprovalsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3072,6 +3184,9 @@ type ListApprovalsRequest struct { Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` Offset uint32 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"` AppealStatuses []string `protobuf:"bytes,7,rep,name=appeal_statuses,json=appealStatuses,proto3" json:"appeal_statuses,omitempty"` + Q string `protobuf:"bytes,8,opt,name=q,proto3" json:"q,omitempty"` + AccountTypes []string `protobuf:"bytes,9,rep,name=account_types,json=accountTypes,proto3" json:"account_types,omitempty"` + ResourceTypes []string `protobuf:"bytes,10,rep,name=resource_types,json=resourceTypes,proto3" json:"resource_types,omitempty"` } func (x *ListApprovalsRequest) Reset() { @@ -3155,12 +3270,34 @@ func (x *ListApprovalsRequest) GetAppealStatuses() []string { return nil } +func (x *ListApprovalsRequest) GetQ() string { + if x != nil { + return x.Q + } + return "" +} + +func (x *ListApprovalsRequest) GetAccountTypes() []string { + if x != nil { + return x.AccountTypes + } + return nil +} + +func (x *ListApprovalsRequest) GetResourceTypes() []string { + if x != nil { + return x.ResourceTypes + } + return nil +} + type ListApprovalsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Approvals []*Approval `protobuf:"bytes,1,rep,name=approvals,proto3" json:"approvals,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListApprovalsResponse) Reset() { @@ -3202,6 +3339,13 @@ func (x *ListApprovalsResponse) GetApprovals() []*Approval { return nil } +func (x *ListApprovalsResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + type UpdateApprovalRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3549,6 +3693,9 @@ type ListGrantsRequest struct { CreatedBy string `protobuf:"bytes,10,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"` OrderBy []string `protobuf:"bytes,11,rep,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` Owner string `protobuf:"bytes,12,opt,name=owner,proto3" json:"owner,omitempty"` + Size uint32 `protobuf:"varint,13,opt,name=size,proto3" json:"size,omitempty"` + Offset uint32 `protobuf:"varint,14,opt,name=offset,proto3" json:"offset,omitempty"` + Q string `protobuf:"bytes,15,opt,name=q,proto3" json:"q,omitempty"` } func (x *ListGrantsRequest) Reset() { @@ -3667,12 +3814,34 @@ func (x *ListGrantsRequest) GetOwner() string { return "" } +func (x *ListGrantsRequest) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListGrantsRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListGrantsRequest) GetQ() string { + if x != nil { + return x.Q + } + return "" +} + type ListGrantsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Grants []*Grant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListGrantsResponse) Reset() { @@ -3714,6 +3883,13 @@ func (x *ListGrantsResponse) GetGrants() []*Grant { return nil } +func (x *ListGrantsResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + type ListUserGrantsRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3729,6 +3905,9 @@ type ListUserGrantsRequest struct { ResourceUrns []string `protobuf:"bytes,8,rep,name=resource_urns,json=resourceUrns,proto3" json:"resource_urns,omitempty"` Roles []string `protobuf:"bytes,9,rep,name=roles,proto3" json:"roles,omitempty"` OrderBy []string `protobuf:"bytes,10,rep,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` + Size uint32 `protobuf:"varint,11,opt,name=size,proto3" json:"size,omitempty"` + Offset uint32 `protobuf:"varint,12,opt,name=offset,proto3" json:"offset,omitempty"` + Q string `protobuf:"bytes,13,opt,name=q,proto3" json:"q,omitempty"` } func (x *ListUserGrantsRequest) Reset() { @@ -3833,12 +4012,34 @@ func (x *ListUserGrantsRequest) GetOrderBy() []string { return nil } +func (x *ListUserGrantsRequest) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ListUserGrantsRequest) GetOffset() uint32 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *ListUserGrantsRequest) GetQ() string { + if x != nil { + return x.Q + } + return "" +} + type ListUserGrantsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Grants []*Grant `protobuf:"bytes,1,rep,name=grants,proto3" json:"grants,omitempty"` + Total int32 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"` } func (x *ListUserGrantsResponse) Reset() { @@ -3880,6 +4081,13 @@ func (x *ListUserGrantsResponse) GetGrants() []*Grant { return nil } +func (x *ListUserGrantsResponse) GetTotal() int32 { + if x != nil { + return x.Total + } + return 0 +} + type GetGrantRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -7541,7 +7749,7 @@ var file_raystack_guardian_v1beta1_guardian_proto_rawDesc = []byte{ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0xfb, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, + 0xf0, 0x02, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, @@ -7556,1239 +7764,1283 @@ var file_raystack_guardian_v1beta1_guardian_proto_rawDesc = []byte{ 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x07, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x56, 0x0a, - 0x17, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x07, 0x61, 0x70, - 0x70, 0x65, 0x61, 0x6c, 0x73, 0x22, 0xb5, 0x02, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, - 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, - 0x72, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, - 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, - 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x72, 0x6e, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, - 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0x52, 0x0a, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, 0x0a, + 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, + 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, + 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x0c, 0x0a, 0x01, 0x71, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x71, 0x12, 0x23, 0x0a, + 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x0b, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x22, 0x6c, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, + 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, + 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x22, 0xaa, 0x03, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, + 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x19, + 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, + 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, + 0x40, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x0c, 0x0a, 0x01, 0x71, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x71, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x68, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x73, 0x22, 0x22, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, + 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0x22, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4e, 0x0a, 0x11, 0x47, + 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, + 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x25, 0x0a, 0x13, 0x43, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x22, 0x51, 0x0a, 0x14, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x25, 0x0a, 0x13, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x51, 0x0a, 0x14, - 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x96, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4d, 0x0a, + 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, + 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x1a, 0x20, 0x0a, 0x06, + 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x51, + 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x22, 0xe7, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, + 0x72, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x72, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x15, 0x52, + 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, + 0x73, 0x22, 0xe7, 0x02, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x55, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, + 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x94, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x53, 0x0a, 0x14, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, - 0x96, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x4d, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, - 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x1a, 0x20, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x51, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, - 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0xe7, 0x01, 0x0a, 0x14, - 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, + 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, + 0x22, 0xb5, 0x02, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, + 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x0c, + 0x0a, 0x01, 0x71, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x71, 0x12, 0x23, 0x0a, 0x0d, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x09, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, - 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x41, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, - 0x0a, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x22, 0xe7, 0x02, 0x0a, 0x13, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x49, 0x64, 0x12, 0x55, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x94, - 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, - 0x31, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x64, 0x65, - 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x53, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, - 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, - 0x6c, 0x52, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x22, 0xdb, 0x01, 0x0a, 0x18, 0x4c, - 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, - 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, - 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, - 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, - 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, - 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, - 0x27, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x22, 0x5e, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, + 0x70, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x74, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x09, 0x61, - 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x22, 0xf6, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, - 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, - 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, - 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, - 0x73, 0x22, 0x5a, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, + 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, 0xd0, + 0x02, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, + 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, + 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x27, + 0x0a, 0x0f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x0c, 0x0a, 0x01, 0x71, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x01, 0x71, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x22, 0x70, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, - 0x61, 0x6c, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x22, 0xd7, 0x01, - 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f, - 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4f, 0x0a, 0x06, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, - 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x38, 0x0a, - 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x53, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, - 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x68, 0x0a, 0x12, - 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x49, 0x64, 0x12, - 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x49, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x50, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, - 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, - 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x6b, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x49, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x53, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, - 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x96, 0x03, 0x0a, 0x11, 0x4c, - 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x23, 0x0a, - 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, - 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x14, 0x0a, - 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, - 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, - 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x42, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x0b, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, - 0x6e, 0x65, 0x72, 0x22, 0x4e, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x61, 0x6c, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x22, 0xd7, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, + 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, + 0x0d, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x4f, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x1a, 0x38, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, + 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x53, 0x0a, + 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x22, 0x68, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x50, 0x0a, 0x13, + 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, + 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x22, 0x6b, + 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x72, 0x6f, + 0x76, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x53, 0x0a, 0x16, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, + 0x22, 0xe6, 0x03, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x49, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, + 0x72, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, + 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, + 0x72, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x5f, 0x62, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x42, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, + 0x40, 0x01, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, + 0x00, 0x40, 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x0c, 0x0a, 0x01, 0x71, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x71, 0x22, 0x64, 0x0a, 0x12, 0x4c, 0x69, 0x73, + 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x38, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x22, + 0xb5, 0x03, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x25, + 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, + 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, + 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, 0x01, + 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x28, 0x00, 0x40, + 0x01, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x0c, 0x0a, 0x01, 0x71, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x71, 0x22, 0x68, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x22, 0x21, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x4a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x22, 0x3a, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x4d, 0x0a, 0x13, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0x3c, 0x0a, 0x12, 0x52, + 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x4d, 0x0a, 0x13, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0xe6, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, 0x0a, + 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x22, 0x50, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, - 0x6e, 0x74, 0x73, 0x22, 0xe5, 0x02, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, - 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, - 0x64, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, - 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, - 0x6c, 0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, - 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x0a, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x22, 0x52, 0x0a, 0x16, 0x4c, - 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, - 0x21, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x22, 0x4a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0x3a, - 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0x4d, 0x0a, 0x13, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, - 0x6e, 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0x3c, 0x0a, 0x12, 0x52, 0x65, 0x76, - 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x4d, 0x0a, 0x13, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, - 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, - 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x22, 0xe6, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, - 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, - 0x25, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, - 0x72, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, - 0x50, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x73, 0x22, 0x86, 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x38, 0x0a, 0x0c, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xf4, 0x07, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, + 0x4d, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x35, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x38, + 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x63, 0x72, 0x65, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x56, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8c, 0x01, 0x0a, + 0x0c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, + 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, + 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x12, 0x46, 0x0a, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1c, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x1a, 0xb4, 0x01, 0x0a, 0x0e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, + 0x6f, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x1a, 0x79, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf9, 0x01, + 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, + 0x12, 0x41, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x29, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, + 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x49, 0x0a, 0x0c, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x22, 0xa6, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x49, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x22, 0x86, 0x01, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x38, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x70, - 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x38, 0x0a, 0x0c, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xf4, 0x07, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, - 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x4d, 0x0a, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x38, 0x0a, 0x0b, - 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x1a, 0x38, 0x0a, 0x0e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x64, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x02, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x4e, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, - 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x56, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x32, - 0x0a, 0x15, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x1a, - 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8c, 0x01, 0x0a, 0x0c, 0x41, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x34, 0x0a, 0x16, 0x61, - 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x50, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x12, 0x46, 0x0a, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1c, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, - 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x1a, 0xb4, 0x01, 0x0a, 0x0e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x3f, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x12, 0x35, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x6f, 0x6c, - 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x1a, 0x79, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x1a, 0x0a, - 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf9, 0x01, 0x0a, 0x08, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x41, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, + 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x02, 0x65, 0x71, 0x22, 0xf2, 0x04, + 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x68, 0x0a, 0x10, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, + 0x0a, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6f, 0x6e, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x6c, + 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4f, 0x6e, + 0x42, 0x65, 0x68, 0x61, 0x6c, 0x66, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, + 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x65, 0x72, + 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x46, 0x0a, 0x20, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x49, 0x6e, 0x12, 0x54, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x09, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x61, + 0x69, 0x6c, 0x73, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x1a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x44, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x1a, 0x3b, 0x0a, + 0x0f, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x76, 0x0a, 0x08, 0x51, 0x75, + 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0xd0, 0x0f, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x05, 0x73, 0x74, 0x65, + 0x70, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, + 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, + 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x49, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x73, 0x22, 0xa6, 0x01, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x49, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x1a, 0x38, 0x0a, 0x0e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x02, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x02, 0x65, 0x71, 0x22, 0xf2, 0x04, 0x0a, 0x12, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x68, 0x0a, 0x10, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, + 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x51, 0x0a, 0x0c, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x37, 0x0a, 0x03, 0x69, 0x61, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x44, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x6f, 0x6e, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x6c, 0x66, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4f, 0x6e, 0x42, 0x65, - 0x68, 0x61, 0x6c, 0x66, 0x12, 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x65, - 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x65, 0x72, 0x6d, 0x61, - 0x6e, 0x65, 0x6e, 0x74, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x46, 0x0a, 0x20, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x1c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x41, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x12, 0x54, 0x0a, 0x09, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x51, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, - 0x73, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x1a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x44, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x1a, 0x3b, 0x0a, 0x0f, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x76, 0x0a, 0x08, 0x51, 0x75, 0x65, 0x73, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0xd0, 0x0f, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, - 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x12, 0x45, 0x0a, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x51, 0x0a, 0x0c, 0x72, 0x65, - 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x49, 0x41, 0x4d, 0x52, 0x03, 0x69, 0x61, 0x6d, 0x12, 0x45, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x1a, + 0xff, 0x01, 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, + 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x68, 0x65, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x68, 0x65, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x73, 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x70, 0x70, + 0x72, 0x6f, 0x76, 0x65, 0x5f, 0x69, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x49, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x70, + 0x72, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, + 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8c, 0x07, 0x0a, + 0x0b, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x02, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x02, 0x6f, 0x6e, 0x12, 0x58, + 0x0a, 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, + 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, + 0x07, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x1a, 0x9e, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, + 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x5f, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, + 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, + 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, + 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xaf, 0x03, 0x0a, 0x10, 0x41, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x6d, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x51, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, - 0x0c, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x37, 0x0a, - 0x03, 0x69, 0x61, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x49, 0x41, - 0x4d, 0x52, 0x03, 0x69, 0x61, 0x6d, 0x12, 0x45, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x1a, 0xff, 0x01, - 0x0a, 0x0c, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x65, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x66, 0x61, - 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x77, 0x68, 0x65, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x68, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, - 0x74, 0x72, 0x61, 0x74, 0x65, 0x67, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x70, 0x70, 0x72, 0x6f, - 0x76, 0x65, 0x5f, 0x69, 0x66, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x70, - 0x72, 0x6f, 0x76, 0x65, 0x49, 0x66, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, - 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, - 0x76, 0x65, 0x72, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x1a, - 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x8c, 0x07, 0x0a, 0x0b, 0x52, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x50, 0x0a, 0x02, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x02, 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x07, - 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x64, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x07, 0x61, - 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x1a, 0x9e, 0x02, 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, 0x69, - 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x23, 0x0a, + 0x69, 0x63, 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, + 0x65, 0x12, 0x42, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, + 0x70, 0x70, 0x65, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3f, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x1a, 0x92, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x55, 0x72, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x75, 0x72, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6e, 0x12, 0x12, 0x0a, - 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, - 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x6e, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x70, - 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xaf, 0x03, 0x0a, 0x10, 0x41, 0x64, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x6d, 0x0a, 0x08, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x51, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x64, - 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, - 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, - 0x42, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x28, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, - 0x65, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x3f, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x1a, 0x92, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x55, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, 0xd7, 0x01, 0x0a, 0x03, 0x49, 0x41, - 0x4d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x2e, 0x0a, - 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x49, 0x0a, - 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x49, 0x41, 0x4d, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbd, 0x07, 0x0a, 0x06, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, 0x12, 0x25, - 0x0a, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, - 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, - 0x12, 0x42, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, - 0x70, 0x65, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x3f, 0x0a, 0x08, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x09, - 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x72, - 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, - 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, - 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x20, 0x0a, 0x0b, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x36, - 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, - 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, - 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x4a, - 0x04, 0x08, 0x10, 0x10, 0x11, 0x22, 0xa4, 0x03, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, + 0x65, 0x72, 0x55, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x1a, 0xd7, 0x01, 0x0a, 0x03, + 0x49, 0x41, 0x4d, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, + 0x2e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x49, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x49, 0x41, 0x4d, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x1a, 0x39, 0x0a, 0x0b, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x70, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x65, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbd, 0x07, 0x0a, 0x06, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x65, 0x61, - 0x6c, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, - 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x63, 0x74, 0x6f, - 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, 0x12, 0x25, - 0x0a, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, - 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, - 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, + 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, + 0x6c, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x39, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x45, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x3f, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x41, + 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, + 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, + 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x13, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x30, 0x0a, 0x07, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xc6, 0x04, 0x0a, - 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, - 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x55, 0x72, - 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x07, 0x64, - 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x47, - 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, - 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x08, 0x63, 0x68, 0x69, - 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x20, + 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x15, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x52, 0x05, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb9, 0x06, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, - 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, - 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x64, - 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x44, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, - 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x62, 0x79, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x42, - 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, 0x0a, 0x0d, - 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, - 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, - 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0e, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x0e, 0x10, 0x0f, 0x4a, 0x04, 0x08, 0x0f, 0x10, + 0x10, 0x4a, 0x04, 0x08, 0x10, 0x10, 0x11, 0x22, 0xa4, 0x03, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x69, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x72, 0x6f, + 0x76, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x65, 0x72, 0x73, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, + 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3f, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x61, - 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x61, 0x6e, 0x65, - 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x50, 0x65, 0x72, 0x6d, - 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2c, 0x0a, - 0x12, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6f, - 0x77, 0x6e, 0x65, 0x72, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, 0x6e, 0x65, - 0x72, 0x22, 0xf1, 0x04, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, - 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0xc6, + 0x04, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x55, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, + 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x12, 0x47, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, - 0x12, 0x3f, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, - 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x12, 0x3f, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, - 0x74, 0x79, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf0, 0x01, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x1b, + 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3f, 0x0a, 0x08, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, + 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x52, 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x1a, 0x39, 0x0a, 0x0b, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb9, 0x06, 0x0a, 0x05, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x64, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x65, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, + 0x62, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, + 0x64, 0x42, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x09, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x64, 0x41, 0x74, 0x12, 0x23, + 0x0a, 0x0d, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x52, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, + 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x42, 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, - 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x5c, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x42, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3f, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x06, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x06, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x61, + 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x73, 0x50, 0x65, + 0x72, 0x6d, 0x61, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x2c, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x22, 0xf1, 0x04, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x41, 0x74, 0x12, 0x3f, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x5f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x2f, 0x0a, 0x13, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0e, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x12, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf0, 0x01, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, + 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x5c, 0x0a, 0x16, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x25, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5a, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x25, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x42, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, - 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x6c, 0x0a, - 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x86, 0x31, 0x0a, 0x0f, 0x47, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x5e, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x0b, - 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, - 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9d, 0x01, 0x0a, 0x10, - 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, - 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x99, 0x01, 0x0a, 0x0e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x30, + 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, + 0x6c, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x42, 0x0a, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x19, 0x0a, + 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x86, 0x31, 0x0a, 0x0f, 0x47, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x8e, 0x01, 0x0a, + 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0x8d, 0x01, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x2d, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, + 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9d, 0x01, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x12, 0x99, 0x01, + 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0xd7, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, + 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x22, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x3a, 0x06, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x12, 0xd7, 0x01, 0x0a, 0x0e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x60, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5a, 0x3a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5a, - 0x37, 0x3a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x2d, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x7d, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x2e, 0x75, 0x72, 0x6e, 0x7d, 0x1a, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, + 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x60, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x5a, 0x3a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x5a, 0x37, 0x3a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x2d, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, + 0x7b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x7d, 0x2f, 0x7b, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x75, 0x72, 0x6e, 0x7d, 0x1a, 0x17, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x19, 0x2a, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa7, 0x01, 0x0a, 0x09, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x7d, 0x2f, 0x72, - 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xa2, 0x01, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, - 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x8e, 0x01, 0x0a, 0x0b, 0x47, 0x65, - 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, - 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x30, 0x2e, - 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa7, 0x01, 0x0a, + 0x09, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x2b, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x12, 0x37, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x7d, + 0x2f, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0xa2, 0x01, 0x0a, 0x10, 0x49, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x32, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, + 0x1a, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x69, 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x8e, 0x01, 0x0a, 0x0b, + 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x12, 0x2d, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, + 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, + 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x92, 0x01, 0x0a, + 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, + 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, - 0x8a, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, + 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x12, 0x8a, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x99, + 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2b, 0x2e, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, + 0x29, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0c, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x11, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, + 0x97, 0x01, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x99, 0x01, 0x0a, - 0x09, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2b, 0x2e, 0x72, 0x61, 0x79, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x1a, 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc6, 0x01, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x12, 0x29, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, - 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1b, 0x3a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x12, 0x97, 0x01, - 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x1a, - 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc6, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, - 0x12, 0x36, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x50, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, - 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, - 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0xa0, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x2f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, + 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, + 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0xa0, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x23, 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x17, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x23, 0x3a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x1a, 0x17, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x96, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x95, 0x01, - 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, - 0x12, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x65, 0x2f, 0x61, 0x70, - 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x86, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, - 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x85, - 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x2b, 0x2e, 0x72, - 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, - 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x95, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6e, 0x63, 0x65, - 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, - 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, - 0x1a, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, - 0x6c, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x12, 0x8c, - 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, - 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x9d, 0x01, - 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, - 0x61, 0x6c, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, - 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x6d, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x8e, 0x01, - 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, - 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, - 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, 0xb6, - 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, - 0x6c, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, + 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, + 0x95, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x73, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x3a, 0x06, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x70, - 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, - 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xb7, 0x01, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x41, - 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x65, 0x2f, + 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x86, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, + 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, + 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x49, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, 0x3a, 0x01, - 0x2a, 0x22, 0x3e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, + 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, + 0x12, 0x85, 0x01, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x2b, + 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, + 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x72, 0x61, + 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x95, 0x01, 0x0a, 0x0c, 0x43, 0x61, 0x6e, + 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x41, 0x70, 0x70, 0x65, + 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1e, 0x1a, 0x1c, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, + 0x65, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, + 0x12, 0x8c, 0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, + 0x6c, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x12, + 0x9d, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x72, + 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x33, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, + 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x41, + 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x6d, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x12, + 0x8e, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, + 0x73, 0x12, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, + 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, + 0x12, 0xb6, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, + 0x76, 0x61, 0x6c, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, + 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, + 0x3a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x72, 0x6f, - 0x76, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, - 0x73, 0x12, 0xc5, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, - 0x6f, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, - 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, + 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xb7, 0x01, 0x0a, 0x0b, 0x41, 0x64, + 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x49, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x43, + 0x3a, 0x01, 0x2a, 0x22, 0x3e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, + 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, + 0x65, 0x72, 0x73, 0x12, 0xc5, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, + 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x48, 0x2a, 0x46, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, 0x70, 0x65, - 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x72, 0x6f, - 0x76, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, - 0x73, 0x2f, 0x7b, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x7d, 0x12, 0x82, 0x01, 0x0a, 0x0a, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x70, 0x70, 0x72, 0x6f, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x48, 0x2a, 0x46, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x70, + 0x70, 0x65, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x73, 0x2f, 0x7b, 0x61, 0x70, 0x70, + 0x72, 0x6f, 0x76, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x76, + 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x7d, 0x12, 0x82, 0x01, 0x0a, 0x0a, + 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x61, 0x79, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x91, - 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, + 0x0f, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x12, 0x91, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x12, 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x12, 0x12, - 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x65, 0x2f, 0x67, 0x72, 0x61, 0x6e, - 0x74, 0x73, 0x12, 0x81, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, - 0x2a, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, - 0x12, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8d, 0x01, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, - 0x32, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x94, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, - 0x1a, 0x1b, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, - 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, 0x92, 0x01, - 0x0a, 0x0c, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x2e, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, - 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, - 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, - 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x1a, 0x16, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x72, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x12, 0xb6, 0x01, 0x0a, 0x18, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x72, 0x61, - 0x6e, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, - 0x3a, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, - 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, - 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x98, 0x01, 0x0a, 0x0f, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, - 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, - 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, - 0x2a, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, + 0x12, 0x12, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6d, 0x65, 0x2f, 0x67, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x12, 0x81, 0x01, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x12, 0x2a, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, + 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8d, 0x01, 0x0a, 0x0b, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, + 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, + 0x01, 0x2a, 0x32, 0x14, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x94, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x12, 0x2d, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, - 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x30, 0x2e, + 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, + 0x01, 0x2a, 0x1a, 0x1b, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x12, + 0x92, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, + 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x1a, 0x16, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x72, 0x65, + 0x76, 0x6f, 0x6b, 0x65, 0x12, 0xb6, 0x01, 0x0a, 0x18, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x12, 0x3a, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, - 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, + 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, + 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1b, 0x3a, 0x01, 0x2a, 0x22, 0x16, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x98, 0x01, + 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, + 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, + 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x61, 0x79, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x92, 0x01, 0x0a, + 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, + 0x30, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x12, - 0x9d, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, - 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x1a, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x42, - 0x4c, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x61, - 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x67, 0x75, - 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x67, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x92, 0x41, - 0x0c, 0x12, 0x07, 0x32, 0x05, 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2a, 0x01, 0x01, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, + 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x72, 0x61, 0x79, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x1a, 0x18, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x42, 0x4c, 0x92, 0x41, 0x0c, 0x12, 0x07, 0x32, 0x05, 0x30, 0x2e, 0x31, 0x2e, 0x30, 0x2a, + 0x01, 0x01, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, + 0x61, 0x79, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x67, + 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, + 0x67, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/api/proto/raystack/guardian/v1beta1/guardian.pb.gw.go b/api/proto/raystack/guardian/v1beta1/guardian.pb.gw.go index d8bb2dfa..bbc802c2 100644 --- a/api/proto/raystack/guardian/v1beta1/guardian.pb.gw.go +++ b/api/proto/raystack/guardian/v1beta1/guardian.pb.gw.go @@ -120,7 +120,7 @@ func local_request_GuardianService_GetProviderTypes_0(ctx context.Context, marsh } var ( - filter_GuardianService_CreateProvider_0 = &utilities.DoubleArray{Encoding: map[string]int{"config": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} + filter_GuardianService_CreateProvider_0 = &utilities.DoubleArray{Encoding: map[string]int{"config": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} ) func request_GuardianService_CreateProvider_0(ctx context.Context, marshaler runtime.Marshaler, client GuardianServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -172,7 +172,7 @@ func local_request_GuardianService_CreateProvider_0(ctx context.Context, marshal } var ( - filter_GuardianService_UpdateProvider_0 = &utilities.DoubleArray{Encoding: map[string]int{"config": 0, "id": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} + filter_GuardianService_UpdateProvider_0 = &utilities.DoubleArray{Encoding: map[string]int{"config": 0, "id": 1}, Base: []int{1, 2, 4, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 2, 3, 3}} ) func request_GuardianService_UpdateProvider_0(ctx context.Context, marshaler runtime.Marshaler, client GuardianServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -258,7 +258,7 @@ func local_request_GuardianService_UpdateProvider_0(ctx context.Context, marshal } var ( - filter_GuardianService_UpdateProvider_1 = &utilities.DoubleArray{Encoding: map[string]int{"config": 0, "type": 1, "urn": 2}, Base: []int{1, 3, 1, 2, 0, 0, 0}, Check: []int{0, 1, 2, 2, 3, 4, 2}} + filter_GuardianService_UpdateProvider_1 = &utilities.DoubleArray{Encoding: map[string]int{"config": 0, "type": 1, "urn": 2}, Base: []int{1, 6, 7, 8, 2, 0, 4, 0, 0, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 5, 2, 7, 2, 2, 3, 4}} ) func request_GuardianService_UpdateProvider_1(ctx context.Context, marshaler runtime.Marshaler, client GuardianServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -700,7 +700,7 @@ func local_request_GuardianService_GetPolicy_0(ctx context.Context, marshaler ru } var ( - filter_GuardianService_CreatePolicy_0 = &utilities.DoubleArray{Encoding: map[string]int{"policy": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} + filter_GuardianService_CreatePolicy_0 = &utilities.DoubleArray{Encoding: map[string]int{"policy": 0}, Base: []int{1, 2, 0, 0}, Check: []int{0, 1, 2, 2}} ) func request_GuardianService_CreatePolicy_0(ctx context.Context, marshaler runtime.Marshaler, client GuardianServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -752,7 +752,7 @@ func local_request_GuardianService_CreatePolicy_0(ctx context.Context, marshaler } var ( - filter_GuardianService_UpdatePolicy_0 = &utilities.DoubleArray{Encoding: map[string]int{"policy": 0, "id": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} + filter_GuardianService_UpdatePolicy_0 = &utilities.DoubleArray{Encoding: map[string]int{"policy": 0, "id": 1}, Base: []int{1, 2, 4, 0, 0, 0, 0}, Check: []int{0, 1, 1, 2, 2, 3, 3}} ) func request_GuardianService_UpdatePolicy_0(ctx context.Context, marshaler runtime.Marshaler, client GuardianServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -2179,20 +2179,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListProviders") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListProviders", runtime.WithHTTPPathPattern("/v1beta1/providers")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListProviders_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListProviders_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListProviders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListProviders_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2202,20 +2204,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetProvider_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetProvider_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2225,20 +2229,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes", runtime.WithHTTPPathPattern("/v1beta1/providers/types")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetProviderTypes_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetProviderTypes_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetProviderTypes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetProviderTypes_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2248,20 +2254,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateProvider", runtime.WithHTTPPathPattern("/v1beta1/providers")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_CreateProvider_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_CreateProvider_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreateProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreateProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2271,20 +2279,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdateProvider_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdateProvider_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2294,20 +2304,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{config.type}/{config.urn}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdateProvider_1(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdateProvider_1(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateProvider_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateProvider_1(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2317,20 +2329,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_DeleteProvider_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_DeleteProvider_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_DeleteProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_DeleteProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2340,20 +2354,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListRoles") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListRoles", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}/resources/{resource_type}/roles")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListRoles_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListRoles_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListRoles_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListRoles_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2363,20 +2379,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportActivities") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportActivities", runtime.WithHTTPPathPattern("/v1beta1/activities/import")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ImportActivities_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ImportActivities_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ImportActivities_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ImportActivities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2386,20 +2404,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetActivity") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetActivity", runtime.WithHTTPPathPattern("/v1beta1/activities/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetActivity_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetActivity_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetActivity_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetActivity_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2409,20 +2429,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListActivities") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListActivities", runtime.WithHTTPPathPattern("/v1beta1/activities")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListActivities_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListActivities_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListActivities_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListActivities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2432,20 +2454,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListPolicies") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListPolicies", runtime.WithHTTPPathPattern("/v1beta1/policies")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListPolicies_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListPolicies_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListPolicies_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListPolicies_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2455,20 +2479,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicy") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicy", runtime.WithHTTPPathPattern("/v1beta1/policies/{id}/versions/{version}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetPolicy_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetPolicy_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetPolicy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2478,20 +2504,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreatePolicy") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreatePolicy", runtime.WithHTTPPathPattern("/v1beta1/policies")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_CreatePolicy_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_CreatePolicy_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreatePolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreatePolicy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2501,20 +2529,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy", runtime.WithHTTPPathPattern("/v1beta1/policies/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdatePolicy_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdatePolicy_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdatePolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdatePolicy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2524,20 +2554,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences", runtime.WithHTTPPathPattern("/v1beta1/policies/{id}/versions/{version}/preferences")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetPolicyPreferences_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetPolicyPreferences_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetPolicyPreferences_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetPolicyPreferences_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2547,20 +2579,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListResources") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListResources", runtime.WithHTTPPathPattern("/v1beta1/resources")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListResources_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListResources_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListResources_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2570,20 +2604,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetResource") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetResource_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2593,20 +2629,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateResource") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdateResource_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdateResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2616,20 +2654,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteResource") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_DeleteResource_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_DeleteResource_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_DeleteResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_DeleteResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2639,20 +2679,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals", runtime.WithHTTPPathPattern("/v1beta1/me/appeals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListUserAppeals_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListUserAppeals_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListUserAppeals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListUserAppeals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2662,20 +2704,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListAppeals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListAppeals", runtime.WithHTTPPathPattern("/v1beta1/appeals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListAppeals_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListAppeals_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListAppeals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListAppeals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2685,20 +2729,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetAppeal") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetAppeal", runtime.WithHTTPPathPattern("/v1beta1/appeals/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetAppeal_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetAppeal_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetAppeal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetAppeal_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2708,20 +2754,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CancelAppeal") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CancelAppeal", runtime.WithHTTPPathPattern("/v1beta1/appeals/{id}/cancel")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_CancelAppeal_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_CancelAppeal_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CancelAppeal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CancelAppeal_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2731,20 +2779,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateAppeal") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateAppeal", runtime.WithHTTPPathPattern("/v1beta1/appeals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_CreateAppeal_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_CreateAppeal_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreateAppeal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreateAppeal_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2754,20 +2804,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals", runtime.WithHTTPPathPattern("/v1beta1/me/approvals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListUserApprovals_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListUserApprovals_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListUserApprovals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListUserApprovals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2777,20 +2829,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListApprovals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListApprovals", runtime.WithHTTPPathPattern("/v1beta1/approvals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListApprovals_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListApprovals_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListApprovals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListApprovals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2800,20 +2854,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateApproval") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateApproval", runtime.WithHTTPPathPattern("/v1beta1/appeals/{id}/approvals/{approval_name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdateApproval_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdateApproval_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateApproval_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateApproval_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2823,20 +2879,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/AddApprover") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/AddApprover", runtime.WithHTTPPathPattern("/v1beta1/appeals/{appeal_id}/approvals/{approval_id}/approvers")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_AddApprover_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_AddApprover_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_AddApprover_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_AddApprover_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2846,20 +2904,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteApprover") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteApprover", runtime.WithHTTPPathPattern("/v1beta1/appeals/{appeal_id}/approvals/{approval_id}/approvers/{email}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_DeleteApprover_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_DeleteApprover_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_DeleteApprover_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_DeleteApprover_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2869,20 +2929,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListGrants") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListGrants", runtime.WithHTTPPathPattern("/v1beta1/grants")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListGrants_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListGrants_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListGrants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListGrants_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2892,20 +2954,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserGrants") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserGrants", runtime.WithHTTPPathPattern("/v1beta1/me/grants")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListUserGrants_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListUserGrants_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListUserGrants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListUserGrants_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2915,20 +2979,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetGrant") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetGrant", runtime.WithHTTPPathPattern("/v1beta1/grants/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetGrant_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetGrant_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetGrant_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2938,20 +3004,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateGrant") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateGrant", runtime.WithHTTPPathPattern("/v1beta1/grants/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdateGrant_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdateGrant_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateGrant_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2961,20 +3029,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrant") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrant", runtime.WithHTTPPathPattern("/v1beta1/grants/{id}/revoke")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_RevokeGrant_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_RevokeGrant_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_RevokeGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_RevokeGrant_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -2984,20 +3054,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrants") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrants", runtime.WithHTTPPathPattern("/v1beta1/grants/revoke")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_RevokeGrants_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_RevokeGrants_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_RevokeGrants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_RevokeGrants_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3007,20 +3079,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider", runtime.WithHTTPPathPattern("/v1beta1/grants/import")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ImportGrantsFromProvider_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ImportGrantsFromProvider_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ImportGrantsFromProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ImportGrantsFromProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3030,20 +3104,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateNamespace") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateNamespace", runtime.WithHTTPPathPattern("/v1beta1/namespaces")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_CreateNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_CreateNamespace_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreateNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreateNamespace_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3053,20 +3129,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetNamespace") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetNamespace", runtime.WithHTTPPathPattern("/v1beta1/namespaces/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_GetNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_GetNamespace_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetNamespace_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3076,20 +3154,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListNamespaces") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListNamespaces", runtime.WithHTTPPathPattern("/v1beta1/namespaces")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_ListNamespaces_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_ListNamespaces_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListNamespaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListNamespaces_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3099,20 +3179,22 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv var stream runtime.ServerTransportStream ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace", runtime.WithHTTPPathPattern("/v1beta1/namespaces/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_GuardianService_UpdateNamespace_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_GuardianService_UpdateNamespace_0(annotatedContext, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateNamespace_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3122,7 +3204,7 @@ func RegisterGuardianServiceHandlerServer(ctx context.Context, mux *runtime.Serv // RegisterGuardianServiceHandlerFromEndpoint is same as RegisterGuardianServiceHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterGuardianServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) + conn, err := grpc.DialContext(ctx, endpoint, opts...) if err != nil { return err } @@ -3161,19 +3243,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListProviders") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListProviders", runtime.WithHTTPPathPattern("/v1beta1/providers")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListProviders_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListProviders_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListProviders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListProviders_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3181,19 +3265,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetProvider_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetProvider_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3201,19 +3287,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes", runtime.WithHTTPPathPattern("/v1beta1/providers/types")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetProviderTypes_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetProviderTypes_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetProviderTypes_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetProviderTypes_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3221,19 +3309,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateProvider", runtime.WithHTTPPathPattern("/v1beta1/providers")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_CreateProvider_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_CreateProvider_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreateProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreateProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3241,19 +3331,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdateProvider_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdateProvider_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3261,19 +3353,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{config.type}/{config.urn}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdateProvider_1(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdateProvider_1(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateProvider_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateProvider_1(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3281,19 +3375,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteProvider", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_DeleteProvider_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_DeleteProvider_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_DeleteProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_DeleteProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3301,19 +3397,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListRoles") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListRoles", runtime.WithHTTPPathPattern("/v1beta1/providers/{id}/resources/{resource_type}/roles")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListRoles_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListRoles_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListRoles_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListRoles_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3321,19 +3419,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportActivities") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportActivities", runtime.WithHTTPPathPattern("/v1beta1/activities/import")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ImportActivities_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ImportActivities_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ImportActivities_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ImportActivities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3341,19 +3441,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetActivity") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetActivity", runtime.WithHTTPPathPattern("/v1beta1/activities/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetActivity_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetActivity_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetActivity_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetActivity_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3361,19 +3463,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListActivities") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListActivities", runtime.WithHTTPPathPattern("/v1beta1/activities")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListActivities_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListActivities_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListActivities_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListActivities_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3381,19 +3485,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListPolicies") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListPolicies", runtime.WithHTTPPathPattern("/v1beta1/policies")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListPolicies_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListPolicies_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListPolicies_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListPolicies_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3401,19 +3507,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicy") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicy", runtime.WithHTTPPathPattern("/v1beta1/policies/{id}/versions/{version}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetPolicy_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetPolicy_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetPolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetPolicy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3421,19 +3529,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreatePolicy") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreatePolicy", runtime.WithHTTPPathPattern("/v1beta1/policies")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_CreatePolicy_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_CreatePolicy_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreatePolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreatePolicy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3441,19 +3551,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy", runtime.WithHTTPPathPattern("/v1beta1/policies/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdatePolicy_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdatePolicy_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdatePolicy_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdatePolicy_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3461,19 +3573,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences", runtime.WithHTTPPathPattern("/v1beta1/policies/{id}/versions/{version}/preferences")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetPolicyPreferences_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetPolicyPreferences_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetPolicyPreferences_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetPolicyPreferences_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3481,19 +3595,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListResources") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListResources", runtime.WithHTTPPathPattern("/v1beta1/resources")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListResources_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListResources_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListResources_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListResources_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3501,19 +3617,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetResource") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetResource_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3521,19 +3639,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateResource") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdateResource_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdateResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3541,19 +3661,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteResource") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteResource", runtime.WithHTTPPathPattern("/v1beta1/resources/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_DeleteResource_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_DeleteResource_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_DeleteResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_DeleteResource_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3561,19 +3683,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals", runtime.WithHTTPPathPattern("/v1beta1/me/appeals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListUserAppeals_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListUserAppeals_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListUserAppeals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListUserAppeals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3581,19 +3705,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListAppeals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListAppeals", runtime.WithHTTPPathPattern("/v1beta1/appeals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListAppeals_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListAppeals_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListAppeals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListAppeals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3601,19 +3727,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetAppeal") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetAppeal", runtime.WithHTTPPathPattern("/v1beta1/appeals/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetAppeal_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetAppeal_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetAppeal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetAppeal_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3621,19 +3749,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CancelAppeal") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CancelAppeal", runtime.WithHTTPPathPattern("/v1beta1/appeals/{id}/cancel")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_CancelAppeal_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_CancelAppeal_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CancelAppeal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CancelAppeal_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3641,19 +3771,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateAppeal") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateAppeal", runtime.WithHTTPPathPattern("/v1beta1/appeals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_CreateAppeal_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_CreateAppeal_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreateAppeal_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreateAppeal_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3661,19 +3793,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals", runtime.WithHTTPPathPattern("/v1beta1/me/approvals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListUserApprovals_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListUserApprovals_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListUserApprovals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListUserApprovals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3681,19 +3815,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListApprovals") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListApprovals", runtime.WithHTTPPathPattern("/v1beta1/approvals")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListApprovals_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListApprovals_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListApprovals_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListApprovals_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3701,19 +3837,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateApproval") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateApproval", runtime.WithHTTPPathPattern("/v1beta1/appeals/{id}/approvals/{approval_name}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdateApproval_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdateApproval_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateApproval_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateApproval_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3721,19 +3859,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/AddApprover") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/AddApprover", runtime.WithHTTPPathPattern("/v1beta1/appeals/{appeal_id}/approvals/{approval_id}/approvers")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_AddApprover_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_AddApprover_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_AddApprover_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_AddApprover_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3741,19 +3881,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteApprover") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/DeleteApprover", runtime.WithHTTPPathPattern("/v1beta1/appeals/{appeal_id}/approvals/{approval_id}/approvers/{email}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_DeleteApprover_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_DeleteApprover_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_DeleteApprover_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_DeleteApprover_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3761,19 +3903,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListGrants") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListGrants", runtime.WithHTTPPathPattern("/v1beta1/grants")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListGrants_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListGrants_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListGrants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListGrants_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3781,19 +3925,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserGrants") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListUserGrants", runtime.WithHTTPPathPattern("/v1beta1/me/grants")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListUserGrants_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListUserGrants_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListUserGrants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListUserGrants_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3801,19 +3947,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetGrant") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetGrant", runtime.WithHTTPPathPattern("/v1beta1/grants/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetGrant_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetGrant_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetGrant_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3821,19 +3969,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateGrant") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateGrant", runtime.WithHTTPPathPattern("/v1beta1/grants/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdateGrant_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdateGrant_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateGrant_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3841,19 +3991,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrant") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrant", runtime.WithHTTPPathPattern("/v1beta1/grants/{id}/revoke")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_RevokeGrant_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_RevokeGrant_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_RevokeGrant_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_RevokeGrant_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3861,19 +4013,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrants") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/RevokeGrants", runtime.WithHTTPPathPattern("/v1beta1/grants/revoke")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_RevokeGrants_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_RevokeGrants_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_RevokeGrants_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_RevokeGrants_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3881,19 +4035,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider", runtime.WithHTTPPathPattern("/v1beta1/grants/import")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ImportGrantsFromProvider_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ImportGrantsFromProvider_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ImportGrantsFromProvider_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ImportGrantsFromProvider_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3901,19 +4057,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateNamespace") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/CreateNamespace", runtime.WithHTTPPathPattern("/v1beta1/namespaces")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_CreateNamespace_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_CreateNamespace_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_CreateNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_CreateNamespace_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3921,19 +4079,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetNamespace") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/GetNamespace", runtime.WithHTTPPathPattern("/v1beta1/namespaces/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_GetNamespace_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_GetNamespace_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_GetNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_GetNamespace_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3941,19 +4101,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListNamespaces") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/ListNamespaces", runtime.WithHTTPPathPattern("/v1beta1/namespaces")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_ListNamespaces_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_ListNamespaces_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_ListNamespaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_ListNamespaces_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -3961,19 +4123,21 @@ func RegisterGuardianServiceHandlerClient(ctx context.Context, mux *runtime.Serv ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace") + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace", runtime.WithHTTPPathPattern("/v1beta1/namespaces/{id}")) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_GuardianService_UpdateNamespace_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) + resp, md, err := request_GuardianService_UpdateNamespace_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) return } - forward_GuardianService_UpdateNamespace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_GuardianService_UpdateNamespace_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) diff --git a/api/proto/raystack/guardian/v1beta1/guardian.swagger.json b/api/proto/raystack/guardian/v1beta1/guardian.swagger.json index 4fa5e7f2..c0097e65 100644 --- a/api/proto/raystack/guardian/v1beta1/guardian.swagger.json +++ b/api/proto/raystack/guardian/v1beta1/guardian.swagger.json @@ -254,6 +254,36 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "size", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "offset", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "q", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "accountTypes", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" } ], "tags": [ @@ -326,7 +356,12 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/v1beta1AddApproverRequest" + "type": "object", + "properties": { + "email": { + "type": "string" + } + } } } ], @@ -438,7 +473,7 @@ "type": "string" }, { - "name": "body", + "name": "action", "in": "body", "required": true, "schema": { @@ -554,6 +589,32 @@ "type": "string" }, "collectionFormat": "multi" + }, + { + "name": "q", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "accountTypes", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "resourceTypes", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" } ], "tags": [ @@ -690,6 +751,26 @@ "in": "query", "required": false, "type": "string" + }, + { + "name": "size", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "offset", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "q", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -818,7 +899,12 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/v1beta1UpdateGrantRequest" + "type": "object", + "properties": { + "owner": { + "type": "string" + } + } } } ], @@ -856,7 +942,12 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/v1beta1RevokeGrantRequest" + "type": "object", + "properties": { + "reason": { + "type": "string" + } + } } } ], @@ -948,6 +1039,36 @@ "type": "string" }, "collectionFormat": "multi" + }, + { + "name": "size", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "offset", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "q", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "accountTypes", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" } ], "tags": [ @@ -1022,6 +1143,32 @@ "type": "string" }, "collectionFormat": "multi" + }, + { + "name": "q", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "accountTypes", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "resourceTypes", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" } ], "tags": [ @@ -1146,6 +1293,26 @@ "type": "string" }, "collectionFormat": "multi" + }, + { + "name": "size", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "offset", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "q", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -1263,7 +1430,12 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/v1beta1UpdateNamespaceRequest" + "type": "object", + "properties": { + "namespace": { + "$ref": "#/definitions/v1beta1Namespace" + } + } } } ], @@ -1311,7 +1483,7 @@ }, "parameters": [ { - "name": "body", + "name": "policy", "in": "body", "required": true, "schema": { @@ -1355,7 +1527,7 @@ "type": "string" }, { - "name": "body", + "name": "policy", "in": "body", "required": true, "schema": { @@ -1487,7 +1659,7 @@ }, "parameters": [ { - "name": "body", + "name": "config", "in": "body", "required": true, "schema": { @@ -1559,11 +1731,43 @@ "type": "string" }, { - "name": "body", + "name": "config", "in": "body", "required": true, "schema": { - "$ref": "#/definitions/v1beta1ProviderConfig" + "type": "object", + "properties": { + "labels": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "credentials": {}, + "appeal": { + "$ref": "#/definitions/ProviderConfigAppealConfig" + }, + "resources": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/ProviderConfigResourceConfig" + } + }, + "allowedAccountTypes": { + "type": "array", + "items": { + "type": "string" + } + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/ProviderConfigProviderParameter" + } + } + } } }, { @@ -1665,7 +1869,7 @@ "type": "string" }, { - "name": "body", + "name": "config", "in": "body", "required": true, "schema": { @@ -1871,7 +2075,7 @@ "type": "string" }, { - "name": "body", + "name": "resource", "in": "body", "required": true, "schema": { @@ -1909,9 +2113,7 @@ "ConditionMatchCondition": { "type": "object", "properties": { - "eq": { - "type": "object" - } + "eq": {} } }, "PolicyAppealConfigDurationOptions": { @@ -1980,9 +2182,7 @@ "provider": { "type": "string" }, - "config": { - "type": "object" - }, + "config": {}, "schema": { "type": "object", "additionalProperties": { @@ -2000,6 +2200,7 @@ "appeals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/RequirementAdditionalAppeal" } } @@ -2045,6 +2246,7 @@ "roles": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Role" } }, @@ -2091,6 +2293,7 @@ "conditions": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Condition" } }, @@ -2157,6 +2360,7 @@ "children": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/guardianv1beta1Resource" } } @@ -2166,14 +2370,11 @@ "protobufAny": { "type": "object", "properties": { - "typeUrl": { + "@type": { "type": "string" - }, - "value": { - "type": "string", - "format": "byte" } - } + }, + "additionalProperties": {} }, "protobufNullValue": { "type": "string", @@ -2196,25 +2397,12 @@ "details": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/protobufAny" } } } }, - "v1beta1AddApproverRequest": { - "type": "object", - "properties": { - "appealId": { - "type": "string" - }, - "approvalId": { - "type": "string" - }, - "email": { - "type": "string" - } - } - }, "v1beta1AddApproverResponse": { "type": "object", "properties": { @@ -2249,7 +2437,8 @@ "type": "string" }, "options": { - "$ref": "#/definitions/v1beta1AppealOptions" + "$ref": "#/definitions/v1beta1AppealOptions", + "title": "optional" }, "labels": { "type": "object", @@ -2258,11 +2447,13 @@ } }, "resource": { - "$ref": "#/definitions/guardianv1beta1Resource" + "$ref": "#/definitions/guardianv1beta1Resource", + "title": "optional" }, "approvals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Approval" } }, @@ -2283,9 +2474,7 @@ "createdBy": { "type": "string" }, - "creator": { - "type": "object" - }, + "creator": {}, "permissions": { "type": "array", "items": { @@ -2306,7 +2495,8 @@ "properties": { "expirationDate": { "type": "string", - "format": "date-time" + "format": "date-time", + "title": "optional" }, "duration": { "type": "string" @@ -2389,6 +2579,7 @@ "resources": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1CreateAppealRequestResource" } }, @@ -2423,6 +2614,7 @@ "appeals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Appeal" } } @@ -2531,6 +2723,7 @@ "providerTypes": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1ProviderType" } } @@ -2653,6 +2846,7 @@ "activities": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1ProviderActivity" } } @@ -2690,6 +2884,7 @@ "grants": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Grant" } } @@ -2701,6 +2896,7 @@ "activities": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1ProviderActivity" } } @@ -2712,8 +2908,13 @@ "appeals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Appeal" } + }, + "total": { + "type": "integer", + "format": "int32" } } }, @@ -2723,8 +2924,13 @@ "approvals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Approval" } + }, + "total": { + "type": "integer", + "format": "int32" } } }, @@ -2734,8 +2940,13 @@ "grants": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Grant" } + }, + "total": { + "type": "integer", + "format": "int32" } } }, @@ -2745,6 +2956,7 @@ "namespaces": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Namespace" } } @@ -2756,6 +2968,7 @@ "policies": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Policy" } } @@ -2767,6 +2980,7 @@ "providers": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Provider" } } @@ -2778,6 +2992,7 @@ "resources": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/guardianv1beta1Resource" } } @@ -2789,6 +3004,7 @@ "roles": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Role" } } @@ -2800,8 +3016,13 @@ "appeals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Appeal" } + }, + "total": { + "type": "integer", + "format": "int32" } } }, @@ -2811,8 +3032,13 @@ "approvals": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Approval" } + }, + "total": { + "type": "integer", + "format": "int32" } } }, @@ -2822,8 +3048,13 @@ "grants": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Grant" } + }, + "total": { + "type": "integer", + "format": "int32" } } }, @@ -2868,6 +3099,7 @@ "steps": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/PolicyApprovalStep" } }, @@ -2888,6 +3120,7 @@ "requirements": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/PolicyRequirement" } }, @@ -2906,6 +3139,7 @@ "durationOptions": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/PolicyAppealConfigDurationOptions" } }, @@ -2921,6 +3155,7 @@ "questions": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/PolicyAppealConfigQuestion" } }, @@ -3037,15 +3272,14 @@ "type": "string" } }, - "credentials": { - "type": "object" - }, + "credentials": {}, "appeal": { "$ref": "#/definitions/ProviderConfigAppealConfig" }, "resources": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/ProviderConfigResourceConfig" } }, @@ -3058,6 +3292,7 @@ "parameters": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/ProviderConfigProviderParameter" } } @@ -3077,17 +3312,6 @@ } } }, - "v1beta1RevokeGrantRequest": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "reason": { - "type": "string" - } - } - }, "v1beta1RevokeGrantResponse": { "type": "object", "properties": { @@ -3140,6 +3364,7 @@ "grants": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v1beta1Grant" } } @@ -3159,9 +3384,7 @@ }, "permissions": { "type": "array", - "items": { - "type": "object" - } + "items": {} } } }, @@ -3173,17 +3396,6 @@ } } }, - "v1beta1UpdateGrantRequest": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "owner": { - "type": "string" - } - } - }, "v1beta1UpdateGrantResponse": { "type": "object", "properties": { @@ -3192,17 +3404,6 @@ } } }, - "v1beta1UpdateNamespaceRequest": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "namespace": { - "$ref": "#/definitions/v1beta1Namespace" - } - } - }, "v1beta1UpdateNamespaceResponse": { "type": "object" }, diff --git a/api/proto/raystack/guardian/v1beta1/guardian_grpc.pb.go b/api/proto/raystack/guardian/v1beta1/guardian_grpc.pb.go index f3ac628c..ec5da0b5 100644 --- a/api/proto/raystack/guardian/v1beta1/guardian_grpc.pb.go +++ b/api/proto/raystack/guardian/v1beta1/guardian_grpc.pb.go @@ -1,4 +1,8 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: raystack/guardian/v1beta1/guardian.proto package guardianv1beta1 @@ -14,6 +18,49 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 +const ( + GuardianService_ListProviders_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListProviders" + GuardianService_GetProvider_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetProvider" + GuardianService_GetProviderTypes_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes" + GuardianService_CreateProvider_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/CreateProvider" + GuardianService_UpdateProvider_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/UpdateProvider" + GuardianService_DeleteProvider_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/DeleteProvider" + GuardianService_ListRoles_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListRoles" + GuardianService_ImportActivities_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ImportActivities" + GuardianService_GetActivity_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetActivity" + GuardianService_ListActivities_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListActivities" + GuardianService_ListPolicies_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListPolicies" + GuardianService_GetPolicy_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetPolicy" + GuardianService_CreatePolicy_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/CreatePolicy" + GuardianService_UpdatePolicy_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy" + GuardianService_GetPolicyPreferences_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences" + GuardianService_ListResources_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListResources" + GuardianService_GetResource_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetResource" + GuardianService_UpdateResource_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/UpdateResource" + GuardianService_DeleteResource_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/DeleteResource" + GuardianService_ListUserAppeals_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals" + GuardianService_ListAppeals_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListAppeals" + GuardianService_GetAppeal_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetAppeal" + GuardianService_CancelAppeal_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/CancelAppeal" + GuardianService_CreateAppeal_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/CreateAppeal" + GuardianService_ListUserApprovals_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals" + GuardianService_ListApprovals_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListApprovals" + GuardianService_UpdateApproval_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/UpdateApproval" + GuardianService_AddApprover_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/AddApprover" + GuardianService_DeleteApprover_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/DeleteApprover" + GuardianService_ListGrants_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListGrants" + GuardianService_ListUserGrants_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListUserGrants" + GuardianService_GetGrant_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetGrant" + GuardianService_UpdateGrant_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/UpdateGrant" + GuardianService_RevokeGrant_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/RevokeGrant" + GuardianService_RevokeGrants_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/RevokeGrants" + GuardianService_ImportGrantsFromProvider_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider" + GuardianService_CreateNamespace_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/CreateNamespace" + GuardianService_GetNamespace_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/GetNamespace" + GuardianService_ListNamespaces_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/ListNamespaces" + GuardianService_UpdateNamespace_FullMethodName = "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace" +) + // GuardianServiceClient is the client API for GuardianService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -71,7 +118,7 @@ func NewGuardianServiceClient(cc grpc.ClientConnInterface) GuardianServiceClient func (c *guardianServiceClient) ListProviders(ctx context.Context, in *ListProvidersRequest, opts ...grpc.CallOption) (*ListProvidersResponse, error) { out := new(ListProvidersResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListProviders", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListProviders_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -80,7 +127,7 @@ func (c *guardianServiceClient) ListProviders(ctx context.Context, in *ListProvi func (c *guardianServiceClient) GetProvider(ctx context.Context, in *GetProviderRequest, opts ...grpc.CallOption) (*GetProviderResponse, error) { out := new(GetProviderResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetProvider", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -89,7 +136,7 @@ func (c *guardianServiceClient) GetProvider(ctx context.Context, in *GetProvider func (c *guardianServiceClient) GetProviderTypes(ctx context.Context, in *GetProviderTypesRequest, opts ...grpc.CallOption) (*GetProviderTypesResponse, error) { out := new(GetProviderTypesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetProviderTypes_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -98,7 +145,7 @@ func (c *guardianServiceClient) GetProviderTypes(ctx context.Context, in *GetPro func (c *guardianServiceClient) CreateProvider(ctx context.Context, in *CreateProviderRequest, opts ...grpc.CallOption) (*CreateProviderResponse, error) { out := new(CreateProviderResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/CreateProvider", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_CreateProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -107,7 +154,7 @@ func (c *guardianServiceClient) CreateProvider(ctx context.Context, in *CreatePr func (c *guardianServiceClient) UpdateProvider(ctx context.Context, in *UpdateProviderRequest, opts ...grpc.CallOption) (*UpdateProviderResponse, error) { out := new(UpdateProviderResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/UpdateProvider", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_UpdateProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -116,7 +163,7 @@ func (c *guardianServiceClient) UpdateProvider(ctx context.Context, in *UpdatePr func (c *guardianServiceClient) DeleteProvider(ctx context.Context, in *DeleteProviderRequest, opts ...grpc.CallOption) (*DeleteProviderResponse, error) { out := new(DeleteProviderResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/DeleteProvider", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_DeleteProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -125,7 +172,7 @@ func (c *guardianServiceClient) DeleteProvider(ctx context.Context, in *DeletePr func (c *guardianServiceClient) ListRoles(ctx context.Context, in *ListRolesRequest, opts ...grpc.CallOption) (*ListRolesResponse, error) { out := new(ListRolesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListRoles", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListRoles_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -134,7 +181,7 @@ func (c *guardianServiceClient) ListRoles(ctx context.Context, in *ListRolesRequ func (c *guardianServiceClient) ImportActivities(ctx context.Context, in *ImportActivitiesRequest, opts ...grpc.CallOption) (*ImportActivitiesResponse, error) { out := new(ImportActivitiesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ImportActivities", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ImportActivities_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -143,7 +190,7 @@ func (c *guardianServiceClient) ImportActivities(ctx context.Context, in *Import func (c *guardianServiceClient) GetActivity(ctx context.Context, in *GetActivityRequest, opts ...grpc.CallOption) (*GetActivityResponse, error) { out := new(GetActivityResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetActivity", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetActivity_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -152,7 +199,7 @@ func (c *guardianServiceClient) GetActivity(ctx context.Context, in *GetActivity func (c *guardianServiceClient) ListActivities(ctx context.Context, in *ListActivitiesRequest, opts ...grpc.CallOption) (*ListActivitiesResponse, error) { out := new(ListActivitiesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListActivities", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListActivities_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -161,7 +208,7 @@ func (c *guardianServiceClient) ListActivities(ctx context.Context, in *ListActi func (c *guardianServiceClient) ListPolicies(ctx context.Context, in *ListPoliciesRequest, opts ...grpc.CallOption) (*ListPoliciesResponse, error) { out := new(ListPoliciesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListPolicies", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListPolicies_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -170,7 +217,7 @@ func (c *guardianServiceClient) ListPolicies(ctx context.Context, in *ListPolici func (c *guardianServiceClient) GetPolicy(ctx context.Context, in *GetPolicyRequest, opts ...grpc.CallOption) (*GetPolicyResponse, error) { out := new(GetPolicyResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetPolicy", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetPolicy_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -179,7 +226,7 @@ func (c *guardianServiceClient) GetPolicy(ctx context.Context, in *GetPolicyRequ func (c *guardianServiceClient) CreatePolicy(ctx context.Context, in *CreatePolicyRequest, opts ...grpc.CallOption) (*CreatePolicyResponse, error) { out := new(CreatePolicyResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/CreatePolicy", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_CreatePolicy_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -188,7 +235,7 @@ func (c *guardianServiceClient) CreatePolicy(ctx context.Context, in *CreatePoli func (c *guardianServiceClient) UpdatePolicy(ctx context.Context, in *UpdatePolicyRequest, opts ...grpc.CallOption) (*UpdatePolicyResponse, error) { out := new(UpdatePolicyResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_UpdatePolicy_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -197,7 +244,7 @@ func (c *guardianServiceClient) UpdatePolicy(ctx context.Context, in *UpdatePoli func (c *guardianServiceClient) GetPolicyPreferences(ctx context.Context, in *GetPolicyPreferencesRequest, opts ...grpc.CallOption) (*GetPolicyPreferencesResponse, error) { out := new(GetPolicyPreferencesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetPolicyPreferences_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -206,7 +253,7 @@ func (c *guardianServiceClient) GetPolicyPreferences(ctx context.Context, in *Ge func (c *guardianServiceClient) ListResources(ctx context.Context, in *ListResourcesRequest, opts ...grpc.CallOption) (*ListResourcesResponse, error) { out := new(ListResourcesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListResources", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListResources_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -215,7 +262,7 @@ func (c *guardianServiceClient) ListResources(ctx context.Context, in *ListResou func (c *guardianServiceClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) { out := new(GetResourceResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetResource", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -224,7 +271,7 @@ func (c *guardianServiceClient) GetResource(ctx context.Context, in *GetResource func (c *guardianServiceClient) UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) { out := new(UpdateResourceResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/UpdateResource", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_UpdateResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -233,7 +280,7 @@ func (c *guardianServiceClient) UpdateResource(ctx context.Context, in *UpdateRe func (c *guardianServiceClient) DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) { out := new(DeleteResourceResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/DeleteResource", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_DeleteResource_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -242,7 +289,7 @@ func (c *guardianServiceClient) DeleteResource(ctx context.Context, in *DeleteRe func (c *guardianServiceClient) ListUserAppeals(ctx context.Context, in *ListUserAppealsRequest, opts ...grpc.CallOption) (*ListUserAppealsResponse, error) { out := new(ListUserAppealsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListUserAppeals_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -251,7 +298,7 @@ func (c *guardianServiceClient) ListUserAppeals(ctx context.Context, in *ListUse func (c *guardianServiceClient) ListAppeals(ctx context.Context, in *ListAppealsRequest, opts ...grpc.CallOption) (*ListAppealsResponse, error) { out := new(ListAppealsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListAppeals", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListAppeals_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -260,7 +307,7 @@ func (c *guardianServiceClient) ListAppeals(ctx context.Context, in *ListAppeals func (c *guardianServiceClient) GetAppeal(ctx context.Context, in *GetAppealRequest, opts ...grpc.CallOption) (*GetAppealResponse, error) { out := new(GetAppealResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetAppeal", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetAppeal_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -269,7 +316,7 @@ func (c *guardianServiceClient) GetAppeal(ctx context.Context, in *GetAppealRequ func (c *guardianServiceClient) CancelAppeal(ctx context.Context, in *CancelAppealRequest, opts ...grpc.CallOption) (*CancelAppealResponse, error) { out := new(CancelAppealResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/CancelAppeal", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_CancelAppeal_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -278,7 +325,7 @@ func (c *guardianServiceClient) CancelAppeal(ctx context.Context, in *CancelAppe func (c *guardianServiceClient) CreateAppeal(ctx context.Context, in *CreateAppealRequest, opts ...grpc.CallOption) (*CreateAppealResponse, error) { out := new(CreateAppealResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/CreateAppeal", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_CreateAppeal_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -287,7 +334,7 @@ func (c *guardianServiceClient) CreateAppeal(ctx context.Context, in *CreateAppe func (c *guardianServiceClient) ListUserApprovals(ctx context.Context, in *ListUserApprovalsRequest, opts ...grpc.CallOption) (*ListUserApprovalsResponse, error) { out := new(ListUserApprovalsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListUserApprovals_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -296,7 +343,7 @@ func (c *guardianServiceClient) ListUserApprovals(ctx context.Context, in *ListU func (c *guardianServiceClient) ListApprovals(ctx context.Context, in *ListApprovalsRequest, opts ...grpc.CallOption) (*ListApprovalsResponse, error) { out := new(ListApprovalsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListApprovals", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListApprovals_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -305,7 +352,7 @@ func (c *guardianServiceClient) ListApprovals(ctx context.Context, in *ListAppro func (c *guardianServiceClient) UpdateApproval(ctx context.Context, in *UpdateApprovalRequest, opts ...grpc.CallOption) (*UpdateApprovalResponse, error) { out := new(UpdateApprovalResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/UpdateApproval", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_UpdateApproval_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -314,7 +361,7 @@ func (c *guardianServiceClient) UpdateApproval(ctx context.Context, in *UpdateAp func (c *guardianServiceClient) AddApprover(ctx context.Context, in *AddApproverRequest, opts ...grpc.CallOption) (*AddApproverResponse, error) { out := new(AddApproverResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/AddApprover", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_AddApprover_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -323,7 +370,7 @@ func (c *guardianServiceClient) AddApprover(ctx context.Context, in *AddApprover func (c *guardianServiceClient) DeleteApprover(ctx context.Context, in *DeleteApproverRequest, opts ...grpc.CallOption) (*DeleteApproverResponse, error) { out := new(DeleteApproverResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/DeleteApprover", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_DeleteApprover_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -332,7 +379,7 @@ func (c *guardianServiceClient) DeleteApprover(ctx context.Context, in *DeleteAp func (c *guardianServiceClient) ListGrants(ctx context.Context, in *ListGrantsRequest, opts ...grpc.CallOption) (*ListGrantsResponse, error) { out := new(ListGrantsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListGrants", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListGrants_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -341,7 +388,7 @@ func (c *guardianServiceClient) ListGrants(ctx context.Context, in *ListGrantsRe func (c *guardianServiceClient) ListUserGrants(ctx context.Context, in *ListUserGrantsRequest, opts ...grpc.CallOption) (*ListUserGrantsResponse, error) { out := new(ListUserGrantsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListUserGrants", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListUserGrants_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -350,7 +397,7 @@ func (c *guardianServiceClient) ListUserGrants(ctx context.Context, in *ListUser func (c *guardianServiceClient) GetGrant(ctx context.Context, in *GetGrantRequest, opts ...grpc.CallOption) (*GetGrantResponse, error) { out := new(GetGrantResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetGrant", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetGrant_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -359,7 +406,7 @@ func (c *guardianServiceClient) GetGrant(ctx context.Context, in *GetGrantReques func (c *guardianServiceClient) UpdateGrant(ctx context.Context, in *UpdateGrantRequest, opts ...grpc.CallOption) (*UpdateGrantResponse, error) { out := new(UpdateGrantResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/UpdateGrant", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_UpdateGrant_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -368,7 +415,7 @@ func (c *guardianServiceClient) UpdateGrant(ctx context.Context, in *UpdateGrant func (c *guardianServiceClient) RevokeGrant(ctx context.Context, in *RevokeGrantRequest, opts ...grpc.CallOption) (*RevokeGrantResponse, error) { out := new(RevokeGrantResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/RevokeGrant", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_RevokeGrant_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -377,7 +424,7 @@ func (c *guardianServiceClient) RevokeGrant(ctx context.Context, in *RevokeGrant func (c *guardianServiceClient) RevokeGrants(ctx context.Context, in *RevokeGrantsRequest, opts ...grpc.CallOption) (*RevokeGrantsResponse, error) { out := new(RevokeGrantsResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/RevokeGrants", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_RevokeGrants_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -386,7 +433,7 @@ func (c *guardianServiceClient) RevokeGrants(ctx context.Context, in *RevokeGran func (c *guardianServiceClient) ImportGrantsFromProvider(ctx context.Context, in *ImportGrantsFromProviderRequest, opts ...grpc.CallOption) (*ImportGrantsFromProviderResponse, error) { out := new(ImportGrantsFromProviderResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ImportGrantsFromProvider_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -395,7 +442,7 @@ func (c *guardianServiceClient) ImportGrantsFromProvider(ctx context.Context, in func (c *guardianServiceClient) CreateNamespace(ctx context.Context, in *CreateNamespaceRequest, opts ...grpc.CallOption) (*CreateNamespaceResponse, error) { out := new(CreateNamespaceResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/CreateNamespace", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_CreateNamespace_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -404,7 +451,7 @@ func (c *guardianServiceClient) CreateNamespace(ctx context.Context, in *CreateN func (c *guardianServiceClient) GetNamespace(ctx context.Context, in *GetNamespaceRequest, opts ...grpc.CallOption) (*GetNamespaceResponse, error) { out := new(GetNamespaceResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/GetNamespace", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_GetNamespace_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -413,7 +460,7 @@ func (c *guardianServiceClient) GetNamespace(ctx context.Context, in *GetNamespa func (c *guardianServiceClient) ListNamespaces(ctx context.Context, in *ListNamespacesRequest, opts ...grpc.CallOption) (*ListNamespacesResponse, error) { out := new(ListNamespacesResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/ListNamespaces", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_ListNamespaces_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -422,7 +469,7 @@ func (c *guardianServiceClient) ListNamespaces(ctx context.Context, in *ListName func (c *guardianServiceClient) UpdateNamespace(ctx context.Context, in *UpdateNamespaceRequest, opts ...grpc.CallOption) (*UpdateNamespaceResponse, error) { out := new(UpdateNamespaceResponse) - err := c.cc.Invoke(ctx, "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace", in, out, opts...) + err := c.cc.Invoke(ctx, GuardianService_UpdateNamespace_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -624,7 +671,7 @@ func _GuardianService_ListProviders_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListProviders", + FullMethod: GuardianService_ListProviders_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListProviders(ctx, req.(*ListProvidersRequest)) @@ -642,7 +689,7 @@ func _GuardianService_GetProvider_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetProvider", + FullMethod: GuardianService_GetProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetProvider(ctx, req.(*GetProviderRequest)) @@ -660,7 +707,7 @@ func _GuardianService_GetProviderTypes_Handler(srv interface{}, ctx context.Cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetProviderTypes", + FullMethod: GuardianService_GetProviderTypes_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetProviderTypes(ctx, req.(*GetProviderTypesRequest)) @@ -678,7 +725,7 @@ func _GuardianService_CreateProvider_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/CreateProvider", + FullMethod: GuardianService_CreateProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).CreateProvider(ctx, req.(*CreateProviderRequest)) @@ -696,7 +743,7 @@ func _GuardianService_UpdateProvider_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/UpdateProvider", + FullMethod: GuardianService_UpdateProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).UpdateProvider(ctx, req.(*UpdateProviderRequest)) @@ -714,7 +761,7 @@ func _GuardianService_DeleteProvider_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/DeleteProvider", + FullMethod: GuardianService_DeleteProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).DeleteProvider(ctx, req.(*DeleteProviderRequest)) @@ -732,7 +779,7 @@ func _GuardianService_ListRoles_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListRoles", + FullMethod: GuardianService_ListRoles_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListRoles(ctx, req.(*ListRolesRequest)) @@ -750,7 +797,7 @@ func _GuardianService_ImportActivities_Handler(srv interface{}, ctx context.Cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ImportActivities", + FullMethod: GuardianService_ImportActivities_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ImportActivities(ctx, req.(*ImportActivitiesRequest)) @@ -768,7 +815,7 @@ func _GuardianService_GetActivity_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetActivity", + FullMethod: GuardianService_GetActivity_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetActivity(ctx, req.(*GetActivityRequest)) @@ -786,7 +833,7 @@ func _GuardianService_ListActivities_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListActivities", + FullMethod: GuardianService_ListActivities_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListActivities(ctx, req.(*ListActivitiesRequest)) @@ -804,7 +851,7 @@ func _GuardianService_ListPolicies_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListPolicies", + FullMethod: GuardianService_ListPolicies_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListPolicies(ctx, req.(*ListPoliciesRequest)) @@ -822,7 +869,7 @@ func _GuardianService_GetPolicy_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetPolicy", + FullMethod: GuardianService_GetPolicy_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetPolicy(ctx, req.(*GetPolicyRequest)) @@ -840,7 +887,7 @@ func _GuardianService_CreatePolicy_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/CreatePolicy", + FullMethod: GuardianService_CreatePolicy_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).CreatePolicy(ctx, req.(*CreatePolicyRequest)) @@ -858,7 +905,7 @@ func _GuardianService_UpdatePolicy_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/UpdatePolicy", + FullMethod: GuardianService_UpdatePolicy_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).UpdatePolicy(ctx, req.(*UpdatePolicyRequest)) @@ -876,7 +923,7 @@ func _GuardianService_GetPolicyPreferences_Handler(srv interface{}, ctx context. } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetPolicyPreferences", + FullMethod: GuardianService_GetPolicyPreferences_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetPolicyPreferences(ctx, req.(*GetPolicyPreferencesRequest)) @@ -894,7 +941,7 @@ func _GuardianService_ListResources_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListResources", + FullMethod: GuardianService_ListResources_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListResources(ctx, req.(*ListResourcesRequest)) @@ -912,7 +959,7 @@ func _GuardianService_GetResource_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetResource", + FullMethod: GuardianService_GetResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetResource(ctx, req.(*GetResourceRequest)) @@ -930,7 +977,7 @@ func _GuardianService_UpdateResource_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/UpdateResource", + FullMethod: GuardianService_UpdateResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).UpdateResource(ctx, req.(*UpdateResourceRequest)) @@ -948,7 +995,7 @@ func _GuardianService_DeleteResource_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/DeleteResource", + FullMethod: GuardianService_DeleteResource_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).DeleteResource(ctx, req.(*DeleteResourceRequest)) @@ -966,7 +1013,7 @@ func _GuardianService_ListUserAppeals_Handler(srv interface{}, ctx context.Conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListUserAppeals", + FullMethod: GuardianService_ListUserAppeals_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListUserAppeals(ctx, req.(*ListUserAppealsRequest)) @@ -984,7 +1031,7 @@ func _GuardianService_ListAppeals_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListAppeals", + FullMethod: GuardianService_ListAppeals_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListAppeals(ctx, req.(*ListAppealsRequest)) @@ -1002,7 +1049,7 @@ func _GuardianService_GetAppeal_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetAppeal", + FullMethod: GuardianService_GetAppeal_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetAppeal(ctx, req.(*GetAppealRequest)) @@ -1020,7 +1067,7 @@ func _GuardianService_CancelAppeal_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/CancelAppeal", + FullMethod: GuardianService_CancelAppeal_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).CancelAppeal(ctx, req.(*CancelAppealRequest)) @@ -1038,7 +1085,7 @@ func _GuardianService_CreateAppeal_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/CreateAppeal", + FullMethod: GuardianService_CreateAppeal_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).CreateAppeal(ctx, req.(*CreateAppealRequest)) @@ -1056,7 +1103,7 @@ func _GuardianService_ListUserApprovals_Handler(srv interface{}, ctx context.Con } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListUserApprovals", + FullMethod: GuardianService_ListUserApprovals_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListUserApprovals(ctx, req.(*ListUserApprovalsRequest)) @@ -1074,7 +1121,7 @@ func _GuardianService_ListApprovals_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListApprovals", + FullMethod: GuardianService_ListApprovals_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListApprovals(ctx, req.(*ListApprovalsRequest)) @@ -1092,7 +1139,7 @@ func _GuardianService_UpdateApproval_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/UpdateApproval", + FullMethod: GuardianService_UpdateApproval_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).UpdateApproval(ctx, req.(*UpdateApprovalRequest)) @@ -1110,7 +1157,7 @@ func _GuardianService_AddApprover_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/AddApprover", + FullMethod: GuardianService_AddApprover_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).AddApprover(ctx, req.(*AddApproverRequest)) @@ -1128,7 +1175,7 @@ func _GuardianService_DeleteApprover_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/DeleteApprover", + FullMethod: GuardianService_DeleteApprover_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).DeleteApprover(ctx, req.(*DeleteApproverRequest)) @@ -1146,7 +1193,7 @@ func _GuardianService_ListGrants_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListGrants", + FullMethod: GuardianService_ListGrants_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListGrants(ctx, req.(*ListGrantsRequest)) @@ -1164,7 +1211,7 @@ func _GuardianService_ListUserGrants_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListUserGrants", + FullMethod: GuardianService_ListUserGrants_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListUserGrants(ctx, req.(*ListUserGrantsRequest)) @@ -1182,7 +1229,7 @@ func _GuardianService_GetGrant_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetGrant", + FullMethod: GuardianService_GetGrant_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetGrant(ctx, req.(*GetGrantRequest)) @@ -1200,7 +1247,7 @@ func _GuardianService_UpdateGrant_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/UpdateGrant", + FullMethod: GuardianService_UpdateGrant_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).UpdateGrant(ctx, req.(*UpdateGrantRequest)) @@ -1218,7 +1265,7 @@ func _GuardianService_RevokeGrant_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/RevokeGrant", + FullMethod: GuardianService_RevokeGrant_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).RevokeGrant(ctx, req.(*RevokeGrantRequest)) @@ -1236,7 +1283,7 @@ func _GuardianService_RevokeGrants_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/RevokeGrants", + FullMethod: GuardianService_RevokeGrants_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).RevokeGrants(ctx, req.(*RevokeGrantsRequest)) @@ -1254,7 +1301,7 @@ func _GuardianService_ImportGrantsFromProvider_Handler(srv interface{}, ctx cont } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ImportGrantsFromProvider", + FullMethod: GuardianService_ImportGrantsFromProvider_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ImportGrantsFromProvider(ctx, req.(*ImportGrantsFromProviderRequest)) @@ -1272,7 +1319,7 @@ func _GuardianService_CreateNamespace_Handler(srv interface{}, ctx context.Conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/CreateNamespace", + FullMethod: GuardianService_CreateNamespace_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).CreateNamespace(ctx, req.(*CreateNamespaceRequest)) @@ -1290,7 +1337,7 @@ func _GuardianService_GetNamespace_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/GetNamespace", + FullMethod: GuardianService_GetNamespace_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).GetNamespace(ctx, req.(*GetNamespaceRequest)) @@ -1308,7 +1355,7 @@ func _GuardianService_ListNamespaces_Handler(srv interface{}, ctx context.Contex } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/ListNamespaces", + FullMethod: GuardianService_ListNamespaces_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).ListNamespaces(ctx, req.(*ListNamespacesRequest)) @@ -1326,7 +1373,7 @@ func _GuardianService_UpdateNamespace_Handler(srv interface{}, ctx context.Conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/raystack.guardian.v1beta1.GuardianService/UpdateNamespace", + FullMethod: GuardianService_UpdateNamespace_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GuardianServiceServer).UpdateNamespace(ctx, req.(*UpdateNamespaceRequest)) diff --git a/cli/job.go b/cli/job.go index 8fe2fb9f..69bf73f8 100644 --- a/cli/job.go +++ b/cli/job.go @@ -43,6 +43,7 @@ func runJobCmd() *cobra.Command { $ guardian job run expiring_grant_notification $ guardian job run revoke_expired_grants $ guardian job run revoke_grants_by_user_criteria + $ guardian job run grant_dormancy_check `), Args: cobra.ExactValidArgs(1), ValidArgs: []string{ @@ -50,6 +51,7 @@ func runJobCmd() *cobra.Command { string(jobs.TypeExpiringGrantNotification), string(jobs.TypeRevokeExpiredGrants), string(jobs.TypeRevokeGrantsByUserCriteria), + string(jobs.TypeGrantDormancyCheck), string(jobs.TypeRevokeExpiredAccess), string(jobs.TypeExpiringAccessNotification), @@ -112,6 +114,10 @@ func runJobCmd() *cobra.Command { handler: handler.RevokeGrantsByUserCriteria, config: config.Jobs.RevokeGrantsByUserCriteria.Config, }, + jobs.TypeGrantDormancyCheck: { + handler: handler.GrantDormancyCheck, + config: config.Jobs.GrantDormancyCheck.Config, + }, // deprecated job names jobs.TypeExpiringAccessNotification: { diff --git a/core/activity/mocks/auditLogger.go b/core/activity/mocks/auditLogger.go index 87682202..385c23ac 100644 --- a/core/activity/mocks/auditLogger.go +++ b/core/activity/mocks/auditLogger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/activity/mocks/providerService.go b/core/activity/mocks/providerService.go index 36b1dd0b..3d85da1c 100644 --- a/core/activity/mocks/providerService.go +++ b/core/activity/mocks/providerService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -23,15 +23,15 @@ func (_m *ProviderService) EXPECT() *ProviderService_Expecter { } // ImportActivities provides a mock function with given fields: _a0, _a1 -func (_m *ProviderService) ImportActivities(_a0 context.Context, _a1 domain.ImportActivitiesFilter) ([]*domain.Activity, error) { +func (_m *ProviderService) ImportActivities(_a0 context.Context, _a1 domain.ListActivitiesFilter) ([]*domain.Activity, error) { ret := _m.Called(_a0, _a1) var r0 []*domain.Activity var r1 error - if rf, ok := ret.Get(0).(func(context.Context, domain.ImportActivitiesFilter) ([]*domain.Activity, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, domain.ListActivitiesFilter) ([]*domain.Activity, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, domain.ImportActivitiesFilter) []*domain.Activity); ok { + if rf, ok := ret.Get(0).(func(context.Context, domain.ListActivitiesFilter) []*domain.Activity); ok { r0 = rf(_a0, _a1) } else { if ret.Get(0) != nil { @@ -39,7 +39,7 @@ func (_m *ProviderService) ImportActivities(_a0 context.Context, _a1 domain.Impo } } - if rf, ok := ret.Get(1).(func(context.Context, domain.ImportActivitiesFilter) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, domain.ListActivitiesFilter) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -55,14 +55,14 @@ type ProviderService_ImportActivities_Call struct { // ImportActivities is a helper method to define mock.On call // - _a0 context.Context -// - _a1 domain.ImportActivitiesFilter +// - _a1 domain.ListActivitiesFilter func (_e *ProviderService_Expecter) ImportActivities(_a0 interface{}, _a1 interface{}) *ProviderService_ImportActivities_Call { return &ProviderService_ImportActivities_Call{Call: _e.mock.On("ImportActivities", _a0, _a1)} } -func (_c *ProviderService_ImportActivities_Call) Run(run func(_a0 context.Context, _a1 domain.ImportActivitiesFilter)) *ProviderService_ImportActivities_Call { +func (_c *ProviderService_ImportActivities_Call) Run(run func(_a0 context.Context, _a1 domain.ListActivitiesFilter)) *ProviderService_ImportActivities_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(domain.ImportActivitiesFilter)) + run(args[0].(context.Context), args[1].(domain.ListActivitiesFilter)) }) return _c } @@ -72,7 +72,7 @@ func (_c *ProviderService_ImportActivities_Call) Return(_a0 []*domain.Activity, return _c } -func (_c *ProviderService_ImportActivities_Call) RunAndReturn(run func(context.Context, domain.ImportActivitiesFilter) ([]*domain.Activity, error)) *ProviderService_ImportActivities_Call { +func (_c *ProviderService_ImportActivities_Call) RunAndReturn(run func(context.Context, domain.ListActivitiesFilter) ([]*domain.Activity, error)) *ProviderService_ImportActivities_Call { _c.Call.Return(run) return _c } diff --git a/core/activity/mocks/repository.go b/core/activity/mocks/repository.go index 7db04ada..9e517f42 100644 --- a/core/activity/mocks/repository.go +++ b/core/activity/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/activity/service.go b/core/activity/service.go index 97b22783..774b04bb 100644 --- a/core/activity/service.go +++ b/core/activity/service.go @@ -18,7 +18,7 @@ type repository interface { //go:generate mockery --name=providerService --exported --with-expecter type providerService interface { - ImportActivities(context.Context, domain.ImportActivitiesFilter) ([]*domain.Activity, error) + ImportActivities(context.Context, domain.ListActivitiesFilter) ([]*domain.Activity, error) } //go:generate mockery --name=auditLogger --exported --with-expecter @@ -61,7 +61,7 @@ func (s *Service) Find(ctx context.Context, filter domain.ListProviderActivities return s.repo.Find(ctx, filter) } -func (s *Service) Import(ctx context.Context, filter domain.ImportActivitiesFilter) ([]*domain.Activity, error) { +func (s *Service) Import(ctx context.Context, filter domain.ListActivitiesFilter) ([]*domain.Activity, error) { activities, err := s.providerService.ImportActivities(ctx, filter) if err != nil { return nil, err diff --git a/core/appeal/mocks/approvalService.go b/core/appeal/mocks/approvalService.go index b866dae0..e4cd674c 100644 --- a/core/appeal/mocks/approvalService.go +++ b/core/appeal/mocks/approvalService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/auditLogger.go b/core/appeal/mocks/auditLogger.go index 87682202..385c23ac 100644 --- a/core/appeal/mocks/auditLogger.go +++ b/core/appeal/mocks/auditLogger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/grantService.go b/core/appeal/mocks/grantService.go index a0a416d5..56298793 100644 --- a/core/appeal/mocks/grantService.go +++ b/core/appeal/mocks/grantService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/iamManager.go b/core/appeal/mocks/iamManager.go index 95812330..a70b9587 100644 --- a/core/appeal/mocks/iamManager.go +++ b/core/appeal/mocks/iamManager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/notifier.go b/core/appeal/mocks/notifier.go index 6735281b..3e618268 100644 --- a/core/appeal/mocks/notifier.go +++ b/core/appeal/mocks/notifier.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/policyService.go b/core/appeal/mocks/policyService.go index 2b01f6fb..5c6e325a 100644 --- a/core/appeal/mocks/policyService.go +++ b/core/appeal/mocks/policyService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/providerService.go b/core/appeal/mocks/providerService.go index 5138a907..5bf951dc 100644 --- a/core/appeal/mocks/providerService.go +++ b/core/appeal/mocks/providerService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/mocks/repository.go b/core/appeal/mocks/repository.go index daa7f0fc..5d20022c 100644 --- a/core/appeal/mocks/repository.go +++ b/core/appeal/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -120,6 +120,59 @@ func (_c *Repository_Find_Call) RunAndReturn(run func(context.Context, *domain.L return _c } +// GetAppealsTotalCount provides a mock function with given fields: _a0, _a1 +func (_m *Repository) GetAppealsTotalCount(_a0 context.Context, _a1 *domain.ListAppealsFilter) (int64, error) { + ret := _m.Called(_a0, _a1) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListAppealsFilter) (int64, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListAppealsFilter) int64); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, *domain.ListAppealsFilter) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_GetAppealsTotalCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAppealsTotalCount' +type Repository_GetAppealsTotalCount_Call struct { + *mock.Call +} + +// GetAppealsTotalCount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *domain.ListAppealsFilter +func (_e *Repository_Expecter) GetAppealsTotalCount(_a0 interface{}, _a1 interface{}) *Repository_GetAppealsTotalCount_Call { + return &Repository_GetAppealsTotalCount_Call{Call: _e.mock.On("GetAppealsTotalCount", _a0, _a1)} +} + +func (_c *Repository_GetAppealsTotalCount_Call) Run(run func(_a0 context.Context, _a1 *domain.ListAppealsFilter)) *Repository_GetAppealsTotalCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*domain.ListAppealsFilter)) + }) + return _c +} + +func (_c *Repository_GetAppealsTotalCount_Call) Return(_a0 int64, _a1 error) *Repository_GetAppealsTotalCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_GetAppealsTotalCount_Call) RunAndReturn(run func(context.Context, *domain.ListAppealsFilter) (int64, error)) *Repository_GetAppealsTotalCount_Call { + _c.Call.Return(run) + return _c +} + // GetByID provides a mock function with given fields: ctx, id func (_m *Repository) GetByID(ctx context.Context, id string) (*domain.Appeal, error) { ret := _m.Called(ctx, id) diff --git a/core/appeal/mocks/resourceService.go b/core/appeal/mocks/resourceService.go index 601338b3..fc57688e 100644 --- a/core/appeal/mocks/resourceService.go +++ b/core/appeal/mocks/resourceService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/appeal/service.go b/core/appeal/service.go index b2b0aa33..a1e11dd3 100644 --- a/core/appeal/service.go +++ b/core/appeal/service.go @@ -38,6 +38,7 @@ type repository interface { Find(context.Context, *domain.ListAppealsFilter) ([]*domain.Appeal, error) GetByID(ctx context.Context, id string) (*domain.Appeal, error) Update(context.Context, *domain.Appeal) error + GetAppealsTotalCount(context.Context, *domain.ListAppealsFilter) (int64, error) } //go:generate mockery --name=iamManager --exported --with-expecter @@ -1221,3 +1222,7 @@ func (s *Service) prepareGrant(ctx context.Context, appeal *domain.Appeal) (newG return grant, deactivatedGrant, nil } + +func (s *Service) GetAppealsTotalCount(ctx context.Context, filters *domain.ListAppealsFilter) (int64, error) { + return s.repo.GetAppealsTotalCount(ctx, filters) +} diff --git a/core/appeal/service_test.go b/core/appeal/service_test.go index e684397d..236e73ba 100644 --- a/core/appeal/service_test.go +++ b/core/appeal/service_test.go @@ -2871,6 +2871,32 @@ func (s *ServiceTestSuite) TestDeleteApprover() { }) } +func (s *ServiceTestSuite) TestGetAppealsTotalCount() { + s.Run("should return error if got error from repository", func() { + expectedError := errors.New("repository error") + s.mockRepository.EXPECT(). + GetAppealsTotalCount(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(0, expectedError).Once() + + actualCount, actualError := s.service.GetAppealsTotalCount(context.Background(), &domain.ListAppealsFilter{}) + + s.Zero(actualCount) + s.EqualError(actualError, expectedError.Error()) + }) + + s.Run("should return appeals count from repository", func() { + expectedCount := int64(1) + s.mockRepository.EXPECT(). + GetAppealsTotalCount(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(expectedCount, nil).Once() + + actualCount, actualError := s.service.GetAppealsTotalCount(context.Background(), &domain.ListAppealsFilter{}) + + s.Equal(expectedCount, actualCount) + s.NoError(actualError) + }) +} + func TestService(t *testing.T) { suite.Run(t, new(ServiceTestSuite)) } diff --git a/core/approval/mocks/policyService.go b/core/approval/mocks/policyService.go index 5ba64cbb..64fa743c 100644 --- a/core/approval/mocks/policyService.go +++ b/core/approval/mocks/policyService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/approval/mocks/repository.go b/core/approval/mocks/repository.go index 230cec2b..4f427904 100644 --- a/core/approval/mocks/repository.go +++ b/core/approval/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -152,6 +152,59 @@ func (_c *Repository_DeleteApprover_Call) RunAndReturn(run func(context.Context, return _c } +// GetApprovalsTotalCount provides a mock function with given fields: _a0, _a1 +func (_m *Repository) GetApprovalsTotalCount(_a0 context.Context, _a1 *domain.ListApprovalsFilter) (int64, error) { + ret := _m.Called(_a0, _a1) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListApprovalsFilter) (int64, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, *domain.ListApprovalsFilter) int64); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, *domain.ListApprovalsFilter) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_GetApprovalsTotalCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetApprovalsTotalCount' +type Repository_GetApprovalsTotalCount_Call struct { + *mock.Call +} + +// GetApprovalsTotalCount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *domain.ListApprovalsFilter +func (_e *Repository_Expecter) GetApprovalsTotalCount(_a0 interface{}, _a1 interface{}) *Repository_GetApprovalsTotalCount_Call { + return &Repository_GetApprovalsTotalCount_Call{Call: _e.mock.On("GetApprovalsTotalCount", _a0, _a1)} +} + +func (_c *Repository_GetApprovalsTotalCount_Call) Run(run func(_a0 context.Context, _a1 *domain.ListApprovalsFilter)) *Repository_GetApprovalsTotalCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*domain.ListApprovalsFilter)) + }) + return _c +} + +func (_c *Repository_GetApprovalsTotalCount_Call) Return(_a0 int64, _a1 error) *Repository_GetApprovalsTotalCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_GetApprovalsTotalCount_Call) RunAndReturn(run func(context.Context, *domain.ListApprovalsFilter) (int64, error)) *Repository_GetApprovalsTotalCount_Call { + _c.Call.Return(run) + return _c +} + // ListApprovals provides a mock function with given fields: _a0, _a1 func (_m *Repository) ListApprovals(_a0 context.Context, _a1 *domain.ListApprovalsFilter) ([]*domain.Approval, error) { ret := _m.Called(_a0, _a1) diff --git a/core/approval/service.go b/core/approval/service.go index ca34478b..1cbff590 100644 --- a/core/approval/service.go +++ b/core/approval/service.go @@ -9,6 +9,7 @@ import ( //go:generate mockery --name=repository --exported --with-expecter type repository interface { BulkInsert(context.Context, []*domain.Approval) error + GetApprovalsTotalCount(context.Context, *domain.ListApprovalsFilter) (int64, error) ListApprovals(context.Context, *domain.ListApprovalsFilter) ([]*domain.Approval, error) AddApprover(context.Context, *domain.Approver) error DeleteApprover(ctx context.Context, approvalID, email string) error @@ -39,6 +40,10 @@ func (s *Service) ListApprovals(ctx context.Context, filters *domain.ListApprova return s.repo.ListApprovals(ctx, filters) } +func (s *Service) GetApprovalsTotalCount(ctx context.Context, filters *domain.ListApprovalsFilter) (int64, error) { + return s.repo.GetApprovalsTotalCount(ctx, filters) +} + func (s *Service) BulkInsert(ctx context.Context, approvals []*domain.Approval) error { return s.repo.BulkInsert(ctx, approvals) } diff --git a/core/approval/service_test.go b/core/approval/service_test.go index 156db472..686301a8 100644 --- a/core/approval/service_test.go +++ b/core/approval/service_test.go @@ -35,6 +35,62 @@ func (s *ServiceTestSuite) SetupTest() { }) } +func (s *ServiceTestSuite) TestListApprovals() { + s.Run("should return error if got error from repository", func() { + expectedError := errors.New("repository error") + s.mockRepository.EXPECT(). + ListApprovals(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(nil, expectedError).Once() + + actualApprovals, actualError := s.service.ListApprovals(context.Background(), &domain.ListApprovalsFilter{}) + + s.Nil(actualApprovals) + s.EqualError(actualError, expectedError.Error()) + }) + + s.Run("should return approvals from repository", func() { + expectedApprovals := []*domain.Approval{ + { + ID: uuid.New().String(), + }, + } + s.mockRepository.EXPECT(). + ListApprovals(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(expectedApprovals, nil).Once() + + actualApprovals, actualError := s.service.ListApprovals(context.Background(), &domain.ListApprovalsFilter{}) + + s.Equal(expectedApprovals, actualApprovals) + s.NoError(actualError) + }) +} + +func (s *ServiceTestSuite) TestGetApprovalsTotalCount() { + s.Run("should return error if got error from repository", func() { + expectedError := errors.New("repository error") + s.mockRepository.EXPECT(). + GetApprovalsTotalCount(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(0, expectedError).Once() + + actualCount, actualError := s.service.GetApprovalsTotalCount(context.Background(), &domain.ListApprovalsFilter{}) + + s.Zero(actualCount) + s.EqualError(actualError, expectedError.Error()) + }) + + s.Run("should return approvals count from repository", func() { + expectedCount := int64(1) + s.mockRepository.EXPECT(). + GetApprovalsTotalCount(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(expectedCount, nil).Once() + + actualCount, actualError := s.service.GetApprovalsTotalCount(context.Background(), &domain.ListApprovalsFilter{}) + + s.Equal(expectedCount, actualCount) + s.NoError(actualError) + }) +} + func (s *ServiceTestSuite) TestBulkInsert() { s.Run("should return error if got error from repository", func() { expectedError := errors.New("repository error") diff --git a/core/grant/mocks/auditLogger.go b/core/grant/mocks/auditLogger.go index 87682202..385c23ac 100644 --- a/core/grant/mocks/auditLogger.go +++ b/core/grant/mocks/auditLogger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/grant/mocks/notifier.go b/core/grant/mocks/notifier.go index 0e5e15a0..4dc056ba 100644 --- a/core/grant/mocks/notifier.go +++ b/core/grant/mocks/notifier.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/grant/mocks/providerService.go b/core/grant/mocks/providerService.go index 236e5857..705222f6 100644 --- a/core/grant/mocks/providerService.go +++ b/core/grant/mocks/providerService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -23,6 +23,51 @@ func (_m *ProviderService) EXPECT() *ProviderService_Expecter { return &ProviderService_Expecter{mock: &_m.Mock} } +// CorrelateGrantActivities provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *ProviderService) CorrelateGrantActivities(_a0 context.Context, _a1 domain.Provider, _a2 []*domain.Grant, _a3 []*domain.Activity) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, []*domain.Grant, []*domain.Activity) error); ok { + r0 = rf(_a0, _a1, _a2, _a3) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// ProviderService_CorrelateGrantActivities_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CorrelateGrantActivities' +type ProviderService_CorrelateGrantActivities_Call struct { + *mock.Call +} + +// CorrelateGrantActivities is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.Provider +// - _a2 []*domain.Grant +// - _a3 []*domain.Activity +func (_e *ProviderService_Expecter) CorrelateGrantActivities(_a0 interface{}, _a1 interface{}, _a2 interface{}, _a3 interface{}) *ProviderService_CorrelateGrantActivities_Call { + return &ProviderService_CorrelateGrantActivities_Call{Call: _e.mock.On("CorrelateGrantActivities", _a0, _a1, _a2, _a3)} +} + +func (_c *ProviderService_CorrelateGrantActivities_Call) Run(run func(_a0 context.Context, _a1 domain.Provider, _a2 []*domain.Grant, _a3 []*domain.Activity)) *ProviderService_CorrelateGrantActivities_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.Provider), args[2].([]*domain.Grant), args[3].([]*domain.Activity)) + }) + return _c +} + +func (_c *ProviderService_CorrelateGrantActivities_Call) Return(_a0 error) *ProviderService_CorrelateGrantActivities_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *ProviderService_CorrelateGrantActivities_Call) RunAndReturn(run func(context.Context, domain.Provider, []*domain.Grant, []*domain.Activity) error) *ProviderService_CorrelateGrantActivities_Call { + _c.Call.Return(run) + return _c +} + // GetByID provides a mock function with given fields: _a0, _a1 func (_m *ProviderService) GetByID(_a0 context.Context, _a1 string) (*domain.Provider, error) { ret := _m.Called(_a0, _a1) @@ -134,6 +179,62 @@ func (_c *ProviderService_ListAccess_Call) RunAndReturn(run func(context.Context return _c } +// ListActivities provides a mock function with given fields: _a0, _a1, _a2 +func (_m *ProviderService) ListActivities(_a0 context.Context, _a1 domain.Provider, _a2 domain.ListActivitiesFilter) ([]*domain.Activity, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 []*domain.Activity + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error)); ok { + return rf(_a0, _a1, _a2) + } + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) []*domain.Activity); ok { + r0 = rf(_a0, _a1, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*domain.Activity) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) error); ok { + r1 = rf(_a0, _a1, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ProviderService_ListActivities_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListActivities' +type ProviderService_ListActivities_Call struct { + *mock.Call +} + +// ListActivities is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.Provider +// - _a2 domain.ListActivitiesFilter +func (_e *ProviderService_Expecter) ListActivities(_a0 interface{}, _a1 interface{}, _a2 interface{}) *ProviderService_ListActivities_Call { + return &ProviderService_ListActivities_Call{Call: _e.mock.On("ListActivities", _a0, _a1, _a2)} +} + +func (_c *ProviderService_ListActivities_Call) Run(run func(_a0 context.Context, _a1 domain.Provider, _a2 domain.ListActivitiesFilter)) *ProviderService_ListActivities_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.Provider), args[2].(domain.ListActivitiesFilter)) + }) + return _c +} + +func (_c *ProviderService_ListActivities_Call) Return(_a0 []*domain.Activity, _a1 error) *ProviderService_ListActivities_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ProviderService_ListActivities_Call) RunAndReturn(run func(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error)) *ProviderService_ListActivities_Call { + _c.Call.Return(run) + return _c +} + // RevokeAccess provides a mock function with given fields: _a0, _a1 func (_m *ProviderService) RevokeAccess(_a0 context.Context, _a1 domain.Grant) error { ret := _m.Called(_a0, _a1) diff --git a/core/grant/mocks/repository.go b/core/grant/mocks/repository.go index b4c3848e..82ec7fff 100644 --- a/core/grant/mocks/repository.go +++ b/core/grant/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -121,6 +121,59 @@ func (_c *Repository_GetByID_Call) RunAndReturn(run func(context.Context, string return _c } +// GetGrantsTotalCount provides a mock function with given fields: _a0, _a1 +func (_m *Repository) GetGrantsTotalCount(_a0 context.Context, _a1 domain.ListGrantsFilter) (int64, error) { + ret := _m.Called(_a0, _a1) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, domain.ListGrantsFilter) (int64, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, domain.ListGrantsFilter) int64); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context, domain.ListGrantsFilter) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Repository_GetGrantsTotalCount_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGrantsTotalCount' +type Repository_GetGrantsTotalCount_Call struct { + *mock.Call +} + +// GetGrantsTotalCount is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.ListGrantsFilter +func (_e *Repository_Expecter) GetGrantsTotalCount(_a0 interface{}, _a1 interface{}) *Repository_GetGrantsTotalCount_Call { + return &Repository_GetGrantsTotalCount_Call{Call: _e.mock.On("GetGrantsTotalCount", _a0, _a1)} +} + +func (_c *Repository_GetGrantsTotalCount_Call) Run(run func(_a0 context.Context, _a1 domain.ListGrantsFilter)) *Repository_GetGrantsTotalCount_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.ListGrantsFilter)) + }) + return _c +} + +func (_c *Repository_GetGrantsTotalCount_Call) Return(_a0 int64, _a1 error) *Repository_GetGrantsTotalCount_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *Repository_GetGrantsTotalCount_Call) RunAndReturn(run func(context.Context, domain.ListGrantsFilter) (int64, error)) *Repository_GetGrantsTotalCount_Call { + _c.Call.Return(run) + return _c +} + // List provides a mock function with given fields: _a0, _a1 func (_m *Repository) List(_a0 context.Context, _a1 domain.ListGrantsFilter) ([]domain.Grant, error) { ret := _m.Called(_a0, _a1) diff --git a/core/grant/mocks/resourceService.go b/core/grant/mocks/resourceService.go index f8c485c8..065d6406 100644 --- a/core/grant/mocks/resourceService.go +++ b/core/grant/mocks/resourceService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/grant/service.go b/core/grant/service.go index 4d99123a..4fb12a51 100644 --- a/core/grant/service.go +++ b/core/grant/service.go @@ -4,10 +4,12 @@ import ( "context" "fmt" "sort" + "strings" "time" "github.com/go-playground/validator/v10" "github.com/raystack/guardian/domain" + "github.com/raystack/guardian/pkg/slices" "github.com/raystack/guardian/plugins/notifiers" "github.com/raystack/guardian/utils" "github.com/raystack/salt/log" @@ -24,6 +26,7 @@ type repository interface { GetByID(context.Context, string) (*domain.Grant, error) Update(context.Context, *domain.Grant) error BulkUpsert(context.Context, []*domain.Grant) error + GetGrantsTotalCount(context.Context, domain.ListGrantsFilter) (int64, error) } //go:generate mockery --name=providerService --exported --with-expecter @@ -31,6 +34,8 @@ type providerService interface { GetByID(context.Context, string) (*domain.Provider, error) RevokeAccess(context.Context, domain.Grant) error ListAccess(context.Context, domain.Provider, []*domain.Resource) (domain.MapResourceAccess, error) + ListActivities(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error) + CorrelateGrantActivities(context.Context, domain.Provider, []*domain.Grant, []*domain.Activity) error } //go:generate mockery --name=resourceService --exported --with-expecter @@ -480,6 +485,129 @@ func (s *Service) ImportFromProvider(ctx context.Context, criteria ImportFromPro return newAndUpdatedGrants, nil } +func (s *Service) DormancyCheck(ctx context.Context, criteria domain.DormancyCheckCriteria) error { + if err := criteria.Validate(); err != nil { + return fmt.Errorf("invalid dormancy check criteria: %w", err) + } + startDate := time.Now().Add(-criteria.Period) + + provider, err := s.providerService.GetByID(ctx, criteria.ProviderID) + if err != nil { + return fmt.Errorf("getting provider details: %w", err) + } + + s.logger.Info("getting active grants", "provider_urn", provider.URN) + grants, err := s.List(ctx, domain.ListGrantsFilter{ + Statuses: []string{string(domain.GrantStatusActive)}, // TODO: evaluate later to use status_in_provider + ProviderTypes: []string{provider.Type}, + ProviderURNs: []string{provider.URN}, + CreatedAtLte: startDate, + }) + if err != nil { + return fmt.Errorf("listing active grants: %w", err) + } + if len(grants) == 0 { + s.logger.Info("no active grants found", "provider_urn", provider.URN) + return nil + } + grantIDs := getGrantIDs(grants) + s.logger.Info(fmt.Sprintf("found %d active grants", len(grants)), "grant_ids", grantIDs, "provider_urn", provider.URN) + + var accountIDs []string + for _, g := range grants { + accountIDs = append(accountIDs, g.AccountID) + } + accountIDs = slices.UniqueStringSlice(accountIDs) + + s.logger.Info("getting activities", "provider_urn", provider.URN) + activities, err := s.providerService.ListActivities(ctx, *provider, domain.ListActivitiesFilter{ + AccountIDs: accountIDs, + TimestampGte: &startDate, + }) + if err != nil { + return fmt.Errorf("listing activities for provider %q: %w", provider.URN, err) + } + s.logger.Info(fmt.Sprintf("found %d activities", len(activities)), "provider_urn", provider.URN) + + grantsPointer := make([]*domain.Grant, len(grants)) + for i, g := range grants { + g := g + grantsPointer[i] = &g + } + if err := s.providerService.CorrelateGrantActivities(ctx, *provider, grantsPointer, activities); err != nil { + return fmt.Errorf("correlating grant activities: %w", err) + } + + s.logger.Info("checking grants dormancy...", "provider_urn", provider.URN) + var dormantGrants []*domain.Grant + var dormantGrantsIDs []string + var dormantGrantsByOwner = map[string][]*domain.Grant{} + for _, g := range grantsPointer { + if len(g.Activities) == 0 { + g.ExpirationDateReason = fmt.Sprintf("%s: %s", domain.GrantExpirationReasonDormant, criteria.RetainDuration) + newExpDate := time.Now().Add(criteria.RetainDuration) + g.ExpirationDate = &newExpDate + g.IsPermanent = false + + dormantGrants = append(dormantGrants, g) + dormantGrantsIDs = append(dormantGrantsIDs, g.ID) + + dormantGrantsByOwner[g.Owner] = append(dormantGrantsByOwner[g.Owner], g) + } + } + s.logger.Info(fmt.Sprintf("found %d dormant grants", len(dormantGrants)), "grant_ids", dormantGrantsIDs, "provider_urn", provider.URN) + + if criteria.DryRun { + s.logger.Info("dry run mode, skipping updating grants expiration date", "provider_urn", provider.URN) + return nil + } + + if err := s.repo.BulkUpsert(ctx, dormantGrants); err != nil { + return fmt.Errorf("updating grants expiration date: %w", err) + } + + var notifications []domain.Notification +prepare_notifications: + for owner, grants := range dormantGrantsByOwner { + var grantsMap []map[string]interface{} + var grantIDs []string + + for _, g := range grants { + grantMap, err := utils.StructToMap(g) + if err != nil { + s.logger.Error("failed to convert grant to map", "error", err) + continue prepare_notifications + } + grantsMap = append(grantsMap, grantMap) + } + + notifications = append(notifications, domain.Notification{ + User: owner, + Labels: map[string]string{ + "owner": owner, + "grant_ids": strings.Join(grantIDs, ", "), + }, + Message: domain.NotificationMessage{ + Type: domain.NotificationTypeUnusedGrant, + Variables: map[string]interface{}{ + "dormant_grants": grantsMap, + "period": criteria.Period.String(), + "retain_duration": criteria.RetainDuration.String(), + "start_date_formatted": startDate.Format("Jan 02, 2006 15:04:05 UTC"), + }, + }, + }) + } + + if errs := s.notifier.Notify(notifications); errs != nil { + for _, err1 := range errs { + s.logger.Error("failed to send notifications", "error", err1.Error(), "provider_urn", provider.URN) + } + } + + return nil +} + func getAccountSignature(accountType, accountID string) string { return fmt.Sprintf("%s:%s", accountType, accountID) } @@ -533,3 +661,15 @@ func reduceGrantsByProviderRole(rc domain.ResourceConfig, grants []*domain.Grant return } + +func getGrantIDs(grants []domain.Grant) []string { + var ids []string + for _, g := range grants { + ids = append(ids, g.ID) + } + return ids +} + +func (s *Service) GetGrantsTotalCount(ctx context.Context, filters domain.ListGrantsFilter) (int64, error) { + return s.repo.GetGrantsTotalCount(ctx, filters) +} diff --git a/core/grant/service_test.go b/core/grant/service_test.go index 807d690a..a6bb3add 100644 --- a/core/grant/service_test.go +++ b/core/grant/service_test.go @@ -892,3 +892,126 @@ func (s *ServiceTestSuite) TestImportFromProvider() { } }) } + +func (s *ServiceTestSuite) TestDormancyCheck() { + s.Run("should update grants and return nil error on success", func() { + s.setup() + + timeNow := time.Now() + dummyProvider := &domain.Provider{ + ID: "test-provider-id", + } + dummyGrants := []domain.Grant{ + { + ID: "g1", + AccountID: "user@example.com", + Permissions: []string{"role-1"}, + IsPermanent: true, + }, + { + ID: "g2", + AccountID: "user2@example.com", + Permissions: []string{"role-2"}, + }, + } + dummyActivities := []*domain.Activity{} + + dormancyCheckCriteria := domain.DormancyCheckCriteria{ + ProviderID: dummyProvider.ID, + Period: 30 * 24 * time.Hour, // 30 days back + RetainDuration: 7 * 24 * time.Hour, // update grant exp date to 7 days from now + } + + newExpDate := timeNow.Add(dormancyCheckCriteria.RetainDuration) + expectedReason := fmt.Sprintf("%s: %s", domain.GrantExpirationReasonDormant, dormancyCheckCriteria.RetainDuration) + expectedUpdatedGrants := []*domain.Grant{ + { + ID: "g1", + AccountID: "user@example.com", + Permissions: []string{"role-1"}, + ExpirationDate: &newExpDate, + IsPermanent: false, + ExpirationDateReason: expectedReason, + }, + { + ID: "g2", + AccountID: "user2@example.com", + Permissions: []string{"role-2"}, + ExpirationDate: &newExpDate, + ExpirationDateReason: expectedReason, + }, + } + + s.mockProviderService.EXPECT(). + GetByID(mock.AnythingOfType("*context.emptyCtx"), dummyProvider.ID). + Return(dummyProvider, nil).Once() + expectedListGrantsFilter := domain.ListGrantsFilter{ + Statuses: []string{string(domain.GrantStatusActive)}, + ProviderTypes: []string{dummyProvider.Type}, + ProviderURNs: []string{dummyProvider.URN}, + CreatedAtLte: timeNow.Add(-dormancyCheckCriteria.Period), + } + s.mockRepository.EXPECT(). + List(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("domain.ListGrantsFilter")). + Run(func(_a0 context.Context, f domain.ListGrantsFilter) { + s.Empty(cmp.Diff(expectedListGrantsFilter, f, cmpopts.EquateApproxTime(time.Second))) + }). + Return(dummyGrants, nil).Once() + timestampGte := timeNow.Add(-dormancyCheckCriteria.Period) + expectedListActivitiesFilter := domain.ListActivitiesFilter{ + AccountIDs: []string{"user@example.com", "user2@example.com"}, + TimestampGte: ×tampGte, + } + s.mockProviderService.EXPECT(). + ListActivities(mock.AnythingOfType("*context.emptyCtx"), *dummyProvider, mock.AnythingOfType("domain.ListActivitiesFilter")). + Run(func(_a0 context.Context, _a1 domain.Provider, f domain.ListActivitiesFilter) { + s.Empty(cmp.Diff(expectedListActivitiesFilter, f, + cmpopts.EquateApproxTime(time.Second), + cmpopts.IgnoreUnexported(domain.ListActivitiesFilter{}), + )) + }). + Return(dummyActivities, nil).Once() + s.mockProviderService.EXPECT(). + CorrelateGrantActivities(mock.AnythingOfType("*context.emptyCtx"), *dummyProvider, mock.AnythingOfType("[]*domain.Grant"), dummyActivities). + Return(nil).Once() + s.mockRepository.EXPECT(). + BulkUpsert(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("[]*domain.Grant")). + Run(func(_a0 context.Context, grants []*domain.Grant) { + s.Empty(cmp.Diff(expectedUpdatedGrants, grants, + cmpopts.EquateApproxTime(time.Second), + )) + }). + Return(nil).Once() + + s.mockNotifier.EXPECT().Notify(mock.Anything).Return(nil).Once() // TODO + + err := s.service.DormancyCheck(context.Background(), dormancyCheckCriteria) + s.NoError(err) + }) +} + +func (s *ServiceTestSuite) TestGetGrantsTotalCount() { + s.Run("should return error if got error from repository", func() { + expectedError := errors.New("repository error") + s.mockRepository.EXPECT(). + GetGrantsTotalCount(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(0, expectedError).Once() + + actualCount, actualError := s.service.GetGrantsTotalCount(context.Background(), domain.ListGrantsFilter{}) + + s.Zero(actualCount) + s.EqualError(actualError, expectedError.Error()) + }) + + s.Run("should return Grants count from repository", func() { + expectedCount := int64(1) + s.mockRepository.EXPECT(). + GetGrantsTotalCount(mock.AnythingOfType("*context.emptyCtx"), mock.Anything). + Return(expectedCount, nil).Once() + + actualCount, actualError := s.service.GetGrantsTotalCount(context.Background(), domain.ListGrantsFilter{}) + + s.Equal(expectedCount, actualCount) + s.NoError(actualError) + }) +} diff --git a/core/policy/mocks/auditLogger.go b/core/policy/mocks/auditLogger.go index 87682202..385c23ac 100644 --- a/core/policy/mocks/auditLogger.go +++ b/core/policy/mocks/auditLogger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/policy/mocks/providerService.go b/core/policy/mocks/providerService.go index 9fbc558b..ea9a584b 100644 --- a/core/policy/mocks/providerService.go +++ b/core/policy/mocks/providerService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/policy/mocks/repository.go b/core/policy/mocks/repository.go index ac5834ac..b81dfb8b 100644 --- a/core/policy/mocks/repository.go +++ b/core/policy/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/policy/mocks/resourceService.go b/core/policy/mocks/resourceService.go index 72d5efc5..0d8d3359 100644 --- a/core/policy/mocks/resourceService.go +++ b/core/policy/mocks/resourceService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/policy/service.go b/core/policy/service.go index 87d36834..44e993c7 100644 --- a/core/policy/service.go +++ b/core/policy/service.go @@ -2,7 +2,6 @@ package policy import ( "context" - "encoding/json" "fmt" "reflect" "regexp" @@ -12,6 +11,7 @@ import ( "github.com/go-playground/validator/v10" "github.com/raystack/guardian/domain" "github.com/raystack/guardian/pkg/evaluator" + "github.com/raystack/guardian/utils" "github.com/raystack/salt/log" ) @@ -217,7 +217,7 @@ func (s *Service) decryptAndDeserializeIAMConfig(c *domain.IAMConfig) error { if err := iamClientConfig.Decrypt(); err != nil { return fmt.Errorf("decrypting iam config: %w", err) } - iamClientConfigMap, err := structToMap(iamClientConfig) + iamClientConfigMap, err := utils.StructToMap(iamClientConfig) if err != nil { return fmt.Errorf("deserializing iam config: %w", err) } @@ -327,7 +327,7 @@ func (s *Service) validateApprover(expr string) error { dummyAppeal := &domain.Appeal{ Resource: &domain.Resource{}, } - dummyAppealMap, err := structToMap(dummyAppeal) + dummyAppealMap, err := utils.StructToMap(dummyAppeal) if err != nil { return fmt.Errorf("parsing appeal to map: %w", err) } @@ -361,23 +361,6 @@ func containsWhitespaces(s string) bool { return r.Match([]byte(s)) } -func structToMap(item interface{}) (map[string]interface{}, error) { - result := map[string]interface{}{} - - if item != nil { - jsonString, err := json.Marshal(item) - if err != nil { - return nil, err - } - - if err := json.Unmarshal(jsonString, &result); err != nil { - return nil, err - } - } - - return result, nil -} - func (s *Service) validateAppealConfig(cfg *domain.PolicyAppealConfig) error { if cfg != nil && cfg.AllowActiveAccessExtensionIn != "" { if err := validateDuration(cfg.AllowActiveAccessExtensionIn); err != nil { diff --git a/core/provider/errors.go b/core/provider/errors.go index c910d22c..860b640d 100644 --- a/core/provider/errors.go +++ b/core/provider/errors.go @@ -20,4 +20,5 @@ var ( ErrUnimplementedMethod = errors.New("method is not yet implemented") ErrImportActivitiesMethodNotSupported = errors.New("import activities is not supported for this provider type") + ErrGetActivityMethodNotSupported = errors.New("get activity is not supported for this provider type") ) diff --git a/core/provider/mocks/activityManager.go b/core/provider/mocks/activityManager.go index 8cf31e2d..d2f74f62 100644 --- a/core/provider/mocks/activityManager.go +++ b/core/provider/mocks/activityManager.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -23,15 +23,15 @@ func (_m *ActivityManager) EXPECT() *ActivityManager_Expecter { } // GetActivities provides a mock function with given fields: _a0, _a1, _a2 -func (_m *ActivityManager) GetActivities(_a0 context.Context, _a1 domain.Provider, _a2 domain.ImportActivitiesFilter) ([]*domain.Activity, error) { +func (_m *ActivityManager) GetActivities(_a0 context.Context, _a1 domain.Provider, _a2 domain.ListActivitiesFilter) ([]*domain.Activity, error) { ret := _m.Called(_a0, _a1, _a2) var r0 []*domain.Activity var r1 error - if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ImportActivitiesFilter) ([]*domain.Activity, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error)); ok { return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ImportActivitiesFilter) []*domain.Activity); ok { + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) []*domain.Activity); ok { r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { @@ -39,7 +39,7 @@ func (_m *ActivityManager) GetActivities(_a0 context.Context, _a1 domain.Provide } } - if rf, ok := ret.Get(1).(func(context.Context, domain.Provider, domain.ImportActivitiesFilter) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) error); ok { r1 = rf(_a0, _a1, _a2) } else { r1 = ret.Error(1) @@ -56,14 +56,14 @@ type ActivityManager_GetActivities_Call struct { // GetActivities is a helper method to define mock.On call // - _a0 context.Context // - _a1 domain.Provider -// - _a2 domain.ImportActivitiesFilter +// - _a2 domain.ListActivitiesFilter func (_e *ActivityManager_Expecter) GetActivities(_a0 interface{}, _a1 interface{}, _a2 interface{}) *ActivityManager_GetActivities_Call { return &ActivityManager_GetActivities_Call{Call: _e.mock.On("GetActivities", _a0, _a1, _a2)} } -func (_c *ActivityManager_GetActivities_Call) Run(run func(_a0 context.Context, _a1 domain.Provider, _a2 domain.ImportActivitiesFilter)) *ActivityManager_GetActivities_Call { +func (_c *ActivityManager_GetActivities_Call) Run(run func(_a0 context.Context, _a1 domain.Provider, _a2 domain.ListActivitiesFilter)) *ActivityManager_GetActivities_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(domain.Provider), args[2].(domain.ImportActivitiesFilter)) + run(args[0].(context.Context), args[1].(domain.Provider), args[2].(domain.ListActivitiesFilter)) }) return _c } @@ -73,7 +73,7 @@ func (_c *ActivityManager_GetActivities_Call) Return(_a0 []*domain.Activity, _a1 return _c } -func (_c *ActivityManager_GetActivities_Call) RunAndReturn(run func(context.Context, domain.Provider, domain.ImportActivitiesFilter) ([]*domain.Activity, error)) *ActivityManager_GetActivities_Call { +func (_c *ActivityManager_GetActivities_Call) RunAndReturn(run func(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error)) *ActivityManager_GetActivities_Call { _c.Call.Return(run) return _c } diff --git a/core/provider/mocks/auditLogger.go b/core/provider/mocks/auditLogger.go index 87682202..385c23ac 100644 --- a/core/provider/mocks/auditLogger.go +++ b/core/provider/mocks/auditLogger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/provider/mocks/dormancyChecker.go b/core/provider/mocks/dormancyChecker.go new file mode 100644 index 00000000..111fac29 --- /dev/null +++ b/core/provider/mocks/dormancyChecker.go @@ -0,0 +1,138 @@ +// Code generated by mockery v2.33.3. DO NOT EDIT. + +package mocks + +import ( + context "context" + + domain "github.com/raystack/guardian/domain" + mock "github.com/stretchr/testify/mock" +) + +// DormancyChecker is an autogenerated mock type for the dormancyChecker type +type DormancyChecker struct { + mock.Mock +} + +type DormancyChecker_Expecter struct { + mock *mock.Mock +} + +func (_m *DormancyChecker) EXPECT() *DormancyChecker_Expecter { + return &DormancyChecker_Expecter{mock: &_m.Mock} +} + +// CorrelateGrantActivities provides a mock function with given fields: _a0, _a1, _a2, _a3 +func (_m *DormancyChecker) CorrelateGrantActivities(_a0 context.Context, _a1 domain.Provider, _a2 []*domain.Grant, _a3 []*domain.Activity) error { + ret := _m.Called(_a0, _a1, _a2, _a3) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, []*domain.Grant, []*domain.Activity) error); ok { + r0 = rf(_a0, _a1, _a2, _a3) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DormancyChecker_CorrelateGrantActivities_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CorrelateGrantActivities' +type DormancyChecker_CorrelateGrantActivities_Call struct { + *mock.Call +} + +// CorrelateGrantActivities is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.Provider +// - _a2 []*domain.Grant +// - _a3 []*domain.Activity +func (_e *DormancyChecker_Expecter) CorrelateGrantActivities(_a0 interface{}, _a1 interface{}, _a2 interface{}, _a3 interface{}) *DormancyChecker_CorrelateGrantActivities_Call { + return &DormancyChecker_CorrelateGrantActivities_Call{Call: _e.mock.On("CorrelateGrantActivities", _a0, _a1, _a2, _a3)} +} + +func (_c *DormancyChecker_CorrelateGrantActivities_Call) Run(run func(_a0 context.Context, _a1 domain.Provider, _a2 []*domain.Grant, _a3 []*domain.Activity)) *DormancyChecker_CorrelateGrantActivities_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.Provider), args[2].([]*domain.Grant), args[3].([]*domain.Activity)) + }) + return _c +} + +func (_c *DormancyChecker_CorrelateGrantActivities_Call) Return(_a0 error) *DormancyChecker_CorrelateGrantActivities_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *DormancyChecker_CorrelateGrantActivities_Call) RunAndReturn(run func(context.Context, domain.Provider, []*domain.Grant, []*domain.Activity) error) *DormancyChecker_CorrelateGrantActivities_Call { + _c.Call.Return(run) + return _c +} + +// ListActivities provides a mock function with given fields: _a0, _a1, _a2 +func (_m *DormancyChecker) ListActivities(_a0 context.Context, _a1 domain.Provider, _a2 domain.ListActivitiesFilter) ([]*domain.Activity, error) { + ret := _m.Called(_a0, _a1, _a2) + + var r0 []*domain.Activity + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error)); ok { + return rf(_a0, _a1, _a2) + } + if rf, ok := ret.Get(0).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) []*domain.Activity); ok { + r0 = rf(_a0, _a1, _a2) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*domain.Activity) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, domain.Provider, domain.ListActivitiesFilter) error); ok { + r1 = rf(_a0, _a1, _a2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DormancyChecker_ListActivities_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListActivities' +type DormancyChecker_ListActivities_Call struct { + *mock.Call +} + +// ListActivities is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.Provider +// - _a2 domain.ListActivitiesFilter +func (_e *DormancyChecker_Expecter) ListActivities(_a0 interface{}, _a1 interface{}, _a2 interface{}) *DormancyChecker_ListActivities_Call { + return &DormancyChecker_ListActivities_Call{Call: _e.mock.On("ListActivities", _a0, _a1, _a2)} +} + +func (_c *DormancyChecker_ListActivities_Call) Run(run func(_a0 context.Context, _a1 domain.Provider, _a2 domain.ListActivitiesFilter)) *DormancyChecker_ListActivities_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.Provider), args[2].(domain.ListActivitiesFilter)) + }) + return _c +} + +func (_c *DormancyChecker_ListActivities_Call) Return(_a0 []*domain.Activity, _a1 error) *DormancyChecker_ListActivities_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *DormancyChecker_ListActivities_Call) RunAndReturn(run func(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error)) *DormancyChecker_ListActivities_Call { + _c.Call.Return(run) + return _c +} + +// NewDormancyChecker creates a new instance of DormancyChecker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewDormancyChecker(t interface { + mock.TestingT + Cleanup(func()) +}) *DormancyChecker { + mock := &DormancyChecker{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/provider/mocks/repository.go b/core/provider/mocks/repository.go index 9800c24e..53fe6d54 100644 --- a/core/provider/mocks/repository.go +++ b/core/provider/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/provider/mocks/resourceService.go b/core/provider/mocks/resourceService.go index d05b52a7..c53eebcd 100644 --- a/core/provider/mocks/resourceService.go +++ b/core/provider/mocks/resourceService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/provider/service.go b/core/provider/service.go index 4d53649c..19cdfcb4 100644 --- a/core/provider/service.go +++ b/core/provider/service.go @@ -45,7 +45,13 @@ type Client interface { //go:generate mockery --name=activityManager --exported --with-expecter type activityManager interface { - GetActivities(context.Context, domain.Provider, domain.ImportActivitiesFilter) ([]*domain.Activity, error) + GetActivities(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error) +} + +//go:generate mockery --name=dormancyChecker --exported --with-expecter +type dormancyChecker interface { + ListActivities(context.Context, domain.Provider, domain.ListActivitiesFilter) ([]*domain.Activity, error) + CorrelateGrantActivities(context.Context, domain.Provider, []*domain.Grant, []*domain.Activity) error } //go:generate mockery --name=resourceService --exported --with-expecter @@ -468,7 +474,7 @@ func (s *Service) ListAccess(ctx context.Context, p domain.Provider, resources [ return providerAccesses, nil } -func (s *Service) ImportActivities(ctx context.Context, filter domain.ImportActivitiesFilter) ([]*domain.Activity, error) { +func (s *Service) ImportActivities(ctx context.Context, filter domain.ListActivitiesFilter) ([]*domain.Activity, error) { p, err := s.GetByID(ctx, filter.ProviderID) if err != nil { return nil, fmt.Errorf("getting provider details: %w", err) @@ -498,6 +504,25 @@ func (s *Service) ImportActivities(ctx context.Context, filter domain.ImportActi return activities, nil } +func (s *Service) ListActivities(ctx context.Context, p domain.Provider, filter domain.ListActivitiesFilter) ([]*domain.Activity, error) { + c := s.getClient(p.Type) + activityClient, ok := c.(dormancyChecker) + if !ok { + return nil, fmt.Errorf("%w: %s", ErrGetActivityMethodNotSupported, p.Type) + } + + return activityClient.ListActivities(ctx, p, filter) +} + +func (s *Service) CorrelateGrantActivities(ctx context.Context, p domain.Provider, grants []*domain.Grant, activities []*domain.Activity) error { + c := s.getClient(p.Type) + activityClient, ok := c.(dormancyChecker) + if !ok { + return fmt.Errorf("%w: %s", ErrGetActivityMethodNotSupported, p.Type) + } + return activityClient.CorrelateGrantActivities(ctx, p, grants, activities) +} + func (s *Service) getResources(ctx context.Context, p *domain.Provider) ([]*domain.Resource, error) { c := s.getClient(p.Type) if c == nil { diff --git a/core/resource/mocks/auditLogger.go b/core/resource/mocks/auditLogger.go index 87682202..385c23ac 100644 --- a/core/resource/mocks/auditLogger.go +++ b/core/resource/mocks/auditLogger.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/core/resource/mocks/repository.go b/core/resource/mocks/repository.go index 80b37c4b..f830baf3 100644 --- a/core/resource/mocks/repository.go +++ b/core/resource/mocks/repository.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/domain/activity.go b/domain/activity.go index 2bb15d08..1662d2b0 100644 --- a/domain/activity.go +++ b/domain/activity.go @@ -32,17 +32,18 @@ type ListProviderActivitiesFilter struct { TimestampLte *time.Time } -type ImportActivitiesFilter struct { - ProviderID string - ResourceIDs []string - AccountIDs []string - TimestampGte *time.Time - TimestampLte *time.Time +type ListActivitiesFilter struct { + ProviderID string + ResourceIDs []string + ResourceIdentifiers []ResourceIdentifier + AccountIDs []string + TimestampGte *time.Time + TimestampLte *time.Time resources map[string]*Resource } -func (f *ImportActivitiesFilter) PopulateResources(resources map[string]*Resource) error { +func (f *ListActivitiesFilter) PopulateResources(resources map[string]*Resource) error { if f.ResourceIDs == nil { return nil } @@ -62,7 +63,7 @@ func (f *ImportActivitiesFilter) PopulateResources(resources map[string]*Resourc return nil } -func (f *ImportActivitiesFilter) GetResources() []*Resource { +func (f *ListActivitiesFilter) GetResources() []*Resource { if f.resources == nil { return nil } diff --git a/domain/appeal.go b/domain/appeal.go index 416b0c39..f7e1f73b 100644 --- a/domain/appeal.go +++ b/domain/appeal.go @@ -1,13 +1,13 @@ package domain import ( - "encoding/json" "errors" "fmt" "reflect" "time" "github.com/raystack/guardian/pkg/evaluator" + "github.com/raystack/guardian/utils" ) const ( @@ -203,7 +203,7 @@ func (a *Appeal) AdvanceApproval(policy *Policy) error { if approval.Status == ApprovalStatusPending { stepConfig := policy.Steps[approval.Index] - appealMap, err := structToMap(a) + appealMap, err := utils.StructToMap(a) if err != nil { return fmt.Errorf("parsing appeal struct to map: %w", err) } @@ -261,36 +261,6 @@ func (a *Appeal) AdvanceApproval(policy *Policy) error { return nil } -func structToMap(item interface{}) (map[string]interface{}, error) { - result := map[string]interface{}{} - - if item != nil { - jsonString, err := json.Marshal(item) - if err != nil { - return nil, err - } - - if err := json.Unmarshal(jsonString, &result); err != nil { - return nil, err - } - } - - return result, nil -} - -func uniqueSlice(arr []string) []string { - keys := map[string]bool{} - result := []string{} - - for _, v := range arr { - if _, exist := keys[v]; !exist { - result = append(result, v) - keys[v] = true - } - } - return result -} - type ApprovalActionType string const ( @@ -307,6 +277,8 @@ type ApprovalAction struct { } type ListAppealsFilter struct { + Q string `mapstructure:"q" validate:"omitempty"` + AccountTypes []string `mapstructure:"account_types" validate:"omitempty,min=1"` CreatedBy string `mapstructure:"created_by" validate:"omitempty,required"` AccountID string `mapstructure:"account_id" validate:"omitempty,required"` AccountIDs []string `mapstructure:"account_ids" validate:"omitempty,required"` @@ -320,4 +292,6 @@ type ListAppealsFilter struct { ResourceTypes []string `mapstructure:"resource_types" validate:"omitempty,min=1"` ResourceURNs []string `mapstructure:"resource_urns" validate:"omitempty,min=1"` OrderBy []string `mapstructure:"order_by" validate:"omitempty,min=1"` + Size int `mapstructure:"size" validate:"omitempty"` + Offset int `mapstructure:"offset" validate:"omitempty"` } diff --git a/domain/approval.go b/domain/approval.go index 75275b82..88dd793d 100644 --- a/domain/approval.go +++ b/domain/approval.go @@ -47,7 +47,10 @@ func (a *Approval) IsManualApproval() bool { } type ListApprovalsFilter struct { + Q string `mapstructure:"q" validate:"omitempty"` AccountID string `mapstructure:"account_id" validate:"omitempty,required"` + AccountTypes []string `mapstructure:"account_types" validate:"omitempty,min=1"` + ResourceTypes []string `mapstructure:"resource_types" validate:"omitempty,min=1"` CreatedBy string `mapstructure:"created_by" validate:"omitempty,required"` Statuses []string `mapstructure:"statuses" validate:"omitempty,min=1"` OrderBy []string `mapstructure:"order_by" validate:"omitempty,min=1"` diff --git a/domain/grant.go b/domain/grant.go index 56f05d60..09759961 100644 --- a/domain/grant.go +++ b/domain/grant.go @@ -8,17 +8,16 @@ import ( ) type GrantStatus string +type GrantSource string const ( GrantStatusActive GrantStatus = "active" GrantStatusInactive GrantStatus = "inactive" -) - -type GrantSource string -const ( GrantSourceAppeal GrantSource = "appeal" GrantSourceImport GrantSource = "import" + + GrantExpirationReasonDormant = "grant/access hasn't been used for a while" ) type Grant struct { @@ -44,8 +43,9 @@ type Grant struct { CreatedAt time.Time `json:"created_at" yaml:"created_at"` UpdatedAt time.Time `json:"updated_at" yaml:"updated_at"` - Resource *Resource `json:"resource,omitempty" yaml:"resource,omitempty"` - Appeal *Appeal `json:"appeal,omitempty" yaml:"appeal,omitempty"` + Resource *Resource `json:"resource,omitempty" yaml:"resource,omitempty"` + Appeal *Appeal `json:"appeal,omitempty" yaml:"appeal,omitempty"` + Activities []*Activity `json:"activities,omitempty" yaml:"activities,omitempty"` } func (g Grant) PermissionsKey() string { @@ -103,6 +103,10 @@ type ListGrantsFilter struct { ExpirationDateLessThan time.Time ExpirationDateGreaterThan time.Time IsPermanent *bool + CreatedAtLte time.Time + Size int `mapstructure:"size" validate:"omitempty"` + Offset int `mapstructure:"offset" validate:"omitempty"` + Q string `mapstructure:"q" validate:"omitempty"` } type RevokeGrantsFilter struct { @@ -139,3 +143,27 @@ func (ae AccessEntry) ToGrant(resource Resource) Grant { // MapResourceAccess is list of UserAccess grouped by resource urn type MapResourceAccess map[string][]AccessEntry + +type DormancyCheckCriteria struct { + ProviderID string + Period time.Duration + RetainDuration time.Duration + DryRun bool +} + +func (c DormancyCheckCriteria) Validate() error { + if c.ProviderID == "" { + return errors.New("provider id is required") + } + if c.Period == 0 { + return errors.New("period is required") + } else if c.Period < 0 { + return errors.New("period must be positive") + } + if c.RetainDuration == 0 { + return errors.New("retain duration is required") + } else if c.RetainDuration < 0 { + return errors.New("retain duration must be positive") + } + return nil +} diff --git a/domain/notifier.go b/domain/notifier.go index 8ffa529d..1aec9efb 100644 --- a/domain/notifier.go +++ b/domain/notifier.go @@ -8,6 +8,7 @@ type NotificationMessages struct { ApproverNotification string `mapstructure:"approver_notification"` OthersAppealApproved string `mapstructure:"others_appeal_approved"` GrantOwnerChanged string `mapstructure:"grant_owner_changed"` + UnusedGrant string `mapstructure:"unused_grant"` } const ( @@ -18,6 +19,7 @@ const ( NotificationTypeAccessRevoked = "AccessRevoked" NotificationTypeApproverNotification = "ApproverNotification" NotificationTypeGrantOwnerChanged = "GrantOwnerChanged" + NotificationTypeUnusedGrant = "UnusedGrant" ) type NotificationMessage struct { diff --git a/domain/policy.go b/domain/policy.go index 28c25e1a..1bf9f4c9 100644 --- a/domain/policy.go +++ b/domain/policy.go @@ -12,6 +12,8 @@ import ( "github.com/go-playground/validator/v10" "github.com/mcuadros/go-lookup" "github.com/raystack/guardian/pkg/evaluator" + "github.com/raystack/guardian/pkg/slices" + "github.com/raystack/guardian/utils" ) const ( @@ -117,7 +119,7 @@ func (s Step) ResolveApprovers(a *Appeal) ([]string, error) { if err := validate.Var(expr, "email"); err == nil { approvers = append(approvers, expr) } else { - appealMap, err := structToMap(a) + appealMap, err := utils.StructToMap(a) if err != nil { return nil, fmt.Errorf("parsing appeal to map: %w", err) } @@ -152,7 +154,7 @@ func (s Step) ResolveApprovers(a *Appeal) ([]string, error) { } } - distinctApprovers := uniqueSlice(approvers) + distinctApprovers := slices.UniqueStringSlice(approvers) if err := validate.Var(distinctApprovers, "dive,email"); err != nil { return nil, err } @@ -239,7 +241,7 @@ func (r *RequirementTrigger) IsMatch(a *Appeal) (bool, error) { } } if r.Expression != "" { - appealMap, err := structToMap(a) + appealMap, err := utils.StructToMap(a) if err != nil { return false, fmt.Errorf("parsing appeal to map: %w", err) } diff --git a/domain/provider.go b/domain/provider.go index 8c27d5f5..89dfa3c7 100644 --- a/domain/provider.go +++ b/domain/provider.go @@ -75,6 +75,7 @@ type ProviderConfig struct { Appeal *AppealConfig `json:"appeal,omitempty" yaml:"appeal,omitempty" validate:"required"` Resources []*ResourceConfig `json:"resources" yaml:"resources" validate:"required"` Parameters []*ProviderParameter `json:"parameters,omitempty" yaml:"parameters,omitempty"` + Activity *ActivityConfig `json:"activity,omitempty" yaml:"activity,omitempty"` } type ProviderParameter struct { @@ -105,3 +106,8 @@ type ProviderType struct { Name string `json:"name" yaml:"name"` ResourceTypes []string `json:"resource_types" yaml:"resource_types"` } + +type ActivityConfig struct { + Source string + Options map[string]interface{} +} diff --git a/go.mod b/go.mod index 81c6fa89..f8138d1d 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( cloud.google.com/go/bigquery v1.25.0 cloud.google.com/go/datacatalog v1.0.0 cloud.google.com/go/iam v0.3.0 - cloud.google.com/go/logging v1.5.0-jsonlog-preview cloud.google.com/go/storage v1.22.1 github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/MakeNowJust/heredoc v1.0.0 @@ -39,7 +38,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.2 go.opentelemetry.io/otel/sdk v1.14.0 - golang.org/x/net v0.10.0 + golang.org/x/net v0.12.0 golang.org/x/oauth2 v0.1.0 golang.org/x/sync v0.1.0 google.golang.org/api v0.84.0 @@ -116,7 +115,7 @@ require ( github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/microcosm-cc/bluemonday v1.0.6 // indirect + github.com/microcosm-cc/bluemonday v1.0.25 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/muesli/reflow v0.2.0 // indirect diff --git a/go.sum b/go.sum index 348b9cf0..d9fde574 100644 --- a/go.sum +++ b/go.sum @@ -57,8 +57,6 @@ cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1 cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/logging v1.5.0-jsonlog-preview h1:ytQ2SSy+rh+fGUDdRo8zHeHTi+fhcZMyUddSgYhbugc= -cloud.google.com/go/logging v1.5.0-jsonlog-preview/go.mod h1:A26OFzlArW55bhS1qMGlgsctgae2DbXoFE7JAtzGVco= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -1002,8 +1000,9 @@ github.com/mcuadros/go-defaults v1.2.0/go.mod h1:WEZtHEVIGYVDqkKSWBdWKUVdRyKlMfu github.com/mcuadros/go-lookup v0.0.0-20200831155250-80f87a4fa5ee h1:7Ac2RNGC8DAwDNd5uZyuYLoJOlVXyBGbO1VtFboDamk= github.com/mcuadros/go-lookup v0.0.0-20200831155250-80f87a4fa5ee/go.mod h1:yd3I5pyIO5TrBH7+Ym94u8qp9xc6NTHAqESeI8kOJY8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/microcosm-cc/bluemonday v1.0.6 h1:ZOvqHKtnx0fUpnbQm3m3zKFWE+DRC+XB1onh8JoEObE= github.com/microcosm-cc/bluemonday v1.0.6/go.mod h1:HOT/6NaBlR0f9XlxD3zolN6Z3N8Lp4pvhp+jLS5ihnI= +github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= +github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= @@ -1599,8 +1598,9 @@ golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.0.0-20220919232410-f2f64ebce3c1/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -2032,7 +2032,6 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210630183607-d20f26d13c79/go.mod h1:yiaVoXHpRzHGyxV3o4DktVWY4mSUErTKaeEOq6C3t3U= diff --git a/internal/server/config.go b/internal/server/config.go index 62b32f63..0b9bd7c8 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -30,6 +30,7 @@ type Jobs struct { RevokeExpiredGrants jobs.Job `mapstructure:"revoke_expired_grants"` ExpiringGrantNotification jobs.Job `mapstructure:"expiring_grant_notification"` RevokeGrantsByUserCriteria jobs.Job `mapstructure:"revoke_grants_by_user_criteria"` + GrantDormancyCheck jobs.Job `mapstructure:"grant_dormancy_check"` // Deprecated: use ExpiringGrantNotification instead ExpiringAccessNotification jobs.Job `mapstructure:"expiring_access_notification"` diff --git a/internal/store/postgres/appeal_repository.go b/internal/store/postgres/appeal_repository.go index c9e69068..50e4da2b 100644 --- a/internal/store/postgres/appeal_repository.go +++ b/internal/store/postgres/appeal_repository.go @@ -138,6 +138,15 @@ func (r *AppealRepository) Find(ctx context.Context, filters *domain.ListAppeals return records, nil } +func (r *AppealRepository) GetAppealsTotalCount(ctx context.Context, filter *domain.ListAppealsFilter) (int64, error) { + db := r.store.db.WithContext(ctx) + db = applyAppealFilter(db, filter) + var count int64 + err := db.Model(&model.Appeal{}).Count(&count).Error + + return count, err +} + // BulkUpsert new record to database func (r *AppealRepository) BulkUpsert(ctx context.Context, appeals []*domain.Appeal) error { models := []*model.Appeal{} @@ -194,3 +203,81 @@ func (r *AppealRepository) Update(ctx context.Context, a *domain.Appeal) error { return nil }) } + +func applyAppealFilter(db *gorm.DB, filters *domain.ListAppealsFilter) *gorm.DB { + db = db.Joins("JOIN resources ON appeals.resource_id = resources.id") + if filters.Q != "" { + // NOTE: avoid adding conditions before this grouped where clause. + // Otherwise, it will be wrapped in parentheses and the query will be invalid. + db = db.Where(db. + Where(`"appeals"."account_id" LIKE ?`, fmt.Sprintf("%%%s%%", filters.Q)). + Or(`"appeals"."role" LIKE ?`, fmt.Sprintf("%%%s%%", filters.Q)). + Or(`"resources"."urn" LIKE ?`, fmt.Sprintf("%%%s%%", filters.Q)), + ) + } + if filters.Statuses != nil { + db = db.Where(`"appeals"."status" IN ?`, filters.Statuses) + } + if filters.AccountTypes != nil { + db = db.Where(`"appeals"."account_type" IN ?`, filters.AccountTypes) + } + if filters.ResourceTypes != nil { + db = db.Where(`"resources"."type" IN ?`, filters.ResourceTypes) + } + if filters.Size > 0 { + db = db.Limit(filters.Size) + } + if filters.Offset > 0 { + db = db.Offset(filters.Offset) + } + if filters.CreatedBy != "" { + db = db.Where(`"appeals"."created_by" = ?`, filters.CreatedBy) + } + accounts := make([]string, 0) + if filters.AccountID != "" { + accounts = append(accounts, filters.AccountID) + } + if filters.AccountIDs != nil { + accounts = append(accounts, filters.AccountIDs...) + } + if len(accounts) > 0 { + db = db.Where(`"appeals"."account_id" IN ?`, accounts) + } + if filters.Statuses != nil { + db = db.Where(`"appeals"."status" IN ?`, filters.Statuses) + } + if filters.ResourceID != "" { + db = db.Where(`"appeals"."resource_id" = ?`, filters.ResourceID) + } + if filters.Role != "" { + db = db.Where(`"appeals"."role" = ?`, filters.Role) + } + if !filters.ExpirationDateLessThan.IsZero() { + db = db.Where(`"options" -> 'expiration_date' < ?`, filters.ExpirationDateLessThan) + } + if !filters.ExpirationDateGreaterThan.IsZero() { + db = db.Where(`"options" -> 'expiration_date' > ?`, filters.ExpirationDateGreaterThan) + } + if filters.OrderBy != nil { + db = addOrderByClause(db, filters.OrderBy, addOrderByClauseOptions{ + statusColumnName: `"appeals"."status"`, + statusesOrder: AppealStatusDefaultSort, + }) + } + + db = db.Joins("Resource") + if filters.ProviderTypes != nil { + db = db.Where(`"Resource"."provider_type" IN ?`, filters.ProviderTypes) + } + if filters.ProviderURNs != nil { + db = db.Where(`"Resource"."provider_urn" IN ?`, filters.ProviderURNs) + } + if filters.ResourceTypes != nil { + db = db.Where(`"Resource"."type" IN ?`, filters.ResourceTypes) + } + if filters.ResourceURNs != nil { + db = db.Where(`"Resource"."urn" IN ?`, filters.ResourceURNs) + } + + return db +} diff --git a/internal/store/postgres/appeal_repository_test.go b/internal/store/postgres/appeal_repository_test.go index 3b112296..947e920d 100644 --- a/internal/store/postgres/appeal_repository_test.go +++ b/internal/store/postgres/appeal_repository_test.go @@ -128,6 +128,70 @@ func (s *AppealRepositoryTestSuite) TestGetByID() { s.Nil(actualError) s.Equal(dummyAppeal.ID, actualRecord.ID) }) + + s.Run("should run query based on filters", func() { + timeNowPlusAnHour := time.Now().Add(time.Hour) + dummyAppeals := []*domain.Appeal{ + { + ResourceID: s.dummyResource.ID, + PolicyID: s.dummyPolicy.ID, + PolicyVersion: s.dummyPolicy.Version, + AccountID: "user@example.com", + AccountType: domain.DefaultAppealAccountType, + Role: "role_test", + Status: domain.AppealStatusApproved, + Permissions: []string{"permission_test"}, + CreatedBy: "user@example.com", + Options: &domain.AppealOptions{ + ExpirationDate: &time.Time{}, + }, + }, + { + ResourceID: s.dummyResource.ID, + PolicyID: s.dummyPolicy.ID, + PolicyVersion: s.dummyPolicy.Version, + AccountID: "user2@example.com", + AccountType: domain.DefaultAppealAccountType, + Status: domain.AppealStatusCanceled, + Role: "role_test", + Permissions: []string{"permission_test_2"}, + CreatedBy: "user2@example.com", + Options: &domain.AppealOptions{ + ExpirationDate: &timeNowPlusAnHour, + }, + }, + } + testCases := []struct { + filters *domain.ListAppealsFilter + expectedArgs []driver.Value + expectedResult []*domain.Appeal + }{ + { + filters: &domain.ListAppealsFilter{ + Q: "user", + }, + expectedResult: []*domain.Appeal{dummyAppeals[0], dummyAppeals[1]}, + }, + { + filters: &domain.ListAppealsFilter{ + AccountTypes: []string{"x-account-type"}, + }, + expectedResult: []*domain.Appeal{dummyAppeals[0], dummyAppeals[1]}, + }, + } + + for _, tc := range testCases { + _, actualError := s.repository.Find(context.Background(), tc.filters) + s.Nil(actualError) + } + }) +} + +func (s *AppealRepositoryTestSuite) TestGetAppealsTotalCount() { + s.Run("should return 0", func() { + _, actualError := s.repository.GetAppealsTotalCount(context.Background(), &domain.ListAppealsFilter{}) + s.Nil(actualError) + }) } func (s *AppealRepositoryTestSuite) TestFind() { @@ -283,6 +347,18 @@ func (s *AppealRepositoryTestSuite) TestFind() { }, expectedResult: []*domain.Appeal{dummyAppeals[1], dummyAppeals[0]}, }, + { + filters: &domain.ListAppealsFilter{ + Q: "user", + }, + expectedResult: []*domain.Appeal{dummyAppeals[1], dummyAppeals[0]}, + }, + { + filters: &domain.ListAppealsFilter{ + AccountTypes: []string{"x-account-type"}, + }, + expectedResult: []*domain.Appeal{dummyAppeals[1], dummyAppeals[0]}, + }, } for _, tc := range testCases { @@ -290,6 +366,33 @@ func (s *AppealRepositoryTestSuite) TestFind() { s.Nil(actualError) } }) + + s.Run("Should return an array size and offset of n on success", func() { + testCases := []struct { + filters *domain.ListAppealsFilter + expectedArgs []driver.Value + expectedResult []*domain.Appeal + }{ + { + filters: &domain.ListAppealsFilter{ + Size: 1, + Offset: 0, + }, + expectedResult: []*domain.Appeal{dummyAppeals[0]}, + }, + { + filters: &domain.ListAppealsFilter{ + Offset: 1, + }, + expectedResult: []*domain.Appeal{dummyAppeals[1]}, + }, + } + for _, tc := range testCases { + _, actualError := s.repository.Find(context.Background(), tc.filters) + s.Nil(actualError) + } + + }) } func (s *AppealRepositoryTestSuite) TestBulkUpsert() { diff --git a/internal/store/postgres/approval_repository.go b/internal/store/postgres/approval_repository.go index e57363b1..c4d6176f 100644 --- a/internal/store/postgres/approval_repository.go +++ b/internal/store/postgres/approval_repository.go @@ -90,6 +90,18 @@ func (r *ApprovalRepository) ListApprovals(ctx context.Context, conditions *doma return records, nil } +func (r *ApprovalRepository) GetApprovalsTotalCount(ctx context.Context, filter *domain.ListApprovalsFilter) (int64, error) { + db := r.store.db.WithContext(ctx) + db = applyFilter(db, filter) + + var count int64 + if err := db.Model(&model.Approval{}).Count(&count).Error; err != nil { + return 0, err + } + + return count, nil +} + func (r *ApprovalRepository) BulkInsert(ctx context.Context, approvals []*domain.Approval) error { models := []*model.Approval{} for _, a := range approvals { @@ -154,3 +166,49 @@ func (r *ApprovalRepository) DeleteApprover(ctx context.Context, approvalID, ema return nil } + +func applyFilter(db *gorm.DB, filter *domain.ListApprovalsFilter) *gorm.DB { + db = db.Joins("Appeal"). + Joins("Appeal.Resource"). + Joins(`JOIN "approvers" ON "approvals"."id" = "approvers"."approval_id"`) + + if filter.Q != "" { + // NOTE: avoid adding conditions before this grouped where clause. + // Otherwise, it will be wrapped in parentheses and the query will be invalid. + db = db.Where(db. + Where(`"Appeal"."account_id" LIKE ?`, fmt.Sprintf("%%%s%%", filter.Q)). + Or(`"Appeal"."role" LIKE ?`, fmt.Sprintf("%%%s%%", filter.Q)). + Or(`"Appeal__Resource"."urn" LIKE ?`, fmt.Sprintf("%%%s%%", filter.Q)), + ) + } + if filter.CreatedBy != "" { + db = db.Where(`"approvers"."email" = ?`, filter.CreatedBy) + } + if filter.Statuses != nil { + db = db.Where(`"approvals"."status" IN ?`, filter.Statuses) + } + if filter.AccountID != "" { + db = db.Where(`"Appeal"."account_id" = ?`, filter.AccountID) + } + if filter.AccountTypes != nil { + db = db.Where(`"Appeal"."account_type" IN ?`, filter.AccountTypes) + } + if filter.ResourceTypes != nil { + db = db.Where(`"Appeal__Resource"."type" IN ?`, filter.ResourceTypes) + } + + if len(filter.AppealStatuses) == 0 { + db = db.Where(`"Appeal"."status" != ?`, domain.AppealStatusCanceled) + } else { + db = db.Where(`"Appeal"."status" IN ?`, filter.AppealStatuses) + } + + if filter.OrderBy != nil { + db = addOrderByClause(db, filter.OrderBy, addOrderByClauseOptions{ + statusColumnName: `"approvals"."status"`, + statusesOrder: AppealStatusDefaultSort, + }) + } + + return db +} diff --git a/internal/store/postgres/approval_repository_test.go b/internal/store/postgres/approval_repository_test.go index a1bb8051..bfa5c77e 100644 --- a/internal/store/postgres/approval_repository_test.go +++ b/internal/store/postgres/approval_repository_test.go @@ -117,8 +117,16 @@ func (s *ApprovalRepositoryTestSuite) TearDownSuite() { } } +func (s *ApprovalRepositoryTestSuite) TestGetApprovalsTotalCount() { + + s.Run("should return 0", func() { + _, actualError := s.repository.GetApprovalsTotalCount(context.Background(), &domain.ListApprovalsFilter{}) + s.Nil(actualError) + }) +} + func (s *ApprovalRepositoryTestSuite) TestListApprovals() { - appealA := &domain.Appeal{ + pendingAppeal := &domain.Appeal{ ResourceID: s.dummyResource.ID, PolicyID: s.dummyPolicy.ID, PolicyVersion: s.dummyPolicy.Version, @@ -130,7 +138,7 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { Status: domain.AppealStatusPending, } - appealB := &domain.Appeal{ + cancelledAppeal := &domain.Appeal{ ResourceID: s.dummyResource.ID, PolicyID: s.dummyPolicy.ID, PolicyVersion: s.dummyPolicy.Version, @@ -142,7 +150,7 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { Status: domain.AppealStatusCanceled, } - s.appealRepository.BulkUpsert(context.Background(), []*domain.Appeal{appealA, appealB}) + s.appealRepository.BulkUpsert(context.Background(), []*domain.Appeal{pendingAppeal, cancelledAppeal}) dummyApprovals := []*domain.Approval{ { @@ -175,20 +183,20 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { { Name: "test-approval-name-4", Index: 1, - AppealID: appealA.ID, + AppealID: pendingAppeal.ID, Status: "test-status-1", PolicyID: "test-policy-id", PolicyVersion: 1, - Appeal: appealA, + Appeal: pendingAppeal, }, { Name: "test-approval-name-5", Index: 1, - AppealID: appealB.ID, + AppealID: cancelledAppeal.ID, Status: "test-status-1", PolicyID: "test-policy-id", PolicyVersion: 1, - Appeal: appealB, + Appeal: cancelledAppeal, }, } @@ -213,12 +221,12 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { }, { ApprovalID: dummyApprovals[3].ID, - AppealID: appealA.ID, + AppealID: pendingAppeal.ID, Email: "approver3@email.com", }, { ApprovalID: dummyApprovals[4].ID, - AppealID: appealB.ID, + AppealID: cancelledAppeal.ID, Email: "approver3@email.com", }, } @@ -244,9 +252,37 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { s.Equal(dummyApprovals[0].ID, approvals[0].ID) }) + s.Run("should return approvals based on query search input", func() { + approvals, err := s.repository.ListApprovals(context.Background(), &domain.ListApprovalsFilter{ + Q: "abc-user", // expected to match account_id: "abc-user@example.com" + }) + + s.NoError(err) + s.Len(approvals, 1) + s.Equal(pendingAppeal.ID, approvals[0].AppealID) + }) + + s.Run("should return list of approvals based account types filter", func() { + approvals, err := s.repository.ListApprovals(context.Background(), &domain.ListApprovalsFilter{ + AccountTypes: []string{"x-account-type"}, // match 0 records + }) + + s.NoError(err) + s.Len(approvals, 0) + }) + + s.Run("should return list of approvals based resource types filter", func() { + approvals, err := s.repository.ListApprovals(context.Background(), &domain.ListApprovalsFilter{ + ResourceTypes: []string{"x-resource-type"}, // match 0 records + }) + + s.NoError(err) + s.Len(approvals, 0) + }) + s.Run("should return list of approvals where appeal status is canceled", func() { approvals, err := s.repository.ListApprovals(context.Background(), &domain.ListApprovalsFilter{ - AccountID: appealB.AccountID, + AccountID: cancelledAppeal.AccountID, CreatedBy: dummyApprover[3].Email, AppealStatuses: []string{domain.AppealStatusCanceled}, OrderBy: []string{"status", "updated_at:desc", "created_at"}, @@ -259,7 +295,7 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { s.Run("should return list of approvals where appeal status is pending", func() { approvals, err := s.repository.ListApprovals(context.Background(), &domain.ListApprovalsFilter{ - AccountID: appealA.AccountID, + AccountID: pendingAppeal.AccountID, CreatedBy: dummyApprover[3].Email, AppealStatuses: []string{domain.AppealStatusPending}, OrderBy: []string{"status", "updated_at:desc", "created_at"}, @@ -292,6 +328,86 @@ func (s *ApprovalRepositoryTestSuite) TestListApprovals() { }) } +func (s *ApprovalRepositoryTestSuite) TestListApprovals__Search() { + s.Run("should pass grouped condition properly and return result accordingly", func() { + dummyAppeals := []*domain.Appeal{ + { + ResourceID: s.dummyResource.ID, + PolicyID: s.dummyPolicy.ID, + PolicyVersion: s.dummyPolicy.Version, + AccountID: "user1@example.com", + AccountType: domain.DefaultAppealAccountType, + Role: "role_test", + Permissions: []string{"permission_test"}, + CreatedBy: "user1@example.com", + Status: domain.AppealStatusPending, + }, + { + ResourceID: s.dummyResource.ID, + PolicyID: s.dummyPolicy.ID, + PolicyVersion: s.dummyPolicy.Version, + AccountID: "user2@example.com", + AccountType: domain.DefaultAppealAccountType, + Role: "role_test", + Permissions: []string{"permission_test"}, + CreatedBy: "user2@example.com", + Status: domain.AppealStatusPending, + }, + } + err := s.appealRepository.BulkUpsert(context.Background(), dummyAppeals) + s.Require().NoError(err) + + dummyApprovals := []*domain.Approval{ + { + Name: "test-approval-name-1", + Index: 0, + AppealID: dummyAppeals[0].ID, + Status: domain.ApprovalStatusPending, + PolicyID: "test-policy-id", + PolicyVersion: 1, + Appeal: dummyAppeals[0], + }, + { + Name: "test-approval-name-1", + Index: 0, + AppealID: dummyAppeals[1].ID, + Status: domain.ApprovalStatusPending, + PolicyID: "test-policy-id", + PolicyVersion: 1, + Appeal: dummyAppeals[1], + }, + } + err = s.repository.BulkInsert(context.Background(), dummyApprovals) + s.Require().NoError(err) + + dummyApprover := []*domain.Approver{ + { + ApprovalID: dummyApprovals[0].ID, + AppealID: dummyAppeals[0].ID, + Email: "approver@email.com", + }, + { + ApprovalID: dummyApprovals[1].ID, + AppealID: dummyAppeals[1].ID, + Email: "approver2@email.com", + }, + } + for _, ap := range dummyApprover { + err = s.repository.AddApprover(context.Background(), ap) + s.Require().NoError(err) + } + + approvals, err := s.repository.ListApprovals(context.Background(), &domain.ListApprovalsFilter{ + CreatedBy: "approver@email.com", + Q: "role_test", + }) + + s.NoError(err) + s.Len(approvals, 1) + s.Equal(dummyApprovals[0].ID, approvals[0].ID) + }) +} + func (s *ApprovalRepositoryTestSuite) TestBulkInsert() { actor := "user@email.com" approvals := []*domain.Approval{ diff --git a/internal/store/postgres/grant_repository.go b/internal/store/postgres/grant_repository.go index 58478179..954f8bef 100644 --- a/internal/store/postgres/grant_repository.go +++ b/internal/store/postgres/grant_repository.go @@ -99,6 +99,15 @@ func (r *GrantRepository) List(ctx context.Context, filter domain.ListGrantsFilt return grants, nil } +func (r *GrantRepository) GetGrantsTotalCount(ctx context.Context, filter domain.ListGrantsFilter) (int64, error) { + db := r.store.db.WithContext(ctx) + db = applyGrantFilter(db, filter) + var count int64 + err := db.Model(&model.Grant{}).Count(&count).Error + + return count, err +} + func (r *GrantRepository) GetByID(ctx context.Context, id string) (*domain.Grant, error) { m := new(model.Grant) if err := r.store.Tx(ctx, func(tx *gorm.DB) error { @@ -244,3 +253,76 @@ func upsertResources(tx *gorm.DB, models []*model.Grant) error { return nil } + +func applyGrantFilter(db *gorm.DB, filter domain.ListGrantsFilter) *gorm.DB { + db = db.Joins("JOIN resources ON grants.resource_id = resources.id") + if filter.Q != "" { + // NOTE: avoid adding conditions before this grouped where clause. + // Otherwise, it will be wrapped in parentheses and the query will be invalid. + db = db.Where(db. + Where(`"grants"."account_id" LIKE ?`, fmt.Sprintf("%%%s%%", filter.Q)). + Or(`"grants"."role" LIKE ?`, fmt.Sprintf("%%%s%%", filter.Q)). + Or(`"resources"."urn" LIKE ?`, fmt.Sprintf("%%%s%%", filter.Q)), + ) + } + if filter.Size > 0 { + db = db.Limit(filter.Size) + } + if filter.Offset > 0 { + db = db.Offset(filter.Offset) + } + if filter.AccountIDs != nil { + db = db.Where(`"grants"."account_id" IN ?`, filter.AccountIDs) + } + if filter.AccountTypes != nil { + db = db.Where(`"grants"."account_type" IN ?`, filter.AccountTypes) + } + if filter.ResourceIDs != nil { + db = db.Where(`"grants"."resource_id" IN ?`, filter.ResourceIDs) + } + if filter.Statuses != nil { + db = db.Where(`"grants"."status" IN ?`, filter.Statuses) + } + if filter.Roles != nil { + db = db.Where(`"grants"."role" IN ?`, filter.Roles) + } + if filter.Permissions != nil { + db = db.Where(`"grants"."permissions" @> ?`, pq.StringArray(filter.Permissions)) + } + if filter.Owner != "" { + db = db.Where(`"grants"."owner" = ?`, filter.Owner) + } else if filter.CreatedBy != "" { + db = db.Where(`"grants"."owner" = ?`, filter.CreatedBy) + } + if filter.IsPermanent != nil { + db = db.Where(`"grants"."is_permanent" = ?`, *filter.IsPermanent) + } + if !filter.CreatedAtLte.IsZero() { + db = db.Where(`"grants"."created_at" <= ?`, filter.CreatedAtLte) + } + if filter.OrderBy != nil { + db = addOrderByClause(db, filter.OrderBy, addOrderByClauseOptions{ + statusColumnName: `"grants"."status"`, + statusesOrder: GrantStatusDefaultSort, + }) + } + if !filter.ExpirationDateLessThan.IsZero() { + db = db.Where(`"grants"."expiration_date" < ?`, filter.ExpirationDateLessThan) + } + if !filter.ExpirationDateGreaterThan.IsZero() { + db = db.Where(`"grants"."expiration_date" > ?`, filter.ExpirationDateGreaterThan) + } + if filter.ProviderTypes != nil { + db = db.Where(`"Resource"."provider_type" IN ?`, filter.ProviderTypes) + } + if filter.ProviderURNs != nil { + db = db.Where(`"Resource"."provider_urn" IN ?`, filter.ProviderURNs) + } + if filter.ResourceTypes != nil { + db = db.Where(`"Resource"."type" IN ?`, filter.ResourceTypes) + } + if filter.ResourceURNs != nil { + db = db.Where(`"Resource"."urn" IN ?`, filter.ResourceURNs) + } + return db +} diff --git a/internal/store/postgres/grant_repository_test.go b/internal/store/postgres/grant_repository_test.go index d6400848..1fc94aea 100644 --- a/internal/store/postgres/grant_repository_test.go +++ b/internal/store/postgres/grant_repository_test.go @@ -2,6 +2,7 @@ package postgres_test import ( "context" + "database/sql/driver" "testing" "time" @@ -119,6 +120,13 @@ func (s *GrantRepositoryTestSuite) TearDownSuite() { } } +func (s *GrantRepositoryTestSuite) TestGetGrantsTotalCount() { + s.Run("should return 0", func() { + _, actualError := s.repository.GetGrantsTotalCount(context.Background(), domain.ListGrantsFilter{}) + + s.Nil(actualError) + }) +} func (s *GrantRepositoryTestSuite) TestList() { expDate := time.Now() dummyGrants := []*domain.Grant{ @@ -179,6 +187,48 @@ func (s *GrantRepositoryTestSuite) TestList() { s.Error(err) s.Nil(grants) }) + s.Run("Should return an array size and offset of n on success", func() { + testCases := []struct { + filters domain.ListGrantsFilter + expectedArgs []driver.Value + expectedResult []*domain.Grant + }{ + { + filters: domain.ListGrantsFilter{ + Size: 1, + Offset: 0, + }, + expectedResult: []*domain.Grant{dummyGrants[0]}, + }, + { + filters: domain.ListGrantsFilter{ + Offset: 1, + }, + expectedResult: []*domain.Grant{dummyGrants[0]}, + }, + } + for _, tc := range testCases { + _, actualError := s.repository.List(context.Background(), tc.filters) + s.Nil(actualError) + } + + }) + + s.Run("Should return an array that matches q", func() { + grants, err := s.repository.List(context.Background(), domain.ListGrantsFilter{ + Q: "123", + }) + + s.NoError(err) + s.Len(grants, 0) + }) + s.Run("Should return an array of grants that matches account type", func() { + grants, err := s.repository.List(context.Background(), domain.ListGrantsFilter{ + AccountTypes: []string{"x-account-type"}, + }) + s.NoError(err) + s.Len(grants, 0) + }) } func (s *GrantRepositoryTestSuite) TestGetByID() { diff --git a/internal/store/postgres/migrations/000018_add-indexes-for-approvals-filter.down.sql b/internal/store/postgres/migrations/000018_add-indexes-for-approvals-filter.down.sql new file mode 100644 index 00000000..15786358 --- /dev/null +++ b/internal/store/postgres/migrations/000018_add-indexes-for-approvals-filter.down.sql @@ -0,0 +1,5 @@ +DROP INDEX IF EXISTS idx_appeals_account_id_at_null; +DROP INDEX IF EXISTS idx_appeals_account_type_at_null; +DROP INDEX IF EXISTS idx_appeals_role_at_null; +DROP INDEX IF EXISTS idx_resources_type_at_null; +DROP INDEX IF EXISTS idx_resources_urn_at_null; \ No newline at end of file diff --git a/internal/store/postgres/migrations/000018_add-indexes-for-approvals-filter.up.sql b/internal/store/postgres/migrations/000018_add-indexes-for-approvals-filter.up.sql new file mode 100644 index 00000000..9ee57ecc --- /dev/null +++ b/internal/store/postgres/migrations/000018_add-indexes-for-approvals-filter.up.sql @@ -0,0 +1,19 @@ +CREATE INDEX if NOT EXISTS idx_appeals_account_id_at_null ON appeals (account_id, deleted_at) +WHERE + deleted_at IS NULL; + +CREATE INDEX if NOT EXISTS idx_appeals_account_type_at_null ON appeals (account_type, deleted_at) +WHERE + deleted_at IS NULL; + +CREATE INDEX if NOT EXISTS idx_appeals_role_at_null ON appeals (role, deleted_at) +WHERE + deleted_at IS NULL; + +CREATE INDEX if NOT EXISTS idx_resources_type_at_null ON resources (type, deleted_at) +WHERE + deleted_at IS NULL; + +CREATE INDEX if NOT EXISTS idx_resources_urn_at_null ON resources (urn, deleted_at) +WHERE + deleted_at IS NULL; \ No newline at end of file diff --git a/jobs/grant_dormancy_check.go b/jobs/grant_dormancy_check.go new file mode 100644 index 00000000..029fcf99 --- /dev/null +++ b/jobs/grant_dormancy_check.go @@ -0,0 +1,50 @@ +package jobs + +import ( + "context" + "fmt" + "time" + + "github.com/raystack/guardian/domain" +) + +type GrantDormancyCheckConfig struct { + DryRun bool `mapstructure:"dry_run"` + Period string `mapstructure:"period"` + RetainGrantFor string `mapstructure:"retain_grant_for"` +} + +func (h *handler) GrantDormancyCheck(ctx context.Context, c Config) error { + var cfg GrantDormancyCheckConfig + if err := c.Decode(&cfg); err != nil { + return fmt.Errorf("invalid config for %s job: %w", TypeRevokeGrantsByUserCriteria, err) + } + + period, err := time.ParseDuration(cfg.Period) + if err != nil { + return fmt.Errorf("invalid period duration: %w", err) + } + retainGrantFor, err := time.ParseDuration(cfg.RetainGrantFor) + if err != nil { + return fmt.Errorf("invalid retain grant for duration: %w", err) + } + + providers, err := h.providerService.Find(ctx) + if err != nil { + return fmt.Errorf("listing providers: %w", err) + } + + for _, p := range providers { + h.logger.Info(fmt.Sprintf("checking dormancy for grants under provider: %q", p.URN)) + if err := h.grantService.DormancyCheck(ctx, domain.DormancyCheckCriteria{ + ProviderID: p.ID, + Period: period, + RetainDuration: retainGrantFor, + DryRun: cfg.DryRun, + }); err != nil { + h.logger.Error(fmt.Sprintf("failed to check dormancy for provider %q", p.URN), "error", err) + } + } + + return nil +} diff --git a/jobs/handler.go b/jobs/handler.go index acb2d699..7ff86645 100644 --- a/jobs/handler.go +++ b/jobs/handler.go @@ -10,17 +10,19 @@ import ( "github.com/raystack/salt/log" ) -//go:generate mockery --name=grantService --exported +//go:generate mockery --name=grantService --exported --with-expecter type grantService interface { List(context.Context, domain.ListGrantsFilter) ([]domain.Grant, error) Revoke(ctx context.Context, id, actor, reason string, opts ...grant.Option) (*domain.Grant, error) BulkRevoke(ctx context.Context, filter domain.RevokeGrantsFilter, actor, reason string) ([]*domain.Grant, error) Update(context.Context, *domain.Grant) error + DormancyCheck(context.Context, domain.DormancyCheckCriteria) error } //go:generate mockery --name=providerService --exported type providerService interface { FetchResources(context.Context) error + Find(context.Context) ([]*domain.Provider, error) } type crypto interface { diff --git a/jobs/jobs.go b/jobs/jobs.go index 25b6fd6a..e3e014b4 100644 --- a/jobs/jobs.go +++ b/jobs/jobs.go @@ -9,6 +9,7 @@ const ( TypeExpiringGrantNotification Type = "expiring_grant_notification" TypeRevokeExpiredGrants Type = "revoke_expired_grants" TypeRevokeGrantsByUserCriteria Type = "revoke_grants_by_user_criteria" + TypeGrantDormancyCheck Type = "grant_dormancy_check" // Deprecated: use RevokeExpiredGrants instead TypeRevokeExpiredAccess Type = "revoke_expired_access" diff --git a/jobs/mocks/grantService.go b/jobs/mocks/grantService.go index a5e12387..0f8aed24 100644 --- a/jobs/mocks/grantService.go +++ b/jobs/mocks/grantService.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -16,6 +16,14 @@ type GrantService struct { mock.Mock } +type GrantService_Expecter struct { + mock *mock.Mock +} + +func (_m *GrantService) EXPECT() *GrantService_Expecter { + return &GrantService_Expecter{mock: &_m.Mock} +} + // BulkRevoke provides a mock function with given fields: ctx, filter, actor, reason func (_m *GrantService) BulkRevoke(ctx context.Context, filter domain.RevokeGrantsFilter, actor string, reason string) ([]*domain.Grant, error) { ret := _m.Called(ctx, filter, actor, reason) @@ -42,6 +50,80 @@ func (_m *GrantService) BulkRevoke(ctx context.Context, filter domain.RevokeGran return r0, r1 } +// GrantService_BulkRevoke_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BulkRevoke' +type GrantService_BulkRevoke_Call struct { + *mock.Call +} + +// BulkRevoke is a helper method to define mock.On call +// - ctx context.Context +// - filter domain.RevokeGrantsFilter +// - actor string +// - reason string +func (_e *GrantService_Expecter) BulkRevoke(ctx interface{}, filter interface{}, actor interface{}, reason interface{}) *GrantService_BulkRevoke_Call { + return &GrantService_BulkRevoke_Call{Call: _e.mock.On("BulkRevoke", ctx, filter, actor, reason)} +} + +func (_c *GrantService_BulkRevoke_Call) Run(run func(ctx context.Context, filter domain.RevokeGrantsFilter, actor string, reason string)) *GrantService_BulkRevoke_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.RevokeGrantsFilter), args[2].(string), args[3].(string)) + }) + return _c +} + +func (_c *GrantService_BulkRevoke_Call) Return(_a0 []*domain.Grant, _a1 error) *GrantService_BulkRevoke_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GrantService_BulkRevoke_Call) RunAndReturn(run func(context.Context, domain.RevokeGrantsFilter, string, string) ([]*domain.Grant, error)) *GrantService_BulkRevoke_Call { + _c.Call.Return(run) + return _c +} + +// DormancyCheck provides a mock function with given fields: _a0, _a1 +func (_m *GrantService) DormancyCheck(_a0 context.Context, _a1 domain.DormancyCheckCriteria) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, domain.DormancyCheckCriteria) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GrantService_DormancyCheck_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DormancyCheck' +type GrantService_DormancyCheck_Call struct { + *mock.Call +} + +// DormancyCheck is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.DormancyCheckCriteria +func (_e *GrantService_Expecter) DormancyCheck(_a0 interface{}, _a1 interface{}) *GrantService_DormancyCheck_Call { + return &GrantService_DormancyCheck_Call{Call: _e.mock.On("DormancyCheck", _a0, _a1)} +} + +func (_c *GrantService_DormancyCheck_Call) Run(run func(_a0 context.Context, _a1 domain.DormancyCheckCriteria)) *GrantService_DormancyCheck_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.DormancyCheckCriteria)) + }) + return _c +} + +func (_c *GrantService_DormancyCheck_Call) Return(_a0 error) *GrantService_DormancyCheck_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GrantService_DormancyCheck_Call) RunAndReturn(run func(context.Context, domain.DormancyCheckCriteria) error) *GrantService_DormancyCheck_Call { + _c.Call.Return(run) + return _c +} + // List provides a mock function with given fields: _a0, _a1 func (_m *GrantService) List(_a0 context.Context, _a1 domain.ListGrantsFilter) ([]domain.Grant, error) { ret := _m.Called(_a0, _a1) @@ -68,6 +150,35 @@ func (_m *GrantService) List(_a0 context.Context, _a1 domain.ListGrantsFilter) ( return r0, r1 } +// GrantService_List_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'List' +type GrantService_List_Call struct { + *mock.Call +} + +// List is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 domain.ListGrantsFilter +func (_e *GrantService_Expecter) List(_a0 interface{}, _a1 interface{}) *GrantService_List_Call { + return &GrantService_List_Call{Call: _e.mock.On("List", _a0, _a1)} +} + +func (_c *GrantService_List_Call) Run(run func(_a0 context.Context, _a1 domain.ListGrantsFilter)) *GrantService_List_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(domain.ListGrantsFilter)) + }) + return _c +} + +func (_c *GrantService_List_Call) Return(_a0 []domain.Grant, _a1 error) *GrantService_List_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GrantService_List_Call) RunAndReturn(run func(context.Context, domain.ListGrantsFilter) ([]domain.Grant, error)) *GrantService_List_Call { + _c.Call.Return(run) + return _c +} + // Revoke provides a mock function with given fields: ctx, id, actor, reason, opts func (_m *GrantService) Revoke(ctx context.Context, id string, actor string, reason string, opts ...grant.Option) (*domain.Grant, error) { _va := make([]interface{}, len(opts)) @@ -101,6 +212,45 @@ func (_m *GrantService) Revoke(ctx context.Context, id string, actor string, rea return r0, r1 } +// GrantService_Revoke_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Revoke' +type GrantService_Revoke_Call struct { + *mock.Call +} + +// Revoke is a helper method to define mock.On call +// - ctx context.Context +// - id string +// - actor string +// - reason string +// - opts ...grant.Option +func (_e *GrantService_Expecter) Revoke(ctx interface{}, id interface{}, actor interface{}, reason interface{}, opts ...interface{}) *GrantService_Revoke_Call { + return &GrantService_Revoke_Call{Call: _e.mock.On("Revoke", + append([]interface{}{ctx, id, actor, reason}, opts...)...)} +} + +func (_c *GrantService_Revoke_Call) Run(run func(ctx context.Context, id string, actor string, reason string, opts ...grant.Option)) *GrantService_Revoke_Call { + _c.Call.Run(func(args mock.Arguments) { + variadicArgs := make([]grant.Option, len(args)-4) + for i, a := range args[4:] { + if a != nil { + variadicArgs[i] = a.(grant.Option) + } + } + run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string), variadicArgs...) + }) + return _c +} + +func (_c *GrantService_Revoke_Call) Return(_a0 *domain.Grant, _a1 error) *GrantService_Revoke_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GrantService_Revoke_Call) RunAndReturn(run func(context.Context, string, string, string, ...grant.Option) (*domain.Grant, error)) *GrantService_Revoke_Call { + _c.Call.Return(run) + return _c +} + // Update provides a mock function with given fields: _a0, _a1 func (_m *GrantService) Update(_a0 context.Context, _a1 *domain.Grant) error { ret := _m.Called(_a0, _a1) @@ -115,6 +265,35 @@ func (_m *GrantService) Update(_a0 context.Context, _a1 *domain.Grant) error { return r0 } +// GrantService_Update_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Update' +type GrantService_Update_Call struct { + *mock.Call +} + +// Update is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 *domain.Grant +func (_e *GrantService_Expecter) Update(_a0 interface{}, _a1 interface{}) *GrantService_Update_Call { + return &GrantService_Update_Call{Call: _e.mock.On("Update", _a0, _a1)} +} + +func (_c *GrantService_Update_Call) Run(run func(_a0 context.Context, _a1 *domain.Grant)) *GrantService_Update_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*domain.Grant)) + }) + return _c +} + +func (_c *GrantService_Update_Call) Return(_a0 error) *GrantService_Update_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GrantService_Update_Call) RunAndReturn(run func(context.Context, *domain.Grant) error) *GrantService_Update_Call { + _c.Call.Return(run) + return _c +} + // NewGrantService creates a new instance of GrantService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewGrantService(t interface { diff --git a/jobs/mocks/providerService.go b/jobs/mocks/providerService.go index 825c6b90..c90564a1 100644 --- a/jobs/mocks/providerService.go +++ b/jobs/mocks/providerService.go @@ -1,10 +1,12 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks import ( context "context" + domain "github.com/raystack/guardian/domain" + mock "github.com/stretchr/testify/mock" ) @@ -27,6 +29,32 @@ func (_m *ProviderService) FetchResources(_a0 context.Context) error { return r0 } +// Find provides a mock function with given fields: _a0 +func (_m *ProviderService) Find(_a0 context.Context) ([]*domain.Provider, error) { + ret := _m.Called(_a0) + + var r0 []*domain.Provider + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*domain.Provider, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) []*domain.Provider); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*domain.Provider) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewProviderService creates a new instance of ProviderService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewProviderService(t interface { diff --git a/jobs/revoke_grants_by_user_criteria.go b/jobs/revoke_grants_by_user_criteria.go index 391000c2..a6d8b1bb 100644 --- a/jobs/revoke_grants_by_user_criteria.go +++ b/jobs/revoke_grants_by_user_criteria.go @@ -18,6 +18,7 @@ type RevokeGrantsByUserCriteriaConfig struct { func (h *handler) RevokeGrantsByUserCriteria(ctx context.Context, c Config) error { h.logger.Info(fmt.Sprintf("starting %q job", TypeRevokeGrantsByUserCriteria)) + defer h.logger.Info(fmt.Sprintf("finished %q job", TypeRevokeGrantsByUserCriteria)) var cfg RevokeGrantsByUserCriteriaConfig if err := c.Decode(&cfg); err != nil { @@ -34,12 +35,19 @@ func (h *handler) RevokeGrantsByUserCriteria(ctx context.Context, c Config) erro return fmt.Errorf("initializing IAM client: %w", err) } + h.logger.Info("getting active grants") activeGrants, err := h.grantService.List(ctx, domain.ListGrantsFilter{ Statuses: []string{string(domain.GrantStatusActive)}, }) if err != nil { return fmt.Errorf("listing active grants: %w", err) } + if len(activeGrants) == 0 { + h.logger.Info("no active grants found") + return nil + } + grantIDs := getGrantIDs(activeGrants) + h.logger.Info(fmt.Sprintf("found %d active grants", len(activeGrants)), "grant_ids", grantIDs) grantsForUser := map[string][]*domain.Grant{} // map[account_id][]grant grantsOwnedByUser := map[string][]*domain.Grant{} // map[owner][]grant @@ -54,52 +62,66 @@ func (h *handler) RevokeGrantsByUserCriteria(ctx context.Context, c Config) erro grantsOwnedByUser[g.Owner] = append(grantsOwnedByUser[g.AccountID], &g) } } + h.logger.Info(fmt.Sprintf("found %d unique users", len(uniqueUserEmails)), "emails", uniqueUserEmails) + counter := 0 for email := range uniqueUserEmails { + counter++ + fmt.Println("") + h.logger.Info(fmt.Sprintf("processing user %d/%d", counter, len(uniqueUserEmails)), "email", email) + + h.logger.Info("fetching user details", "email", email) userDetails, err := fetchUserDetails(iamClient, email) if err != nil { - h.logger.Debug("fetching user details", "email", email, "error", err) + h.logger.Error("failed to fetch user details", "email", email, "error", err) continue } + h.logger.Info("checking criteria against user", "email", email, "criteria", cfg.UserCriteria.String()) if criteriaSatisfied, err := evaluateCriteria(cfg.UserCriteria, userDetails); err != nil { - h.logger.Error("checking criteria against user", "email", email, "criteria", cfg.UserCriteria.String(), "error", err) + h.logger.Error("failed to check criteria", "email", email, "error", err) } else if !criteriaSatisfied { - h.logger.Debug("criteria not satisfied", "email", email) + h.logger.Info("criteria not satisfied", "email", email) continue } - // revoking grants with account_id == email - if revokedGrants, err := h.revokeUserGrants(ctx, email); err != nil { - h.logger.Error("revoking user grants", "account_id", email, "error", err) - } else { - revokedGrantIDs := []string{} - for _, g := range revokedGrants { - revokedGrantIDs = append(revokedGrantIDs, g.ID) - } - h.logger.Info("grant revocation successful", "count", len(revokedGrantIDs), "grant_ids", revokedGrantIDs) - } - - // reassigning grants owned by the user to the new owner + h.logger.Info("evaluating new owner", "email", email, "expression", cfg.ReassignOwnershipTo.String()) newOwner, err := h.evaluateNewOwner(cfg.ReassignOwnershipTo, userDetails) if err != nil { h.logger.Error("evaluating new owner", "email", email, "error", err) continue } - successfulGrants, failedGrants := h.reassignGrantsOwnership(ctx, grantsOwnedByUser[email], newOwner) - if len(successfulGrants) > 0 { - successfulGrantIDs := []string{} - for _, g := range successfulGrants { - successfulGrantIDs = append(successfulGrantIDs, g.ID) + h.logger.Info(fmt.Sprintf("evaluated new owner: %q", newOwner), "email", email) + + if !cfg.DryRun { + // revoking grants with account_id == email + h.logger.Info("revoking user active grants", "email", email) + if revokedGrants, err := h.revokeUserGrants(ctx, email); err != nil { + h.logger.Error("failed to reovke grants", "email", email, "error", err) + } else { + revokedGrantIDs := []string{} + for _, g := range revokedGrants { + revokedGrantIDs = append(revokedGrantIDs, g.ID) + } + h.logger.Info("grant revocation successful", "count", len(revokedGrantIDs), "grant_ids", revokedGrantIDs) } - h.logger.Info("grant ownership reassignment successful", "count", len(successfulGrantIDs), "grant_ids", successfulGrantIDs) - } - if len(failedGrants) > 0 { - failedGrantIDs := []string{} - for _, g := range failedGrants { - failedGrantIDs = append(failedGrantIDs, g.ID) + + // reassigning grants owned by the user to the new owner + successfulGrants, failedGrants := h.reassignGrantsOwnership(ctx, grantsOwnedByUser[email], newOwner) + if len(successfulGrants) > 0 { + successfulGrantIDs := []string{} + for _, g := range successfulGrants { + successfulGrantIDs = append(successfulGrantIDs, g.ID) + } + h.logger.Info("grant ownership reassignment successful", "count", len(successfulGrantIDs), "grant_ids", successfulGrantIDs) + } + if len(failedGrants) > 0 { + failedGrantIDs := []string{} + for _, g := range failedGrants { + failedGrantIDs = append(failedGrantIDs, g.ID) + } + h.logger.Error("grant ownership reassignment failed", "count", len(failedGrantIDs), "grant_ids", failedGrantIDs) } - h.logger.Error("grant ownership reassignment failed", "count", len(failedGrantIDs), "grant_ids", failedGrantIDs) } } @@ -181,3 +203,11 @@ func (h *handler) reassignGrantsOwnership(ctx context.Context, ownedGrants []*do return successfulGrants, failedGrants } + +func getGrantIDs(grants []domain.Grant) []string { + var ids []string + for _, g := range grants { + ids = append(ids, g.ID) + } + return ids +} diff --git a/plugins/identities/http.go b/plugins/identities/http.go index 171d9315..6298840a 100644 --- a/plugins/identities/http.go +++ b/plugins/identities/http.go @@ -2,6 +2,7 @@ package identities import ( "context" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -36,8 +37,11 @@ type HTTPAuthConfig struct { // google_idtoken Audience string `mapstructure:"audience,omitempty" json:"audience,omitempty" yaml:"audience,omitempty" validate:"required_if=Type google_idtoken"` - // TODO: allow base64 encoded credentials - CredentialsJSON string `mapstructure:"credentials_json,omitempty" json:"credentials_json,omitempty" yaml:"credentials_json,omitempty" validate:"required_if=Type google_idtoken"` + // CredentialsJSON accept a JSON stringified credentials + // Deprecated: CredentialsJSON is deprecated, use CredentialsJSONBase64 instead + CredentialsJSON string `mapstructure:"credentials_json,omitempty" json:"credentials_json,omitempty" yaml:"credentials_json,omitempty"` + // CredentialsJSONBase64 accept a base64 encoded JSON stringified credentials + CredentialsJSONBase64 string `mapstructure:"credentials_json_base64,omitempty" json:"credentials_json_base64,omitempty" yaml:"credentials_json_base64,omitempty"` } // HTTPClientConfig is the configuration required by iam.Client @@ -52,7 +56,30 @@ type HTTPClientConfig struct { } func (c *HTTPClientConfig) Validate() error { - return c.validator.Struct(c) + if err := c.validator.Struct(c); err != nil { + return err + } + + if c.Auth.Type == "google_idtoken" { + switch { + case c.Auth.CredentialsJSONBase64 != "": + v, err := base64.StdEncoding.DecodeString(c.Auth.CredentialsJSONBase64) + if err != nil { + return fmt.Errorf("invalid base64 value on credentials_json_base64: %w", err) + } + if !isValidJSON(string(v)) { + return fmt.Errorf("invalid json value on credentials_json_base64") + } + case c.Auth.CredentialsJSON != "": + if !isValidJSON(c.Auth.CredentialsJSON) { + return fmt.Errorf("invalid json value on credentials_json") + } + default: + return fmt.Errorf("missing credentials for google_idtoken auth") + } + } + + return nil } func (c *HTTPClientConfig) Encrypt() error { @@ -88,6 +115,13 @@ func (c *HTTPClientConfig) Encrypt() error { } c.Auth.CredentialsJSON = encryptedValue } + if c.Auth.CredentialsJSONBase64 != "" { + encryptedValue, err := c.crypto.Encrypt(c.Auth.CredentialsJSONBase64) + if err != nil { + return err + } + c.Auth.CredentialsJSONBase64 = encryptedValue + } } return nil @@ -126,6 +160,13 @@ func (c *HTTPClientConfig) Decrypt() error { } c.Auth.CredentialsJSON = decryptedValue } + if c.Auth.CredentialsJSONBase64 != "" { + decryptedValue, err := c.crypto.Decrypt(c.Auth.CredentialsJSONBase64) + if err != nil { + return err + } + c.Auth.CredentialsJSONBase64 = decryptedValue + } } return nil @@ -150,9 +191,23 @@ func NewHTTPClient(config *HTTPClientConfig) (*HTTPClient, error) { httpClient = http.DefaultClient } - if config.Auth != nil && config.Auth.Type == "google_idtoken" { + if config.Auth.Type == "google_idtoken" { + var creds []byte + switch { + case config.Auth.CredentialsJSONBase64 != "": + v, err := base64.StdEncoding.DecodeString(config.Auth.CredentialsJSONBase64) + if err != nil { + return nil, fmt.Errorf("decoding credentials_json_base64: %w", err) + } + creds = v + case config.Auth.CredentialsJSON != "": + creds = []byte(config.Auth.CredentialsJSON) + default: + return nil, fmt.Errorf("missing credentials for google_idtoken auth") + } + ctx := context.Background() - ts, err := idtoken.NewTokenSource(ctx, config.Auth.Audience, idtoken.WithCredentialsJSON([]byte(config.Auth.CredentialsJSON))) + ts, err := idtoken.NewTokenSource(ctx, config.Auth.Audience, idtoken.WithCredentialsJSON(creds)) if err != nil { return nil, err } @@ -236,3 +291,8 @@ func (c *HTTPClient) setAuth(req *http.Request) { } } } + +func isValidJSON(s string) bool { + var v interface{} + return json.Unmarshal([]byte(s), &v) == nil +} diff --git a/plugins/notifiers/slack/templates/UnusedGrant.json b/plugins/notifiers/slack/templates/UnusedGrant.json new file mode 100644 index 00000000..3c7d497c --- /dev/null +++ b/plugins/notifiers/slack/templates/UnusedGrant.json @@ -0,0 +1,9 @@ +[ + { + "type":"section", + "text":{ + "type":"mrkdwn", + "text":"We have advanced the expiration date for the following grants due to inactivity since `{{.start_date}}`:{{ range .dormant_grants }}\n>*ID*: `{{.id}}`\n>*Account ID*: `{{.account_id}}`\n>*Resource*: `{{.resource.urn}}` ({{.resource.provider_type}} {{.resource.type}})\n>*Role*: `{{.role}}`\n>*Expiration Date* (new): `{{.expiration_date}}`\n{{end}}" + } + } + ] \ No newline at end of file diff --git a/plugins/providers/bigquery/activity.go b/plugins/providers/bigquery/activity.go index ecacfd03..5f092a02 100644 --- a/plugins/providers/bigquery/activity.go +++ b/plugins/providers/bigquery/activity.go @@ -8,10 +8,8 @@ import ( "strings" "time" - "cloud.google.com/go/logging" - "cloud.google.com/go/logging/logadmin" "github.com/raystack/guardian/domain" - "google.golang.org/api/iterator" + "google.golang.org/api/logging/v2" "google.golang.org/api/option" "google.golang.org/genproto/googleapis/cloud/audit" ) @@ -21,6 +19,10 @@ var ( ErrEmptyActivityPayload = errors.New("couldn't get payload from log entry") ) +const ( + PrivateLogViewerPermission = "logging.privateLogEntries.list" +) + type auditLog struct { *audit.AuditLog } @@ -51,22 +53,31 @@ func (a auditLog) GetResource(p domain.Provider) *domain.Resource { } type Activity struct { - *logging.Entry + *logging.LogEntry } func (a Activity) getAuditLog() (*auditLog, error) { - l, ok := a.Payload.(*audit.AuditLog) - if !ok { - return nil, fmt.Errorf("%w: %T", ErrInvalidActivityPayloadType, a.Payload) + payload, err := a.ProtoPayload.MarshalJSON() + if err != nil { + return nil, fmt.Errorf("marshalling proto payload: %w", err) + } + var al audit.AuditLog + if err := json.Unmarshal(payload, &al); err != nil { + return nil, fmt.Errorf("unmarshalling proto payload: %w", err) } - return &auditLog{l}, nil + return &auditLog{&al}, nil } func (a Activity) ToDomainActivity(p domain.Provider) (*domain.Activity, error) { + t, err := time.Parse(time.RFC3339Nano, a.Timestamp) + if err != nil { + return nil, fmt.Errorf("parsing timestamp: %w", err) + } + activity := &domain.Activity{ ProviderID: p.ID, - Timestamp: a.Timestamp, - ProviderActivityID: a.InsertID, + Timestamp: t, + ProviderActivityID: a.InsertId, } al, err := a.getAuditLog() @@ -86,7 +97,7 @@ func (a Activity) ToDomainActivity(p domain.Provider) (*domain.Activity, error) loggingEntryMetadata := map[string]interface{}{} loggingEntryMap := map[string]interface{}{ "payload": al, - "insert_id": a.InsertID, + "insert_id": a.InsertId, "severity": a.Severity, "resource": a.Resource, "labels": a.Labels, @@ -94,7 +105,7 @@ func (a Activity) ToDomainActivity(p domain.Provider) (*domain.Activity, error) "trace": a.Trace, "source_location": a.SourceLocation, "timestamp": a.Timestamp, - "span_id": a.SpanID, + "span_id": a.SpanId, "trace_sampled": a.TraceSampled, } if jsonData, err := json.Marshal(loggingEntryMap); err != nil { @@ -118,7 +129,8 @@ func (a Activity) ToDomainActivity(p domain.Provider) (*domain.Activity, error) } type cloudLoggingClient struct { - client *logadmin.Client + client *logging.Service + projectID string } func NewCloudLoggingClient(ctx context.Context, projectID string, credentialsJSON []byte) (*cloudLoggingClient, error) { @@ -126,13 +138,14 @@ func NewCloudLoggingClient(ctx context.Context, projectID string, credentialsJSO if credentialsJSON != nil { options = append(options, option.WithCredentialsJSON(credentialsJSON)) } - client, err := logadmin.NewClient(ctx, projectID, options...) + service, err := logging.NewService(ctx, options...) if err != nil { return nil, err } return &cloudLoggingClient{ - client: client, + client: service, + projectID: projectID, }, nil } @@ -158,80 +171,33 @@ func (r bqResource) fullURN() string { return s } -type ImportActivitiesFilter struct { - domain.ImportActivitiesFilter - Types []string - Authorizations []string - Limit int -} - -type bqFilter ImportActivitiesFilter - -func (f bqFilter) String() string { - criteria := []string{ - `protoPayload.serviceName="bigquery.googleapis.com"`, - `resource.type="bigquery_dataset"`, // exclude logs for bigquery jobs ("bigquery_project") - } - - if len(f.AccountIDs) > 0 { - criteria = append(criteria, - fmt.Sprintf(`protoPayload.authenticationInfo.principalEmail=("%s")`, strings.Join(f.AccountIDs, `" OR "`)), - ) - } - - resources := f.GetResources() - if len(resources) > 0 { - resourceNames := []string{} - for _, r := range resources { - resourceNames = append(resourceNames, (*bqResource)(r).fullURN()) - } - criteria = append(criteria, fmt.Sprintf(`protoPayload.resourceName:("%s")`, strings.Join(resourceNames, `" OR "`))) - // uses ":" (has/contains) operator instead of "=" (equals) operator for resource name so that the result will also - // include activities on tables under the specified dataset (e.g. "projects/xxx/datasets/yyy" will also include - // activities on "projects/xxx/datasets/yyy/tables/zzz") - } - if len(f.Types) > 0 { - criteria = append(criteria, fmt.Sprintf(`protoPayload.methodName=("%s")`, strings.Join(f.Types, `" OR "`))) - } - // TODO: authorizations - if f.TimestampGte != nil { - criteria = append(criteria, fmt.Sprintf(`timestamp>="%s"`, f.TimestampGte.Format(time.RFC3339))) - } - if f.TimestampLte != nil { - criteria = append(criteria, fmt.Sprintf(`timestamp<="%s"`, f.TimestampLte.Format(time.RFC3339))) - } - - return strings.Join(criteria, " AND ") -} - -func (c *cloudLoggingClient) ListLogEntries(ctx context.Context, filter ImportActivitiesFilter) ([]*Activity, error) { +func (c *cloudLoggingClient) ListLogEntries(ctx context.Context, filter string, limit int) ([]*Activity, error) { var entries []*Activity - options := []logadmin.EntriesOption{logadmin.Filter(bqFilter(filter).String())} - if filter.Limit > 0 { - options = append(options, logadmin.NewestFirst()) + req := &logging.ListLogEntriesRequest{ + Filter: filter, + ResourceNames: []string{`projects/` + c.projectID}, + } + if limit > 0 { + req.OrderBy = "timestamp desc" } - it := c.client.Entries(ctx, options...) - for { - if filter.Limit > 0 && len(entries) >= filter.Limit { - break - } - e, err := it.Next() - if err != nil { - if err == iterator.Done { - break + errLimitReached := errors.New("limit reached") + if err := c.client.Entries.List(req).Pages(ctx, func(page *logging.ListLogEntriesResponse) error { + for _, e := range page.Entries { + if limit != 0 && len(entries) >= limit { + return errLimitReached } - return nil, fmt.Errorf("iterating over cloud logging entries: %w", err) - } - if e != nil { entries = append(entries, &Activity{e}) } + return nil + }); err != nil && err != errLimitReached { + return nil, err } return entries, nil } -func (c *cloudLoggingClient) Close() error { - return c.client.Close() +func (c *cloudLoggingClient) GetLogBucket(ctx context.Context, name string) (*logging.LogBucket, error) { + return c.client.Projects.Locations.Buckets.Get(name).Context(ctx).Do() } diff --git a/plugins/providers/bigquery/activity_test.go b/plugins/providers/bigquery/activity_test.go index f9569990..c3f46f5c 100644 --- a/plugins/providers/bigquery/activity_test.go +++ b/plugins/providers/bigquery/activity_test.go @@ -1,14 +1,16 @@ package bigquery_test import ( + "encoding/json" "testing" "time" - "cloud.google.com/go/logging" "github.com/raystack/guardian/domain" "github.com/raystack/guardian/plugins/providers/bigquery" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "google.golang.org/api/googleapi" + "google.golang.org/api/logging/v2" "google.golang.org/genproto/googleapis/cloud/audit" ) @@ -19,28 +21,30 @@ func TestActivity_ToProviderActivity(t *testing.T) { Type: "bigquery", URN: "dummy-provider-urn", } - a := bigquery.Activity{ - &logging.Entry{ - InsertID: "dummy-insert-id", - Timestamp: now, - Payload: &audit.AuditLog{ - MethodName: "test-method-name", - AuthenticationInfo: &audit.AuthenticationInfo{ - PrincipalEmail: "test-principal-email", - }, - AuthorizationInfo: []*audit.AuthorizationInfo{ - { - Permission: "test-permission", - }, - }, - ResourceName: "projects/xxx/datasets/yyy/tables/zzz", + auditLog := &audit.AuditLog{ + MethodName: "test-method-name", + AuthenticationInfo: &audit.AuthenticationInfo{ + PrincipalEmail: "test-principal-email", + }, + AuthorizationInfo: []*audit.AuthorizationInfo{ + { + Permission: "test-permission", }, }, + ResourceName: "projects/xxx/datasets/yyy/tables/zzz", + } + auditLogBytes, err := json.Marshal(auditLog) + if err != nil { + require.NoError(t, err) + } + a := bigquery.Activity{ + &logging.LogEntry{ + InsertId: "dummy-insert-id", + Timestamp: now.Format(time.RFC3339Nano), + ProtoPayload: googleapi.RawMessage(auditLogBytes), + }, } - timestampStr, err := a.Timestamp.MarshalJSON() - require.NoError(t, err) - timestampStr = timestampStr[1 : len(timestampStr)-1] // trim quotes expectedMetadata := map[string]interface{}{ "logging_entry": map[string]interface{}{ "payload": map[string]interface{}{ @@ -55,23 +59,26 @@ func TestActivity_ToProviderActivity(t *testing.T) { }, "resource_name": "projects/xxx/datasets/yyy/tables/zzz", }, - "insert_id": a.InsertID, - "severity": float64(0), + "insert_id": a.InsertId, + "severity": "", "resource": nil, "labels": nil, "operation": nil, "trace": "", "source_location": nil, - "timestamp": string(timestampStr), + "timestamp": a.Timestamp, "span_id": "", "trace_sampled": false, }, } + expectedTimestamp, err := time.Parse(time.RFC3339Nano, a.Timestamp) + require.NoError(t, err) + expectedActivity := &domain.Activity{ ProviderID: dummyProvider.ID, ProviderActivityID: "dummy-insert-id", - Timestamp: a.Timestamp, + Timestamp: expectedTimestamp, Type: "test-method-name", AccountID: "test-principal-email", AccountType: "user", diff --git a/plugins/providers/bigquery/client.go b/plugins/providers/bigquery/client.go index ae10259c..8e921231 100644 --- a/plugins/providers/bigquery/client.go +++ b/plugins/providers/bigquery/client.go @@ -9,6 +9,7 @@ import ( bq "cloud.google.com/go/bigquery" "github.com/raystack/guardian/domain" bqApi "google.golang.org/api/bigquery/v2" + "google.golang.org/api/cloudresourcemanager/v1" "google.golang.org/api/iam/v1" "google.golang.org/api/iterator" "google.golang.org/api/option" @@ -19,6 +20,7 @@ type bigQueryClient struct { client *bq.Client iamService *iam.Service apiClient *bqApi.Service + crmService *cloudresourcemanager.Service } func NewBigQueryClient(projectID string, opts ...option.ClientOption) (*bigQueryClient, error) { @@ -38,11 +40,17 @@ func NewBigQueryClient(projectID string, opts ...option.ClientOption) (*bigQuery return nil, err } + crmService, err := cloudresourcemanager.NewService(ctx, opts...) + if err != nil { + return nil, err + } + return &bigQueryClient{ projectID: projectID, client: client, iamService: iamService, apiClient: apiClient, + crmService: crmService, }, nil } @@ -329,6 +337,34 @@ func (c *bigQueryClient) GetRolePermissions(ctx context.Context, role string) ([ return iamRole.IncludedPermissions, nil } +func (c *bigQueryClient) ListRolePermissions(ctx context.Context, roleIDs []string) (map[string][]string, error) { + permissions := make(map[string][]string) + + iamRoles, err := c.iamService.Roles.List().Context(ctx).Do() + if err != nil { + return nil, err + } + + for _, iamRole := range iamRoles.Roles { + if containsString(roleIDs, iamRole.Name) { + permissions[iamRole.Name] = iamRole.IncludedPermissions + } + } + + return permissions, nil +} + +func (c *bigQueryClient) CheckGrantedPermission(ctx context.Context, permissions []string) ([]string, error) { + res, err := c.crmService.Projects.TestIamPermissions(c.projectID, &cloudresourcemanager.TestIamPermissionsRequest{ + Permissions: permissions, + }).Context(ctx).Do() + if err != nil { + return nil, err + } + + return res.Permissions, nil +} + func (c *bigQueryClient) getGrantableRolesForTables() ([]string, error) { var resourceName string ctx := context.Background() diff --git a/plugins/providers/bigquery/config.go b/plugins/providers/bigquery/config.go index b8382540..ab77d6cb 100644 --- a/plugins/providers/bigquery/config.go +++ b/plugins/providers/bigquery/config.go @@ -138,6 +138,13 @@ func (c *Config) parseAndValidate() error { return err } + if c.ProviderConfig.Activity != nil { + ac := activityConfig{c.ProviderConfig.Activity} + if err := ac.Validate(); err != nil { + return fmt.Errorf("validating activity config: %w", err) + } + } + permissionValidationErrors := []error{} for _, resource := range c.ProviderConfig.Resources { diff --git a/plugins/providers/bigquery/errors.go b/plugins/providers/bigquery/errors.go index 4cbf3a39..53b29dad 100644 --- a/plugins/providers/bigquery/errors.go +++ b/plugins/providers/bigquery/errors.go @@ -27,4 +27,7 @@ var ( ErrInvalidTablePermission = errors.New("provided permission is not supported for table resource") ErrEmptyResource = errors.New("this bigquery project has no resources") ErrCannotVerifyTablePermission = errors.New("cannot verify the table permissions since this bigquery project does not have any tables") + + ErrInvalidTimeRange = errors.New("specified time range exceeds the activity log retention period") + ErrPrivateLogViewerAccessNotGranted = errors.New("private log viewer access not granted") ) diff --git a/plugins/providers/bigquery/mocks/BigQueryClient.go b/plugins/providers/bigquery/mocks/BigQueryClient.go index 9cd9534d..794b1c33 100644 --- a/plugins/providers/bigquery/mocks/BigQueryClient.go +++ b/plugins/providers/bigquery/mocks/BigQueryClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -27,6 +27,61 @@ func (_m *BigQueryClient) EXPECT() *BigQueryClient_Expecter { return &BigQueryClient_Expecter{mock: &_m.Mock} } +// CheckGrantedPermission provides a mock function with given fields: _a0, _a1 +func (_m *BigQueryClient) CheckGrantedPermission(_a0 context.Context, _a1 []string) ([]string, error) { + ret := _m.Called(_a0, _a1) + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []string) ([]string, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, []string) []string); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BigQueryClient_CheckGrantedPermission_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckGrantedPermission' +type BigQueryClient_CheckGrantedPermission_Call struct { + *mock.Call +} + +// CheckGrantedPermission is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 []string +func (_e *BigQueryClient_Expecter) CheckGrantedPermission(_a0 interface{}, _a1 interface{}) *BigQueryClient_CheckGrantedPermission_Call { + return &BigQueryClient_CheckGrantedPermission_Call{Call: _e.mock.On("CheckGrantedPermission", _a0, _a1)} +} + +func (_c *BigQueryClient_CheckGrantedPermission_Call) Run(run func(_a0 context.Context, _a1 []string)) *BigQueryClient_CheckGrantedPermission_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]string)) + }) + return _c +} + +func (_c *BigQueryClient_CheckGrantedPermission_Call) Return(_a0 []string, _a1 error) *BigQueryClient_CheckGrantedPermission_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BigQueryClient_CheckGrantedPermission_Call) RunAndReturn(run func(context.Context, []string) ([]string, error)) *BigQueryClient_CheckGrantedPermission_Call { + _c.Call.Return(run) + return _c +} + // GetDatasets provides a mock function with given fields: _a0 func (_m *BigQueryClient) GetDatasets(_a0 context.Context) ([]*bigquery.Dataset, error) { ret := _m.Called(_a0) @@ -337,6 +392,61 @@ func (_c *BigQueryClient_ListAccess_Call) RunAndReturn(run func(context.Context, return _c } +// ListRolePermissions provides a mock function with given fields: _a0, _a1 +func (_m *BigQueryClient) ListRolePermissions(_a0 context.Context, _a1 []string) (map[string][]string, error) { + ret := _m.Called(_a0, _a1) + + var r0 map[string][]string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []string) (map[string][]string, error)); ok { + return rf(_a0, _a1) + } + if rf, ok := ret.Get(0).(func(context.Context, []string) map[string][]string); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string][]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BigQueryClient_ListRolePermissions_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRolePermissions' +type BigQueryClient_ListRolePermissions_Call struct { + *mock.Call +} + +// ListRolePermissions is a helper method to define mock.On call +// - _a0 context.Context +// - _a1 []string +func (_e *BigQueryClient_Expecter) ListRolePermissions(_a0 interface{}, _a1 interface{}) *BigQueryClient_ListRolePermissions_Call { + return &BigQueryClient_ListRolePermissions_Call{Call: _e.mock.On("ListRolePermissions", _a0, _a1)} +} + +func (_c *BigQueryClient_ListRolePermissions_Call) Run(run func(_a0 context.Context, _a1 []string)) *BigQueryClient_ListRolePermissions_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]string)) + }) + return _c +} + +func (_c *BigQueryClient_ListRolePermissions_Call) Return(_a0 map[string][]string, _a1 error) *BigQueryClient_ListRolePermissions_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *BigQueryClient_ListRolePermissions_Call) RunAndReturn(run func(context.Context, []string) (map[string][]string, error)) *BigQueryClient_ListRolePermissions_Call { + _c.Call.Return(run) + return _c +} + // ResolveDatasetRole provides a mock function with given fields: role func (_m *BigQueryClient) ResolveDatasetRole(role string) (gobigquery.AccessRole, error) { ret := _m.Called(role) diff --git a/plugins/providers/bigquery/mocks/cloudLoggingClientI.go b/plugins/providers/bigquery/mocks/cloudLoggingClientI.go index fac4d813..e5dee688 100644 --- a/plugins/providers/bigquery/mocks/cloudLoggingClientI.go +++ b/plugins/providers/bigquery/mocks/cloudLoggingClientI.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -7,6 +7,8 @@ import ( bigquery "github.com/raystack/guardian/plugins/providers/bigquery" + logging "google.golang.org/api/logging/v2" + mock "github.com/stretchr/testify/mock" ) @@ -23,66 +25,80 @@ func (_m *CloudLoggingClientI) EXPECT() *CloudLoggingClientI_Expecter { return &CloudLoggingClientI_Expecter{mock: &_m.Mock} } -// Close provides a mock function with given fields: -func (_m *CloudLoggingClientI) Close() error { - ret := _m.Called() +// GetLogBucket provides a mock function with given fields: ctx, name +func (_m *CloudLoggingClientI) GetLogBucket(ctx context.Context, name string) (*logging.LogBucket, error) { + ret := _m.Called(ctx, name) - var r0 error - if rf, ok := ret.Get(0).(func() error); ok { - r0 = rf() + var r0 *logging.LogBucket + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*logging.LogBucket, error)); ok { + return rf(ctx, name) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *logging.LogBucket); ok { + r0 = rf(ctx, name) } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*logging.LogBucket) + } } - return r0 + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -// CloudLoggingClientI_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' -type CloudLoggingClientI_Close_Call struct { +// CloudLoggingClientI_GetLogBucket_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLogBucket' +type CloudLoggingClientI_GetLogBucket_Call struct { *mock.Call } -// Close is a helper method to define mock.On call -func (_e *CloudLoggingClientI_Expecter) Close() *CloudLoggingClientI_Close_Call { - return &CloudLoggingClientI_Close_Call{Call: _e.mock.On("Close")} +// GetLogBucket is a helper method to define mock.On call +// - ctx context.Context +// - name string +func (_e *CloudLoggingClientI_Expecter) GetLogBucket(ctx interface{}, name interface{}) *CloudLoggingClientI_GetLogBucket_Call { + return &CloudLoggingClientI_GetLogBucket_Call{Call: _e.mock.On("GetLogBucket", ctx, name)} } -func (_c *CloudLoggingClientI_Close_Call) Run(run func()) *CloudLoggingClientI_Close_Call { +func (_c *CloudLoggingClientI_GetLogBucket_Call) Run(run func(ctx context.Context, name string)) *CloudLoggingClientI_GetLogBucket_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context), args[1].(string)) }) return _c } -func (_c *CloudLoggingClientI_Close_Call) Return(_a0 error) *CloudLoggingClientI_Close_Call { - _c.Call.Return(_a0) +func (_c *CloudLoggingClientI_GetLogBucket_Call) Return(_a0 *logging.LogBucket, _a1 error) *CloudLoggingClientI_GetLogBucket_Call { + _c.Call.Return(_a0, _a1) return _c } -func (_c *CloudLoggingClientI_Close_Call) RunAndReturn(run func() error) *CloudLoggingClientI_Close_Call { +func (_c *CloudLoggingClientI_GetLogBucket_Call) RunAndReturn(run func(context.Context, string) (*logging.LogBucket, error)) *CloudLoggingClientI_GetLogBucket_Call { _c.Call.Return(run) return _c } -// ListLogEntries provides a mock function with given fields: _a0, _a1 -func (_m *CloudLoggingClientI) ListLogEntries(_a0 context.Context, _a1 bigquery.ImportActivitiesFilter) ([]*bigquery.Activity, error) { - ret := _m.Called(_a0, _a1) +// ListLogEntries provides a mock function with given fields: _a0, _a1, _a2 +func (_m *CloudLoggingClientI) ListLogEntries(_a0 context.Context, _a1 string, _a2 int) ([]*bigquery.Activity, error) { + ret := _m.Called(_a0, _a1, _a2) var r0 []*bigquery.Activity var r1 error - if rf, ok := ret.Get(0).(func(context.Context, bigquery.ImportActivitiesFilter) ([]*bigquery.Activity, error)); ok { - return rf(_a0, _a1) + if rf, ok := ret.Get(0).(func(context.Context, string, int) ([]*bigquery.Activity, error)); ok { + return rf(_a0, _a1, _a2) } - if rf, ok := ret.Get(0).(func(context.Context, bigquery.ImportActivitiesFilter) []*bigquery.Activity); ok { - r0 = rf(_a0, _a1) + if rf, ok := ret.Get(0).(func(context.Context, string, int) []*bigquery.Activity); ok { + r0 = rf(_a0, _a1, _a2) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*bigquery.Activity) } } - if rf, ok := ret.Get(1).(func(context.Context, bigquery.ImportActivitiesFilter) error); ok { - r1 = rf(_a0, _a1) + if rf, ok := ret.Get(1).(func(context.Context, string, int) error); ok { + r1 = rf(_a0, _a1, _a2) } else { r1 = ret.Error(1) } @@ -97,14 +113,15 @@ type CloudLoggingClientI_ListLogEntries_Call struct { // ListLogEntries is a helper method to define mock.On call // - _a0 context.Context -// - _a1 bigquery.ImportActivitiesFilter -func (_e *CloudLoggingClientI_Expecter) ListLogEntries(_a0 interface{}, _a1 interface{}) *CloudLoggingClientI_ListLogEntries_Call { - return &CloudLoggingClientI_ListLogEntries_Call{Call: _e.mock.On("ListLogEntries", _a0, _a1)} +// - _a1 string +// - _a2 int +func (_e *CloudLoggingClientI_Expecter) ListLogEntries(_a0 interface{}, _a1 interface{}, _a2 interface{}) *CloudLoggingClientI_ListLogEntries_Call { + return &CloudLoggingClientI_ListLogEntries_Call{Call: _e.mock.On("ListLogEntries", _a0, _a1, _a2)} } -func (_c *CloudLoggingClientI_ListLogEntries_Call) Run(run func(_a0 context.Context, _a1 bigquery.ImportActivitiesFilter)) *CloudLoggingClientI_ListLogEntries_Call { +func (_c *CloudLoggingClientI_ListLogEntries_Call) Run(run func(_a0 context.Context, _a1 string, _a2 int)) *CloudLoggingClientI_ListLogEntries_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(bigquery.ImportActivitiesFilter)) + run(args[0].(context.Context), args[1].(string), args[2].(int)) }) return _c } @@ -114,7 +131,7 @@ func (_c *CloudLoggingClientI_ListLogEntries_Call) Return(_a0 []*bigquery.Activi return _c } -func (_c *CloudLoggingClientI_ListLogEntries_Call) RunAndReturn(run func(context.Context, bigquery.ImportActivitiesFilter) ([]*bigquery.Activity, error)) *CloudLoggingClientI_ListLogEntries_Call { +func (_c *CloudLoggingClientI_ListLogEntries_Call) RunAndReturn(run func(context.Context, string, int) ([]*bigquery.Activity, error)) *CloudLoggingClientI_ListLogEntries_Call { _c.Call.Return(run) return _c } diff --git a/plugins/providers/bigquery/mocks/encryptor.go b/plugins/providers/bigquery/mocks/encryptor.go index 3aca60d0..df0be2a4 100644 --- a/plugins/providers/bigquery/mocks/encryptor.go +++ b/plugins/providers/bigquery/mocks/encryptor.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/plugins/providers/bigquery/model.go b/plugins/providers/bigquery/model.go index 3117445e..0982a85c 100644 --- a/plugins/providers/bigquery/model.go +++ b/plugins/providers/bigquery/model.go @@ -5,8 +5,10 @@ import ( "strings" bq "cloud.google.com/go/bigquery" + "github.com/mitchellh/mapstructure" "github.com/raystack/guardian/core/resource" "github.com/raystack/guardian/domain" + "github.com/raystack/guardian/utils" ) const ( @@ -146,3 +148,35 @@ func (r BigQueryResourceName) BigQueryResourceID() string { } return urn } + +type cloudLoggingOptions struct { + LogBucket string `json:"log_bucket" yaml:"log_bucket" mapstructure:"log_bucket"` +} + +type activityConfig struct { + *domain.ActivityConfig +} + +func (c activityConfig) Validate() error { + validSources := []string{"default", "cloud_logging"} + if !utils.ContainsString(validSources, c.ActivityConfig.Source) { + return fmt.Errorf("invalid source: %q, allowed values %v", c.ActivityConfig.Source, validSources) + } + + return nil +} + +func (c activityConfig) GetCloudLoggingOptions() (*cloudLoggingOptions, error) { + if c.ActivityConfig == nil || (c.ActivityConfig.Source == "cloud_logging" && c.ActivityConfig.Options == nil) { + return &cloudLoggingOptions{}, nil + } + if c.ActivityConfig.Source != "cloud_logging" { + return nil, fmt.Errorf("invalid source: %q", c.ActivityConfig.Source) + } + + result := &cloudLoggingOptions{} + if err := mapstructure.Decode(c.ActivityConfig.Options, result); err != nil { + return nil, fmt.Errorf("decoding options: %w", err) + } + return result, nil +} diff --git a/plugins/providers/bigquery/model_test.go b/plugins/providers/bigquery/model_test.go index 22fe1726..3a7581fc 100644 --- a/plugins/providers/bigquery/model_test.go +++ b/plugins/providers/bigquery/model_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/raystack/guardian/core/resource" + "github.com/raystack/guardian/domain" "github.com/raystack/guardian/plugins/providers/bigquery" "github.com/stretchr/testify/assert" diff --git a/plugins/providers/bigquery/provider.go b/plugins/providers/bigquery/provider.go index 88e96ad6..5677c56a 100644 --- a/plugins/providers/bigquery/provider.go +++ b/plugins/providers/bigquery/provider.go @@ -15,8 +15,10 @@ import ( "github.com/raystack/guardian/core/provider" "github.com/raystack/guardian/domain" "github.com/raystack/guardian/pkg/slices" + "github.com/raystack/guardian/utils" "github.com/raystack/salt/log" "golang.org/x/sync/errgroup" + "google.golang.org/api/logging/v2" "google.golang.org/api/option" ) @@ -50,12 +52,14 @@ type BigQueryClient interface { ResolveDatasetRole(role string) (bq.AccessRole, error) ListAccess(ctx context.Context, resources []*domain.Resource) (domain.MapResourceAccess, error) GetRolePermissions(context.Context, string) ([]string, error) + ListRolePermissions(context.Context, []string) (map[string][]string, error) + CheckGrantedPermission(context.Context, []string) ([]string, error) } //go:generate mockery --name=cloudLoggingClientI --exported --with-expecter type cloudLoggingClientI interface { - Close() error - ListLogEntries(context.Context, ImportActivitiesFilter) ([]*Activity, error) + ListLogEntries(context.Context, string, int) ([]*Activity, error) + GetLogBucket(ctx context.Context, name string) (*logging.LogBucket, error) } //go:generate mockery --name=encryptor --exported --with-expecter @@ -296,16 +300,48 @@ func (p *Provider) ListAccess(ctx context.Context, pc domain.ProviderConfig, res return bqClient.ListAccess(ctx, resources) } -func (p *Provider) GetActivities(ctx context.Context, pd domain.Provider, filter domain.ImportActivitiesFilter) ([]*domain.Activity, error) { +func (p *Provider) GetActivities(ctx context.Context, pd domain.Provider, filter domain.ListActivitiesFilter) ([]*domain.Activity, error) { logClient, err := p.getCloudLoggingClient(ctx, *pd.Config) if err != nil { return nil, fmt.Errorf("initializing cloud logging client: %w", err) } - entries, err := logClient.ListLogEntries(ctx, ImportActivitiesFilter{ - ImportActivitiesFilter: filter, - Types: BigQueryAuditMetadataMethods, - }) + var resourceNames []string + for _, r := range filter.GetResources() { + resourceNames = append(resourceNames, (*bqResource)(r).fullURN()) + } + filters := []string{ + `protoPayload.serviceName="bigquery.googleapis.com"`, + `resource.type="bigquery_dataset"`, // exclude logs for bigquery jobs ("bigquery_project") + } + if len(filter.AccountIDs) > 0 { + filters = append(filters, + `protoPayload.authenticationInfo.principalEmail=("`+strings.Join(filter.AccountIDs, `" OR "`)+`")`, + ) + } + resources := filter.GetResources() + if len(resources) > 0 { + filters = append(filters, + // uses ":" (has/contains) operator instead of "=" (equals) operator for resource name so that the result will also + // include activities on tables under the specified dataset (e.g. "projects/xxx/datasets/yyy" will also include + // activities on "projects/xxx/datasets/yyy/tables/zzz") + `protoPayload.resourceName:("`+strings.Join(resourceNames, `" OR "`)+`")`, + ) + } + filters = append(filters, + `protoPayload.methodName=("`+strings.Join(BigQueryAuditMetadataMethods, `" OR "`)+`")`, + ) + if filter.TimestampGte != nil { + filters = append(filters, + `timestamp>="`+filter.TimestampGte.Format(time.RFC3339)+`"`, + ) + } + if filter.TimestampLte != nil { + filters = append(filters, + `timestamp<="`+filter.TimestampLte.Format(time.RFC3339)+`"`, + ) + } + entries, err := logClient.ListLogEntries(ctx, strings.Join(filters, " AND "), 0) if err != nil { return nil, fmt.Errorf("listing log entries: %w", err) } @@ -340,6 +376,133 @@ func (p *Provider) GetActivities(ctx context.Context, pd domain.Provider, filter return activities, nil } +// ListActivities returns list of activities +func (p *Provider) ListActivities(ctx context.Context, pd domain.Provider, filter domain.ListActivitiesFilter) ([]*domain.Activity, error) { + if pd.Type != p.typeName { + return nil, ErrProviderTypeMismatch + } + creds, err := ParseCredentials(pd.Config.Credentials, p.encryptor) + if err != nil { + return nil, fmt.Errorf("parsing credentials: %w", err) + } + bqClient, err := p.getBigQueryClient(*creds) + if err != nil { + return nil, fmt.Errorf("initializing bigquery client: %w", err) + } + logClient, err := p.getCloudLoggingClient(ctx, *pd.Config) + if err != nil { + return nil, fmt.Errorf("initializing cloud logging client: %w", err) + } + + // check time range against logging retention period + activityConfig := activityConfig{pd.Config.Activity} + clo, err := activityConfig.GetCloudLoggingOptions() + if err != nil { + return nil, fmt.Errorf("getting cloud logging options: %w", err) + } + decryptedCreds, err := ParseCredentials(pd.Config.Credentials, p.encryptor) + if err != nil { + return nil, fmt.Errorf("parsing credentials: %w", err) + } + bucketName := clo.LogBucket + if bucketName == "" { + bucketName = decryptedCreds.ResourceName + "/locations/global/buckets/_Default" + } + logBucket, err := logClient.GetLogBucket(ctx, bucketName) + if err != nil { + return nil, fmt.Errorf("getting log bucket: %w", err) + } + retentionDuration, err := time.ParseDuration(fmt.Sprintf("%dh", 24*logBucket.RetentionDays)) + if err != nil { + return nil, fmt.Errorf("invalid bucket's retention period: %q: %w", logBucket.RetentionDays, err) + } + if filter.TimestampGte != nil && time.Since(*filter.TimestampGte) > retentionDuration { + return nil, fmt.Errorf("%w: log bucket's retention in days: %q", ErrInvalidTimeRange, logBucket.RetentionDays) + } else { + t := time.Now().Add(-retentionDuration) + filter.TimestampGte = &t + } + + // check private log viewer access is granted + if grantedPermissions, err := bqClient.CheckGrantedPermission(ctx, []string{PrivateLogViewerPermission}); err != nil { + return nil, fmt.Errorf("checking granted permission: %w", err) + } else if !utils.ContainsString(grantedPermissions, PrivateLogViewerPermission) { + return nil, fmt.Errorf("%w: %q permissions is required", ErrPrivateLogViewerAccessNotGranted, PrivateLogViewerPermission) + } + + filters := []string{ + `protoPayload.serviceName="bigquery.googleapis.com"`, + `logName:"` + decryptedCreds.ResourceName + `/logs/cloudaudit.googleapis.com%2F"`, // `logName:"projects/{{project_id}}/logs/cloudaudit.googleapis.com%2F"` + `protoPayload.authorizationInfo.granted=true`, + `protoPayload.authorizationInfo.permission!=null`, + } + if len(filter.AccountIDs) > 0 { + filters = append(filters, + `protoPayload.authenticationInfo.principalEmail=("`+strings.Join(filter.AccountIDs, `" OR "`)+`")`, + ) + } + if filter.TimestampGte != nil && !filter.TimestampGte.IsZero() { + filters = append(filters, `timestamp>="`+filter.TimestampGte.Format(time.RFC3339)+`"`) + } + if filter.TimestampLte != nil && !filter.TimestampLte.IsZero() { + filters = append(filters, `timestamp<="`+filter.TimestampLte.Format(time.RFC3339)+`"`) + } + + entries, err := logClient.ListLogEntries(ctx, strings.Join(filters, " AND "), 0) + if err != nil { + return nil, fmt.Errorf("listing log entries: %w", err) + } + + var activities []*domain.Activity + for _, e := range entries { + a, err := e.ToDomainActivity(pd) + if err != nil { + return nil, fmt.Errorf("converting log entry to provider activity: %w", err) + } + activities = append(activities, a) + } + + return activities, nil +} + +func (p *Provider) CorrelateGrantActivities(ctx context.Context, pd domain.Provider, grants []*domain.Grant, activities []*domain.Activity) error { + creds, err := ParseCredentials(pd.Config.Credentials, p.encryptor) + if err != nil { + return fmt.Errorf("parsing credentials: %w", err) + } + + client, err := p.getBigQueryClient(*creds) + if err != nil { + return err + } + + var allRoles []string + for _, g := range grants { + allRoles = append(allRoles, g.Permissions...) // grant.Permissions is slice of gcloud roles + } + uniqueRoles := slices.UniqueStringSlice(allRoles) + permissions, err := client.ListRolePermissions(ctx, uniqueRoles) + if err != nil { + return fmt.Errorf("listing role permissions: %w", err) + } + + for _, g := range grants { + var combinedPermissions []string + for _, role := range g.Permissions { + combinedPermissions = append(combinedPermissions, permissions[role]...) + } + combinedPermissions = slices.UniqueStringSlice(combinedPermissions) + + for _, a := range activities { + if isSubset(a.Authorizations, combinedPermissions) { + g.Activities = append(g.Activities, a) + } + } + } + + return nil +} + func (p *Provider) getBigQueryClient(credentials Credentials) (BigQueryClient, error) { projectID := strings.Replace(credentials.ResourceName, "projects/", "", 1) if p.Clients[projectID] != nil { @@ -497,3 +660,17 @@ func translateDatasetRoleToBigQueryRole(role string) string { return role } } + +// isSubset checks if `subset` is a subset of `superset` +func isSubset(subset, superset []string) bool { + checkset := make(map[string]bool) + for _, element := range subset { + checkset[element] = true + } + for _, element := range superset { + if checkset[element] { + delete(checkset, element) + } + } + return len(checkset) == 0 +} diff --git a/plugins/providers/bigquery/provider_test.go b/plugins/providers/bigquery/provider_test.go index 43dc70ef..53bdffa2 100644 --- a/plugins/providers/bigquery/provider_test.go +++ b/plugins/providers/bigquery/provider_test.go @@ -3,12 +3,13 @@ package bigquery_test import ( "context" "encoding/base64" + "encoding/json" "errors" "fmt" + "strings" "testing" "time" - "cloud.google.com/go/logging" "github.com/google/go-cmp/cmp" "github.com/raystack/guardian/core/provider" "github.com/raystack/guardian/domain" @@ -18,7 +19,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" - "google.golang.org/genproto/googleapis/api/monitoredres" + "google.golang.org/api/googleapi" + "google.golang.org/api/logging/v2" "google.golang.org/genproto/googleapis/cloud/audit" ) @@ -256,6 +258,9 @@ func TestCreateConfig(t *testing.T) { ResourceName: "projects/test-resource-name", }, URN: providerURN, + Activity: &domain.ActivityConfig{ + Source: "default", + }, } encryptor.On("Encrypt", `{"type":"service_account"}`).Return(`{"type":"service_account"}`, nil) @@ -1057,24 +1062,30 @@ func (s *BigQueryProviderTestSuite) TestGetActivities_Success() { s.Run("should map bigquery logging entries to guardian activities", func() { now := time.Now() + auditLog := &audit.AuditLog{ + ResourceName: "projects/test-project-id/datasets/test-dataset-id", + ServiceName: "bigquery.googleapis.com", + AuthenticationInfo: &audit.AuthenticationInfo{ + PrincipalEmail: "user@example.com", + }, + AuthorizationInfo: []*audit.AuthorizationInfo{ + { + Permission: "bigquery.datasets.get", + }, + }, + } + auditLogBytes, err := json.Marshal(auditLog) + if err != nil { + s.Require().NoError(err) + } + expectedBigQueryActivities := []*bigquery.Activity{ { - &logging.Entry{ - Timestamp: now, - InsertID: "test-activity-id", - Payload: &audit.AuditLog{ - ResourceName: "projects/test-project-id/datasets/test-dataset-id", - ServiceName: "bigquery.googleapis.com", - AuthenticationInfo: &audit.AuthenticationInfo{ - PrincipalEmail: "user@example.com", - }, - AuthorizationInfo: []*audit.AuthorizationInfo{ - { - Permission: "bigquery.datasets.get", - }, - }, - }, - Resource: &monitoredres.MonitoredResource{ + &logging.LogEntry{ + Timestamp: now.Format(time.RFC3339Nano), + InsertId: "test-activity-id", + ProtoPayload: googleapi.RawMessage(auditLogBytes), + Resource: &logging.MonitoredResource{ Type: "bigquery_dataset", Labels: map[string]string{ "dataset_id": "test-dataset-id", @@ -1084,10 +1095,13 @@ func (s *BigQueryProviderTestSuite) TestGetActivities_Success() { }, }, } + expectedListLogEntriesFilter := strings.Join([]string{ + `protoPayload.serviceName="bigquery.googleapis.com"`, + `resource.type="bigquery_dataset"`, + fmt.Sprintf(`protoPayload.methodName=("%s")`, strings.Join(bigquery.BigQueryAuditMetadataMethods, `" OR "`)), + }, ` AND `) s.mockCloudLoggingClient.EXPECT(). - ListLogEntries(mock.AnythingOfType("*context.emptyCtx"), bigquery.ImportActivitiesFilter{ - Types: bigquery.BigQueryAuditMetadataMethods, - }).Return(expectedBigQueryActivities, nil).Once() + ListLogEntries(mock.AnythingOfType("*context.emptyCtx"), expectedListLogEntriesFilter, 0).Return(expectedBigQueryActivities, nil).Once() s.mockBigQueryClient.EXPECT(). GetRolePermissions(mock.AnythingOfType("*context.emptyCtx"), "roles/bigquery.dataViewer").Return([]string{"bigquery.datasets.get"}, nil).Once() s.mockBigQueryClient.EXPECT(). @@ -1133,7 +1147,7 @@ func (s *BigQueryProviderTestSuite) TestGetActivities_Success() { }, "type": "bigquery_dataset", }, - "severity": float64(0), + "severity": "", "source_location": nil, "span_id": "", "timestamp": now.Format(time.RFC3339Nano), @@ -1144,7 +1158,7 @@ func (s *BigQueryProviderTestSuite) TestGetActivities_Success() { }, } - actualActivities, err := s.provider.GetActivities(context.Background(), *s.validProvider, domain.ImportActivitiesFilter{}) + actualActivities, err := s.provider.GetActivities(context.Background(), *s.validProvider, domain.ListActivitiesFilter{}) s.mockCloudLoggingClient.AssertExpectations(s.T()) s.mockBigQueryClient.AssertExpectations(s.T()) @@ -1167,7 +1181,7 @@ func (s *BigQueryProviderTestSuite) TestGetActivities_Success() { }, }, } - _, err := s.provider.GetActivities(context.Background(), *invalidProvider, domain.ImportActivitiesFilter{}) + _, err := s.provider.GetActivities(context.Background(), *invalidProvider, domain.ListActivitiesFilter{}) s.mockEncryptor.AssertExpectations(s.T()) s.ErrorIs(err, expectedError) @@ -1176,15 +1190,173 @@ func (s *BigQueryProviderTestSuite) TestGetActivities_Success() { s.Run("should return error if there is an error on listing log entries", func() { expectedError := errors.New("error") s.mockCloudLoggingClient.EXPECT(). - ListLogEntries(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("bigquery.ImportActivitiesFilter")).Return(nil, expectedError).Once() + ListLogEntries(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("string"), 0).Return(nil, expectedError).Once() - _, err := s.provider.GetActivities(context.Background(), *s.validProvider, domain.ImportActivitiesFilter{}) + _, err := s.provider.GetActivities(context.Background(), *s.validProvider, domain.ListActivitiesFilter{}) s.mockCloudLoggingClient.AssertExpectations(s.T()) s.ErrorIs(err, expectedError) }) } +func (s *BigQueryProviderTestSuite) TestListActivities() { + timeNow := time.Now() + + s.Run("should return list of activity on success", func() { + expectedLogBucket := &logging.LogBucket{ + RetentionDays: 30, + } + s.mockCloudLoggingClient.EXPECT(). + GetLogBucket(mock.AnythingOfType("*context.emptyCtx"), fmt.Sprintf("projects/%s/locations/global/buckets/_Default", s.dummyProjectID)). + Return(expectedLogBucket, nil).Once() + s.mockBigQueryClient.EXPECT(). + CheckGrantedPermission(mock.AnythingOfType("*context.emptyCtx"), []string{bigquery.PrivateLogViewerPermission}). + Return([]string{bigquery.PrivateLogViewerPermission}, nil).Once() + expectedBqActivities := []*bigquery.Activity{ + { + LogEntry: &logging.LogEntry{ + Timestamp: timeNow.Format(time.RFC3339Nano), + ProtoPayload: googleapi.RawMessage(`{ + "authentication_info": { "principal_email": "user@example.com" }, + "authorization_info": [ + { "permission": "bigquery.datasets.get" } + ], + "resource_name": "projects/test-project-id/datasets/test-dataset-id" +}`), + }, + }, + } + s.mockCloudLoggingClient.EXPECT(). + ListLogEntries(mock.AnythingOfType("*context.emptyCtx"), mock.AnythingOfType("string"), 0). + Return(expectedBqActivities, nil).Once() + + expectedActivities := []*domain.Activity{ + { + AccountType: "user", + AccountID: "user@example.com", + Timestamp: timeNow, + Authorizations: []string{"bigquery.datasets.get"}, + Metadata: map[string]interface{}{ + "logging_entry": map[string]interface{}{ + "insert_id": string(""), + "labels": nil, + "operation": nil, + "payload": map[string]interface{}{ + "authentication_info": map[string]interface{}{ + "principal_email": "user@example.com", + }, + "authorization_info": []interface{}{ + map[string]interface{}{ + "permission": "bigquery.datasets.get", + }, + }, + "resource_name": "projects/test-project-id/datasets/test-dataset-id", + }, + "resource": nil, + "severity": "", + "source_location": nil, + "span_id": "", + "timestamp": timeNow.Format(time.RFC3339Nano), + "trace": "", + "trace_sampled": false, + }, + }, + Resource: &domain.Resource{ + ProviderType: s.validProvider.Type, + ProviderURN: s.validProvider.URN, + Type: "dataset", + URN: "test-project-id:test-dataset-id", + Name: "test-dataset-id", + }, + }, + } + + activities, err := s.provider.ListActivities(context.Background(), *s.validProvider, domain.ListActivitiesFilter{ + AccountIDs: []string{"user@example.com", "user2@example.com"}, + }) + + s.NoError(err) + s.Empty(cmp.Diff(expectedActivities, activities)) + }) + + s.Run("should return error if specified time range is more than the log bucket's retention period", func() { + s.mockCloudLoggingClient.EXPECT(). + GetLogBucket(mock.AnythingOfType("*context.emptyCtx"), fmt.Sprintf("projects/%s/locations/global/buckets/_Default", s.dummyProjectID)). + Return(&logging.LogBucket{ + RetentionDays: 30, + }, nil).Once() + + timestampGte := timeNow.Add(-32 * 24 * time.Hour) + _, err := s.provider.ListActivities(context.Background(), *s.validProvider, domain.ListActivitiesFilter{ + TimestampGte: ×tampGte, + }) + + s.mockCloudLoggingClient.AssertExpectations(s.T()) + s.ErrorIs(err, bigquery.ErrInvalidTimeRange) + }) + + s.Run("should return error if credentials doesn't have bigquery.privateLogViewer permission", func() { + s.mockCloudLoggingClient.EXPECT(). + GetLogBucket(mock.AnythingOfType("*context.emptyCtx"), fmt.Sprintf("projects/%s/locations/global/buckets/_Default", s.dummyProjectID)). + Return(&logging.LogBucket{ + RetentionDays: 30, + }, nil).Once() + s.mockBigQueryClient.EXPECT(). + CheckGrantedPermission(mock.AnythingOfType("*context.emptyCtx"), []string{bigquery.PrivateLogViewerPermission}). + Return([]string{}, nil).Once() + + _, err := s.provider.ListActivities(context.Background(), *s.validProvider, domain.ListActivitiesFilter{}) + + s.mockCloudLoggingClient.AssertExpectations(s.T()) + s.ErrorIs(err, bigquery.ErrPrivateLogViewerAccessNotGranted) + }) +} + +func (s *BigQueryProviderTestSuite) TestCorrelateGrantActivities() { + s.Run("should attach activities to the related grants and return nil error on success", func() { + dummyRolePermissions := map[string][]string{ + "role-1": {"permission-1", "permission-2"}, + "role-2": {"permission-3", "permission-4"}, + "role-3": {"permission-4"}, + "role-4": {"permission-1", "permission-2", "permission-3"}, + } + grants := []*domain.Grant{ + {ID: "g1", Permissions: []string{"role-1"}}, + {ID: "g2", Permissions: []string{"role-2"}}, + {ID: "g3", Permissions: []string{"role-3"}}, + {ID: "g4", Permissions: []string{"role-4"}}, + } + activities := []*domain.Activity{ + {ID: "a1", Authorizations: []string{"permission-1", "permission-2"}}, + {ID: "a2", Authorizations: []string{"permission-3"}}, + {ID: "a3", Authorizations: []string{"permission-1"}}, + {ID: "a4", Authorizations: []string{"permission-2"}}, + } + + expectedUniqueRoles := []string{"role-1", "role-2", "role-3", "role-4"} + s.mockBigQueryClient.EXPECT(). + ListRolePermissions(mock.AnythingOfType("*context.emptyCtx"), expectedUniqueRoles). + Return(dummyRolePermissions, nil).Once() + expectedAssociatedGrants := map[string][]string{ + "g1": {"a1", "a3", "a4"}, + "g2": {"a2"}, + "g3": {}, + "g4": {"a1", "a2", "a3", "a4"}, + } + + err := s.provider.CorrelateGrantActivities(context.Background(), *s.validProvider, grants, activities) + s.NoError(err) + for _, g := range grants { + expectedActivityIDs := expectedAssociatedGrants[g.ID] + actualActivityIDs := []string{} + for _, a := range g.Activities { + actualActivityIDs = append(actualActivityIDs, a.ID) + } + s.Equal(expectedActivityIDs, actualActivityIDs) + } + }) +} + func initProvider() *bigquery.Provider { crypto := new(mocks.Encryptor) l := log.NewNoop() diff --git a/plugins/providers/gcloudiam/client.go b/plugins/providers/gcloudiam/client.go index 6e7a9bec..d8ecee08 100644 --- a/plugins/providers/gcloudiam/client.go +++ b/plugins/providers/gcloudiam/client.go @@ -41,42 +41,55 @@ func newIamClient(credentialsJSON []byte, resourceName string) (*iamClient, erro }, nil } -func (c *iamClient) GetRoles() ([]*Role, error) { - var roles []*Role +func (c *iamClient) ListServiceAccounts(ctx context.Context) ([]*iam.ServiceAccount, error) { + res, err := c.iamService.Projects.ServiceAccounts.List(c.resourceName).Context(ctx).Do() + if err != nil { + return nil, err + } + return res.Accounts, nil +} - ctx := context.TODO() - req := c.iamService.Roles.List() - if err := req.Pages(ctx, func(page *iam.ListRolesResponse) error { - for _, role := range page.Roles { - roles = append(roles, c.fromIamRole(role)) +func (c *iamClient) GetGrantableRoles(ctx context.Context, resourceType string) ([]*iam.Role, error) { + var fullResourceName string + switch resourceType { + case ResourceTypeOrganization: + orgID := strings.Replace(c.resourceName, ResourceNameOrganizationPrefix, "", 1) + fullResourceName = fmt.Sprintf("//cloudresourcemanager.googleapis.com/organizations/%s", orgID) + + case ResourceTypeProject: + projectID := strings.Replace(c.resourceName, ResourceNameProjectPrefix, "", 1) + fullResourceName = fmt.Sprintf("//cloudresourcemanager.googleapis.com/projects/%s", projectID) + + case ResourceTypeServiceAccount: + projectID := strings.Replace(c.resourceName, ResourceNameProjectPrefix, "", 1) + res, err := c.iamService.Projects.ServiceAccounts.List(c.resourceName).PageSize(1).Context(ctx).Do() + if err != nil { + return nil, fmt.Errorf("getting a sample of service account: %w", err) } - return nil - }); err != nil { - return nil, err + if res.Accounts == nil || len(res.Accounts) == 0 { + return nil, fmt.Errorf("no service accounts found in project %s", projectID) + } + fullResourceName = fmt.Sprintf("//iam.googleapis.com/%s", res.Accounts[0].Name) + + default: + return nil, fmt.Errorf("unknown resource type %s", resourceType) } - if strings.HasPrefix(c.resourceName, ResourceNameProjectPrefix) { - projectRolesReq := c.iamService.Projects.Roles.List(c.resourceName) - if err := projectRolesReq.Pages(ctx, func(page *iam.ListRolesResponse) error { - for _, role := range page.Roles { - roles = append(roles, c.fromIamRole(role)) - } - return nil - }); err != nil { - return nil, err + roles := []*iam.Role{} + nextPageToken := "" + for { + req := &iam.QueryGrantableRolesRequest{ + FullResourceName: fullResourceName, + PageToken: nextPageToken, } - } else if strings.HasPrefix(c.resourceName, ResourceNameOrganizationPrefix) { - orgRolesReq := c.iamService.Organizations.Roles.List(c.resourceName) - if err := orgRolesReq.Pages(ctx, func(page *iam.ListRolesResponse) error { - for _, role := range page.Roles { - roles = append(roles, c.fromIamRole(role)) - } - return nil - }); err != nil { + res, err := c.iamService.Roles.QueryGrantableRoles(req).Context(ctx).Do() + if err != nil { return nil, err } - } else { - return nil, ErrInvalidResourceName + roles = append(roles, res.Roles...) + if nextPageToken = res.NextPageToken; nextPageToken == "" { + break + } } return roles, nil @@ -138,6 +151,71 @@ func (c *iamClient) RevokeAccess(accountType, accountID, role string) error { return err } +func (c *iamClient) GrantServiceAccountAccess(ctx context.Context, sa, accountType, accountID, role string) error { + policy, err := c.iamService.Projects.ServiceAccounts. + GetIamPolicy(sa).Context(ctx).Do() + if err != nil { + return fmt.Errorf("getting IAM policy of service account %q: %w", sa, err) + } + + member := fmt.Sprintf("%s:%s", accountType, accountID) + roleExists := false + for _, b := range policy.Bindings { + if b.Role == role { + if containsString(b.Members, member) { + return ErrPermissionAlreadyExists + } + b.Members = append(b.Members, member) + } + } + if !roleExists { + policy.Bindings = append(policy.Bindings, &iam.Binding{ + Role: role, + Members: []string{member}, + }) + } + + if _, err := c.iamService.Projects.ServiceAccounts. + SetIamPolicy(sa, &iam.SetIamPolicyRequest{Policy: policy}). + Context(ctx).Do(); err != nil { + return fmt.Errorf("setting IAM policy of service account %q: %w", sa, err) + } + + return nil +} + +func (c *iamClient) RevokeServiceAccountAccess(ctx context.Context, sa, accountType, accountID, role string) error { + policy, err := c.iamService.Projects.ServiceAccounts. + GetIamPolicy(sa).Context(ctx).Do() + if err != nil { + return fmt.Errorf("getting IAM policy of service account %q: %w", sa, err) + } + + member := fmt.Sprintf("%s:%s", accountType, accountID) + for _, b := range policy.Bindings { + if b.Role == role { + removeIndex := -1 + for i, m := range b.Members { + if m == member { + removeIndex = i + } + } + if removeIndex == -1 { + return ErrPermissionNotFound + } + b.Members = append(b.Members[:removeIndex], b.Members[removeIndex+1:]...) + } + } + + if _, err := c.iamService.Projects.ServiceAccounts. + SetIamPolicy(sa, &iam.SetIamPolicyRequest{Policy: policy}). + Context(ctx).Do(); err != nil { + return fmt.Errorf("setting IAM policy of service account %q: %w", sa, err) + } + + return nil +} + func (c *iamClient) ListAccess(ctx context.Context, resources []*domain.Resource) (domain.MapResourceAccess, error) { policy, err := c.getIamPolicy(ctx) if err != nil { @@ -195,14 +273,6 @@ func (c *iamClient) setIamPolicy(ctx context.Context, policy *cloudresourcemanag return nil, ErrInvalidResourceName } -func (c *iamClient) fromIamRole(r *iam.Role) *Role { - return &Role{ - Name: r.Name, - Title: r.Title, - Description: r.Description, - } -} - func containsString(arr []string, v string) bool { for _, item := range arr { if item == v { diff --git a/plugins/providers/gcloudiam/config.go b/plugins/providers/gcloudiam/config.go index 7426d89e..f075339f 100644 --- a/plugins/providers/gcloudiam/config.go +++ b/plugins/providers/gcloudiam/config.go @@ -1,6 +1,7 @@ package gcloudiam import ( + "context" "encoding/base64" "errors" "fmt" @@ -9,6 +10,7 @@ import ( "github.com/go-playground/validator/v10" "github.com/mitchellh/mapstructure" "github.com/raystack/guardian/domain" + "github.com/raystack/guardian/utils" ) const ( @@ -102,12 +104,29 @@ func (c *Config) parseAndValidate() error { c.ProviderConfig.Credentials = credentials } - if len(c.ProviderConfig.Resources) != 1 { - return ErrShouldHaveOneResource + if c.ProviderConfig.Resources == nil || len(c.ProviderConfig.Resources) == 0 { + return errors.New("empty resource config") } - r := c.ProviderConfig.Resources[0] - if err := c.validateResourceConfig(r); err != nil { - validationErrors = append(validationErrors, err) + uniqueResourceTypes := make(map[string]bool) + for _, rc := range c.ProviderConfig.Resources { + if _, ok := uniqueResourceTypes[rc.Type]; ok { + validationErrors = append(validationErrors, fmt.Errorf("duplicate resource type: %q", rc.Type)) + } + uniqueResourceTypes[rc.Type] = true + + allowedResourceTypes := []string{} + if strings.HasPrefix(credentials.ResourceName, ResourceNameOrganizationPrefix) { + allowedResourceTypes = []string{ResourceTypeOrganization} + } else if strings.HasPrefix(credentials.ResourceName, ResourceNameProjectPrefix) { + allowedResourceTypes = []string{ResourceTypeProject, ResourceTypeServiceAccount} + } + if !utils.ContainsString(allowedResourceTypes, rc.Type) { + validationErrors = append(validationErrors, fmt.Errorf("invalid resource type: %q", rc.Type)) + } + + if len(rc.Roles) == 0 { + validationErrors = append(validationErrors, ErrRolesShouldNotBeEmpty) + } } if len(validationErrors) > 0 { @@ -142,37 +161,14 @@ func (c *Config) validateCredentials(value interface{}) (*Credentials, error) { return &credentials, nil } -func (c *Config) validateResourceConfig(resource *domain.ResourceConfig) error { - resourceTypeValidation := fmt.Sprintf("oneof=%s %s", ResourceTypeProject, ResourceTypeOrganization) - if err := c.validator.Var(resource.Type, resourceTypeValidation); err != nil { - return err - } - - if len(resource.Roles) == 0 { - return ErrRolesShouldNotBeEmpty - } - - return nil -} - func (c *Config) validatePermissions(resource *domain.ResourceConfig, client GcloudIamClient) error { - iamRoles, err := client.GetRoles() + iamRoles, err := client.GetGrantableRoles(context.TODO(), resource.Type) if err != nil { return err } - - var roles []*domain.Role - for _, r := range iamRoles { - roles = append(roles, &domain.Role{ - ID: r.Name, - Name: r.Title, - Description: r.Description, - }) - } - - rolesMap := make(map[string]*domain.Role) - for _, role := range roles { - rolesMap[role.ID] = role + rolesMap := make(map[string]bool) + for _, role := range iamRoles { + rolesMap[role.Name] = true } for _, ro := range resource.Roles { diff --git a/plugins/providers/gcloudiam/mocks/GcloudIamClient.go b/plugins/providers/gcloudiam/mocks/GcloudIamClient.go index 0e6058af..9dfd3d91 100644 --- a/plugins/providers/gcloudiam/mocks/GcloudIamClient.go +++ b/plugins/providers/gcloudiam/mocks/GcloudIamClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks @@ -6,7 +6,8 @@ import ( context "context" domain "github.com/raystack/guardian/domain" - gcloudiam "github.com/raystack/guardian/plugins/providers/gcloudiam" + + iam "google.golang.org/api/iam/v1" mock "github.com/stretchr/testify/mock" ) @@ -24,25 +25,25 @@ func (_m *GcloudIamClient) EXPECT() *GcloudIamClient_Expecter { return &GcloudIamClient_Expecter{mock: &_m.Mock} } -// GetRoles provides a mock function with given fields: -func (_m *GcloudIamClient) GetRoles() ([]*gcloudiam.Role, error) { - ret := _m.Called() +// GetGrantableRoles provides a mock function with given fields: ctx, resourceType +func (_m *GcloudIamClient) GetGrantableRoles(ctx context.Context, resourceType string) ([]*iam.Role, error) { + ret := _m.Called(ctx, resourceType) - var r0 []*gcloudiam.Role + var r0 []*iam.Role var r1 error - if rf, ok := ret.Get(0).(func() ([]*gcloudiam.Role, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func(context.Context, string) ([]*iam.Role, error)); ok { + return rf(ctx, resourceType) } - if rf, ok := ret.Get(0).(func() []*gcloudiam.Role); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func(context.Context, string) []*iam.Role); ok { + r0 = rf(ctx, resourceType) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]*gcloudiam.Role) + r0 = ret.Get(0).([]*iam.Role) } } - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, resourceType) } else { r1 = ret.Error(1) } @@ -50,29 +51,31 @@ func (_m *GcloudIamClient) GetRoles() ([]*gcloudiam.Role, error) { return r0, r1 } -// GcloudIamClient_GetRoles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRoles' -type GcloudIamClient_GetRoles_Call struct { +// GcloudIamClient_GetGrantableRoles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetGrantableRoles' +type GcloudIamClient_GetGrantableRoles_Call struct { *mock.Call } -// GetRoles is a helper method to define mock.On call -func (_e *GcloudIamClient_Expecter) GetRoles() *GcloudIamClient_GetRoles_Call { - return &GcloudIamClient_GetRoles_Call{Call: _e.mock.On("GetRoles")} +// GetGrantableRoles is a helper method to define mock.On call +// - ctx context.Context +// - resourceType string +func (_e *GcloudIamClient_Expecter) GetGrantableRoles(ctx interface{}, resourceType interface{}) *GcloudIamClient_GetGrantableRoles_Call { + return &GcloudIamClient_GetGrantableRoles_Call{Call: _e.mock.On("GetGrantableRoles", ctx, resourceType)} } -func (_c *GcloudIamClient_GetRoles_Call) Run(run func()) *GcloudIamClient_GetRoles_Call { +func (_c *GcloudIamClient_GetGrantableRoles_Call) Run(run func(ctx context.Context, resourceType string)) *GcloudIamClient_GetGrantableRoles_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context), args[1].(string)) }) return _c } -func (_c *GcloudIamClient_GetRoles_Call) Return(_a0 []*gcloudiam.Role, _a1 error) *GcloudIamClient_GetRoles_Call { +func (_c *GcloudIamClient_GetGrantableRoles_Call) Return(_a0 []*iam.Role, _a1 error) *GcloudIamClient_GetGrantableRoles_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *GcloudIamClient_GetRoles_Call) RunAndReturn(run func() ([]*gcloudiam.Role, error)) *GcloudIamClient_GetRoles_Call { +func (_c *GcloudIamClient_GetGrantableRoles_Call) RunAndReturn(run func(context.Context, string) ([]*iam.Role, error)) *GcloudIamClient_GetGrantableRoles_Call { _c.Call.Return(run) return _c } @@ -121,6 +124,52 @@ func (_c *GcloudIamClient_GrantAccess_Call) RunAndReturn(run func(string, string return _c } +// GrantServiceAccountAccess provides a mock function with given fields: ctx, sa, accountType, accountID, roles +func (_m *GcloudIamClient) GrantServiceAccountAccess(ctx context.Context, sa string, accountType string, accountID string, roles string) error { + ret := _m.Called(ctx, sa, accountType, accountID, roles) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) error); ok { + r0 = rf(ctx, sa, accountType, accountID, roles) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GcloudIamClient_GrantServiceAccountAccess_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GrantServiceAccountAccess' +type GcloudIamClient_GrantServiceAccountAccess_Call struct { + *mock.Call +} + +// GrantServiceAccountAccess is a helper method to define mock.On call +// - ctx context.Context +// - sa string +// - accountType string +// - accountID string +// - roles string +func (_e *GcloudIamClient_Expecter) GrantServiceAccountAccess(ctx interface{}, sa interface{}, accountType interface{}, accountID interface{}, roles interface{}) *GcloudIamClient_GrantServiceAccountAccess_Call { + return &GcloudIamClient_GrantServiceAccountAccess_Call{Call: _e.mock.On("GrantServiceAccountAccess", ctx, sa, accountType, accountID, roles)} +} + +func (_c *GcloudIamClient_GrantServiceAccountAccess_Call) Run(run func(ctx context.Context, sa string, accountType string, accountID string, roles string)) *GcloudIamClient_GrantServiceAccountAccess_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string), args[4].(string)) + }) + return _c +} + +func (_c *GcloudIamClient_GrantServiceAccountAccess_Call) Return(_a0 error) *GcloudIamClient_GrantServiceAccountAccess_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GcloudIamClient_GrantServiceAccountAccess_Call) RunAndReturn(run func(context.Context, string, string, string, string) error) *GcloudIamClient_GrantServiceAccountAccess_Call { + _c.Call.Return(run) + return _c +} + // ListAccess provides a mock function with given fields: ctx, resources func (_m *GcloudIamClient) ListAccess(ctx context.Context, resources []*domain.Resource) (domain.MapResourceAccess, error) { ret := _m.Called(ctx, resources) @@ -176,6 +225,60 @@ func (_c *GcloudIamClient_ListAccess_Call) RunAndReturn(run func(context.Context return _c } +// ListServiceAccounts provides a mock function with given fields: _a0 +func (_m *GcloudIamClient) ListServiceAccounts(_a0 context.Context) ([]*iam.ServiceAccount, error) { + ret := _m.Called(_a0) + + var r0 []*iam.ServiceAccount + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]*iam.ServiceAccount, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) []*iam.ServiceAccount); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*iam.ServiceAccount) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GcloudIamClient_ListServiceAccounts_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListServiceAccounts' +type GcloudIamClient_ListServiceAccounts_Call struct { + *mock.Call +} + +// ListServiceAccounts is a helper method to define mock.On call +// - _a0 context.Context +func (_e *GcloudIamClient_Expecter) ListServiceAccounts(_a0 interface{}) *GcloudIamClient_ListServiceAccounts_Call { + return &GcloudIamClient_ListServiceAccounts_Call{Call: _e.mock.On("ListServiceAccounts", _a0)} +} + +func (_c *GcloudIamClient_ListServiceAccounts_Call) Run(run func(_a0 context.Context)) *GcloudIamClient_ListServiceAccounts_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *GcloudIamClient_ListServiceAccounts_Call) Return(_a0 []*iam.ServiceAccount, _a1 error) *GcloudIamClient_ListServiceAccounts_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *GcloudIamClient_ListServiceAccounts_Call) RunAndReturn(run func(context.Context) ([]*iam.ServiceAccount, error)) *GcloudIamClient_ListServiceAccounts_Call { + _c.Call.Return(run) + return _c +} + // RevokeAccess provides a mock function with given fields: accountType, accountID, role func (_m *GcloudIamClient) RevokeAccess(accountType string, accountID string, role string) error { ret := _m.Called(accountType, accountID, role) @@ -220,6 +323,52 @@ func (_c *GcloudIamClient_RevokeAccess_Call) RunAndReturn(run func(string, strin return _c } +// RevokeServiceAccountAccess provides a mock function with given fields: ctx, sa, accountType, accountID, role +func (_m *GcloudIamClient) RevokeServiceAccountAccess(ctx context.Context, sa string, accountType string, accountID string, role string) error { + ret := _m.Called(ctx, sa, accountType, accountID, role) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, string) error); ok { + r0 = rf(ctx, sa, accountType, accountID, role) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GcloudIamClient_RevokeServiceAccountAccess_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RevokeServiceAccountAccess' +type GcloudIamClient_RevokeServiceAccountAccess_Call struct { + *mock.Call +} + +// RevokeServiceAccountAccess is a helper method to define mock.On call +// - ctx context.Context +// - sa string +// - accountType string +// - accountID string +// - role string +func (_e *GcloudIamClient_Expecter) RevokeServiceAccountAccess(ctx interface{}, sa interface{}, accountType interface{}, accountID interface{}, role interface{}) *GcloudIamClient_RevokeServiceAccountAccess_Call { + return &GcloudIamClient_RevokeServiceAccountAccess_Call{Call: _e.mock.On("RevokeServiceAccountAccess", ctx, sa, accountType, accountID, role)} +} + +func (_c *GcloudIamClient_RevokeServiceAccountAccess_Call) Run(run func(ctx context.Context, sa string, accountType string, accountID string, role string)) *GcloudIamClient_RevokeServiceAccountAccess_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string), args[4].(string)) + }) + return _c +} + +func (_c *GcloudIamClient_RevokeServiceAccountAccess_Call) Return(_a0 error) *GcloudIamClient_RevokeServiceAccountAccess_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GcloudIamClient_RevokeServiceAccountAccess_Call) RunAndReturn(run func(context.Context, string, string, string, string) error) *GcloudIamClient_RevokeServiceAccountAccess_Call { + _c.Call.Return(run) + return _c +} + // NewGcloudIamClient creates a new instance of GcloudIamClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewGcloudIamClient(t interface { diff --git a/plugins/providers/gcloudiam/mocks/encryptor.go b/plugins/providers/gcloudiam/mocks/encryptor.go index 3aca60d0..df0be2a4 100644 --- a/plugins/providers/gcloudiam/mocks/encryptor.go +++ b/plugins/providers/gcloudiam/mocks/encryptor.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/plugins/providers/gcloudiam/provider.go b/plugins/providers/gcloudiam/provider.go index 89a74063..212347f8 100644 --- a/plugins/providers/gcloudiam/provider.go +++ b/plugins/providers/gcloudiam/provider.go @@ -3,20 +3,23 @@ package gcloudiam import ( "errors" "fmt" - "strings" "github.com/mitchellh/mapstructure" "github.com/raystack/guardian/core/provider" "github.com/raystack/guardian/domain" "golang.org/x/net/context" + "google.golang.org/api/iam/v1" ) //go:generate mockery --name=GcloudIamClient --exported --with-expecter type GcloudIamClient interface { - GetRoles() ([]*Role, error) + GetGrantableRoles(ctx context.Context, resourceType string) ([]*iam.Role, error) GrantAccess(accountType, accountID, role string) error RevokeAccess(accountType, accountID, role string) error ListAccess(ctx context.Context, resources []*domain.Resource) (domain.MapResourceAccess, error) + ListServiceAccounts(context.Context) ([]*iam.ServiceAccount, error) + GrantServiceAccountAccess(ctx context.Context, sa, accountType, accountID, roles string) error + RevokeServiceAccountAccess(ctx context.Context, sa, accountType, accountID, role string) error } //go:generate mockery --name=encryptor --exported --with-expecter @@ -67,30 +70,55 @@ func (p *Provider) CreateConfig(pc *domain.ProviderConfig) error { } func (p *Provider) GetResources(pc *domain.ProviderConfig) ([]*domain.Resource, error) { - var creds Credentials - if err := mapstructure.Decode(pc.Credentials, &creds); err != nil { - return nil, err - } + resources := []*domain.Resource{} + + for _, rc := range pc.Resources { + switch rc.Type { + case ResourceTypeProject, ResourceTypeOrganization: + var creds Credentials + if err := mapstructure.Decode(pc.Credentials, &creds); err != nil { + return nil, err + } + resources = append(resources, &domain.Resource{ + ProviderType: pc.Type, + ProviderURN: pc.URN, + Type: rc.Type, + URN: creds.ResourceName, + Name: fmt.Sprintf("%s - GCP IAM", creds.ResourceName), + }) + + case ResourceTypeServiceAccount: + client, err := p.getIamClient(pc) + if err != nil { + return nil, fmt.Errorf("initializing iam client: %w", err) + } + + serviceAccounts, err := client.ListServiceAccounts(context.TODO()) + if err != nil { + return nil, fmt.Errorf("listing service accounts: %w", err) + } - var t string - if strings.HasPrefix(creds.ResourceName, "project") { - t = ResourceTypeProject - } else if strings.HasPrefix(creds.ResourceName, "organization") { - t = ResourceTypeOrganization + // TODO: filter + + for _, sa := range serviceAccounts { + resources = append(resources, &domain.Resource{ + ProviderType: pc.Type, + ProviderURN: pc.URN, + Type: rc.Type, + URN: sa.Name, + Name: sa.Email, + }) + } + + default: + return nil, ErrInvalidResourceType + } } - return []*domain.Resource{ - { - ProviderType: pc.Type, - ProviderURN: pc.URN, - Type: t, - URN: creds.ResourceName, - Name: fmt.Sprintf("%s - GCP IAM", creds.ResourceName), - }, - }, nil + return resources, nil } -func (p *Provider) GrantAccess(pc *domain.ProviderConfig, a domain.Grant) error { +func (p *Provider) GrantAccess(pc *domain.ProviderConfig, g domain.Grant) error { // TODO: validate provider config and appeal var creds Credentials @@ -103,23 +131,33 @@ func (p *Provider) GrantAccess(pc *domain.ProviderConfig, a domain.Grant) error return err } - if a.Resource.Type == ResourceTypeProject || a.Resource.Type == ResourceTypeOrganization { - for _, p := range a.Permissions { - permission := fmt.Sprint(p) - if err := client.GrantAccess(a.AccountType, a.AccountID, permission); err != nil { + switch g.Resource.Type { + case ResourceTypeProject, ResourceTypeOrganization: + for _, p := range g.Permissions { + if err := client.GrantAccess(g.AccountType, g.AccountID, p); err != nil { if !errors.Is(err, ErrPermissionAlreadyExists) { return err } } } + return nil + case ResourceTypeServiceAccount: + for _, p := range g.Permissions { + if err := client.GrantServiceAccountAccess(context.TODO(), g.Resource.URN, g.AccountType, g.AccountID, p); err != nil { + if !errors.Is(err, ErrPermissionAlreadyExists) { + return err + } + } + } return nil - } - return ErrInvalidResourceType + default: + return ErrInvalidResourceType + } } -func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, a domain.Grant) error { +func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, g domain.Grant) error { var creds Credentials if err := mapstructure.Decode(pc.Credentials, &creds); err != nil { return err @@ -130,27 +168,33 @@ func (p *Provider) RevokeAccess(pc *domain.ProviderConfig, a domain.Grant) error return err } - if a.Resource.Type == ResourceTypeProject || a.Resource.Type == ResourceTypeOrganization { - for _, p := range a.Permissions { - permission := fmt.Sprint(p) - if err := client.RevokeAccess(a.AccountType, a.AccountID, permission); err != nil { + switch g.Resource.Type { + case ResourceTypeProject, ResourceTypeOrganization: + for _, p := range g.Permissions { + if err := client.RevokeAccess(g.AccountType, g.AccountID, p); err != nil { if !errors.Is(err, ErrPermissionNotFound) { return err } } } + return nil + case ResourceTypeServiceAccount: + for _, p := range g.Permissions { + if err := client.RevokeServiceAccountAccess(context.TODO(), g.Resource.URN, g.AccountType, g.AccountID, p); err != nil { + if !errors.Is(err, ErrPermissionNotFound) { + return err + } + } + } return nil - } - return ErrInvalidResourceType + default: + return ErrInvalidResourceType + } } func (p *Provider) GetRoles(pc *domain.ProviderConfig, resourceType string) ([]*domain.Role, error) { - if resourceType != ResourceTypeProject && resourceType != ResourceTypeOrganization { - return nil, ErrInvalidResourceType - } - return provider.GetRoles(pc, resourceType) } diff --git a/plugins/providers/gcloudiam/provider_test.go b/plugins/providers/gcloudiam/provider_test.go index 7a056737..cc8fd51e 100644 --- a/plugins/providers/gcloudiam/provider_test.go +++ b/plugins/providers/gcloudiam/provider_test.go @@ -10,6 +10,7 @@ import ( "github.com/raystack/guardian/plugins/providers/gcloudiam/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "google.golang.org/api/iam/v1" ) func TestCreateConfig(t *testing.T) { @@ -96,9 +97,11 @@ func TestCreateConfig(t *testing.T) { } testcases := []struct { - pc *domain.ProviderConfig + name string + pc *domain.ProviderConfig }{ { + name: "empty resource config", pc: &domain.ProviderConfig{ Credentials: gcloudiam.Credentials{ ServiceAccountKey: base64.StdEncoding.EncodeToString([]byte("service-account-key-json")), @@ -107,6 +110,7 @@ func TestCreateConfig(t *testing.T) { }, }, { + name: "invalid resource type", pc: &domain.ProviderConfig{ Credentials: gcloudiam.Credentials{ ServiceAccountKey: base64.StdEncoding.EncodeToString([]byte("service-account-key-json")), @@ -120,6 +124,39 @@ func TestCreateConfig(t *testing.T) { }, }, { + name: "duplicate resource types", + pc: &domain.ProviderConfig{ + Credentials: gcloudiam.Credentials{ + ServiceAccountKey: base64.StdEncoding.EncodeToString([]byte("service-account-key-json")), + ResourceName: "projects/test-resource-name", + }, + Resources: []*domain.ResourceConfig{ + { + Type: gcloudiam.ResourceTypeProject, + }, + { + Type: gcloudiam.ResourceTypeProject, + }, + }, + }, + }, + { + name: "service_account resource type in organization-level provider", + pc: &domain.ProviderConfig{ + Credentials: gcloudiam.Credentials{ + ServiceAccountKey: base64.StdEncoding.EncodeToString([]byte("service-account-key-json")), + ResourceName: "organizations/my-organization-id", + }, + Resources: []*domain.ResourceConfig{ + { + Type: gcloudiam.ResourceTypeServiceAccount, + }, + }, + URN: providerURN, + }, + }, + { + name: "empty roles", pc: &domain.ProviderConfig{ Credentials: gcloudiam.Credentials{ ServiceAccountKey: base64.StdEncoding.EncodeToString([]byte("service-account-key-json")), @@ -152,16 +189,16 @@ func TestCreateConfig(t *testing.T) { crypto.On("Encrypt", `{"type":"service_account"}`).Return("", expectedError) - gcloudRole1 := &gcloudiam.Role{ - Name: "roles/bigquery.admin", - Title: "BigQuery Admin", - Description: "Administer all BigQuery resources and data", + gCloudRolesList := []*iam.Role{ + { + Name: "roles/bigquery.admin", + Title: "BigQuery Admin", + Description: "Administer all BigQuery resources and data", + }, } - - gCloudRolesList := []*gcloudiam.Role{} - gCloudRolesList = append(gCloudRolesList, gcloudRole1) - - client.On("GetRoles").Return(gCloudRolesList, nil).Once() + client.EXPECT(). + GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeProject). + Return(gCloudRolesList, nil).Once() pc := &domain.ProviderConfig{ Resources: []*domain.ResourceConfig{ @@ -197,16 +234,16 @@ func TestCreateConfig(t *testing.T) { providerURN: client, } - gcloudRole1 := &gcloudiam.Role{ - Name: "roles/bigquery.admin", - Title: "BigQuery Admin", - Description: "Administer all BigQuery resources and data", + gCloudRolesList := []*iam.Role{ + { + Name: "roles/bigquery.admin", + Title: "BigQuery Admin", + Description: "Administer all BigQuery resources and data", + }, } - - gCloudRolesList := []*gcloudiam.Role{} - gCloudRolesList = append(gCloudRolesList, gcloudRole1) - - client.On("GetRoles").Return(gCloudRolesList, nil).Once() + client.EXPECT(). + GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeProject). + Return(gCloudRolesList, nil).Once() crypto.On("Encrypt", `{"type":"service_account"}`).Return(`{"type":"service_account"}`, nil) @@ -257,6 +294,9 @@ func TestGetResources(t *testing.T) { Type: domain.ProviderTypeGCloudIAM, URN: "test-project-id", Credentials: "invalid-creds", + Resources: []*domain.ResourceConfig{ + {Type: gcloudiam.ResourceTypeProject}, + }, } actualResources, actualError := p.GetResources(pc) @@ -265,31 +305,50 @@ func TestGetResources(t *testing.T) { assert.Error(t, actualError) }) + providerURN := "test-provider-urn" + crypto := new(mocks.Encryptor) + client := new(mocks.GcloudIamClient) + p := gcloudiam.NewProvider("", crypto) + p.Clients = map[string]gcloudiam.GcloudIamClient{ + providerURN: client, + } + t.Run("should check for valid roles in provider config and return project resource object", func(t *testing.T) { - providerURN := "test-provider-urn" - crypto := new(mocks.Encryptor) - client := new(mocks.GcloudIamClient) - p := gcloudiam.NewProvider("", crypto) - p.Clients = map[string]gcloudiam.GcloudIamClient{ - providerURN: client, + projectRoles := []*iam.Role{ + { + Name: "roles/bigquery.admin", + Title: "BigQuery Admin", + Description: "Administer all BigQuery resources and data", + }, + { + Name: "roles/apigateway.viewer", + Title: "ApiGateway Viewer", + Description: "Read-only access to ApiGateway and related resources", + }, } - - gcloudRole1 := &gcloudiam.Role{ - Name: "roles/bigquery.admin", - Title: "BigQuery Admin", - Description: "Administer all BigQuery resources and data", + saRoles := []*iam.Role{ + { + Name: "roles/workstations.serviceAgent", + Title: "Workstations Service Agent", + Description: "Grants the Workstations Service Account access to manage resources in consumer project.", + }, } - - gcloudRole2 := &gcloudiam.Role{ - Name: "roles/apigateway.viewer", - Title: "ApiGateway Viewer", - Description: "Read-only access to ApiGateway and related resources", + client.EXPECT(). + GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeProject). + Return(projectRoles, nil).Once() + client.EXPECT(). + GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeServiceAccount). + Return(saRoles, nil).Once() + + expectedServiceAccounts := []*iam.ServiceAccount{ + { + Name: "sa-name", + Email: "sa-email", + }, } - gCloudRolesList := []*gcloudiam.Role{} - gCloudRolesList = append(gCloudRolesList, gcloudRole1) - gCloudRolesList = append(gCloudRolesList, gcloudRole2) - - client.On("GetRoles").Return(gCloudRolesList, nil).Once() + client.EXPECT(). + ListServiceAccounts(mock.AnythingOfType("*context.emptyCtx")). + Return(expectedServiceAccounts, nil).Once() pc := &domain.ProviderConfig{ Type: domain.ProviderTypeGCloudIAM, @@ -300,7 +359,7 @@ func TestGetResources(t *testing.T) { }, Resources: []*domain.ResourceConfig{ { - Type: "project", + Type: gcloudiam.ResourceTypeProject, Roles: []*domain.Role{ { ID: "role-1", @@ -314,6 +373,15 @@ func TestGetResources(t *testing.T) { }, }, }, + { + Type: gcloudiam.ResourceTypeServiceAccount, + Roles: []*domain.Role{ + { + ID: "role-1", + Permissions: []interface{}{"roles/workstations.serviceAgent"}, + }, + }, + }, }, } @@ -325,6 +393,13 @@ func TestGetResources(t *testing.T) { URN: "project/test-resource-name", Name: "project/test-resource-name - GCP IAM", }, + { + ProviderType: pc.Type, + ProviderURN: pc.URN, + Type: gcloudiam.ResourceTypeServiceAccount, + URN: "sa-name", + Name: "sa-email", + }, } actualResources, actualError := p.GetResources(pc) @@ -333,23 +408,16 @@ func TestGetResources(t *testing.T) { }) t.Run("should return organization resource object", func(t *testing.T) { - providerURN := "test-provider-urn" - crypto := new(mocks.Encryptor) - client := new(mocks.GcloudIamClient) - p := gcloudiam.NewProvider("", crypto) - p.Clients = map[string]gcloudiam.GcloudIamClient{ - providerURN: client, - } - gcloudRole := &gcloudiam.Role{ - Name: "roles/organisation.admin", - Title: "Organisation Admin", - Description: "Administer all Organisation resources and data", + gCloudRolesList := []*iam.Role{ + { + Name: "roles/organisation.admin", + Title: "Organisation Admin", + Description: "Administer all Organisation resources and data", + }, } - - gCloudRolesList := []*gcloudiam.Role{} - gCloudRolesList = append(gCloudRolesList, gcloudRole) - - client.On("GetRoles").Return(gCloudRolesList, nil).Once() + client.EXPECT(). + GetGrantableRoles(mock.AnythingOfType("*context.emptyCtx"), gcloudiam.ResourceTypeOrganization). + Return(gCloudRolesList, nil).Once() pc := &domain.ProviderConfig{ Type: domain.ProviderTypeGCloudIAM, URN: providerURN, @@ -358,7 +426,7 @@ func TestGetResources(t *testing.T) { }, Resources: []*domain.ResourceConfig{ { - Type: "organization", + Type: gcloudiam.ResourceTypeOrganization, Roles: []*domain.Role{ { ID: "role-1", @@ -385,6 +453,65 @@ func TestGetResources(t *testing.T) { assert.Equal(t, expectedResources, actualResources) assert.Nil(t, actualError) }) + + t.Run("should return error if resource type in invalid", func(t *testing.T) { + pc := &domain.ProviderConfig{ + Type: domain.ProviderTypeGCloudIAM, + URN: providerURN, + Credentials: map[string]interface{}{ + "resource_name": "project/test-resource-name", + }, + Resources: []*domain.ResourceConfig{ + {Type: "invalid-resource-type"}, + }, + } + _, err := p.GetResources(pc) + + assert.ErrorIs(t, err, gcloudiam.ErrInvalidResourceType) + }) + + t.Run("get service accounts resources", func(t *testing.T) { + t.Run("should return error if client initialization failed", func(t *testing.T) { + pc := &domain.ProviderConfig{ + Type: domain.ProviderTypeGCloudIAM, + URN: providerURN, + Credentials: map[string]interface{}{ + "resource_name": make(chan int), + }, + Resources: []*domain.ResourceConfig{ + { + Type: gcloudiam.ResourceTypeServiceAccount, + }, + }, + } + + _, actualError := p.GetResources(pc) + + assert.Error(t, actualError) + }) + + t.Run("should return error if client returns an error", func(t *testing.T) { + expectedError := errors.New("client error") + client.On("ListServiceAccounts", mock.AnythingOfType("*context.emptyCtx")).Return(nil, expectedError).Once() + + pc := &domain.ProviderConfig{ + Type: domain.ProviderTypeGCloudIAM, + URN: providerURN, + Credentials: map[string]interface{}{ + "resource_name": "project/test-resource-name", + }, + Resources: []*domain.ResourceConfig{ + { + Type: gcloudiam.ResourceTypeServiceAccount, + }, + }, + } + + _, actualError := p.GetResources(pc) + + assert.ErrorIs(t, actualError, expectedError) + }) + }) } func TestGrantAccess(t *testing.T) { @@ -443,15 +570,107 @@ func TestGrantAccess(t *testing.T) { }) t.Run("should return error if there is an error in granting the access", func(t *testing.T) { + expectedError := errors.New("client error in granting access") + testCases := []struct { + name string + resourceType string + expectedError error + setExpectationFunc func(*mocks.GcloudIamClient) + }{ + { + name: "for project", + resourceType: gcloudiam.ResourceTypeProject, + expectedError: expectedError, + setExpectationFunc: func(c *mocks.GcloudIamClient) { + c.EXPECT(). + GrantAccess(mock.Anything, mock.Anything, mock.Anything). + Return(expectedError).Once() + }, + }, + { + name: "for organization", + resourceType: gcloudiam.ResourceTypeOrganization, + expectedError: expectedError, + setExpectationFunc: func(c *mocks.GcloudIamClient) { + c.EXPECT(). + GrantAccess(mock.Anything, mock.Anything, mock.Anything). + Return(expectedError).Once() + }, + }, + { + name: "for service account", + resourceType: gcloudiam.ResourceTypeServiceAccount, + expectedError: expectedError, + setExpectationFunc: func(c *mocks.GcloudIamClient) { + c.EXPECT(). + GrantServiceAccountAccess(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(expectedError).Once() + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + providerURN := "test-provider-urn" + crypto := new(mocks.Encryptor) + client := new(mocks.GcloudIamClient) + p := gcloudiam.NewProvider("", crypto) + p.Clients = map[string]gcloudiam.GcloudIamClient{ + providerURN: client, + } + + tc.setExpectationFunc(client) + + pc := &domain.ProviderConfig{ + Resources: []*domain.ResourceConfig{ + { + Type: tc.resourceType, + Roles: []*domain.Role{ + { + ID: "role-1", + Name: "role-name-1", + Permissions: []interface{}{"permission-1"}, + }, + { + ID: "role-2", + Name: "role-name-2", + Permissions: []interface{}{"permission-2"}, + }, + }, + }, + }, + URN: providerURN, + } + a := domain.Grant{ + Resource: &domain.Resource{ + Type: tc.resourceType, + URN: "999", + Name: "test-role", + }, + Role: "role-1", + Permissions: []string{"permission-1"}, + } + + actualError := p.GrantAccess(pc, a) + + assert.EqualError(t, actualError, tc.expectedError.Error()) + }) + } + }) + + t.Run("should return nil error if granting access is successful", func(t *testing.T) { providerURN := "test-provider-urn" - expectedError := errors.New("client error") crypto := new(mocks.Encryptor) client := new(mocks.GcloudIamClient) + expectedRole := "role-1" + expectedAccountType := "user" + expectedAccountID := "test@email.com" + expectedPermission := "roles/bigquery.admin" p := gcloudiam.NewProvider("", crypto) p.Clients = map[string]gcloudiam.GcloudIamClient{ providerURN: client, } - client.On("GrantAccess", mock.Anything, mock.Anything, mock.Anything).Return(expectedError).Once() + client.On("GrantAccess", expectedAccountType, expectedAccountID, expectedPermission).Return(nil).Once() pc := &domain.ProviderConfig{ Resources: []*domain.ResourceConfig{ @@ -473,71 +692,64 @@ func TestGrantAccess(t *testing.T) { }, URN: providerURN, } - a := domain.Grant{ + g := domain.Grant{ Resource: &domain.Resource{ Type: gcloudiam.ResourceTypeProject, - URN: "999", - Name: "test-role", + URN: "test-role", }, - Role: "role-1", + Role: expectedRole, + AccountType: expectedAccountType, + AccountID: expectedAccountID, + ResourceID: "999", + ID: "999", Permissions: []string{"roles/bigquery.admin"}, } - actualError := p.GrantAccess(pc, a) + actualError := p.GrantAccess(pc, g) - assert.EqualError(t, actualError, expectedError.Error()) + assert.Nil(t, actualError) }) - t.Run("should return nil error if granting access is successful", func(t *testing.T) { + t.Run("successful grant access to a service account", func(t *testing.T) { providerURN := "test-provider-urn" crypto := new(mocks.Encryptor) client := new(mocks.GcloudIamClient) - expectedRole := "role-1" - expectedAccountType := "user" - expectedAccountID := "test@email.com" - expectedPermission := "roles/bigquery.admin" p := gcloudiam.NewProvider("", crypto) p.Clients = map[string]gcloudiam.GcloudIamClient{ providerURN: client, } - client.On("GrantAccess", expectedAccountType, expectedAccountID, expectedPermission).Return(nil).Once() pc := &domain.ProviderConfig{ + URN: providerURN, Resources: []*domain.ResourceConfig{ { - Type: gcloudiam.ResourceTypeProject, + Type: gcloudiam.ResourceTypeServiceAccount, Roles: []*domain.Role{ { - ID: "role-1", - Name: "BigQuery", - Permissions: []interface{}{"roles/bigquery.admin"}, - }, - { - ID: "role-2", - Name: "Api gateway", - Permissions: []interface{}{"roles/apigateway.viewer"}, + ID: "test-role", + Permissions: []interface{}{"test-permission"}, }, }, }, }, - URN: providerURN, } - a := domain.Grant{ + g := domain.Grant{ Resource: &domain.Resource{ - Type: gcloudiam.ResourceTypeProject, - URN: "test-role", + Type: gcloudiam.ResourceTypeServiceAccount, + URN: "sa-urn", }, - Role: expectedRole, - AccountType: expectedAccountType, - AccountID: expectedAccountID, - ResourceID: "999", - ID: "999", - Permissions: []string{"roles/bigquery.admin"}, + Role: "test-role", + AccountType: "test-account-type", + AccountID: "test-account-id", + Permissions: []string{"test-permission"}, } - actualError := p.GrantAccess(pc, a) + client.EXPECT(). + GrantServiceAccountAccess(mock.AnythingOfType("*context.emptyCtx"), g.Resource.URN, g.AccountType, g.AccountID, g.Permissions[0]). + Return(nil).Once() - assert.Nil(t, actualError) + err := p.GrantAccess(pc, g) + assert.NoError(t, err) }) } @@ -573,15 +785,107 @@ func TestRevokeAccess(t *testing.T) { }) t.Run("should return error if there is an error in revoking the access", func(t *testing.T) { + expectedError := errors.New("client error in revoking access") + testCases := []struct { + name string + resourceType string + expectedError error + setExpectationFunc func(*mocks.GcloudIamClient) + }{ + { + name: "for project", + resourceType: gcloudiam.ResourceTypeProject, + expectedError: expectedError, + setExpectationFunc: func(c *mocks.GcloudIamClient) { + c.EXPECT(). + RevokeAccess(mock.Anything, mock.Anything, mock.Anything). + Return(expectedError).Once() + }, + }, + { + name: "for organization", + resourceType: gcloudiam.ResourceTypeOrganization, + expectedError: expectedError, + setExpectationFunc: func(c *mocks.GcloudIamClient) { + c.EXPECT(). + RevokeAccess(mock.Anything, mock.Anything, mock.Anything). + Return(expectedError).Once() + }, + }, + { + name: "for service account", + resourceType: gcloudiam.ResourceTypeServiceAccount, + expectedError: expectedError, + setExpectationFunc: func(c *mocks.GcloudIamClient) { + c.EXPECT(). + RevokeServiceAccountAccess(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(expectedError).Once() + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + providerURN := "test-provider-urn" + crypto := new(mocks.Encryptor) + client := new(mocks.GcloudIamClient) + p := gcloudiam.NewProvider("", crypto) + p.Clients = map[string]gcloudiam.GcloudIamClient{ + providerURN: client, + } + + tc.setExpectationFunc(client) + + pc := &domain.ProviderConfig{ + Resources: []*domain.ResourceConfig{ + { + Type: tc.resourceType, + Roles: []*domain.Role{ + { + ID: "role-1", + Name: "role-name-1", + Permissions: []interface{}{"permission-1"}, + }, + { + ID: "role-2", + Name: "role-name-2", + Permissions: []interface{}{"permission-2"}, + }, + }, + }, + }, + URN: providerURN, + } + a := domain.Grant{ + Resource: &domain.Resource{ + Type: tc.resourceType, + URN: "999", + Name: "test-role", + }, + Role: "role-1", + Permissions: []string{"permission-1"}, + } + + actualError := p.RevokeAccess(pc, a) + + assert.EqualError(t, actualError, tc.expectedError.Error()) + }) + } + }) + + t.Run("should return nil error if revoking access is successful", func(t *testing.T) { providerURN := "test-provider-urn" - expectedError := errors.New("client error") crypto := new(mocks.Encryptor) client := new(mocks.GcloudIamClient) + expectedRole := "role-1" + expectedPermission := "roles/bigquery.admin" + expectedAccountType := "user" + expectedAccountID := "test@email.com" p := gcloudiam.NewProvider("", crypto) p.Clients = map[string]gcloudiam.GcloudIamClient{ providerURN: client, } - client.On("RevokeAccess", mock.Anything, mock.Anything, mock.Anything).Return(expectedError).Once() + client.On("RevokeAccess", expectedAccountType, expectedAccountID, expectedPermission).Return(nil).Once() pc := &domain.ProviderConfig{ Resources: []*domain.ResourceConfig{ @@ -606,67 +910,60 @@ func TestRevokeAccess(t *testing.T) { a := domain.Grant{ Resource: &domain.Resource{ Type: gcloudiam.ResourceTypeProject, - URN: "999", - Name: "test-role", + URN: "test-role", }, - Role: "role-1", - Permissions: []string{"roles/bigquery.admin"}, + Role: expectedRole, + AccountType: expectedAccountType, + AccountID: expectedAccountID, + ResourceID: "999", + ID: "999", } actualError := p.RevokeAccess(pc, a) - assert.EqualError(t, actualError, expectedError.Error()) + assert.Nil(t, actualError) }) - t.Run("should return nil error if revoking access is successful", func(t *testing.T) { + t.Run("successful revoke access to a service account", func(t *testing.T) { providerURN := "test-provider-urn" crypto := new(mocks.Encryptor) client := new(mocks.GcloudIamClient) - expectedRole := "role-1" - expectedPermission := "roles/bigquery.admin" - expectedAccountType := "user" - expectedAccountID := "test@email.com" p := gcloudiam.NewProvider("", crypto) p.Clients = map[string]gcloudiam.GcloudIamClient{ providerURN: client, } - client.On("RevokeAccess", expectedAccountType, expectedAccountID, expectedPermission).Return(nil).Once() pc := &domain.ProviderConfig{ + URN: providerURN, Resources: []*domain.ResourceConfig{ { - Type: gcloudiam.ResourceTypeProject, + Type: gcloudiam.ResourceTypeServiceAccount, Roles: []*domain.Role{ { - ID: "role-1", - Name: "BigQuery", - Permissions: []interface{}{"roles/bigquery.admin"}, - }, - { - ID: "role-2", - Name: "Api gateway", - Permissions: []interface{}{"roles/apigateway.viewer"}, + ID: "test-role", + Permissions: []interface{}{"test-permission"}, }, }, }, }, - URN: providerURN, } - a := domain.Grant{ + g := domain.Grant{ Resource: &domain.Resource{ - Type: gcloudiam.ResourceTypeProject, - URN: "test-role", + Type: gcloudiam.ResourceTypeServiceAccount, + URN: "sa-urn", }, - Role: expectedRole, - AccountType: expectedAccountType, - AccountID: expectedAccountID, - ResourceID: "999", - ID: "999", + Role: "test-role", + AccountType: "test-account-type", + AccountID: "test-account-id", + Permissions: []string{"test-permission"}, } - actualError := p.RevokeAccess(pc, a) + client.EXPECT(). + RevokeServiceAccountAccess(mock.AnythingOfType("*context.emptyCtx"), g.Resource.URN, g.AccountType, g.AccountID, g.Permissions[0]). + Return(nil).Once() - assert.Nil(t, actualError) + err := p.RevokeAccess(pc, g) + assert.NoError(t, err) }) } diff --git a/plugins/providers/gcloudiam/resource.go b/plugins/providers/gcloudiam/resource.go index ed3efc8c..76f64b4c 100644 --- a/plugins/providers/gcloudiam/resource.go +++ b/plugins/providers/gcloudiam/resource.go @@ -1,8 +1,9 @@ package gcloudiam const ( - ResourceTypeProject = "project" - ResourceTypeOrganization = "organization" + ResourceTypeProject = "project" + ResourceTypeOrganization = "organization" + ResourceTypeServiceAccount = "service_account" ) type Role struct { diff --git a/plugins/providers/gcs/mocks/Crypto.go b/plugins/providers/gcs/mocks/Crypto.go index d554c963..12dcb72d 100644 --- a/plugins/providers/gcs/mocks/Crypto.go +++ b/plugins/providers/gcs/mocks/Crypto.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/plugins/providers/gcs/mocks/GCSClient.go b/plugins/providers/gcs/mocks/GCSClient.go index be3a545c..8ad7fcd7 100644 --- a/plugins/providers/gcs/mocks/GCSClient.go +++ b/plugins/providers/gcs/mocks/GCSClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.32.4. DO NOT EDIT. +// Code generated by mockery v2.33.3. DO NOT EDIT. package mocks diff --git a/utils/struct.go b/utils/struct.go new file mode 100644 index 00000000..78b45951 --- /dev/null +++ b/utils/struct.go @@ -0,0 +1,21 @@ +package utils + +import "encoding/json" + +// StructToMap converts a struct to a map using json marshalling +func StructToMap(v interface{}) (map[string]interface{}, error) { + result := map[string]interface{}{} + + if v != nil { + jsonString, err := json.Marshal(v) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(jsonString, &result); err != nil { + return nil, err + } + } + + return result, nil +} diff --git a/utils/struct_test.go b/utils/struct_test.go new file mode 100644 index 00000000..67b3b138 --- /dev/null +++ b/utils/struct_test.go @@ -0,0 +1,58 @@ +package utils_test + +import ( + "testing" + + "github.com/raystack/guardian/utils" + "github.com/stretchr/testify/assert" +) + +type testStructToMap struct { + Key string `json:"key"` + OmittedKey string `json:"omitted_key,omitempty"` +} + +func TestStructToMap(t *testing.T) { + testCases := []struct { + name string + input interface{} + expected map[string]interface{} + }{ + { + name: "should return map with all fields", + input: testStructToMap{ + Key: "value", + OmittedKey: "value", + }, + expected: map[string]interface{}{ + "key": "value", + "omitted_key": "value", + }, + }, + { + name: "should return map with omitted fields", + input: testStructToMap{ + Key: "value", + }, + expected: map[string]interface{}{ + "key": "value", + }, + }, + { + name: "should return empty map when input is nil", + input: nil, + expected: map[string]interface{}{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result, err := utils.StructToMap(tc.input) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + assert.Equal(t, tc.expected, result) + }) + } +} diff --git a/utils/time.go b/utils/time.go index 8573d127..0e4f1741 100644 --- a/utils/time.go +++ b/utils/time.go @@ -3,8 +3,10 @@ package utils import ( "fmt" "time" +) - "github.com/raystack/guardian/domain" +const ( + PermanentDurationLabel = "Permanent" ) // GetReadableDuration returns a human-readable duration string in integer days preferably, or the original string if it's either not a valid duration or a days value is not integer. @@ -24,5 +26,5 @@ func GetReadableDuration(durationStr string) (string, error) { return durationStr, nil } - return domain.PermanentDurationLabel, nil + return PermanentDurationLabel, nil }