From 3172c53e1b6f50d8a14191cec07f3dc5e70166a9 Mon Sep 17 00:00:00 2001 From: Arinda Arif <79823430+arinda-arif@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:30:25 +0700 Subject: [PATCH] feat: resource upsert (#239) * feat: add upsert resource in resource service * feat: add upsert resource in resource handler * feat: accept multiple resources in upsert resource api * feat: add resource upload command * feat: add error message to the upsert response * fix: return error when failure found in resource upload command * chore: update latest proto * chore: update to latest proto with unary changes * test: fix broken test cases in resource upsert * refactor: reuse resource upsert & diff detection logic from deploy, in new upsert api * chore: reword resource upload command examples * feat: add successful resource names in resource upsert response * chore: update proton commit --- Makefile | 2 +- client/cmd/resource/resource.go | 1 + client/cmd/resource/upload.go | 193 ++++ core/resource/handler/v1beta1/resource.go | 60 ++ .../resource/handler/v1beta1/resource_test.go | 191 ++++ core/resource/service/resource_service.go | 112 ++- .../resource/service/resource_service_test.go | 246 ++++- core/resource/status.go | 2 + .../optimus/core/v1beta1/resource.pb.go | 841 ++++++++++++------ .../optimus/core/v1beta1/resource.pb.gw.go | 155 ++++ .../core/v1beta1/resource.swagger.json | 102 ++- .../optimus/core/v1beta1/resource_grpc.pb.go | 38 + 12 files changed, 1639 insertions(+), 304 deletions(-) create mode 100644 client/cmd/resource/upload.go diff --git a/Makefile b/Makefile index b6d5c6ae1d..6805ac438f 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ NAME = "github.com/goto/optimus" LAST_COMMIT := $(shell git rev-parse --short HEAD) LAST_TAG := "$(shell git rev-list --tags --max-count=1)" OPMS_VERSION := "$(shell git describe --tags ${LAST_TAG})-next" -PROTON_COMMIT := "5499ce17808277216119aa715a105b688875666f" +PROTON_COMMIT := "0278f0402ee9d1b5f392e03c7f45160879924d78" .PHONY: build test test-ci generate-proto unit-test-ci integration-test vet coverage clean install lint diff --git a/client/cmd/resource/resource.go b/client/cmd/resource/resource.go index 05355f4b49..8215cbb08e 100644 --- a/client/cmd/resource/resource.go +++ b/client/cmd/resource/resource.go @@ -20,6 +20,7 @@ func NewResourceCommand() *cobra.Command { cmd.AddCommand(NewChangeNamespaceCommand()) cmd.AddCommand(NewApplyCommand()) cmd.AddCommand(NewDeleteCommand()) + cmd.AddCommand(NewUploadCommand()) cmd.AddCommand(NewPlanCommand()) return cmd } diff --git a/client/cmd/resource/upload.go b/client/cmd/resource/upload.go new file mode 100644 index 0000000000..ffb13049f7 --- /dev/null +++ b/client/cmd/resource/upload.go @@ -0,0 +1,193 @@ +package resource + +import ( + "context" + "fmt" + "time" + + "github.com/MakeNowJust/heredoc" + "github.com/goto/salt/log" + "github.com/spf13/afero" + "github.com/spf13/cobra" + + "github.com/goto/optimus/client/cmd/internal/connection" + "github.com/goto/optimus/client/cmd/internal/logger" + "github.com/goto/optimus/client/local" + "github.com/goto/optimus/client/local/model" + "github.com/goto/optimus/client/local/specio" + "github.com/goto/optimus/config" + "github.com/goto/optimus/core/resource" + pb "github.com/goto/optimus/protos/gotocompany/optimus/core/v1beta1" +) + +const ( + uploadTimeout = time.Minute * 30 + defaultBatchSize = 10 +) + +type uploadCommand struct { + logger log.Logger + connection connection.Connection + + clientConfig *config.ClientConfig + configFilePath string + + namespaceName string + resourceNames []string + batchSize int + + resourceSpecReadWriter local.SpecReadWriter[*model.ResourceSpec] +} + +// NewUploadCommand initializes command for uploading a single resource +func NewUploadCommand() *cobra.Command { + uploadCmd := &uploadCommand{ + logger: logger.NewClientLogger(), + } + + cmd := &cobra.Command{ + Use: "upload", + Short: "Upload a resource to server", + Long: heredoc.Doc(`Apply local changes to destination server which includes creating/updating resources`), + Example: "optimus resource upload -R -n ", + Annotations: map[string]string{ + "group:core": "true", + }, + RunE: uploadCmd.RunE, + PreRunE: uploadCmd.PreRunE, + } + cmd.Flags().StringVarP(&uploadCmd.configFilePath, "config", "c", uploadCmd.configFilePath, "File path for client configuration") + cmd.Flags().StringVarP(&uploadCmd.namespaceName, "namespace", "n", "", "Namespace name in which the resources resides") + cmd.Flags().StringSliceVarP(&uploadCmd.resourceNames, "resources", "R", nil, "Resource names") + cmd.Flags().IntVarP(&uploadCmd.batchSize, "batch-size", "b", defaultBatchSize, "Number of resources to upload in a batch") + + cmd.MarkFlagRequired("namespace") + return cmd +} + +func (u *uploadCommand) PreRunE(_ *cobra.Command, _ []string) error { + var err error + u.clientConfig, err = config.LoadClientConfig(u.configFilePath) + if err != nil { + return err + } + u.connection = connection.New(u.logger, u.clientConfig) + + resourceSpecReadWriter, err := specio.NewResourceSpecReadWriter(afero.NewOsFs()) + if err != nil { + return fmt.Errorf("couldn't instantiate resource spec reader") + } + u.resourceSpecReadWriter = resourceSpecReadWriter + + return nil +} + +func (u *uploadCommand) RunE(_ *cobra.Command, _ []string) error { + namespace, err := u.clientConfig.GetNamespaceByName(u.namespaceName) + if err != nil { + return err + } + + return u.upload(namespace) +} + +func (u *uploadCommand) upload(namespace *config.Namespace) error { + conn, err := u.connection.Create(u.clientConfig.Host) + if err != nil { + return err + } + defer conn.Close() + + resourceClient := pb.NewResourceServiceClient(conn) + + ctx, cancelFunc := context.WithTimeout(context.Background(), uploadTimeout) + defer cancelFunc() + + isFailed := false + for _, ds := range namespace.Datastore { + resourceSpecs, err := u.getResourceSpecs(ds.Path) + if err != nil { + u.logger.Error(err.Error()) + isFailed = true + continue + } + + resourceProtos := make([]*pb.ResourceSpecification, 0) + for _, resourceSpec := range resourceSpecs { + resourceProto, err := resourceSpec.ToProto() + if err != nil { + u.logger.Error(err.Error()) + isFailed = true + continue + } + resourceProtos = append(resourceProtos, resourceProto) + } + + countResources := len(resourceProtos) + for i := 0; i < countResources; i += u.batchSize { + endIndex := i + u.batchSize + if countResources < endIndex { + endIndex = countResources + } + + upsertRequest := &pb.UpsertResourceRequest{ + ProjectName: u.clientConfig.Project.Name, + NamespaceName: namespace.Name, + DatastoreName: ds.Type, + Resources: resourceProtos[i:endIndex], + } + + resp, err := resourceClient.UpsertResource(ctx, upsertRequest) + if err != nil { + u.logger.Error("Unable to upload resource of namespace %s, err: %s", u.namespaceName, err) + isFailed = true + } + for _, result := range resp.Results { + message := result.Message + if message != "" { + message = fmt.Sprintf("(%s)", message) + } + if result.Status == resource.StatusFailure.String() { + u.logger.Error("[%s] %s %s", result.Status, result.ResourceName, message) + isFailed = true + continue + } + u.logger.Info("[%s] %s %s", result.Status, result.ResourceName, message) + } + } + } + if isFailed { + return fmt.Errorf("upload resource specifications to namespace %s failed", u.namespaceName) + } + u.logger.Info("finished uploading resource specifications to server\n") + return nil +} + +func (u *uploadCommand) getResourceSpecs(namespaceResourcePath string) ([]*model.ResourceSpec, error) { + allResourcesInNamespace, err := u.resourceSpecReadWriter.ReadAll(namespaceResourcePath) + if err != nil { + return nil, err + } + resourceNameToSpecMap := make(map[string]*model.ResourceSpec, len(allResourcesInNamespace)) + for _, spec := range allResourcesInNamespace { + resourceNameToSpecMap[spec.Name] = spec + } + + resourceSpecs := make([]*model.ResourceSpec, 0) + + if len(u.resourceNames) == 0 { + for _, spec := range resourceNameToSpecMap { + resourceSpecs = append(resourceSpecs, spec) + } + return resourceSpecs, nil + } + + for _, resourceName := range u.resourceNames { + resourceSpec, ok := resourceNameToSpecMap[resourceName] + if !ok { + return nil, fmt.Errorf("resource %s not found in namespace %s", resourceName, u.namespaceName) + } + resourceSpecs = append(resourceSpecs, resourceSpec) + } + return resourceSpecs, nil +} diff --git a/core/resource/handler/v1beta1/resource.go b/core/resource/handler/v1beta1/resource.go index eef6ef410e..1d8c8d00f6 100644 --- a/core/resource/handler/v1beta1/resource.go +++ b/core/resource/handler/v1beta1/resource.go @@ -26,6 +26,7 @@ const ( type ResourceService interface { Create(ctx context.Context, res *resource.Resource) error Update(ctx context.Context, res *resource.Resource, logWriter writer.LogWriter) error + Upsert(ctx context.Context, res *resource.Resource, logWriter writer.LogWriter) error Delete(ctx context.Context, req *resource.DeleteRequest) (*resource.DeleteResponse, error) ChangeNamespace(ctx context.Context, datastore resource.Store, resourceFullName string, oldTenant, newTenant tenant.Tenant) error Get(ctx context.Context, tnnt tenant.Tenant, store resource.Store, resourceName string) (*resource.Resource, error) @@ -266,6 +267,65 @@ func (rh ResourceHandler) UpdateResource(ctx context.Context, req *pb.UpdateReso return &pb.UpdateResourceResponse{}, nil } +func (rh ResourceHandler) UpsertResource(ctx context.Context, req *pb.UpsertResourceRequest) (*pb.UpsertResourceResponse, error) { + tnnt, err := tenant.NewTenant(req.GetProjectName(), req.GetNamespaceName()) + if err != nil { + rh.l.Error("invalid tenant information request project [%s] namespace [%s]: %s", req.GetProjectName(), req.GetNamespaceName(), err) + return nil, errors.GRPCErr(err, "failed to upsert resource") + } + + store, err := resource.FromStringToStore(req.GetDatastoreName()) + if err != nil { + rh.l.Error("invalid datastore name [%s]: %s", req.GetDatastoreName(), err) + return nil, errors.GRPCErr(err, "invalid upsert resource request") + } + + if len(req.Resources) == 0 { + return nil, errors.InvalidArgument(resource.EntityResource, "empty resource") + } + + logWriter := writer.NewLogWriter(rh.l) + result := make([]*pb.ResourceStatus, 0) + + var successfulResourceNames []string + for _, reqResource := range req.Resources { + resourceSpec, err := fromResourceProto(reqResource, tnnt, store) + if err != nil { + errMsg := fmt.Sprintf("error adapting resource [%s]: %s", reqResource.GetName(), err) + logWriter.Write(writer.LogLevelError, errMsg) + result = append(result, rh.newResourceStatus(reqResource.GetName(), resource.StatusFailure.String(), errMsg)) + continue + } + + if err = rh.service.Upsert(ctx, resourceSpec, logWriter); err != nil { + errMsg := fmt.Sprintf("error deploying resource [%s]: %s", reqResource.GetName(), err) + logWriter.Write(writer.LogLevelError, errMsg) + result = append(result, rh.newResourceStatus(reqResource.GetName(), resource.StatusFailure.String(), errMsg)) + continue + } + + result = append(result, rh.newResourceStatus(resourceSpec.FullName(), resourceSpec.Status().String(), "")) + raiseResourceDatastoreEventMetric(tnnt, resourceSpec.Store().String(), resourceSpec.Kind(), resourceSpec.Status().String()) + + if resourceSpec.Status() == resource.StatusSuccess { + successfulResourceNames = append(successfulResourceNames, resourceSpec.FullName()) + } + } + + return &pb.UpsertResourceResponse{ + Results: result, + SuccessfulResourceNames: successfulResourceNames, + }, nil +} + +func (ResourceHandler) newResourceStatus(name, status, message string) *pb.ResourceStatus { + return &pb.ResourceStatus{ + ResourceName: name, + Status: status, + Message: message, + } +} + func (rh ResourceHandler) DeleteResource(ctx context.Context, req *pb.DeleteResourceRequest) (*pb.DeleteResourceResponse, error) { tnnt, err := tenant.NewTenant(req.GetProjectName(), req.GetNamespaceName()) if err != nil { diff --git a/core/resource/handler/v1beta1/resource_test.go b/core/resource/handler/v1beta1/resource_test.go index 12382869a4..15a361875d 100644 --- a/core/resource/handler/v1beta1/resource_test.go +++ b/core/resource/handler/v1beta1/resource_test.go @@ -713,6 +713,192 @@ func TestResourceHandler(t *testing.T) { assert.Nil(t, err) }) }) + t.Run("UpsertResource", func(t *testing.T) { + t.Run("returns error when tenant is invalid", func(t *testing.T) { + service := new(resourceService) + handler := v1beta1.NewResourceHandler(logger, service) + + req := &pb.UpsertResourceRequest{ + ProjectName: "", + DatastoreName: "bigquery", + Resources: nil, + NamespaceName: "", + } + + _, err := handler.UpsertResource(ctx, req) + assert.NotNil(t, err) + assert.EqualError(t, err, "rpc error: code = InvalidArgument desc = invalid argument for entity "+ + "project: project name is empty: failed to upsert resource") + }) + t.Run("returns error when store is invalid", func(t *testing.T) { + service := new(resourceService) + handler := v1beta1.NewResourceHandler(logger, service) + + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "", + Resources: nil, + NamespaceName: "ns", + } + + _, err := handler.UpsertResource(ctx, req) + assert.NotNil(t, err) + assert.EqualError(t, err, "rpc error: code = InvalidArgument desc = invalid argument for entity "+ + "resource: unknown store : invalid upsert resource request") + }) + t.Run("returns error when resource is nil", func(t *testing.T) { + service := new(resourceService) + handler := v1beta1.NewResourceHandler(logger, service) + + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "bigquery", + Resources: nil, + NamespaceName: "ns", + } + + _, err := handler.UpsertResource(ctx, req) + assert.NotNil(t, err) + assert.ErrorContains(t, err, "empty resource") + }) + t.Run("not process a resource when kind is empty", func(t *testing.T) { + service := new(resourceService) + handler := v1beta1.NewResourceHandler(logger, service) + + spec, _ := structpb.NewStruct(map[string]interface{}{"a": "b"}) + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "bigquery", + Resources: []*pb.ResourceSpecification{ + { + Name: "proj.ds.table1", + Version: 0, + Type: "", + Spec: spec, + }, + }, + NamespaceName: "ns", + } + + resp, err := handler.UpsertResource(ctx, req) + assert.Nil(t, err) + assert.Contains(t, resp.Results[0].Message, "empty resource type for proj.ds.table1") + }) + t.Run("returns error when service returns error", func(t *testing.T) { + service := new(resourceService) + service.On("Upsert", ctx, mock.Anything, mock.Anything).Return(errors.New("validation failure")) + defer service.AssertExpectations(t) + + handler := v1beta1.NewResourceHandler(logger, service) + + spec, _ := structpb.NewStruct(map[string]interface{}{"a": "b"}) + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "bigquery", + Resources: []*pb.ResourceSpecification{ + { + Version: 0, + Name: "proj.set.table", + Type: "table", + Spec: spec, + }, + }, + NamespaceName: "ns", + } + + resp, err := handler.UpsertResource(ctx, req) + assert.Nil(t, err) + assert.Contains(t, resp.Results[0].Message, "validation failure") + }) + t.Run("skip invalid resource and proceed other resource", func(t *testing.T) { + service := new(resourceService) + service.On("Upsert", ctx, mock.Anything, mock.Anything).Return(nil).Once() + defer service.AssertExpectations(t) + + handler := v1beta1.NewResourceHandler(logger, service) + + spec, _ := structpb.NewStruct(map[string]interface{}{"a": "b"}) + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "bigquery", + Resources: []*pb.ResourceSpecification{ + { + Version: 0, + Name: "proj.set.table1", + Type: "", + Spec: spec, + }, + { + Version: 0, + Name: "proj.set.table2", + Type: "table", + Spec: spec, + }, + }, + NamespaceName: "ns", + } + + resp, err := handler.UpsertResource(ctx, req) + assert.Nil(t, err) + assert.Contains(t, resp.Results[0].Message, "empty resource type for proj.set.table1") + }) + t.Run("upsert a single resource successfully", func(t *testing.T) { + service := new(resourceService) + service.On("Upsert", ctx, mock.Anything, mock.Anything).Return(nil) + defer service.AssertExpectations(t) + + handler := v1beta1.NewResourceHandler(logger, service) + + spec, _ := structpb.NewStruct(map[string]interface{}{"description": "test"}) + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "bigquery", + Resources: []*pb.ResourceSpecification{ + { + Version: 0, + Name: "proj.set.table", + Type: "table", + Spec: spec, + }, + }, + NamespaceName: "ns", + } + + _, err := handler.UpsertResource(ctx, req) + assert.Nil(t, err) + }) + t.Run("upsert a multiple resource successfully", func(t *testing.T) { + service := new(resourceService) + service.On("Upsert", ctx, mock.Anything, mock.Anything).Return(nil).Twice() + defer service.AssertExpectations(t) + + handler := v1beta1.NewResourceHandler(logger, service) + + spec, _ := structpb.NewStruct(map[string]interface{}{"description": "test"}) + req := &pb.UpsertResourceRequest{ + ProjectName: "proj", + DatastoreName: "bigquery", + Resources: []*pb.ResourceSpecification{ + { + Version: 0, + Name: "proj.set.table", + Type: "table", + Spec: spec, + }, + { + Version: 0, + Name: "proj.set.table2", + Type: "table", + Spec: spec, + }, + }, + NamespaceName: "ns", + } + + _, err := handler.UpsertResource(ctx, req) + assert.Nil(t, err) + }) + }) t.Run("ApplyResource", func(t *testing.T) { t.Run("returns error when tenant is invalid", func(t *testing.T) { service := new(resourceService) @@ -952,6 +1138,11 @@ func (r *resourceService) Update(ctx context.Context, res *resource.Resource, lo return args.Error(0) } +func (r *resourceService) Upsert(ctx context.Context, res *resource.Resource, logWriter writer.LogWriter) error { + args := r.Called(ctx, res, logWriter) + return args.Error(0) +} + func (r *resourceService) Delete(ctx context.Context, req *resource.DeleteRequest) (*resource.DeleteResponse, error) { args := r.Called(ctx, req) var jobs *resource.DeleteResponse diff --git a/core/resource/service/resource_service.go b/core/resource/service/resource_service.go index 55411d1670..1bedea9213 100644 --- a/core/resource/service/resource_service.go +++ b/core/resource/service/resource_service.go @@ -184,6 +184,63 @@ func (rs ResourceService) Update(ctx context.Context, incoming *resource.Resourc return nil } +func (rs ResourceService) Upsert(ctx context.Context, incoming *resource.Resource, logWriter writer.LogWriter) error { // nolint:gocritic + if err := rs.mgr.Validate(incoming); err != nil { + rs.logger.Error("error validating resource [%s]: %s", incoming.FullName(), err) + return err + } + incoming.MarkValidationSuccess() + + urn, err := rs.mgr.GetURN(incoming) + if err != nil { + rs.logger.Error("error validating resource [%s]: %s", incoming.FullName(), err) + return err + } + + err = incoming.UpdateURN(urn) + if err != nil { + rs.logger.Error("error updating urn of resource [%s]: %s", incoming.FullName(), err) + return err + } + + existing, err := rs.repo.ReadByFullName(ctx, incoming.Tenant(), incoming.Store(), incoming.FullName(), false) + if err != nil { + if !errors.IsErrorType(err, errors.ErrNotFound) { + rs.logger.Error("error getting resource [%s]: %s", incoming.FullName(), err) + return err + } + } + + if err := rs.identifyResourceToUpdateOnStore(ctx, incoming, existing); err != nil { + rs.logger.Error("error identifying resource [%s] before updating on store : %s", incoming.FullName(), err) + return err + } + + switch incoming.Status() { + case resource.StatusToCreate: + if err := rs.mgr.CreateResource(ctx, incoming); err != nil { + rs.logger.Error("error creating resource [%s] to manager: %s", incoming.FullName(), err) + return err + } + rs.raiseCreateEvent(incoming) + case resource.StatusToUpdate: + if err := rs.mgr.UpdateResource(ctx, incoming); err != nil { + rs.logger.Error("error updating resource [%s] to manager: %s", incoming.FullName(), err) + return err + } + rs.raiseUpdateEvent(incoming, existing.GetUpdateImpact(incoming)) + if err = rs.handleRefreshDownstream(ctx, + []*resource.Resource{incoming}, + map[string]*resource.Resource{existing.FullName(): existing}, + logWriter, + ); err != nil { + rs.logger.Error("error refreshing downstream for resource [%s]: %s", existing.FullName(), err) + return err + } + } + return nil +} + func (rs ResourceService) Delete(ctx context.Context, req *resource.DeleteRequest) (*resource.DeleteResponse, error) { existing, err := rs.Get(ctx, req.Tenant, req.Datastore, req.FullName) if err != nil { @@ -379,43 +436,44 @@ func (rs ResourceService) getResourcesToBatchUpdate(ctx context.Context, incomin me := errors.NewMultiError("error in resources to batch update") for _, incoming := range incomings { - if incoming.Status() != resource.StatusValidationSuccess { - continue - } - - existing, ok := existingMappedByFullName[incoming.FullName()] - if !ok { - _ = incoming.MarkToCreate() - err := rs.repo.Create(ctx, incoming) - if err == nil { - toUpdateOnStore = append(toUpdateOnStore, incoming) - } + err := rs.identifyResourceToUpdateOnStore(ctx, incoming, existingMappedByFullName[incoming.FullName()]) + if err != nil { me.Append(err) continue } - - if resource.StatusIsSuccess(existing.Status()) && incoming.Equal(existing) { - _ = incoming.MarkSkipped() - rs.logger.Warn("resource [%s] is skipped because it has no changes", existing.FullName()) - continue - } - - if resource.StatusForToCreate(existing.Status()) { - _ = incoming.MarkToCreate() - } else if resource.StatusForToUpdate(existing.Status()) { - _ = incoming.MarkToUpdate() - } - - err := rs.repo.Update(ctx, incoming) - if err == nil { + if incoming.Status() == resource.StatusToCreate || incoming.Status() == resource.StatusToUpdate { toUpdateOnStore = append(toUpdateOnStore, incoming) } - me.Append(err) } return toUpdateOnStore, me.ToErr() } +func (rs ResourceService) identifyResourceToUpdateOnStore(ctx context.Context, incoming, existing *resource.Resource) error { + if incoming.Status() != resource.StatusValidationSuccess { + return nil + } + + if existing == nil { + _ = incoming.MarkToCreate() + return rs.repo.Create(ctx, incoming) + } + + if resource.StatusIsSuccess(existing.Status()) && incoming.Equal(existing) { + _ = incoming.MarkSkipped() + rs.logger.Warn("resource [%s] is skipped because it has no changes", existing.FullName()) + return nil + } + + if resource.StatusForToCreate(existing.Status()) { + _ = incoming.MarkToCreate() + } else { + _ = incoming.MarkToUpdate() + } + + return rs.repo.Update(ctx, incoming) +} + func (rs ResourceService) raiseCreateEvent(res *resource.Resource) { // nolint:gocritic if res.Status() != resource.StatusSuccess { return diff --git a/core/resource/service/resource_service_test.go b/core/resource/service/resource_service_test.go index ff7202ac0e..70c145f06f 100644 --- a/core/resource/service/resource_service_test.go +++ b/core/resource/service/resource_service_test.go @@ -457,6 +457,245 @@ func TestResourceService(t *testing.T) { }) }) + t.Run("Upsert", func(t *testing.T) { + t.Run("returns error if resource is invalid", func(t *testing.T) { + invalid := &resource.Resource{} + + mgr := NewResourceManager(t) + mgr.On("Validate", invalid).Return(errors.New("validation error")) + + rscService := service.NewResourceService(logger, nil, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, invalid, logWriter) + assert.Error(t, actualError) + assert.ErrorContains(t, actualError, "validation error") + }) + + t.Run("returns error cannot get resource urn", func(t *testing.T) { + incoming, err := resource.NewResource("project.dataset", "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + + mgr := NewResourceManager(t) + mgr.On("Validate", incoming).Return(nil) + mgr.On("GetURN", incoming).Return(resource.ZeroURN(), errors.New("urn error")) + + rscService := service.NewResourceService(logger, nil, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, incoming, logWriter) + assert.Error(t, actualError) + assert.ErrorContains(t, actualError, "urn error") + }) + + t.Run("returns error if cannot update resource urn", func(t *testing.T) { + incoming, err := resource.NewResource("project.dataset", "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + err = incoming.UpdateURN(tableURN) + assert.NoError(t, err) + + mgr := NewResourceManager(t) + mgr.On("Validate", incoming).Return(nil) + mgr.On("GetURN", incoming).Return(tableURN, nil) + + rscService := service.NewResourceService(logger, nil, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, incoming, logWriter) + assert.Error(t, actualError) + assert.ErrorContains(t, actualError, "urn already present") + }) + + onlyActive := false + + t.Run("returns error if unknown error is encountered when getting existing resource", func(t *testing.T) { + incoming, err := resource.NewResource("project.dataset", "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + + mgr := NewResourceManager(t) + mgr.On("Validate", incoming).Return(nil) + mgr.On("GetURN", incoming).Return(tableURN, nil) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, incoming.FullName(), onlyActive).Return(nil, errors.New("unknown error")) + + rscService := service.NewResourceService(logger, repo, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, incoming, logWriter) + assert.ErrorContains(t, actualError, "unknown error") + }) + + t.Run("resource does not exist in repository", func(t *testing.T) { + t.Run("returns error if error is encountered when creating resource to repository", func(t *testing.T) { + incoming, err := resource.NewResource("project.dataset", "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, incoming.FullName(), onlyActive).Return(nil, oErrors.NotFound(resource.EntityResource, "resource not found")) + repo.On("Create", ctx, mock.Anything).Return(errors.New("error creating resource")) + + mgr := NewResourceManager(t) + mgr.On("Validate", incoming).Return(nil) + mgr.On("GetURN", incoming).Return(tableURN, nil) + + rscService := service.NewResourceService(logger, repo, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, incoming, logWriter) + assert.ErrorContains(t, actualError, "error creating resource") + }) + + t.Run("returns error if error is encountered when creating to store", func(t *testing.T) { + incoming, err := resource.NewResource("project.dataset", "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, incoming.FullName(), onlyActive).Return(nil, oErrors.NotFound(resource.EntityResource, "resource not found")) + repo.On("Create", ctx, incoming).Return(nil) + + mgr := NewResourceManager(t) + mgr.On("Validate", incoming).Return(nil) + mgr.On("GetURN", incoming).Return(tableURN, nil) + mgr.On("CreateResource", ctx, incoming).Return(errors.New("error creating to store")) + + rscService := service.NewResourceService(logger, repo, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, incoming, logWriter) + assert.ErrorContains(t, actualError, "error creating to store") + }) + + t.Run("returns nil if no error is encountered", func(t *testing.T) { + incoming, err := resource.NewResource("project.dataset", "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, incoming.FullName(), onlyActive).Return(nil, oErrors.NotFound(resource.EntityResource, "resource not found")) + repo.On("Create", ctx, incoming).Return(nil) + + mgr := NewResourceManager(t) + mgr.On("Validate", incoming).Return(nil) + mgr.On("GetURN", incoming).Return(tableURN, nil) + mgr.On("CreateResource", ctx, incoming).Return(nil) + + eventHandler := newEventHandler(t) + + rscService := service.NewResourceService(logger, repo, nil, mgr, eventHandler, nil) + + actualError := rscService.Upsert(ctx, incoming, logWriter) + assert.NoError(t, actualError) + }) + }) + + t.Run("resource already exists in repository", func(t *testing.T) { + t.Run("returns error if error is encountered when updating to repo", func(t *testing.T) { + fullName := "project.dataset" + resourceToUpdate, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + existingResource, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + existingResource = resource.FromExisting(existingResource, resource.ReplaceStatus(resource.StatusToUpdate)) + + mgr := NewResourceManager(t) + mgr.On("Validate", resourceToUpdate).Return(nil) + mgr.On("GetURN", resourceToUpdate).Return(datasetURN, nil) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, fullName, onlyActive).Return(existingResource, nil) + repo.On("Update", ctx, mock.Anything).Return(errors.New("unknown error")) + + rscService := service.NewResourceService(logger, repo, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, resourceToUpdate, logWriter) + assert.ErrorContains(t, actualError, "unknown error") + }) + + t.Run("returns error if error is encountered when updating to store", func(t *testing.T) { + fullName := "project.dataset" + resourceToUpdate, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + existingResource, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, spec) + assert.NoError(t, err) + existingResource = resource.FromExisting(existingResource, resource.ReplaceStatus(resource.StatusToUpdate)) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, fullName, onlyActive).Return(existingResource, nil) + repo.On("Update", ctx, mock.Anything).Return(nil) + + mgr := NewResourceManager(t) + mgr.On("Validate", mock.Anything).Return(nil) + mgr.On("GetURN", mock.Anything).Return(datasetURN, nil) + mgr.On("UpdateResource", ctx, mock.Anything).Return(errors.New("unknown error")) + + rscService := service.NewResourceService(logger, repo, nil, mgr, nil, nil) + + actualError := rscService.Upsert(ctx, resourceToUpdate, logWriter) + assert.ErrorContains(t, actualError, "unknown error") + }) + + t.Run("returns error if encountered error when refreshing downstream", func(t *testing.T) { + fullName := "project.dataset" + incomingSpec := map[string]any{"view_query": "select 1;"} + resourceToUpdate, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, incomingSpec) + assert.NoError(t, err) + existingSpec := map[string]any{"view_query": "select 2;"} + existingResource, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, existingSpec) + assert.NoError(t, err) + existingResource = resource.FromExisting(existingResource, resource.ReplaceStatus(resource.StatusToUpdate)) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, fullName, onlyActive).Return(existingResource, nil) + repo.On("Update", ctx, mock.Anything).Return(nil) + + mgr := NewResourceManager(t) + mgr.On("Validate", mock.Anything).Return(nil) + mgr.On("GetURN", mock.Anything).Return(datasetURN, nil) + mgr.On("UpdateResource", ctx, mock.Anything).Run(func(args mock.Arguments) { + res, ok := args[1].(*resource.Resource) + if ok { + res.MarkSuccess() + } + }).Return(nil) + + eventHandler := newEventHandler(t) + eventHandler.On("HandleEvent", mock.Anything) + + refresher := new(mockDownstreamRefresher) + refresher.On("RefreshResourceDownstream", ctx, mock.Anything, logWriter).Return(errors.New("unknown error")) + + rscService := service.NewResourceService(logger, repo, refresher, mgr, eventHandler, nil) + + actualError := rscService.Upsert(ctx, resourceToUpdate, logWriter) + assert.ErrorContains(t, actualError, "unknown error") + }) + + t.Run("returns nil if no error is encountered", func(t *testing.T) { + fullName := "project.dataset" + incomingSpec := map[string]any{"view_query": "select 1;"} + resourceToUpdate, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, incomingSpec) + assert.NoError(t, err) + existingSpec := map[string]any{"view_query": "select 2;"} + existingResource, err := resource.NewResource(fullName, "dataset", resource.Bigquery, tnnt, meta, existingSpec) + assert.NoError(t, err) + existingResource = resource.FromExisting(existingResource, resource.ReplaceStatus(resource.StatusToUpdate)) + + repo := newResourceRepository(t) + repo.On("ReadByFullName", ctx, tnnt, resource.Bigquery, fullName, onlyActive).Return(existingResource, nil) + repo.On("Update", ctx, mock.Anything).Return(nil) + + mgr := NewResourceManager(t) + mgr.On("Validate", mock.Anything).Return(nil) + mgr.On("GetURN", mock.Anything).Return(datasetURN, nil) + mgr.On("UpdateResource", ctx, mock.Anything).Return(nil) + + eventHandler := newEventHandler(t) + + refresher := new(mockDownstreamRefresher) + refresher.On("RefreshResourceDownstream", ctx, mock.Anything, logWriter).Return(nil) + + rscService := service.NewResourceService(logger, repo, refresher, mgr, eventHandler, nil) + + actualError := rscService.Upsert(ctx, resourceToUpdate, logWriter) + assert.NoError(t, actualError) + }) + }) + }) + t.Run("Get", func(t *testing.T) { onlyActive := true t.Run("returns nil and error if resource name is empty", func(t *testing.T) { @@ -741,7 +980,12 @@ func TestResourceService(t *testing.T) { repo := newResourceRepository(t) repo.On("ReadAll", ctx, tnnt, resource.Bigquery, onlyActive).Return([]*resource.Resource{existingResource}, nil) - repo.On("Update", ctx, incomingResourceToUpdate).Return(nil) + repo.On("Update", ctx, incomingResourceToUpdate).Run(func(args mock.Arguments) { + res, ok := args[1].(*resource.Resource) + if ok { + res.MarkToUpdate() + } + }).Return(nil) urn, err := resource.ParseURN("bigquery://project:dataset.view1") assert.NoError(t, err) diff --git a/core/resource/status.go b/core/resource/status.go index 5dc6fb79df..34e3c801a8 100644 --- a/core/resource/status.go +++ b/core/resource/status.go @@ -21,6 +21,8 @@ const ( StatusUpdateFailure Status = "update_failure" StatusExistInStore Status = "exist_in_store" StatusSuccess Status = "success" + + StatusFailure Status = "failed" ) func (s Status) String() string { diff --git a/protos/gotocompany/optimus/core/v1beta1/resource.pb.go b/protos/gotocompany/optimus/core/v1beta1/resource.pb.go index 29fc3dfbe9..7188997e13 100644 --- a/protos/gotocompany/optimus/core/v1beta1/resource.pb.go +++ b/protos/gotocompany/optimus/core/v1beta1/resource.pb.go @@ -638,6 +638,211 @@ func (x *UpdateResourceResponse) GetMessage() string { return "" } +type UpsertResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProjectName string `protobuf:"bytes,1,opt,name=project_name,json=projectName,proto3" json:"project_name,omitempty"` + DatastoreName string `protobuf:"bytes,2,opt,name=datastore_name,json=datastoreName,proto3" json:"datastore_name,omitempty"` + Resources []*ResourceSpecification `protobuf:"bytes,3,rep,name=resources,proto3" json:"resources,omitempty"` + NamespaceName string `protobuf:"bytes,4,opt,name=namespace_name,json=namespaceName,proto3" json:"namespace_name,omitempty"` +} + +func (x *UpsertResourceRequest) Reset() { + *x = UpsertResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpsertResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertResourceRequest) ProtoMessage() {} + +func (x *UpsertResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertResourceRequest.ProtoReflect.Descriptor instead. +func (*UpsertResourceRequest) Descriptor() ([]byte, []int) { + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{10} +} + +func (x *UpsertResourceRequest) GetProjectName() string { + if x != nil { + return x.ProjectName + } + return "" +} + +func (x *UpsertResourceRequest) GetDatastoreName() string { + if x != nil { + return x.DatastoreName + } + return "" +} + +func (x *UpsertResourceRequest) GetResources() []*ResourceSpecification { + if x != nil { + return x.Resources + } + return nil +} + +func (x *UpsertResourceRequest) GetNamespaceName() string { + if x != nil { + return x.NamespaceName + } + return "" +} + +type UpsertResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Results []*ResourceStatus `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` + SuccessfulResourceNames []string `protobuf:"bytes,4,rep,name=successful_resource_names,json=successfulResourceNames,proto3" json:"successful_resource_names,omitempty"` +} + +func (x *UpsertResourceResponse) Reset() { + *x = UpsertResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpsertResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpsertResourceResponse) ProtoMessage() {} + +func (x *UpsertResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpsertResourceResponse.ProtoReflect.Descriptor instead. +func (*UpsertResourceResponse) Descriptor() ([]byte, []int) { + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{11} +} + +func (x *UpsertResourceResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *UpsertResourceResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *UpsertResourceResponse) GetResults() []*ResourceStatus { + if x != nil { + return x.Results + } + return nil +} + +func (x *UpsertResourceResponse) GetSuccessfulResourceNames() []string { + if x != nil { + return x.SuccessfulResourceNames + } + return nil +} + +type ResourceStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ResourceName string `protobuf:"bytes,1,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *ResourceStatus) Reset() { + *x = ResourceStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceStatus) ProtoMessage() {} + +func (x *ResourceStatus) ProtoReflect() protoreflect.Message { + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResourceStatus.ProtoReflect.Descriptor instead. +func (*ResourceStatus) Descriptor() ([]byte, []int) { + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{12} +} + +func (x *ResourceStatus) GetResourceName() string { + if x != nil { + return x.ResourceName + } + return "" +} + +func (x *ResourceStatus) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *ResourceStatus) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + // ResourceSpecification are datastore specification representation of a resource type ResourceSpecification struct { state protoimpl.MessageState @@ -655,7 +860,7 @@ type ResourceSpecification struct { func (x *ResourceSpecification) Reset() { *x = ResourceSpecification{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[10] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -668,7 +873,7 @@ func (x *ResourceSpecification) String() string { func (*ResourceSpecification) ProtoMessage() {} func (x *ResourceSpecification) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[10] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -681,7 +886,7 @@ func (x *ResourceSpecification) ProtoReflect() protoreflect.Message { // Deprecated: Use ResourceSpecification.ProtoReflect.Descriptor instead. func (*ResourceSpecification) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{10} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{13} } func (x *ResourceSpecification) GetVersion() int32 { @@ -741,7 +946,7 @@ type ChangeResourceNamespaceRequest struct { func (x *ChangeResourceNamespaceRequest) Reset() { *x = ChangeResourceNamespaceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[11] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -754,7 +959,7 @@ func (x *ChangeResourceNamespaceRequest) String() string { func (*ChangeResourceNamespaceRequest) ProtoMessage() {} func (x *ChangeResourceNamespaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[11] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -767,7 +972,7 @@ func (x *ChangeResourceNamespaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeResourceNamespaceRequest.ProtoReflect.Descriptor instead. func (*ChangeResourceNamespaceRequest) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{11} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{14} } func (x *ChangeResourceNamespaceRequest) GetProjectName() string { @@ -814,7 +1019,7 @@ type ChangeResourceNamespaceResponse struct { func (x *ChangeResourceNamespaceResponse) Reset() { *x = ChangeResourceNamespaceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[12] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -827,7 +1032,7 @@ func (x *ChangeResourceNamespaceResponse) String() string { func (*ChangeResourceNamespaceResponse) ProtoMessage() {} func (x *ChangeResourceNamespaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[12] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -840,7 +1045,7 @@ func (x *ChangeResourceNamespaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ChangeResourceNamespaceResponse.ProtoReflect.Descriptor instead. func (*ChangeResourceNamespaceResponse) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{12} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{15} } type ApplyResourcesRequest struct { @@ -857,7 +1062,7 @@ type ApplyResourcesRequest struct { func (x *ApplyResourcesRequest) Reset() { *x = ApplyResourcesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[13] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -870,7 +1075,7 @@ func (x *ApplyResourcesRequest) String() string { func (*ApplyResourcesRequest) ProtoMessage() {} func (x *ApplyResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[13] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -883,7 +1088,7 @@ func (x *ApplyResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyResourcesRequest.ProtoReflect.Descriptor instead. func (*ApplyResourcesRequest) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{13} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{16} } func (x *ApplyResourcesRequest) GetProjectName() string { @@ -925,7 +1130,7 @@ type ApplyResourcesResponse struct { func (x *ApplyResourcesResponse) Reset() { *x = ApplyResourcesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[14] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -938,7 +1143,7 @@ func (x *ApplyResourcesResponse) String() string { func (*ApplyResourcesResponse) ProtoMessage() {} func (x *ApplyResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[14] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -951,7 +1156,7 @@ func (x *ApplyResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApplyResourcesResponse.ProtoReflect.Descriptor instead. func (*ApplyResourcesResponse) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{14} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{17} } func (x *ApplyResourcesResponse) GetStatuses() []*ApplyResourcesResponse_ResourceStatus { @@ -976,7 +1181,7 @@ type DeleteResourceRequest struct { func (x *DeleteResourceRequest) Reset() { *x = DeleteResourceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[15] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -989,7 +1194,7 @@ func (x *DeleteResourceRequest) String() string { func (*DeleteResourceRequest) ProtoMessage() {} func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[15] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1002,7 +1207,7 @@ func (x *DeleteResourceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteResourceRequest.ProtoReflect.Descriptor instead. func (*DeleteResourceRequest) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{15} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{18} } func (x *DeleteResourceRequest) GetProjectName() string { @@ -1051,7 +1256,7 @@ type DeleteResourceResponse struct { func (x *DeleteResourceResponse) Reset() { *x = DeleteResourceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[16] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1064,7 +1269,7 @@ func (x *DeleteResourceResponse) String() string { func (*DeleteResourceResponse) ProtoMessage() {} func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[16] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1077,7 +1282,7 @@ func (x *DeleteResourceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteResourceResponse.ProtoReflect.Descriptor instead. func (*DeleteResourceResponse) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{16} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{19} } func (x *DeleteResourceResponse) GetDownstreamJobs() []string { @@ -1100,7 +1305,7 @@ type ApplyResourcesResponse_ResourceStatus struct { func (x *ApplyResourcesResponse_ResourceStatus) Reset() { *x = ApplyResourcesResponse_ResourceStatus{} if protoimpl.UnsafeEnabled { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[19] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1113,7 +1318,7 @@ func (x *ApplyResourcesResponse_ResourceStatus) String() string { func (*ApplyResourcesResponse_ResourceStatus) ProtoMessage() {} func (x *ApplyResourcesResponse_ResourceStatus) ProtoReflect() protoreflect.Message { - mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[19] + mi := &file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1126,7 +1331,7 @@ func (x *ApplyResourcesResponse_ResourceStatus) ProtoReflect() protoreflect.Mess // Deprecated: Use ApplyResourcesResponse_ResourceStatus.ProtoReflect.Descriptor instead. func (*ApplyResourcesResponse_ResourceStatus) Descriptor() ([]byte, []int) { - return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{14, 0} + return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP(), []int{17, 0} } func (x *ApplyResourcesResponse_ResourceStatus) GetResourceName() string { @@ -1265,226 +1470,275 @@ var file_gotocompany_optimus_core_v1beta1_resource_proto_rawDesc = []byte{ 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xbc, - 0x03, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x73, 0x70, - 0x65, 0x63, 0x18, 0x05, 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, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x5b, 0x0a, 0x06, 0x61, 0x73, 0x73, 0x65, 0x74, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, - 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x61, 0x73, - 0x73, 0x65, 0x74, 0x73, 0x12, 0x5b, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x07, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, - 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x41, 0x73, 0x73, 0x65, 0x74, 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, 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, 0x03, 0x10, 0x04, 0x22, 0xe4, 0x01, - 0x0a, 0x1e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, - 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xaf, 0x01, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, - 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, - 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xdf, + 0x01, 0x0a, 0x15, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, + 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xe4, 0x01, 0x0a, 0x16, 0x41, 0x70, - 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x47, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x6d, 0x65, 0x12, 0x55, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, + 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x22, 0xd4, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x4a, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, + 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x19, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x17, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x67, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 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, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0xbc, 0x03, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, + 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 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, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x5b, 0x0a, 0x06, 0x61, 0x73, 0x73, + 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, + 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, + 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x12, 0x5b, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x43, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, - 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x1a, 0x65, 0x0a, 0x0e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 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, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, - 0x22, 0xc3, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, - 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x6a, - 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x6f, 0x77, 0x6e, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4a, 0x6f, 0x62, 0x73, 0x32, 0x8a, 0x0f, 0x0a, 0x0f, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xb0, 0x01, - 0x0a, 0x1b, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x2e, + 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x41, 0x73, 0x73, 0x65, 0x74, 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, 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, 0x03, 0x10, 0x04, 0x22, + 0xe4, 0x01, 0x0a, 0x1e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, + 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x21, 0x0a, 0x1f, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xaf, 0x01, 0x0a, 0x15, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xe4, 0x01, 0x0a, 0x16, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x47, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, + 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, + 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x08, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x1a, 0x65, 0x0a, 0x0e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x23, 0x0a, + 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 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, 0x16, 0x0a, 0x06, 0x72, 0x65, + 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, + 0x6f, 0x6e, 0x22, 0xc3, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x25, 0x0a, 0x0e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x41, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x64, 0x6f, 0x77, + 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4a, 0x6f, 0x62, 0x73, 0x32, 0x83, 0x11, 0x0a, 0x0f, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0xb0, 0x01, 0x0a, 0x1b, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x44, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, + 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x45, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, + 0x30, 0x01, 0x12, 0x8c, 0x02, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x42, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, + 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x60, 0x12, 0x5e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, + 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0xee, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x45, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, - 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, - 0x12, 0x8c, 0x02, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x42, - 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, - 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x70, - 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x43, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, - 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x66, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x60, 0x12, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x63, 0x22, 0x5e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0xee, 0x01, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, - 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x67, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, - 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x69, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x63, 0x22, 0x5e, 0x2f, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, - 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x01, 0x2a, - 0x12, 0xf5, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x12, 0x35, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, - 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, - 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, + 0x01, 0x2a, 0x12, 0xf5, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x35, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, + 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x67, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, + 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x52, 0x65, + 0x61, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x76, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x70, 0x12, 0x6e, 0x2f, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xee, 0x01, 0x0a, 0x0e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, + 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, + 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, + 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, + 0x65, 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, 0x76, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x70, 0x12, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x22, 0x69, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x63, 0x1a, 0x5e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xee, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x67, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, - 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, - 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x69, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x63, 0x1a, 0x5e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, - 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0xfb, 0x01, 0x0a, 0x0e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x67, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0xf6, 0x01, 0x0a, 0x0e, + 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, + 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x73, 0x65, 0x72, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x71, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6b, 0x22, 0x66, 0x2f, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, + 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2d, 0x75, 0x70, 0x73, 0x65, 0x72, + 0x74, 0x3a, 0x01, 0x2a, 0x12, 0xfb, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, + 0x72, 0x65, 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, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, + 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, 0x76, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x70, 0x2a, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, + 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x40, + 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, + 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x41, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, + 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e, 0x22, 0x39, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x63, 0x68, 0x61, + 0x6e, 0x67, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2d, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0xf5, 0x01, 0x0a, 0x0e, 0x41, 0x70, + 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 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, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 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, - 0x76, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x70, 0x2a, 0x6e, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6a, 0x22, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x7b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x40, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, - 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x41, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, - 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x44, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3e, - 0x22, 0x39, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x2f, 0x7b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, - 0x7d, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0xf5, - 0x01, 0x0a, 0x0e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x12, 0x37, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, - 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x67, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, - 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x70, - 0x70, 0x6c, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x6a, 0x22, 0x65, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x2f, 0x7b, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2f, 0x7b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x7d, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x2f, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2d, 0x61, 0x70, - 0x70, 0x6c, 0x79, 0x3a, 0x01, 0x2a, 0x42, 0xa4, 0x01, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x6e, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x42, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, - 0x72, 0x50, 0x01, 0x5a, 0x1e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x67, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x74, 0x69, - 0x6d, 0x75, 0x73, 0x92, 0x41, 0x47, 0x12, 0x05, 0x32, 0x03, 0x30, 0x2e, 0x31, 0x1a, 0x0e, 0x31, - 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x3a, 0x39, 0x31, 0x30, 0x30, 0x22, 0x04, 0x2f, - 0x61, 0x70, 0x69, 0x2a, 0x01, 0x01, 0x72, 0x25, 0x0a, 0x23, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x75, - 0x73, 0x20, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x3a, 0x01, + 0x2a, 0x42, 0xa4, 0x01, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2e, 0x6f, 0x70, 0x74, + 0x69, 0x6d, 0x75, 0x73, 0x42, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x50, 0x01, 0x5a, 0x1e, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x74, 0x6f, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x92, 0x41, + 0x47, 0x12, 0x05, 0x32, 0x03, 0x30, 0x2e, 0x31, 0x1a, 0x0e, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, + 0x30, 0x2e, 0x31, 0x3a, 0x39, 0x31, 0x30, 0x30, 0x22, 0x04, 0x2f, 0x61, 0x70, 0x69, 0x2a, 0x01, + 0x01, 0x72, 0x25, 0x0a, 0x23, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x75, 0x73, 0x20, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1499,7 +1753,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescGZIP() []byte { return file_gotocompany_optimus_core_v1beta1_resource_proto_rawDescData } -var file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 23) var file_gotocompany_optimus_core_v1beta1_resource_proto_goTypes = []interface{}{ (*DeployResourceSpecificationRequest)(nil), // 0: gotocompany.optimus.core.v1beta1.DeployResourceSpecificationRequest (*DeployResourceSpecificationResponse)(nil), // 1: gotocompany.optimus.core.v1beta1.DeployResourceSpecificationResponse @@ -1511,51 +1765,58 @@ var file_gotocompany_optimus_core_v1beta1_resource_proto_goTypes = []interface{} (*ReadResourceResponse)(nil), // 7: gotocompany.optimus.core.v1beta1.ReadResourceResponse (*UpdateResourceRequest)(nil), // 8: gotocompany.optimus.core.v1beta1.UpdateResourceRequest (*UpdateResourceResponse)(nil), // 9: gotocompany.optimus.core.v1beta1.UpdateResourceResponse - (*ResourceSpecification)(nil), // 10: gotocompany.optimus.core.v1beta1.ResourceSpecification - (*ChangeResourceNamespaceRequest)(nil), // 11: gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceRequest - (*ChangeResourceNamespaceResponse)(nil), // 12: gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceResponse - (*ApplyResourcesRequest)(nil), // 13: gotocompany.optimus.core.v1beta1.ApplyResourcesRequest - (*ApplyResourcesResponse)(nil), // 14: gotocompany.optimus.core.v1beta1.ApplyResourcesResponse - (*DeleteResourceRequest)(nil), // 15: gotocompany.optimus.core.v1beta1.DeleteResourceRequest - (*DeleteResourceResponse)(nil), // 16: gotocompany.optimus.core.v1beta1.DeleteResourceResponse - nil, // 17: gotocompany.optimus.core.v1beta1.ResourceSpecification.AssetsEntry - nil, // 18: gotocompany.optimus.core.v1beta1.ResourceSpecification.LabelsEntry - (*ApplyResourcesResponse_ResourceStatus)(nil), // 19: gotocompany.optimus.core.v1beta1.ApplyResourcesResponse.ResourceStatus - (*Log)(nil), // 20: gotocompany.optimus.core.v1beta1.Log - (*structpb.Struct)(nil), // 21: google.protobuf.Struct + (*UpsertResourceRequest)(nil), // 10: gotocompany.optimus.core.v1beta1.UpsertResourceRequest + (*UpsertResourceResponse)(nil), // 11: gotocompany.optimus.core.v1beta1.UpsertResourceResponse + (*ResourceStatus)(nil), // 12: gotocompany.optimus.core.v1beta1.ResourceStatus + (*ResourceSpecification)(nil), // 13: gotocompany.optimus.core.v1beta1.ResourceSpecification + (*ChangeResourceNamespaceRequest)(nil), // 14: gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceRequest + (*ChangeResourceNamespaceResponse)(nil), // 15: gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceResponse + (*ApplyResourcesRequest)(nil), // 16: gotocompany.optimus.core.v1beta1.ApplyResourcesRequest + (*ApplyResourcesResponse)(nil), // 17: gotocompany.optimus.core.v1beta1.ApplyResourcesResponse + (*DeleteResourceRequest)(nil), // 18: gotocompany.optimus.core.v1beta1.DeleteResourceRequest + (*DeleteResourceResponse)(nil), // 19: gotocompany.optimus.core.v1beta1.DeleteResourceResponse + nil, // 20: gotocompany.optimus.core.v1beta1.ResourceSpecification.AssetsEntry + nil, // 21: gotocompany.optimus.core.v1beta1.ResourceSpecification.LabelsEntry + (*ApplyResourcesResponse_ResourceStatus)(nil), // 22: gotocompany.optimus.core.v1beta1.ApplyResourcesResponse.ResourceStatus + (*Log)(nil), // 23: gotocompany.optimus.core.v1beta1.Log + (*structpb.Struct)(nil), // 24: google.protobuf.Struct } var file_gotocompany_optimus_core_v1beta1_resource_proto_depIdxs = []int32{ - 10, // 0: gotocompany.optimus.core.v1beta1.DeployResourceSpecificationRequest.resources:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification - 20, // 1: gotocompany.optimus.core.v1beta1.DeployResourceSpecificationResponse.log_status:type_name -> gotocompany.optimus.core.v1beta1.Log - 10, // 2: gotocompany.optimus.core.v1beta1.ListResourceSpecificationResponse.resources:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification - 10, // 3: gotocompany.optimus.core.v1beta1.CreateResourceRequest.resource:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification - 10, // 4: gotocompany.optimus.core.v1beta1.ReadResourceResponse.resource:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification - 10, // 5: gotocompany.optimus.core.v1beta1.UpdateResourceRequest.resource:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification - 21, // 6: gotocompany.optimus.core.v1beta1.ResourceSpecification.spec:type_name -> google.protobuf.Struct - 17, // 7: gotocompany.optimus.core.v1beta1.ResourceSpecification.assets:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification.AssetsEntry - 18, // 8: gotocompany.optimus.core.v1beta1.ResourceSpecification.labels:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification.LabelsEntry - 19, // 9: gotocompany.optimus.core.v1beta1.ApplyResourcesResponse.statuses:type_name -> gotocompany.optimus.core.v1beta1.ApplyResourcesResponse.ResourceStatus - 0, // 10: gotocompany.optimus.core.v1beta1.ResourceService.DeployResourceSpecification:input_type -> gotocompany.optimus.core.v1beta1.DeployResourceSpecificationRequest - 2, // 11: gotocompany.optimus.core.v1beta1.ResourceService.ListResourceSpecification:input_type -> gotocompany.optimus.core.v1beta1.ListResourceSpecificationRequest - 4, // 12: gotocompany.optimus.core.v1beta1.ResourceService.CreateResource:input_type -> gotocompany.optimus.core.v1beta1.CreateResourceRequest - 6, // 13: gotocompany.optimus.core.v1beta1.ResourceService.ReadResource:input_type -> gotocompany.optimus.core.v1beta1.ReadResourceRequest - 8, // 14: gotocompany.optimus.core.v1beta1.ResourceService.UpdateResource:input_type -> gotocompany.optimus.core.v1beta1.UpdateResourceRequest - 15, // 15: gotocompany.optimus.core.v1beta1.ResourceService.DeleteResource:input_type -> gotocompany.optimus.core.v1beta1.DeleteResourceRequest - 11, // 16: gotocompany.optimus.core.v1beta1.ResourceService.ChangeResourceNamespace:input_type -> gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceRequest - 13, // 17: gotocompany.optimus.core.v1beta1.ResourceService.ApplyResources:input_type -> gotocompany.optimus.core.v1beta1.ApplyResourcesRequest - 1, // 18: gotocompany.optimus.core.v1beta1.ResourceService.DeployResourceSpecification:output_type -> gotocompany.optimus.core.v1beta1.DeployResourceSpecificationResponse - 3, // 19: gotocompany.optimus.core.v1beta1.ResourceService.ListResourceSpecification:output_type -> gotocompany.optimus.core.v1beta1.ListResourceSpecificationResponse - 5, // 20: gotocompany.optimus.core.v1beta1.ResourceService.CreateResource:output_type -> gotocompany.optimus.core.v1beta1.CreateResourceResponse - 7, // 21: gotocompany.optimus.core.v1beta1.ResourceService.ReadResource:output_type -> gotocompany.optimus.core.v1beta1.ReadResourceResponse - 9, // 22: gotocompany.optimus.core.v1beta1.ResourceService.UpdateResource:output_type -> gotocompany.optimus.core.v1beta1.UpdateResourceResponse - 16, // 23: gotocompany.optimus.core.v1beta1.ResourceService.DeleteResource:output_type -> gotocompany.optimus.core.v1beta1.DeleteResourceResponse - 12, // 24: gotocompany.optimus.core.v1beta1.ResourceService.ChangeResourceNamespace:output_type -> gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceResponse - 14, // 25: gotocompany.optimus.core.v1beta1.ResourceService.ApplyResources:output_type -> gotocompany.optimus.core.v1beta1.ApplyResourcesResponse - 18, // [18:26] is the sub-list for method output_type - 10, // [10:18] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 13, // 0: gotocompany.optimus.core.v1beta1.DeployResourceSpecificationRequest.resources:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification + 23, // 1: gotocompany.optimus.core.v1beta1.DeployResourceSpecificationResponse.log_status:type_name -> gotocompany.optimus.core.v1beta1.Log + 13, // 2: gotocompany.optimus.core.v1beta1.ListResourceSpecificationResponse.resources:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification + 13, // 3: gotocompany.optimus.core.v1beta1.CreateResourceRequest.resource:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification + 13, // 4: gotocompany.optimus.core.v1beta1.ReadResourceResponse.resource:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification + 13, // 5: gotocompany.optimus.core.v1beta1.UpdateResourceRequest.resource:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification + 13, // 6: gotocompany.optimus.core.v1beta1.UpsertResourceRequest.resources:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification + 12, // 7: gotocompany.optimus.core.v1beta1.UpsertResourceResponse.results:type_name -> gotocompany.optimus.core.v1beta1.ResourceStatus + 24, // 8: gotocompany.optimus.core.v1beta1.ResourceSpecification.spec:type_name -> google.protobuf.Struct + 20, // 9: gotocompany.optimus.core.v1beta1.ResourceSpecification.assets:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification.AssetsEntry + 21, // 10: gotocompany.optimus.core.v1beta1.ResourceSpecification.labels:type_name -> gotocompany.optimus.core.v1beta1.ResourceSpecification.LabelsEntry + 22, // 11: gotocompany.optimus.core.v1beta1.ApplyResourcesResponse.statuses:type_name -> gotocompany.optimus.core.v1beta1.ApplyResourcesResponse.ResourceStatus + 0, // 12: gotocompany.optimus.core.v1beta1.ResourceService.DeployResourceSpecification:input_type -> gotocompany.optimus.core.v1beta1.DeployResourceSpecificationRequest + 2, // 13: gotocompany.optimus.core.v1beta1.ResourceService.ListResourceSpecification:input_type -> gotocompany.optimus.core.v1beta1.ListResourceSpecificationRequest + 4, // 14: gotocompany.optimus.core.v1beta1.ResourceService.CreateResource:input_type -> gotocompany.optimus.core.v1beta1.CreateResourceRequest + 6, // 15: gotocompany.optimus.core.v1beta1.ResourceService.ReadResource:input_type -> gotocompany.optimus.core.v1beta1.ReadResourceRequest + 8, // 16: gotocompany.optimus.core.v1beta1.ResourceService.UpdateResource:input_type -> gotocompany.optimus.core.v1beta1.UpdateResourceRequest + 10, // 17: gotocompany.optimus.core.v1beta1.ResourceService.UpsertResource:input_type -> gotocompany.optimus.core.v1beta1.UpsertResourceRequest + 18, // 18: gotocompany.optimus.core.v1beta1.ResourceService.DeleteResource:input_type -> gotocompany.optimus.core.v1beta1.DeleteResourceRequest + 14, // 19: gotocompany.optimus.core.v1beta1.ResourceService.ChangeResourceNamespace:input_type -> gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceRequest + 16, // 20: gotocompany.optimus.core.v1beta1.ResourceService.ApplyResources:input_type -> gotocompany.optimus.core.v1beta1.ApplyResourcesRequest + 1, // 21: gotocompany.optimus.core.v1beta1.ResourceService.DeployResourceSpecification:output_type -> gotocompany.optimus.core.v1beta1.DeployResourceSpecificationResponse + 3, // 22: gotocompany.optimus.core.v1beta1.ResourceService.ListResourceSpecification:output_type -> gotocompany.optimus.core.v1beta1.ListResourceSpecificationResponse + 5, // 23: gotocompany.optimus.core.v1beta1.ResourceService.CreateResource:output_type -> gotocompany.optimus.core.v1beta1.CreateResourceResponse + 7, // 24: gotocompany.optimus.core.v1beta1.ResourceService.ReadResource:output_type -> gotocompany.optimus.core.v1beta1.ReadResourceResponse + 9, // 25: gotocompany.optimus.core.v1beta1.ResourceService.UpdateResource:output_type -> gotocompany.optimus.core.v1beta1.UpdateResourceResponse + 11, // 26: gotocompany.optimus.core.v1beta1.ResourceService.UpsertResource:output_type -> gotocompany.optimus.core.v1beta1.UpsertResourceResponse + 19, // 27: gotocompany.optimus.core.v1beta1.ResourceService.DeleteResource:output_type -> gotocompany.optimus.core.v1beta1.DeleteResourceResponse + 15, // 28: gotocompany.optimus.core.v1beta1.ResourceService.ChangeResourceNamespace:output_type -> gotocompany.optimus.core.v1beta1.ChangeResourceNamespaceResponse + 17, // 29: gotocompany.optimus.core.v1beta1.ResourceService.ApplyResources:output_type -> gotocompany.optimus.core.v1beta1.ApplyResourcesResponse + 21, // [21:30] is the sub-list for method output_type + 12, // [12:21] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_gotocompany_optimus_core_v1beta1_resource_proto_init() } @@ -1686,7 +1947,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResourceSpecification); i { + switch v := v.(*UpsertResourceRequest); i { case 0: return &v.state case 1: @@ -1698,7 +1959,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChangeResourceNamespaceRequest); i { + switch v := v.(*UpsertResourceResponse); i { case 0: return &v.state case 1: @@ -1710,7 +1971,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ChangeResourceNamespaceResponse); i { + switch v := v.(*ResourceStatus); i { case 0: return &v.state case 1: @@ -1722,7 +1983,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyResourcesRequest); i { + switch v := v.(*ResourceSpecification); i { case 0: return &v.state case 1: @@ -1734,7 +1995,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ApplyResourcesResponse); i { + switch v := v.(*ChangeResourceNamespaceRequest); i { case 0: return &v.state case 1: @@ -1746,7 +2007,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResourceRequest); i { + switch v := v.(*ChangeResourceNamespaceResponse); i { case 0: return &v.state case 1: @@ -1758,7 +2019,31 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResourceResponse); i { + switch v := v.(*ApplyResourcesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ApplyResourcesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResourceRequest); i { case 0: return &v.state case 1: @@ -1770,6 +2055,18 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { } } file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_gotocompany_optimus_core_v1beta1_resource_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ApplyResourcesResponse_ResourceStatus); i { case 0: return &v.state @@ -1788,7 +2085,7 @@ func file_gotocompany_optimus_core_v1beta1_resource_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_gotocompany_optimus_core_v1beta1_resource_proto_rawDesc, NumEnums: 0, - NumMessages: 20, + NumMessages: 23, NumExtensions: 0, NumServices: 1, }, diff --git a/protos/gotocompany/optimus/core/v1beta1/resource.pb.gw.go b/protos/gotocompany/optimus/core/v1beta1/resource.pb.gw.go index 9a49c54cbd..159cb06ba9 100644 --- a/protos/gotocompany/optimus/core/v1beta1/resource.pb.gw.go +++ b/protos/gotocompany/optimus/core/v1beta1/resource.pb.gw.go @@ -451,6 +451,114 @@ func local_request_ResourceService_UpdateResource_0(ctx context.Context, marshal } +func request_ResourceService_UpsertResource_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpsertResourceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["project_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_name") + } + + protoReq.ProjectName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_name", err) + } + + val, ok = pathParams["namespace_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace_name") + } + + protoReq.NamespaceName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace_name", err) + } + + val, ok = pathParams["datastore_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "datastore_name") + } + + protoReq.DatastoreName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "datastore_name", err) + } + + msg, err := client.UpsertResource(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ResourceService_UpsertResource_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq UpsertResourceRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["project_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_name") + } + + protoReq.ProjectName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_name", err) + } + + val, ok = pathParams["namespace_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace_name") + } + + protoReq.NamespaceName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace_name", err) + } + + val, ok = pathParams["datastore_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "datastore_name") + } + + protoReq.DatastoreName, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "datastore_name", err) + } + + msg, err := server.UpsertResource(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_ResourceService_DeleteResource_0 = &utilities.DoubleArray{Encoding: map[string]int{"project_name": 0, "namespace_name": 1, "datastore_name": 2, "resource_name": 3}, Base: []int{1, 1, 2, 3, 4, 0, 0, 0, 0}, Check: []int{0, 1, 1, 1, 1, 2, 3, 4, 5}} ) @@ -855,6 +963,29 @@ func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.Serv }) + mux.Handle("POST", pattern_ResourceService_UpsertResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/gotocompany.optimus.core.v1beta1.ResourceService/UpsertResource", runtime.WithHTTPPathPattern("/v1beta1/project/{project_name}/namespace/{namespace_name}/datastore/{datastore_name}/resources-upsert")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ResourceService_UpsertResource_0(rctx, 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) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_UpsertResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1045,6 +1176,26 @@ func RegisterResourceServiceHandlerClient(ctx context.Context, mux *runtime.Serv }) + mux.Handle("POST", pattern_ResourceService_UpsertResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req, "/gotocompany.optimus.core.v1beta1.ResourceService/UpsertResource", runtime.WithHTTPPathPattern("/v1beta1/project/{project_name}/namespace/{namespace_name}/datastore/{datastore_name}/resources-upsert")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ResourceService_UpsertResource_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ResourceService_UpsertResource_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("DELETE", pattern_ResourceService_DeleteResource_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1117,6 +1268,8 @@ var ( pattern_ResourceService_UpdateResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7}, []string{"v1beta1", "project", "project_name", "namespace", "namespace_name", "datastore", "datastore_name", "resource"}, "")) + pattern_ResourceService_UpsertResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7}, []string{"v1beta1", "project", "project_name", "namespace", "namespace_name", "datastore", "datastore_name", "resources-upsert"}, "")) + pattern_ResourceService_DeleteResource_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5, 1, 0, 4, 1, 5, 6, 2, 7, 1, 0, 4, 1, 5, 8}, []string{"v1beta1", "project", "project_name", "namespace", "namespace_name", "datastore", "datastore_name", "resource", "resource_name"}, "")) pattern_ResourceService_ChangeResourceNamespace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1beta1", "project", "project_name", "change-resource-namespace"}, "")) @@ -1133,6 +1286,8 @@ var ( forward_ResourceService_UpdateResource_0 = runtime.ForwardResponseMessage + forward_ResourceService_UpsertResource_0 = runtime.ForwardResponseMessage + forward_ResourceService_DeleteResource_0 = runtime.ForwardResponseMessage forward_ResourceService_ChangeResourceNamespace_0 = runtime.ForwardResponseMessage diff --git a/protos/gotocompany/optimus/core/v1beta1/resource.swagger.json b/protos/gotocompany/optimus/core/v1beta1/resource.swagger.json index 95b12d1561..2a5ce1de08 100644 --- a/protos/gotocompany/optimus/core/v1beta1/resource.swagger.json +++ b/protos/gotocompany/optimus/core/v1beta1/resource.swagger.json @@ -385,10 +385,69 @@ "ResourceService" ] } + }, + "/v1beta1/project/{projectName}/namespace/{namespaceName}/datastore/{datastoreName}/resources-upsert": { + "post": { + "summary": "UpsertResource updates/inserts a resource specification of a datastore in project", + "operationId": "ResourceService_UpsertResource", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/v1beta1UpsertResourceResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "projectName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "namespaceName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "datastoreName", + "in": "path", + "required": true, + "type": "string" + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "object", + "properties": { + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/v1beta1ResourceSpecification" + } + } + } + } + } + ], + "tags": [ + "ResourceService" + ] + } } }, "definitions": { - "ApplyResourcesResponseResourceStatus": { + "corev1beta1ResourceStatus": { "type": "object", "properties": { "resourceName": { @@ -397,7 +456,7 @@ "status": { "type": "string" }, - "reason": { + "message": { "type": "string" } } @@ -446,11 +505,25 @@ "statuses": { "type": "array", "items": { - "$ref": "#/definitions/ApplyResourcesResponseResourceStatus" + "$ref": "#/definitions/v1beta1ApplyResourcesResponseResourceStatus" } } } }, + "v1beta1ApplyResourcesResponseResourceStatus": { + "type": "object", + "properties": { + "resourceName": { + "type": "string" + }, + "status": { + "type": "string" + }, + "reason": { + "type": "string" + } + } + }, "v1beta1ChangeResourceNamespaceResponse": { "type": "object" }, @@ -574,6 +647,29 @@ "type": "string" } } + }, + "v1beta1UpsertResourceResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "results": { + "type": "array", + "items": { + "$ref": "#/definitions/corev1beta1ResourceStatus" + } + }, + "successfulResourceNames": { + "type": "array", + "items": { + "type": "string" + } + } + } } }, "externalDocs": { diff --git a/protos/gotocompany/optimus/core/v1beta1/resource_grpc.pb.go b/protos/gotocompany/optimus/core/v1beta1/resource_grpc.pb.go index a2fbd7325e..8934b9265c 100644 --- a/protos/gotocompany/optimus/core/v1beta1/resource_grpc.pb.go +++ b/protos/gotocompany/optimus/core/v1beta1/resource_grpc.pb.go @@ -34,6 +34,8 @@ type ResourceServiceClient interface { ReadResource(ctx context.Context, in *ReadResourceRequest, opts ...grpc.CallOption) (*ReadResourceResponse, error) // UpdateResource updates a resource specification of a datastore in project UpdateResource(ctx context.Context, in *UpdateResourceRequest, opts ...grpc.CallOption) (*UpdateResourceResponse, error) + // UpsertResource updates/inserts a resource specification of a datastore in project + UpsertResource(ctx context.Context, in *UpsertResourceRequest, opts ...grpc.CallOption) (*UpsertResourceResponse, error) // DeleteResource soft delete a specific resource DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) // ChangeJobNamespace move a job spec from one namespace to another @@ -117,6 +119,15 @@ func (c *resourceServiceClient) UpdateResource(ctx context.Context, in *UpdateRe return out, nil } +func (c *resourceServiceClient) UpsertResource(ctx context.Context, in *UpsertResourceRequest, opts ...grpc.CallOption) (*UpsertResourceResponse, error) { + out := new(UpsertResourceResponse) + err := c.cc.Invoke(ctx, "/gotocompany.optimus.core.v1beta1.ResourceService/UpsertResource", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *resourceServiceClient) DeleteResource(ctx context.Context, in *DeleteResourceRequest, opts ...grpc.CallOption) (*DeleteResourceResponse, error) { out := new(DeleteResourceResponse) err := c.cc.Invoke(ctx, "/gotocompany.optimus.core.v1beta1.ResourceService/DeleteResource", in, out, opts...) @@ -160,6 +171,8 @@ type ResourceServiceServer interface { ReadResource(context.Context, *ReadResourceRequest) (*ReadResourceResponse, error) // UpdateResource updates a resource specification of a datastore in project UpdateResource(context.Context, *UpdateResourceRequest) (*UpdateResourceResponse, error) + // UpsertResource updates/inserts a resource specification of a datastore in project + UpsertResource(context.Context, *UpsertResourceRequest) (*UpsertResourceResponse, error) // DeleteResource soft delete a specific resource DeleteResource(context.Context, *DeleteResourceRequest) (*DeleteResourceResponse, error) // ChangeJobNamespace move a job spec from one namespace to another @@ -188,6 +201,9 @@ func (UnimplementedResourceServiceServer) ReadResource(context.Context, *ReadRes func (UnimplementedResourceServiceServer) UpdateResource(context.Context, *UpdateResourceRequest) (*UpdateResourceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateResource not implemented") } +func (UnimplementedResourceServiceServer) UpsertResource(context.Context, *UpsertResourceRequest) (*UpsertResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpsertResource not implemented") +} func (UnimplementedResourceServiceServer) DeleteResource(context.Context, *DeleteResourceRequest) (*DeleteResourceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteResource not implemented") } @@ -308,6 +324,24 @@ func _ResourceService_UpdateResource_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _ResourceService_UpsertResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpsertResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceServiceServer).UpsertResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/gotocompany.optimus.core.v1beta1.ResourceService/UpsertResource", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceServiceServer).UpsertResource(ctx, req.(*UpsertResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _ResourceService_DeleteResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteResourceRequest) if err := dec(in); err != nil { @@ -385,6 +419,10 @@ var ResourceService_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpdateResource", Handler: _ResourceService_UpdateResource_Handler, }, + { + MethodName: "UpsertResource", + Handler: _ResourceService_UpsertResource_Handler, + }, { MethodName: "DeleteResource", Handler: _ResourceService_DeleteResource_Handler,