diff --git a/pkg/storage/README.md b/pkg/storage/README.md new file mode 100644 index 00000000000..508a59eb7a6 --- /dev/null +++ b/pkg/storage/README.md @@ -0,0 +1,4 @@ +This includes two packages + +api = the protobuf and common helpers useful for both client and server +server = the server support.... \ No newline at end of file diff --git a/pkg/storage/api/buf.gen.yaml b/pkg/storage/api/buf.gen.yaml new file mode 100644 index 00000000000..65658280dc1 --- /dev/null +++ b/pkg/storage/api/buf.gen.yaml @@ -0,0 +1,10 @@ +version: v1 +plugins: + - plugin: go + out: pkg/storage/api + opt: paths=source_relative + - plugin: go-grpc + out: pkg/storage/api + opt: + - paths=source_relative + - require_unimplemented_servers=false diff --git a/pkg/storage/api/buf.yaml b/pkg/storage/api/buf.yaml new file mode 100644 index 00000000000..1a5194568a9 --- /dev/null +++ b/pkg/storage/api/buf.yaml @@ -0,0 +1,7 @@ +version: v1 +breaking: + use: + - FILE +lint: + use: + - DEFAULT diff --git a/pkg/storage/api/event.go b/pkg/storage/api/event.go new file mode 100644 index 00000000000..5fea08e8dfa --- /dev/null +++ b/pkg/storage/api/event.go @@ -0,0 +1,219 @@ +package api + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "sync/atomic" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/grafana/grafana/pkg/infra/appcontext" + "github.com/grafana/grafana/pkg/services/apiserver/utils" + "github.com/grafana/grafana/pkg/services/auth/identity" +) + +type WriteEvent struct { + EventID int64 + Key *ResourceKey // the request key + Requester identity.Requester + Operation ResourceOperation + PreviousRV int64 // only for Update+Delete + Value []byte + + Object utils.GrafanaMetaAccessor + OldObject utils.GrafanaMetaAccessor + + // Change metadata + FolderChanged bool + + // The status will be populated for any error + Status *StatusResult + Error error +} + +func (e *WriteEvent) BadRequest(err error, message string, a ...any) *WriteEvent { + e.Error = err + e.Status = &StatusResult{ + Status: "Failure", + Message: fmt.Sprintf(message, a...), + Code: http.StatusBadRequest, + } + return e +} + +// Verify that all required fields are set, and the user has permission to set the common metadata fields +type EventValidator interface { + PrepareCreate(ctx context.Context, req *CreateRequest) (*WriteEvent, error) + PrepareUpdate(ctx context.Context, req *UpdateRequest, current []byte) (*WriteEvent, error) +} + +type EventValidatorOptions struct { + // Get the next EventID + NextEventID func() int64 + + // Check if a user has access to write folders + // When this is nil, no resources can have folders configured + FolderAccess func(ctx context.Context, user identity.Requester, uid string) bool + + // When configured, this will make sure a user is allowed to save to a given origin + OriginAccess func(ctx context.Context, user identity.Requester, origin string) bool +} + +type eventValidator struct { + opts EventValidatorOptions +} + +func NewEventValidator(opts EventValidatorOptions) EventValidator { + if opts.NextEventID == nil { + counter := atomic.Int64{} + opts.NextEventID = func() int64 { + return counter.Add(1) + } + } + return &eventValidator{opts} +} + +type dummyObject struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` +} + +var _ EventValidator = &eventValidator{} + +func (v *eventValidator) newEvent(ctx context.Context, key *ResourceKey, value, oldValue []byte) *WriteEvent { + var err error + event := &WriteEvent{ + EventID: v.opts.NextEventID(), + Key: key, + Value: value, + } + event.Requester, err = appcontext.User(ctx) + if err != nil { + return event.BadRequest(err, "unable to get user") + } + + dummy := &dummyObject{} + err = json.Unmarshal(value, dummy) + if err != nil { + return event.BadRequest(err, "error reading json") + } + + obj, err := utils.MetaAccessor(dummy) + if err != nil { + return event.BadRequest(err, "invalid object in json") + } + if obj.GetUID() == "" { + return event.BadRequest(nil, "the UID must be set") + } + if obj.GetGenerateName() != "" { + return event.BadRequest(nil, "can not save value with generate name") + } + if obj.GetKind() == "" { + return event.BadRequest(nil, "expecting resources with a kind in the body") + } + if obj.GetName() != key.Name { + return event.BadRequest(nil, "key name does not match the name in the body") + } + if obj.GetNamespace() != key.Namespace { + return event.BadRequest(nil, "key namespace does not match the namespace in the body") + } + folder := obj.GetFolder() + if folder != "" { + if v.opts.FolderAccess == nil { + return event.BadRequest(err, "folders are not supported") + } else if !v.opts.FolderAccess(ctx, event.Requester, folder) { + return event.BadRequest(err, "unable to add resource to folder") // 403? + } + } + origin, err := obj.GetOriginInfo() + if err != nil { + return event.BadRequest(err, "invalid origin info") + } + if origin != nil && v.opts.OriginAccess != nil { + if !v.opts.OriginAccess(ctx, event.Requester, origin.Name) { + return event.BadRequest(err, "not allowed to write resource to origin (%s)", origin.Name) + } + } + event.Object = obj + + // This is an update + if oldValue != nil { + dummy := &dummyObject{} + err = json.Unmarshal(oldValue, dummy) + if err != nil { + return event.BadRequest(err, "error reading old json value") + } + old, err := utils.MetaAccessor(dummy) + if err != nil { + return event.BadRequest(err, "invalid object inside old json") + } + if key.Name != old.GetName() { + return event.BadRequest(err, "the old value has a different name (%s != %s)", key.Name, old.GetName()) + } + + // Can not change creation timestamps+user + if obj.GetCreatedBy() != old.GetCreatedBy() { + return event.BadRequest(err, "can not change the created by metadata (%s != %s)", obj.GetCreatedBy(), old.GetCreatedBy()) + } + if obj.GetCreationTimestamp() != old.GetCreationTimestamp() { + return event.BadRequest(err, "can not change the CreationTimestamp metadata (%v != %v)", obj.GetCreationTimestamp(), old.GetCreationTimestamp()) + } + + oldFolder := obj.GetFolder() + if oldFolder != folder { + event.FolderChanged = true + } + event.OldObject = old + } else if folder != "" { + event.FolderChanged = true + } + return event +} + +func (v *eventValidator) PrepareCreate(ctx context.Context, req *CreateRequest) (*WriteEvent, error) { + event := v.newEvent(ctx, req.Key, req.Value, nil) + event.Operation = ResourceOperation_CREATED + if event.Status != nil { + return event, nil + } + + // Make sure the created by user is accurate + //---------------------------------------- + val := event.Object.GetCreatedBy() + if val != "" && val != event.Requester.GetUID().String() { + return event.BadRequest(nil, "created by annotation does not match: metadata.annotations#"+utils.AnnoKeyCreatedBy), nil + } + + // Create can not have updated properties + //---------------------------------------- + if event.Object.GetUpdatedBy() != "" { + return event.BadRequest(nil, "unexpected metadata.annotations#"+utils.AnnoKeyCreatedBy), nil + } + ts, err := event.Object.GetUpdatedTimestamp() + if err != nil { + return event.BadRequest(nil, fmt.Sprintf("invalid timestamp: %s", err)), nil + } + if ts != nil { + return event.BadRequest(nil, "unexpected metadata.annotations#"+utils.AnnoKeyUpdatedTimestamp), nil + } + return event, nil +} + +func (v *eventValidator) PrepareUpdate(ctx context.Context, req *UpdateRequest, current []byte) (*WriteEvent, error) { + event := v.newEvent(ctx, req.Key, req.Value, current) + event.Operation = ResourceOperation_UPDATED + if event.Status != nil { + return event, nil + } + + // Make sure the update user is accurate + //---------------------------------------- + val := event.Object.GetUpdatedBy() + if val != "" && val != event.Requester.GetUID().String() { + return event.BadRequest(nil, "created by annotation does not match: metadata.annotations#"+utils.AnnoKeyUpdatedBy), nil + } + + return event, nil +} diff --git a/pkg/storage/api/go.mod b/pkg/storage/api/go.mod new file mode 100644 index 00000000000..70f36959f35 --- /dev/null +++ b/pkg/storage/api/go.mod @@ -0,0 +1,15 @@ +module github.com/grafana/grafana/pkg/storage/api + +go 1.21.10 + +require ( + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.34.1 +) + +require ( + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect +) diff --git a/pkg/storage/api/go.sum b/pkg/storage/api/go.sum new file mode 100644 index 00000000000..5adf844d177 --- /dev/null +++ b/pkg/storage/api/go.sum @@ -0,0 +1,7 @@ +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 h1:Q2RxlXqh1cgzzUgV261vBO2jI5R/3DD1J2pM0nI4NhU= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= diff --git a/pkg/storage/api/resource.go b/pkg/storage/api/resource.go new file mode 100644 index 00000000000..4458a9500fa --- /dev/null +++ b/pkg/storage/api/resource.go @@ -0,0 +1,50 @@ +package api + +import ( + "bytes" + "fmt" +) + +// NamespacedPath is a path that can be used to isolate tenant data +// NOTE: this strategy does not allow quickly searching across namespace boundaries with a prefix +func (x *ResourceKey) NamespacedPath() string { + var buffer bytes.Buffer + if x.Namespace == "" { + buffer.WriteString("__cluster__") + } else { + buffer.WriteString(x.Namespace) + } + if x.Group == "" { + return buffer.String() + } + buffer.WriteString("/") + buffer.WriteString(x.Group) + + if x.Resource == "" { + return buffer.String() + } + buffer.WriteString("/") + buffer.WriteString(x.Resource) + + if x.Name == "" { + return buffer.String() + } + buffer.WriteString("/") + buffer.WriteString(x.Name) + + if x.ResourceVersion > 0 { + buffer.WriteString("/") + buffer.WriteString(fmt.Sprintf("%.20d", x.ResourceVersion)) + } + return buffer.String() +} + +// Return a copy without the resource version +func (x *ResourceKey) WithoutResourceVersion() *ResourceKey { + return &ResourceKey{ + Namespace: x.Namespace, + Group: x.Group, + Resource: x.Resource, + Name: x.Name, + } +} diff --git a/pkg/storage/api/resource.pb.go b/pkg/storage/api/resource.pb.go new file mode 100644 index 00000000000..44f05065c5d --- /dev/null +++ b/pkg/storage/api/resource.pb.go @@ -0,0 +1,3040 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc (unknown) +// source: resource.proto + +package api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ResourceOperation int32 + +const ( + ResourceOperation_UNKNOWN ResourceOperation = 0 + ResourceOperation_CREATED ResourceOperation = 1 + ResourceOperation_UPDATED ResourceOperation = 2 + ResourceOperation_DELETED ResourceOperation = 3 + ResourceOperation_BOOKMARK ResourceOperation = 4 +) + +// Enum value maps for ResourceOperation. +var ( + ResourceOperation_name = map[int32]string{ + 0: "UNKNOWN", + 1: "CREATED", + 2: "UPDATED", + 3: "DELETED", + 4: "BOOKMARK", + } + ResourceOperation_value = map[string]int32{ + "UNKNOWN": 0, + "CREATED": 1, + "UPDATED": 2, + "DELETED": 3, + "BOOKMARK": 4, + } +) + +func (x ResourceOperation) Enum() *ResourceOperation { + p := new(ResourceOperation) + *p = x + return p +} + +func (x ResourceOperation) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ResourceOperation) Descriptor() protoreflect.EnumDescriptor { + return file_resource_proto_enumTypes[0].Descriptor() +} + +func (ResourceOperation) Type() protoreflect.EnumType { + return &file_resource_proto_enumTypes[0] +} + +func (x ResourceOperation) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ResourceOperation.Descriptor instead. +func (ResourceOperation) EnumDescriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{0} +} + +type Sort_Order int32 + +const ( + Sort_ASC Sort_Order = 0 + Sort_DESC Sort_Order = 1 +) + +// Enum value maps for Sort_Order. +var ( + Sort_Order_name = map[int32]string{ + 0: "ASC", + 1: "DESC", + } + Sort_Order_value = map[string]int32{ + "ASC": 0, + "DESC": 1, + } +) + +func (x Sort_Order) Enum() *Sort_Order { + p := new(Sort_Order) + *p = x + return p +} + +func (x Sort_Order) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Sort_Order) Descriptor() protoreflect.EnumDescriptor { + return file_resource_proto_enumTypes[1].Descriptor() +} + +func (Sort_Order) Type() protoreflect.EnumType { + return &file_resource_proto_enumTypes[1] +} + +func (x Sort_Order) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Sort_Order.Descriptor instead. +func (Sort_Order) EnumDescriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{17, 0} +} + +type HealthCheckResponse_ServingStatus int32 + +const ( + HealthCheckResponse_UNKNOWN HealthCheckResponse_ServingStatus = 0 + HealthCheckResponse_SERVING HealthCheckResponse_ServingStatus = 1 + HealthCheckResponse_NOT_SERVING HealthCheckResponse_ServingStatus = 2 + HealthCheckResponse_SERVICE_UNKNOWN HealthCheckResponse_ServingStatus = 3 // Used only by the Watch method. +) + +// Enum value maps for HealthCheckResponse_ServingStatus. +var ( + HealthCheckResponse_ServingStatus_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SERVING", + 2: "NOT_SERVING", + 3: "SERVICE_UNKNOWN", + } + HealthCheckResponse_ServingStatus_value = map[string]int32{ + "UNKNOWN": 0, + "SERVING": 1, + "NOT_SERVING": 2, + "SERVICE_UNKNOWN": 3, + } +) + +func (x HealthCheckResponse_ServingStatus) Enum() *HealthCheckResponse_ServingStatus { + p := new(HealthCheckResponse_ServingStatus) + *p = x + return p +} + +func (x HealthCheckResponse_ServingStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HealthCheckResponse_ServingStatus) Descriptor() protoreflect.EnumDescriptor { + return file_resource_proto_enumTypes[2].Descriptor() +} + +func (HealthCheckResponse_ServingStatus) Type() protoreflect.EnumType { + return &file_resource_proto_enumTypes[2] +} + +func (x HealthCheckResponse_ServingStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use HealthCheckResponse_ServingStatus.Descriptor instead. +func (HealthCheckResponse_ServingStatus) EnumDescriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{29, 0} +} + +type ResourceKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Namespace (tenant) + Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` + // Resource Group + Group string `protobuf:"bytes,1,opt,name=group,proto3" json:"group,omitempty"` + // The resource type + Resource string `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"` + // Resource identifier (unique within namespace+group+resource) + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + // The resource version + ResourceVersion int64 `protobuf:"varint,5,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *ResourceKey) Reset() { + *x = ResourceKey{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceKey) ProtoMessage() {} + +func (x *ResourceKey) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[0] + 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 ResourceKey.ProtoReflect.Descriptor instead. +func (*ResourceKey) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{0} +} + +func (x *ResourceKey) GetNamespace() string { + if x != nil { + return x.Namespace + } + return "" +} + +func (x *ResourceKey) GetGroup() string { + if x != nil { + return x.Group + } + return "" +} + +func (x *ResourceKey) GetResource() string { + if x != nil { + return x.Resource + } + return "" +} + +func (x *ResourceKey) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ResourceKey) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type ResourceWrapper struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The resource version + ResourceVersion int64 `protobuf:"varint,1,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` + // Full kubernetes json bytes (although the resource version may not be accurate) + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Operation + Operation ResourceOperation `protobuf:"varint,3,opt,name=operation,proto3,enum=api.ResourceOperation" json:"operation,omitempty"` + // The resource has an attached blob + HasBlob bool `protobuf:"varint,4,opt,name=has_blob,json=hasBlob,proto3" json:"has_blob,omitempty"` +} + +func (x *ResourceWrapper) Reset() { + *x = ResourceWrapper{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceWrapper) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceWrapper) ProtoMessage() {} + +func (x *ResourceWrapper) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[1] + 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 ResourceWrapper.ProtoReflect.Descriptor instead. +func (*ResourceWrapper) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{1} +} + +func (x *ResourceWrapper) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +func (x *ResourceWrapper) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *ResourceWrapper) GetOperation() ResourceOperation { + if x != nil { + return x.Operation + } + return ResourceOperation_UNKNOWN +} + +func (x *ResourceWrapper) GetHasBlob() bool { + if x != nil { + return x.HasBlob + } + return false +} + +// The history and trash commands need access to commit messages +type ResourceMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The resource version + ResourceVersion int64 `protobuf:"varint,1,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` + // The optional commit message + Operation ResourceOperation `protobuf:"varint,2,opt,name=operation,proto3,enum=api.ResourceOperation" json:"operation,omitempty"` + // Size of the full resource body + Size int32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + // Hash for the resource + Hash string `protobuf:"bytes,4,opt,name=hash,proto3" json:"hash,omitempty"` + // The optional commit message + Message string `protobuf:"bytes,5,opt,name=message,proto3" json:"message,omitempty"` + // The kubernetes metadata section (not the full resource) + // https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L111 + ObjectMeta []byte `protobuf:"bytes,6,opt,name=object_meta,json=objectMeta,proto3" json:"object_meta,omitempty"` + // The resource has an attached blob + HasBlob bool `protobuf:"varint,7,opt,name=has_blob,json=hasBlob,proto3" json:"has_blob,omitempty"` +} + +func (x *ResourceMeta) Reset() { + *x = ResourceMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceMeta) ProtoMessage() {} + +func (x *ResourceMeta) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[2] + 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 ResourceMeta.ProtoReflect.Descriptor instead. +func (*ResourceMeta) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{2} +} + +func (x *ResourceMeta) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +func (x *ResourceMeta) GetOperation() ResourceOperation { + if x != nil { + return x.Operation + } + return ResourceOperation_UNKNOWN +} + +func (x *ResourceMeta) GetSize() int32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *ResourceMeta) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *ResourceMeta) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ResourceMeta) GetObjectMeta() []byte { + if x != nil { + return x.ObjectMeta + } + return nil +} + +func (x *ResourceMeta) GetHasBlob() bool { + if x != nil { + return x.HasBlob + } + return false +} + +// Basic blob metadata +type BlobInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Content Length + Size int64 `protobuf:"varint,1,opt,name=size,proto3" json:"size,omitempty"` + // MD5 digest of the body + ETag string `protobuf:"bytes,2,opt,name=ETag,proto3" json:"ETag,omitempty"` + // Content type header + ContentType string `protobuf:"bytes,3,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` +} + +func (x *BlobInfo) Reset() { + *x = BlobInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlobInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlobInfo) ProtoMessage() {} + +func (x *BlobInfo) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[3] + 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 BlobInfo.ProtoReflect.Descriptor instead. +func (*BlobInfo) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{3} +} + +func (x *BlobInfo) GetSize() int64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *BlobInfo) GetETag() string { + if x != nil { + return x.ETag + } + return "" +} + +func (x *BlobInfo) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +// Status structure is copied from: +// https://github.com/kubernetes/apimachinery/blob/v0.30.1/pkg/apis/meta/v1/generated.proto#L979 +type StatusResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status of the operation. + // One of: "Success" or "Failure". + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // A human-readable description of the status of this operation. + // +optional + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + // A machine-readable description of why this operation is in the + // "Failure" status. If this value is empty there + // is no information available. A Reason clarifies an HTTP status + // code but does not override it. + // +optional + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` + // Suggested HTTP return code for this status, 0 if not set. + // +optional + Code int32 `protobuf:"varint,4,opt,name=code,proto3" json:"code,omitempty"` +} + +func (x *StatusResult) Reset() { + *x = StatusResult{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusResult) ProtoMessage() {} + +func (x *StatusResult) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[4] + 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 StatusResult.ProtoReflect.Descriptor instead. +func (*StatusResult) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{4} +} + +func (x *StatusResult) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +func (x *StatusResult) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *StatusResult) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *StatusResult) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +// TODO? support PresignedUrls for upload? +type CreateBlob struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Content type header + ContentType string `protobuf:"bytes,1,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // Raw value to write + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *CreateBlob) Reset() { + *x = CreateBlob{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateBlob) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateBlob) ProtoMessage() {} + +func (x *CreateBlob) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[5] + 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 CreateBlob.ProtoReflect.Descriptor instead. +func (*CreateBlob) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateBlob) GetContentType() string { + if x != nil { + return x.ContentType + } + return "" +} + +func (x *CreateBlob) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +type CreateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Requires group+resource to be configuired + // If name is not set, a unique name will be generated + // The resourceVersion should not be set + Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The resource JSON. + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Optional commit message + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + // Optionally include a large binary object + Blob *CreateBlob `protobuf:"bytes,4,opt,name=blob,proto3" json:"blob,omitempty"` +} + +func (x *CreateRequest) Reset() { + *x = CreateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateRequest) ProtoMessage() {} + +func (x *CreateRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[6] + 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 CreateRequest.ProtoReflect.Descriptor instead. +func (*CreateRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{6} +} + +func (x *CreateRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *CreateRequest) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *CreateRequest) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *CreateRequest) GetBlob() *CreateBlob { + if x != nil { + return x.Blob + } + return nil +} + +type CreateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status code + Status *StatusResult `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // The updated resource version + ResourceVersion int64 `protobuf:"varint,2,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *CreateResponse) Reset() { + *x = CreateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateResponse) ProtoMessage() {} + +func (x *CreateResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[7] + 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 CreateResponse.ProtoReflect.Descriptor instead. +func (*CreateResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{7} +} + +func (x *CreateResponse) GetStatus() *StatusResult { + if x != nil { + return x.Status + } + return nil +} + +func (x *CreateResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type UpdateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Full key must be set + Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The resource JSON. + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + // Optional commit message + // +optional + Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` + // Optionally link a resource object + Blob *CreateBlob `protobuf:"bytes,4,opt,name=blob,proto3" json:"blob,omitempty"` +} + +func (x *UpdateRequest) Reset() { + *x = UpdateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRequest) ProtoMessage() {} + +func (x *UpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[8] + 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 UpdateRequest.ProtoReflect.Descriptor instead. +func (*UpdateRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *UpdateRequest) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *UpdateRequest) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *UpdateRequest) GetBlob() *CreateBlob { + if x != nil { + return x.Blob + } + return nil +} + +type UpdateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status code + Status *StatusResult `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // The updated resource version + ResourceVersion int64 `protobuf:"varint,2,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *UpdateResponse) Reset() { + *x = UpdateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateResponse) ProtoMessage() {} + +func (x *UpdateResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[9] + 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 UpdateResponse.ProtoReflect.Descriptor instead. +func (*UpdateResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{9} +} + +func (x *UpdateResponse) GetStatus() *StatusResult { + if x != nil { + return x.Status + } + return nil +} + +func (x *UpdateResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type DeleteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Preconditions: make sure the uid matches the current saved value + // +optional + Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` +} + +func (x *DeleteRequest) Reset() { + *x = DeleteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteRequest) ProtoMessage() {} + +func (x *DeleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_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 DeleteRequest.ProtoReflect.Descriptor instead. +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{10} +} + +func (x *DeleteRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *DeleteRequest) GetUid() string { + if x != nil { + return x.Uid + } + return "" +} + +type DeleteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status code + Status *StatusResult `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // The new resource version + ResourceVersion int64 `protobuf:"varint,2,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *DeleteResponse) Reset() { + *x = DeleteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteResponse) ProtoMessage() {} + +func (x *DeleteResponse) ProtoReflect() protoreflect.Message { + mi := &file_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 DeleteResponse.ProtoReflect.Descriptor instead. +func (*DeleteResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{11} +} + +func (x *DeleteResponse) GetStatus() *StatusResult { + if x != nil { + return x.Status + } + return nil +} + +func (x *DeleteResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type GetResourceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *GetResourceRequest) Reset() { + *x = GetResourceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceRequest) ProtoMessage() {} + +func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { + mi := &file_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 GetResourceRequest.ProtoReflect.Descriptor instead. +func (*GetResourceRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{12} +} + +func (x *GetResourceRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +type GetResourceResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status code + Status *StatusResult `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // The new resource version + ResourceVersion int64 `protobuf:"varint,2,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` + // The properties + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + // A Signed URL that will let you fetch the blob + // If this value starts with # you must read the bytes using the GetResourceBlob request + BlobUrl string `protobuf:"bytes,4,opt,name=blob_url,json=blobUrl,proto3" json:"blob_url,omitempty"` +} + +func (x *GetResourceResponse) Reset() { + *x = GetResourceResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetResourceResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetResourceResponse) ProtoMessage() {} + +func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[13] + 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 GetResourceResponse.ProtoReflect.Descriptor instead. +func (*GetResourceResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{13} +} + +func (x *GetResourceResponse) GetStatus() *StatusResult { + if x != nil { + return x.Status + } + return nil +} + +func (x *GetResourceResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +func (x *GetResourceResponse) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *GetResourceResponse) GetBlobUrl() string { + if x != nil { + return x.BlobUrl + } + return "" +} + +type GetBlobRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *GetBlobRequest) Reset() { + *x = GetBlobRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlobRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlobRequest) ProtoMessage() {} + +func (x *GetBlobRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[14] + 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 GetBlobRequest.ProtoReflect.Descriptor instead. +func (*GetBlobRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{14} +} + +func (x *GetBlobRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +type GetBlobResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Status code + Status *StatusResult `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` + // Headers + Info *BlobInfo `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` + // The raw object value + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *GetBlobResponse) Reset() { + *x = GetBlobResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlobResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlobResponse) ProtoMessage() {} + +func (x *GetBlobResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[15] + 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 GetBlobResponse.ProtoReflect.Descriptor instead. +func (*GetBlobResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{15} +} + +func (x *GetBlobResponse) GetStatus() *StatusResult { + if x != nil { + return x.Status + } + return nil +} + +func (x *GetBlobResponse) GetInfo() *BlobInfo { + if x != nil { + return x.Info + } + return nil +} + +func (x *GetBlobResponse) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +// The label filtering requirements: +// https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/labels/selector.go#L141 +type Requirement struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Operator string `protobuf:"bytes,2,opt,name=operator,proto3" json:"operator,omitempty"` // See https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/selection/operator.go#L21 + Values []string `protobuf:"bytes,3,rep,name=values,proto3" json:"values,omitempty"` // typically one value, but depends on the operator +} + +func (x *Requirement) Reset() { + *x = Requirement{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Requirement) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Requirement) ProtoMessage() {} + +func (x *Requirement) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[16] + 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 Requirement.ProtoReflect.Descriptor instead. +func (*Requirement) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{16} +} + +func (x *Requirement) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *Requirement) GetOperator() string { + if x != nil { + return x.Operator + } + return "" +} + +func (x *Requirement) GetValues() []string { + if x != nil { + return x.Values + } + return nil +} + +type Sort struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Field string `protobuf:"bytes,1,opt,name=field,proto3" json:"field,omitempty"` + Order Sort_Order `protobuf:"varint,2,opt,name=order,proto3,enum=api.Sort_Order" json:"order,omitempty"` +} + +func (x *Sort) Reset() { + *x = Sort{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Sort) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Sort) ProtoMessage() {} + +func (x *Sort) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[17] + 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 Sort.ProtoReflect.Descriptor instead. +func (*Sort) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{17} +} + +func (x *Sort) GetField() string { + if x != nil { + return x.Field + } + return "" +} + +func (x *Sort) GetOrder() Sort_Order { + if x != nil { + return x.Order + } + return Sort_ASC +} + +type ListOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Maximum number of items to return + // NOTE responses will also be limited by the response payload size + Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + // Namespace+Group+Resource+etc + Key *ResourceKey `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + // Match label + Labels []*Requirement `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty"` + // Match fields (not yet supported) + Fields []*Requirement `protobuf:"bytes,5,rep,name=fields,proto3" json:"fields,omitempty"` + // Limit results to items in a specific folder (not a query for everything under that folder!) + Folder string `protobuf:"bytes,6,opt,name=folder,proto3" json:"folder,omitempty"` +} + +func (x *ListOptions) Reset() { + *x = ListOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOptions) ProtoMessage() {} + +func (x *ListOptions) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[18] + 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 ListOptions.ProtoReflect.Descriptor instead. +func (*ListOptions) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{18} +} + +func (x *ListOptions) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *ListOptions) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *ListOptions) GetLabels() []*Requirement { + if x != nil { + return x.Labels + } + return nil +} + +func (x *ListOptions) GetFields() []*Requirement { + if x != nil { + return x.Fields + } + return nil +} + +func (x *ListOptions) GetFolder() string { + if x != nil { + return x.Folder + } + return "" +} + +type ListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Starting from the requested page (other query parameters must match!) + NextPageToken string `protobuf:"bytes,1,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // Filtering + Options *ListOptions `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` + // Sorting instructions `field ASC/DESC` + Sort []*Sort `protobuf:"bytes,3,rep,name=sort,proto3" json:"sort,omitempty"` +} + +func (x *ListRequest) Reset() { + *x = ListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListRequest) ProtoMessage() {} + +func (x *ListRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[19] + 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 ListRequest.ProtoReflect.Descriptor instead. +func (*ListRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{19} +} + +func (x *ListRequest) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *ListRequest) GetOptions() *ListOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *ListRequest) GetSort() []*Sort { + if x != nil { + return x.Sort + } + return nil +} + +type ListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items []*ResourceWrapper `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + // When more results exist, pass this in the next request + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // ResourceVersion of the list response + ResourceVersion int64 `protobuf:"varint,3,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` + // remainingItemCount is the number of subsequent items in the list which are not included in this + // list response. If the list request contained label or field selectors, then the number of + // remaining items is unknown and the field will be left unset and omitted during serialization. + // If the list is complete (either because it is not chunking or because this is the last chunk), + // then there are no more remaining items and this field will be left unset and omitted during + // serialization. + // + // The intended use of the remainingItemCount is *estimating* the size of a collection. Clients + // should not rely on the remainingItemCount to be set or to be exact. + // +optional + RemainingItemCount int64 `protobuf:"varint,4,opt,name=remaining_item_count,json=remainingItemCount,proto3" json:"remaining_item_count,omitempty"` // 0 won't be set either (no next page token) +} + +func (x *ListResponse) Reset() { + *x = ListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResponse) ProtoMessage() {} + +func (x *ListResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[20] + 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 ListResponse.ProtoReflect.Descriptor instead. +func (*ListResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{20} +} + +func (x *ListResponse) GetItems() []*ResourceWrapper { + if x != nil { + return x.Items + } + return nil +} + +func (x *ListResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *ListResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +func (x *ListResponse) GetRemainingItemCount() int64 { + if x != nil { + return x.RemainingItemCount + } + return 0 +} + +type WatchRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // ResourceVersion of last changes. Empty will default to full history + Since int64 `protobuf:"varint,1,opt,name=since,proto3" json:"since,omitempty"` + // Watch specific entities + Key *ResourceKey `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + // Additional options + Options *ListOptions `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` + // Return initial events + SendInitialEvents bool `protobuf:"varint,4,opt,name=send_initial_events,json=sendInitialEvents,proto3" json:"send_initial_events,omitempty"` + // When done with initial events, send a bookmark event + AllowWatchBookmarks bool `protobuf:"varint,5,opt,name=allow_watch_bookmarks,json=allowWatchBookmarks,proto3" json:"allow_watch_bookmarks,omitempty"` +} + +func (x *WatchRequest) Reset() { + *x = WatchRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WatchRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchRequest) ProtoMessage() {} + +func (x *WatchRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[21] + 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 WatchRequest.ProtoReflect.Descriptor instead. +func (*WatchRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{21} +} + +func (x *WatchRequest) GetSince() int64 { + if x != nil { + return x.Since + } + return 0 +} + +func (x *WatchRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *WatchRequest) GetOptions() *ListOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *WatchRequest) GetSendInitialEvents() bool { + if x != nil { + return x.SendInitialEvents + } + return false +} + +func (x *WatchRequest) GetAllowWatchBookmarks() bool { + if x != nil { + return x.AllowWatchBookmarks + } + return false +} + +type WatchResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Timestamp the event was sent + Timestamp int64 `protobuf:"varint,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // Entity that was created, updated, or deleted + Resource *ResourceWrapper `protobuf:"bytes,2,opt,name=resource,proto3" json:"resource,omitempty"` + // previous version of the entity (in update+delete events) + Previous *ResourceWrapper `protobuf:"bytes,3,opt,name=previous,proto3" json:"previous,omitempty"` +} + +func (x *WatchResponse) Reset() { + *x = WatchResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WatchResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WatchResponse) ProtoMessage() {} + +func (x *WatchResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[22] + 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 WatchResponse.ProtoReflect.Descriptor instead. +func (*WatchResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{22} +} + +func (x *WatchResponse) GetTimestamp() int64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *WatchResponse) GetResource() *ResourceWrapper { + if x != nil { + return x.Resource + } + return nil +} + +func (x *WatchResponse) GetPrevious() *ResourceWrapper { + if x != nil { + return x.Previous + } + return nil +} + +type HistoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Starting from the requested page (other query parameters must match!) + NextPageToken string `protobuf:"bytes,1,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // Maximum number of items to return + Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + // Resource identifier + Key *ResourceKey `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + // List the deleted values (eg, show trash) + ShowDeleted bool `protobuf:"varint,4,opt,name=show_deleted,json=showDeleted,proto3" json:"show_deleted,omitempty"` +} + +func (x *HistoryRequest) Reset() { + *x = HistoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HistoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistoryRequest) ProtoMessage() {} + +func (x *HistoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[23] + 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 HistoryRequest.ProtoReflect.Descriptor instead. +func (*HistoryRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{23} +} + +func (x *HistoryRequest) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *HistoryRequest) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *HistoryRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *HistoryRequest) GetShowDeleted() bool { + if x != nil { + return x.ShowDeleted + } + return false +} + +type HistoryResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items []*ResourceMeta `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + // More results exist... pass this in the next request + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // ResourceVersion of the list response + ResourceVersion int64 `protobuf:"varint,3,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *HistoryResponse) Reset() { + *x = HistoryResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HistoryResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistoryResponse) ProtoMessage() {} + +func (x *HistoryResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[24] + 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 HistoryResponse.ProtoReflect.Descriptor instead. +func (*HistoryResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{24} +} + +func (x *HistoryResponse) GetItems() []*ResourceMeta { + if x != nil { + return x.Items + } + return nil +} + +func (x *HistoryResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *HistoryResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type OriginRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Starting from the requested page (other query parameters must match!) + NextPageToken string `protobuf:"bytes,1,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // Maximum number of items to return + Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + // Resource identifier + Key *ResourceKey `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` + // List the deleted values (eg, show trash) + Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` +} + +func (x *OriginRequest) Reset() { + *x = OriginRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OriginRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OriginRequest) ProtoMessage() {} + +func (x *OriginRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[25] + 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 OriginRequest.ProtoReflect.Descriptor instead. +func (*OriginRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{25} +} + +func (x *OriginRequest) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *OriginRequest) GetLimit() int64 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *OriginRequest) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *OriginRequest) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +type ResourceOriginInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The resource + Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Size of the full resource body + ResourceSize int32 `protobuf:"varint,2,opt,name=resource_size,json=resourceSize,proto3" json:"resource_size,omitempty"` + // Hash for the resource + ResourceHash string `protobuf:"bytes,3,opt,name=resource_hash,json=resourceHash,proto3" json:"resource_hash,omitempty"` + // The origin name + Origin string `protobuf:"bytes,4,opt,name=origin,proto3" json:"origin,omitempty"` + // Path on the origin + Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + // Verification hash from the origin + Hash string `protobuf:"bytes,6,opt,name=hash,proto3" json:"hash,omitempty"` + // Change time from the origin + Timestamp int64 `protobuf:"varint,7,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *ResourceOriginInfo) Reset() { + *x = ResourceOriginInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResourceOriginInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResourceOriginInfo) ProtoMessage() {} + +func (x *ResourceOriginInfo) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[26] + 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 ResourceOriginInfo.ProtoReflect.Descriptor instead. +func (*ResourceOriginInfo) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{26} +} + +func (x *ResourceOriginInfo) GetKey() *ResourceKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *ResourceOriginInfo) GetResourceSize() int32 { + if x != nil { + return x.ResourceSize + } + return 0 +} + +func (x *ResourceOriginInfo) GetResourceHash() string { + if x != nil { + return x.ResourceHash + } + return "" +} + +func (x *ResourceOriginInfo) GetOrigin() string { + if x != nil { + return x.Origin + } + return "" +} + +func (x *ResourceOriginInfo) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *ResourceOriginInfo) GetHash() string { + if x != nil { + return x.Hash + } + return "" +} + +func (x *ResourceOriginInfo) GetTimestamp() int64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +type OriginResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Items []*ResourceOriginInfo `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + // More results exist... pass this in the next request + NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` + // ResourceVersion of the list response + ResourceVersion int64 `protobuf:"varint,3,opt,name=resource_version,json=resourceVersion,proto3" json:"resource_version,omitempty"` +} + +func (x *OriginResponse) Reset() { + *x = OriginResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OriginResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OriginResponse) ProtoMessage() {} + +func (x *OriginResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[27] + 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 OriginResponse.ProtoReflect.Descriptor instead. +func (*OriginResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{27} +} + +func (x *OriginResponse) GetItems() []*ResourceOriginInfo { + if x != nil { + return x.Items + } + return nil +} + +func (x *OriginResponse) GetNextPageToken() string { + if x != nil { + return x.NextPageToken + } + return "" +} + +func (x *OriginResponse) GetResourceVersion() int64 { + if x != nil { + return x.ResourceVersion + } + return 0 +} + +type HealthCheckRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` +} + +func (x *HealthCheckRequest) Reset() { + *x = HealthCheckRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckRequest) ProtoMessage() {} + +func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[28] + 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 HealthCheckRequest.ProtoReflect.Descriptor instead. +func (*HealthCheckRequest) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{28} +} + +func (x *HealthCheckRequest) GetService() string { + if x != nil { + return x.Service + } + return "" +} + +type HealthCheckResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status HealthCheckResponse_ServingStatus `protobuf:"varint,1,opt,name=status,proto3,enum=api.HealthCheckResponse_ServingStatus" json:"status,omitempty"` +} + +func (x *HealthCheckResponse) Reset() { + *x = HealthCheckResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_resource_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HealthCheckResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HealthCheckResponse) ProtoMessage() {} + +func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message { + mi := &file_resource_proto_msgTypes[29] + 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 HealthCheckResponse.ProtoReflect.Descriptor instead. +func (*HealthCheckResponse) Descriptor() ([]byte, []int) { + return file_resource_proto_rawDescGZIP(), []int{29} +} + +func (x *HealthCheckResponse) GetStatus() HealthCheckResponse_ServingStatus { + if x != nil { + return x.Status + } + return HealthCheckResponse_UNKNOWN +} + +var File_resource_proto protoreflect.FileDescriptor + +var file_resource_proto_rawDesc = []byte{ + 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x03, 0x61, 0x70, 0x69, 0x22, 0x9c, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa3, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x6f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x68, 0x61, 0x73, 0x42, 0x6c, 0x6f, 0x62, 0x22, 0xed, 0x01, 0x0a, 0x0c, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x29, 0x0a, 0x10, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, + 0x19, 0x0a, 0x08, 0x68, 0x61, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x68, 0x61, 0x73, 0x42, 0x6c, 0x6f, 0x62, 0x22, 0x55, 0x0a, 0x08, 0x42, 0x6c, + 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x45, 0x54, + 0x61, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x54, 0x61, 0x67, 0x12, 0x21, + 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x6c, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 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, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, + 0x45, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x88, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 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, 0x12, 0x23, 0x0a, 0x04, + 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x04, 0x62, 0x6c, 0x6f, + 0x62, 0x22, 0x66, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, + 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x88, 0x01, 0x0a, 0x0d, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 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, 0x12, + 0x23, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x04, + 0x62, 0x6c, 0x6f, 0x62, 0x22, 0x66, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x45, 0x0a, 0x0d, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x75, 0x69, 0x64, 0x22, 0x66, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x38, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x9c, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x6c, 0x6f, + 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x6c, 0x6f, + 0x62, 0x55, 0x72, 0x6c, 0x22, 0x34, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x75, 0x0a, 0x0f, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x6c, 0x6f, + 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x53, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x16, + 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x5f, 0x0a, 0x04, 0x53, 0x6f, 0x72, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x25, 0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x2e, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x52, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x1a, 0x0a, 0x05, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x53, 0x43, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x44, 0x45, 0x53, 0x43, 0x10, 0x01, 0x22, 0xb3, 0x01, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x22, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x28, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x28, 0x0a, 0x06, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x22, 0x80, 0x01, + 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, + 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x1d, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, + 0x22, 0xbf, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, + 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x30, 0x0a, 0x14, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x74, + 0x65, 0x6d, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, + 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x22, 0xd8, 0x01, 0x0a, 0x0c, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x73, 0x65, 0x6e, + 0x64, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x73, 0x65, 0x6e, 0x64, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x5f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x62, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, + 0x6b, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x57, + 0x61, 0x74, 0x63, 0x68, 0x42, 0x6f, 0x6f, 0x6b, 0x6d, 0x61, 0x72, 0x6b, 0x73, 0x22, 0x91, 0x01, + 0x0a, 0x0d, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x30, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x72, + 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, + 0x30, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x08, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, + 0x73, 0x22, 0x95, 0x01, 0x0a, 0x0e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, + 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, + 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x68, 0x6f, 0x77, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x68, + 0x6f, 0x77, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x8d, 0x01, 0x0a, 0x0f, 0x48, 0x69, + 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, + 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, + 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x29, + 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x89, 0x01, 0x0a, 0x0d, 0x4f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, + 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x22, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0xe0, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x22, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x4f, 0x72, 0x69, + 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, + 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x2e, 0x0a, + 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0xa6, 0x01, + 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4f, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x01, + 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, + 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x2a, 0x55, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x0a, 0x07, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, + 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x12, + 0x0c, 0x0a, 0x08, 0x42, 0x4f, 0x4f, 0x4b, 0x4d, 0x41, 0x52, 0x4b, 0x10, 0x04, 0x32, 0xa8, 0x04, + 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, + 0x40, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x17, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x31, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x12, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x4c, 0x69, + 0x73, 0x74, 0x12, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x12, 0x11, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x34, 0x0a, 0x07, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, + 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x34, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x13, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, + 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x49, 0x73, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2c, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x67, + 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_resource_proto_rawDescOnce sync.Once + file_resource_proto_rawDescData = file_resource_proto_rawDesc +) + +func file_resource_proto_rawDescGZIP() []byte { + file_resource_proto_rawDescOnce.Do(func() { + file_resource_proto_rawDescData = protoimpl.X.CompressGZIP(file_resource_proto_rawDescData) + }) + return file_resource_proto_rawDescData +} + +var file_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 3) +var file_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_resource_proto_goTypes = []interface{}{ + (ResourceOperation)(0), // 0: api.ResourceOperation + (Sort_Order)(0), // 1: api.Sort.Order + (HealthCheckResponse_ServingStatus)(0), // 2: api.HealthCheckResponse.ServingStatus + (*ResourceKey)(nil), // 3: api.ResourceKey + (*ResourceWrapper)(nil), // 4: api.ResourceWrapper + (*ResourceMeta)(nil), // 5: api.ResourceMeta + (*BlobInfo)(nil), // 6: api.BlobInfo + (*StatusResult)(nil), // 7: api.StatusResult + (*CreateBlob)(nil), // 8: api.CreateBlob + (*CreateRequest)(nil), // 9: api.CreateRequest + (*CreateResponse)(nil), // 10: api.CreateResponse + (*UpdateRequest)(nil), // 11: api.UpdateRequest + (*UpdateResponse)(nil), // 12: api.UpdateResponse + (*DeleteRequest)(nil), // 13: api.DeleteRequest + (*DeleteResponse)(nil), // 14: api.DeleteResponse + (*GetResourceRequest)(nil), // 15: api.GetResourceRequest + (*GetResourceResponse)(nil), // 16: api.GetResourceResponse + (*GetBlobRequest)(nil), // 17: api.GetBlobRequest + (*GetBlobResponse)(nil), // 18: api.GetBlobResponse + (*Requirement)(nil), // 19: api.Requirement + (*Sort)(nil), // 20: api.Sort + (*ListOptions)(nil), // 21: api.ListOptions + (*ListRequest)(nil), // 22: api.ListRequest + (*ListResponse)(nil), // 23: api.ListResponse + (*WatchRequest)(nil), // 24: api.WatchRequest + (*WatchResponse)(nil), // 25: api.WatchResponse + (*HistoryRequest)(nil), // 26: api.HistoryRequest + (*HistoryResponse)(nil), // 27: api.HistoryResponse + (*OriginRequest)(nil), // 28: api.OriginRequest + (*ResourceOriginInfo)(nil), // 29: api.ResourceOriginInfo + (*OriginResponse)(nil), // 30: api.OriginResponse + (*HealthCheckRequest)(nil), // 31: api.HealthCheckRequest + (*HealthCheckResponse)(nil), // 32: api.HealthCheckResponse +} +var file_resource_proto_depIdxs = []int32{ + 0, // 0: api.ResourceWrapper.operation:type_name -> api.ResourceOperation + 0, // 1: api.ResourceMeta.operation:type_name -> api.ResourceOperation + 3, // 2: api.CreateRequest.key:type_name -> api.ResourceKey + 8, // 3: api.CreateRequest.blob:type_name -> api.CreateBlob + 7, // 4: api.CreateResponse.status:type_name -> api.StatusResult + 3, // 5: api.UpdateRequest.key:type_name -> api.ResourceKey + 8, // 6: api.UpdateRequest.blob:type_name -> api.CreateBlob + 7, // 7: api.UpdateResponse.status:type_name -> api.StatusResult + 3, // 8: api.DeleteRequest.key:type_name -> api.ResourceKey + 7, // 9: api.DeleteResponse.status:type_name -> api.StatusResult + 3, // 10: api.GetResourceRequest.key:type_name -> api.ResourceKey + 7, // 11: api.GetResourceResponse.status:type_name -> api.StatusResult + 3, // 12: api.GetBlobRequest.key:type_name -> api.ResourceKey + 7, // 13: api.GetBlobResponse.status:type_name -> api.StatusResult + 6, // 14: api.GetBlobResponse.info:type_name -> api.BlobInfo + 1, // 15: api.Sort.order:type_name -> api.Sort.Order + 3, // 16: api.ListOptions.key:type_name -> api.ResourceKey + 19, // 17: api.ListOptions.labels:type_name -> api.Requirement + 19, // 18: api.ListOptions.fields:type_name -> api.Requirement + 21, // 19: api.ListRequest.options:type_name -> api.ListOptions + 20, // 20: api.ListRequest.sort:type_name -> api.Sort + 4, // 21: api.ListResponse.items:type_name -> api.ResourceWrapper + 3, // 22: api.WatchRequest.key:type_name -> api.ResourceKey + 21, // 23: api.WatchRequest.options:type_name -> api.ListOptions + 4, // 24: api.WatchResponse.resource:type_name -> api.ResourceWrapper + 4, // 25: api.WatchResponse.previous:type_name -> api.ResourceWrapper + 3, // 26: api.HistoryRequest.key:type_name -> api.ResourceKey + 5, // 27: api.HistoryResponse.items:type_name -> api.ResourceMeta + 3, // 28: api.OriginRequest.key:type_name -> api.ResourceKey + 3, // 29: api.ResourceOriginInfo.key:type_name -> api.ResourceKey + 29, // 30: api.OriginResponse.items:type_name -> api.ResourceOriginInfo + 2, // 31: api.HealthCheckResponse.status:type_name -> api.HealthCheckResponse.ServingStatus + 15, // 32: api.ResourceStore.GetResource:input_type -> api.GetResourceRequest + 9, // 33: api.ResourceStore.Create:input_type -> api.CreateRequest + 11, // 34: api.ResourceStore.Update:input_type -> api.UpdateRequest + 13, // 35: api.ResourceStore.Delete:input_type -> api.DeleteRequest + 22, // 36: api.ResourceStore.List:input_type -> api.ListRequest + 24, // 37: api.ResourceStore.Watch:input_type -> api.WatchRequest + 17, // 38: api.ResourceStore.GetBlob:input_type -> api.GetBlobRequest + 26, // 39: api.ResourceStore.History:input_type -> api.HistoryRequest + 28, // 40: api.ResourceStore.Origin:input_type -> api.OriginRequest + 31, // 41: api.ResourceStore.IsHealthy:input_type -> api.HealthCheckRequest + 16, // 42: api.ResourceStore.GetResource:output_type -> api.GetResourceResponse + 10, // 43: api.ResourceStore.Create:output_type -> api.CreateResponse + 12, // 44: api.ResourceStore.Update:output_type -> api.UpdateResponse + 14, // 45: api.ResourceStore.Delete:output_type -> api.DeleteResponse + 23, // 46: api.ResourceStore.List:output_type -> api.ListResponse + 25, // 47: api.ResourceStore.Watch:output_type -> api.WatchResponse + 18, // 48: api.ResourceStore.GetBlob:output_type -> api.GetBlobResponse + 27, // 49: api.ResourceStore.History:output_type -> api.HistoryResponse + 30, // 50: api.ResourceStore.Origin:output_type -> api.OriginResponse + 32, // 51: api.ResourceStore.IsHealthy:output_type -> api.HealthCheckResponse + 42, // [42:52] is the sub-list for method output_type + 32, // [32:42] is the sub-list for method input_type + 32, // [32:32] is the sub-list for extension type_name + 32, // [32:32] is the sub-list for extension extendee + 0, // [0:32] is the sub-list for field type_name +} + +func init() { file_resource_proto_init() } +func file_resource_proto_init() { + if File_resource_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_resource_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceWrapper); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlobInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateBlob); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetResourceResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlobRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlobResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Requirement); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Sort); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WatchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WatchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HistoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HistoryResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OriginRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResourceOriginInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OriginResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_resource_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HealthCheckResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_resource_proto_rawDesc, + NumEnums: 3, + NumMessages: 30, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_resource_proto_goTypes, + DependencyIndexes: file_resource_proto_depIdxs, + EnumInfos: file_resource_proto_enumTypes, + MessageInfos: file_resource_proto_msgTypes, + }.Build() + File_resource_proto = out.File + file_resource_proto_rawDesc = nil + file_resource_proto_goTypes = nil + file_resource_proto_depIdxs = nil +} diff --git a/pkg/storage/api/resource.proto b/pkg/storage/api/resource.proto new file mode 100644 index 00000000000..7221c223607 --- /dev/null +++ b/pkg/storage/api/resource.proto @@ -0,0 +1,415 @@ +syntax = "proto3"; +package api; + +option go_package = "github.com/grafana/grafana/pkg/storage/api"; + +message ResourceKey { + // Namespace (tenant) + string namespace = 2; + // Resource Group + string group = 1; + // The resource type + string resource = 3; + // Resource identifier (unique within namespace+group+resource) + string name = 4; + // The resource version + int64 resource_version = 5; +} + +enum ResourceOperation { + UNKNOWN = 0; + CREATED = 1; + UPDATED = 2; + DELETED = 3; + BOOKMARK = 4; +} + +message ResourceWrapper { + // The resource version + int64 resource_version = 1; + + // Full kubernetes json bytes (although the resource version may not be accurate) + bytes value = 2; + + // Operation + ResourceOperation operation = 3; + + // The resource has an attached blob + bool has_blob = 4; +} + +// The history and trash commands need access to commit messages +message ResourceMeta { + // The resource version + int64 resource_version = 1; + + // The optional commit message + ResourceOperation operation = 2; + + // Size of the full resource body + int32 size = 3; + + // Hash for the resource + string hash = 4; + + // The optional commit message + string message = 5; + + // The kubernetes metadata section (not the full resource) + // https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L111 + bytes object_meta = 6; + + // The resource has an attached blob + bool has_blob = 7; +} + +// Basic blob metadata +message BlobInfo { + // Content Length + int64 size = 1; + + // MD5 digest of the body + string ETag = 2; + + // Content type header + string content_type = 3; +} + +// Status structure is copied from: +// https://github.com/kubernetes/apimachinery/blob/v0.30.1/pkg/apis/meta/v1/generated.proto#L979 +message StatusResult { + // Status of the operation. + // One of: "Success" or "Failure". + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + string status = 1; + // A human-readable description of the status of this operation. + // +optional + string message = 2; + // A machine-readable description of why this operation is in the + // "Failure" status. If this value is empty there + // is no information available. A Reason clarifies an HTTP status + // code but does not override it. + // +optional + string reason = 3; + // Suggested HTTP return code for this status, 0 if not set. + // +optional + int32 code = 4; +} + +// TODO? support PresignedUrls for upload? +message CreateBlob { + // Content type header + string content_type = 1; + + // Raw value to write + bytes value = 2; +} + +// ---------------------------------- +// CRUD Objects +// ---------------------------------- + +message CreateRequest { + // Requires group+resource to be configuired + // If name is not set, a unique name will be generated + // The resourceVersion should not be set + ResourceKey key = 1; + + // The resource JSON. + bytes value = 2; + + // Optional commit message + string message = 3; + + // Optionally include a large binary object + CreateBlob blob = 4; +} + +message CreateResponse { + // Status code + StatusResult status = 1; + + // The updated resource version + int64 resource_version = 2; +} + +message UpdateRequest { + // Full key must be set + ResourceKey key = 1; + + // The resource JSON. + bytes value = 2; + + // Optional commit message + // +optional + string message = 3; + + // Optionally link a resource object + CreateBlob blob = 4; +} + +message UpdateResponse { + // Status code + StatusResult status = 1; + + // The updated resource version + int64 resource_version = 2; +} + +message DeleteRequest { + ResourceKey key = 1; + + // Preconditions: make sure the uid matches the current saved value + // +optional + string uid = 2; +} + +message DeleteResponse { + // Status code + StatusResult status = 1; + + // The new resource version + int64 resource_version = 2; +} + +message GetResourceRequest { + ResourceKey key = 1; +} + +message GetResourceResponse { + // Status code + StatusResult status = 1; + + // The new resource version + int64 resource_version = 2; + + // The properties + bytes value = 3; + + // A Signed URL that will let you fetch the blob + // If this value starts with # you must read the bytes using the GetResourceBlob request + string blob_url = 4; +} + +message GetBlobRequest { + ResourceKey key = 1; +} + +message GetBlobResponse { + // Status code + StatusResult status = 1; + + // Headers + BlobInfo info = 2; + + // The raw object value + bytes value = 3; +} + +// ---------------------------------- +// List Request/Response +// ---------------------------------- + +// The label filtering requirements: +// https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/labels/selector.go#L141 +message Requirement { + string key = 1; + string operator = 2; // See https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/selection/operator.go#L21 + repeated string values = 3; // typically one value, but depends on the operator +} + +message Sort { + enum Order { + ASC = 0; + DESC = 1; + } + string field = 1; + Order order = 2; +} + +message ListOptions { + // Maximum number of items to return + // NOTE responses will also be limited by the response payload size + int64 limit = 2; + + // Namespace+Group+Resource+etc + ResourceKey key = 3; + + // Match label + repeated Requirement labels = 4; + + // Match fields (not yet supported) + repeated Requirement fields = 5; + + // Limit results to items in a specific folder (not a query for everything under that folder!) + string folder = 6; +} + +message ListRequest { + // Starting from the requested page (other query parameters must match!) + string next_page_token = 1; + + // Filtering + ListOptions options = 2; + + // Sorting instructions `field ASC/DESC` + repeated Sort sort = 3; +} + +message ListResponse { + repeated ResourceWrapper items = 1; + + // When more results exist, pass this in the next request + string next_page_token = 2; + + // ResourceVersion of the list response + int64 resource_version = 3; + + // remainingItemCount is the number of subsequent items in the list which are not included in this + // list response. If the list request contained label or field selectors, then the number of + // remaining items is unknown and the field will be left unset and omitted during serialization. + // If the list is complete (either because it is not chunking or because this is the last chunk), + // then there are no more remaining items and this field will be left unset and omitted during + // serialization. + // + // The intended use of the remainingItemCount is *estimating* the size of a collection. Clients + // should not rely on the remainingItemCount to be set or to be exact. + // +optional + int64 remaining_item_count = 4; // 0 won't be set either (no next page token) +} + +message WatchRequest { + // ResourceVersion of last changes. Empty will default to full history + int64 since = 1; + + // Watch specific entities + ResourceKey key = 2; + + // Additional options + ListOptions options = 3; + + // Return initial events + bool send_initial_events = 4; + + // When done with initial events, send a bookmark event + bool allow_watch_bookmarks = 5; +} + +message WatchResponse { + // Timestamp the event was sent + int64 timestamp = 1; + + // Entity that was created, updated, or deleted + ResourceWrapper resource = 2; + + // previous version of the entity (in update+delete events) + ResourceWrapper previous = 3; +} + +message HistoryRequest { + // Starting from the requested page (other query parameters must match!) + string next_page_token = 1; + + // Maximum number of items to return + int64 limit = 2; + + // Resource identifier + ResourceKey key = 3; + + // List the deleted values (eg, show trash) + bool show_deleted = 4; +} + +message HistoryResponse { + repeated ResourceMeta items = 1; + + // More results exist... pass this in the next request + string next_page_token = 2; + + // ResourceVersion of the list response + int64 resource_version = 3; +} + +message OriginRequest { + // Starting from the requested page (other query parameters must match!) + string next_page_token = 1; + + // Maximum number of items to return + int64 limit = 2; + + // Resource identifier + ResourceKey key = 3; + + // List the deleted values (eg, show trash) + string origin = 4; +} + +message ResourceOriginInfo { + // The resource + ResourceKey key = 1; + + // Size of the full resource body + int32 resource_size = 2; + + // Hash for the resource + string resource_hash = 3; + + // The origin name + string origin = 4; + + // Path on the origin + string path = 5; + + // Verification hash from the origin + string hash = 6; + + // Change time from the origin + int64 timestamp = 7; +} + +message OriginResponse { + repeated ResourceOriginInfo items = 1; + + // More results exist... pass this in the next request + string next_page_token = 2; + + // ResourceVersion of the list response + int64 resource_version = 3; +} + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. + } + ServingStatus status = 1; +} + +// The entity store provides a basic CRUD+watch for any resource +service ResourceStore { + rpc GetResource(GetResourceRequest) returns (GetResourceResponse); + rpc Create(CreateRequest) returns (CreateResponse); + rpc Update(UpdateRequest) returns (UpdateResponse); + rpc Delete(DeleteRequest) returns (DeleteResponse); + rpc List(ListRequest) returns (ListResponse); + rpc Watch(WatchRequest) returns (stream WatchResponse); + + // Get the raw blob bytes and metadata + rpc GetBlob(GetBlobRequest) returns (GetBlobResponse); + + // Show resource history (and trash) + rpc History(HistoryRequest) returns (HistoryResponse); + + // Used for efficient provisioning + rpc Origin(OriginRequest) returns (OriginResponse); + + // Check if the service is healthy + rpc IsHealthy(HealthCheckRequest) returns (HealthCheckResponse); +} diff --git a/pkg/storage/api/resource_grpc.pb.go b/pkg/storage/api/resource_grpc.pb.go new file mode 100644 index 00000000000..656a467c97c --- /dev/null +++ b/pkg/storage/api/resource_grpc.pb.go @@ -0,0 +1,490 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.4.0 +// - protoc (unknown) +// source: resource.proto + +package api + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 + +const ( + ResourceStore_GetResource_FullMethodName = "/api.ResourceStore/GetResource" + ResourceStore_Create_FullMethodName = "/api.ResourceStore/Create" + ResourceStore_Update_FullMethodName = "/api.ResourceStore/Update" + ResourceStore_Delete_FullMethodName = "/api.ResourceStore/Delete" + ResourceStore_List_FullMethodName = "/api.ResourceStore/List" + ResourceStore_Watch_FullMethodName = "/api.ResourceStore/Watch" + ResourceStore_GetBlob_FullMethodName = "/api.ResourceStore/GetBlob" + ResourceStore_History_FullMethodName = "/api.ResourceStore/History" + ResourceStore_Origin_FullMethodName = "/api.ResourceStore/Origin" + ResourceStore_IsHealthy_FullMethodName = "/api.ResourceStore/IsHealthy" +) + +// ResourceStoreClient is the client API for ResourceStore service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// The entity store provides a basic CRUD+watch for any resource +type ResourceStoreClient interface { + GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) + Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error) + Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*UpdateResponse, error) + Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) + List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) + Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (ResourceStore_WatchClient, error) + // Get the raw blob bytes and metadata + GetBlob(ctx context.Context, in *GetBlobRequest, opts ...grpc.CallOption) (*GetBlobResponse, error) + // Show resource history (and trash) + History(ctx context.Context, in *HistoryRequest, opts ...grpc.CallOption) (*HistoryResponse, error) + // Used for efficient provisioning + Origin(ctx context.Context, in *OriginRequest, opts ...grpc.CallOption) (*OriginResponse, error) + // Check if the service is healthy + IsHealthy(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) +} + +type resourceStoreClient struct { + cc grpc.ClientConnInterface +} + +func NewResourceStoreClient(cc grpc.ClientConnInterface) ResourceStoreClient { + return &resourceStoreClient{cc} +} + +func (c *resourceStoreClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetResourceResponse) + err := c.cc.Invoke(ctx, ResourceStore_GetResource_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(CreateResponse) + err := c.cc.Invoke(ctx, ResourceStore_Create_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) Update(ctx context.Context, in *UpdateRequest, opts ...grpc.CallOption) (*UpdateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(UpdateResponse) + err := c.cc.Invoke(ctx, ResourceStore_Update_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(DeleteResponse) + err := c.cc.Invoke(ctx, ResourceStore_Delete_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListResponse) + err := c.cc.Invoke(ctx, ResourceStore_List_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (ResourceStore_WatchClient, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &ResourceStore_ServiceDesc.Streams[0], ResourceStore_Watch_FullMethodName, cOpts...) + if err != nil { + return nil, err + } + x := &resourceStoreWatchClient{ClientStream: stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type ResourceStore_WatchClient interface { + Recv() (*WatchResponse, error) + grpc.ClientStream +} + +type resourceStoreWatchClient struct { + grpc.ClientStream +} + +func (x *resourceStoreWatchClient) Recv() (*WatchResponse, error) { + m := new(WatchResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *resourceStoreClient) GetBlob(ctx context.Context, in *GetBlobRequest, opts ...grpc.CallOption) (*GetBlobResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetBlobResponse) + err := c.cc.Invoke(ctx, ResourceStore_GetBlob_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) History(ctx context.Context, in *HistoryRequest, opts ...grpc.CallOption) (*HistoryResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(HistoryResponse) + err := c.cc.Invoke(ctx, ResourceStore_History_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) Origin(ctx context.Context, in *OriginRequest, opts ...grpc.CallOption) (*OriginResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(OriginResponse) + err := c.cc.Invoke(ctx, ResourceStore_Origin_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *resourceStoreClient) IsHealthy(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(HealthCheckResponse) + err := c.cc.Invoke(ctx, ResourceStore_IsHealthy_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ResourceStoreServer is the server API for ResourceStore service. +// All implementations should embed UnimplementedResourceStoreServer +// for forward compatibility +// +// The entity store provides a basic CRUD+watch for any resource +type ResourceStoreServer interface { + GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) + Create(context.Context, *CreateRequest) (*CreateResponse, error) + Update(context.Context, *UpdateRequest) (*UpdateResponse, error) + Delete(context.Context, *DeleteRequest) (*DeleteResponse, error) + List(context.Context, *ListRequest) (*ListResponse, error) + Watch(*WatchRequest, ResourceStore_WatchServer) error + // Get the raw blob bytes and metadata + GetBlob(context.Context, *GetBlobRequest) (*GetBlobResponse, error) + // Show resource history (and trash) + History(context.Context, *HistoryRequest) (*HistoryResponse, error) + // Used for efficient provisioning + Origin(context.Context, *OriginRequest) (*OriginResponse, error) + // Check if the service is healthy + IsHealthy(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) +} + +// UnimplementedResourceStoreServer should be embedded to have forward compatible implementations. +type UnimplementedResourceStoreServer struct { +} + +func (UnimplementedResourceStoreServer) GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetResource not implemented") +} +func (UnimplementedResourceStoreServer) Create(context.Context, *CreateRequest) (*CreateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") +} +func (UnimplementedResourceStoreServer) Update(context.Context, *UpdateRequest) (*UpdateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") +} +func (UnimplementedResourceStoreServer) Delete(context.Context, *DeleteRequest) (*DeleteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (UnimplementedResourceStoreServer) List(context.Context, *ListRequest) (*ListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method List not implemented") +} +func (UnimplementedResourceStoreServer) Watch(*WatchRequest, ResourceStore_WatchServer) error { + return status.Errorf(codes.Unimplemented, "method Watch not implemented") +} +func (UnimplementedResourceStoreServer) GetBlob(context.Context, *GetBlobRequest) (*GetBlobResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlob not implemented") +} +func (UnimplementedResourceStoreServer) History(context.Context, *HistoryRequest) (*HistoryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method History not implemented") +} +func (UnimplementedResourceStoreServer) Origin(context.Context, *OriginRequest) (*OriginResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Origin not implemented") +} +func (UnimplementedResourceStoreServer) IsHealthy(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsHealthy not implemented") +} + +// UnsafeResourceStoreServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ResourceStoreServer will +// result in compilation errors. +type UnsafeResourceStoreServer interface { + mustEmbedUnimplementedResourceStoreServer() +} + +func RegisterResourceStoreServer(s grpc.ServiceRegistrar, srv ResourceStoreServer) { + s.RegisterService(&ResourceStore_ServiceDesc, srv) +} + +func _ResourceStore_GetResource_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetResourceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).GetResource(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_GetResource_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).GetResource(ctx, req.(*GetResourceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_Create_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).Create(ctx, req.(*CreateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).Update(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_Update_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).Update(ctx, req.(*UpdateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_Delete_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).Delete(ctx, req.(*DeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_List_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).List(ctx, req.(*ListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(WatchRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ResourceStoreServer).Watch(m, &resourceStoreWatchServer{ServerStream: stream}) +} + +type ResourceStore_WatchServer interface { + Send(*WatchResponse) error + grpc.ServerStream +} + +type resourceStoreWatchServer struct { + grpc.ServerStream +} + +func (x *resourceStoreWatchServer) Send(m *WatchResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _ResourceStore_GetBlob_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlobRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).GetBlob(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_GetBlob_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).GetBlob(ctx, req.(*GetBlobRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_History_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HistoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).History(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_History_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).History(ctx, req.(*HistoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_Origin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(OriginRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).Origin(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_Origin_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).Origin(ctx, req.(*OriginRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ResourceStore_IsHealthy_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ResourceStoreServer).IsHealthy(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ResourceStore_IsHealthy_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ResourceStoreServer).IsHealthy(ctx, req.(*HealthCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ResourceStore_ServiceDesc is the grpc.ServiceDesc for ResourceStore service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ResourceStore_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "api.ResourceStore", + HandlerType: (*ResourceStoreServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetResource", + Handler: _ResourceStore_GetResource_Handler, + }, + { + MethodName: "Create", + Handler: _ResourceStore_Create_Handler, + }, + { + MethodName: "Update", + Handler: _ResourceStore_Update_Handler, + }, + { + MethodName: "Delete", + Handler: _ResourceStore_Delete_Handler, + }, + { + MethodName: "List", + Handler: _ResourceStore_List_Handler, + }, + { + MethodName: "GetBlob", + Handler: _ResourceStore_GetBlob_Handler, + }, + { + MethodName: "History", + Handler: _ResourceStore_History_Handler, + }, + { + MethodName: "Origin", + Handler: _ResourceStore_Origin_Handler, + }, + { + MethodName: "IsHealthy", + Handler: _ResourceStore_IsHealthy_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Watch", + Handler: _ResourceStore_Watch_Handler, + ServerStreams: true, + }, + }, + Metadata: "resource.proto", +} diff --git a/pkg/storage/api/testdata/01_create_playlist.json b/pkg/storage/api/testdata/01_create_playlist.json new file mode 100644 index 00000000000..b0272532e8d --- /dev/null +++ b/pkg/storage/api/testdata/01_create_playlist.json @@ -0,0 +1,25 @@ +{ + "apiVersion": "playlist.grafana.app/v0alpha1", + "kind": "Playlist", + "metadata": { + "name": "fdgsv37qslr0ga", + "namespace": "default", + "annotations": { + "grafana.app/originName": "elsewhere", + "grafana.app/originPath": "path/to/item", + "grafana.app/originTimestamp": "2024-02-02T00:00:00Z" + }, + "creationTimestamp": "2024-03-03T00:00:00Z", + "uid": "8tGrXJgGbFI0" + }, + "spec": { + "title": "hello", + "interval": "5m", + "items": [ + { + "type": "dashboard_by_uid", + "value": "vmie2cmWz" + } + ] + } +} \ No newline at end of file diff --git a/pkg/storage/server/go.mod b/pkg/storage/server/go.mod new file mode 100644 index 00000000000..365d6f9766f --- /dev/null +++ b/pkg/storage/server/go.mod @@ -0,0 +1,156 @@ +module github.com/grafana/grafana/pkg/storage/server + +go 1.21.10 + +require ( + github.com/bwmarrin/snowflake v0.3.0 + github.com/gorilla/mux v1.8.1 + github.com/grafana/grafana-plugin-sdk-go v0.234.0 + github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240409140820-518d3341d58f + github.com/prometheus/client_golang v1.19.0 + github.com/stretchr/testify v1.9.0 + go.opentelemetry.io/otel/trace v1.26.0 + golang.org/x/mod v0.18.0 + k8s.io/apimachinery v0.29.3 + k8s.io/apiserver v0.29.2 + k8s.io/client-go v0.29.3 + k8s.io/component-base v0.29.2 + k8s.io/klog/v2 v2.120.1 + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 +) + +require ( + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/NYTimes/gziphandler v1.1.1 // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect + github.com/apache/arrow/go/v15 v15.0.2 // indirect + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cheekybits/genny v1.0.0 // indirect + github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/getkin/kin-openapi v0.124.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-logr/zapr v1.3.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.4 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/btree v1.1.2 // indirect + github.com/google/cel-go v0.17.7 // indirect + github.com/google/flatbuffers v24.3.25+incompatible // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20240416155748-26353dc0451f // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-plugin v1.6.1 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/invopop/yaml v0.3.1 // indirect + github.com/jonboulle/clockwork v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/magefile/mage v1.15.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattetti/filebuffer v1.0.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.1.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/pierrec/lz4/v4 v4.1.21 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.14.0 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/smartystreets/goconvey v1.6.4 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect + github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect + github.com/unknwon/com v1.0.1 // indirect + github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a // indirect + github.com/urfave/cli v1.22.15 // indirect + github.com/zeebo/xxh3 v1.0.2 // indirect + go.etcd.io/etcd/api/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect + go.etcd.io/etcd/client/v3 v3.5.10 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 // indirect + go.opentelemetry.io/contrib/propagators/jaeger v1.26.0 // indirect + go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0 // indirect + go.opentelemetry.io/otel v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0 // indirect + go.opentelemetry.io/otel/metric v1.26.0 // indirect + go.opentelemetry.io/otel/sdk v1.26.0 // indirect + go.opentelemetry.io/proto/otlp v1.2.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.26.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.22.0 // indirect + golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240520151616-dc85e6b867a5 // indirect + google.golang.org/grpc v1.64.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect + gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.29.3 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.28.0 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +)