mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
now with basic test
This commit is contained in:
parent
f481f11d3a
commit
b44333730f
@ -62,6 +62,8 @@ type GrafanaMetaAccessor interface {
|
||||
SetUpdatedBy(user string)
|
||||
GetFolder() string
|
||||
SetFolder(uid string)
|
||||
SetAnnotation(key string, val string)
|
||||
|
||||
GetSlug() string
|
||||
SetSlug(v string)
|
||||
|
||||
@ -111,7 +113,7 @@ func (m *grafanaMetaAccessor) Object() metav1.Object {
|
||||
return m.obj
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) set(key string, val string) {
|
||||
func (m *grafanaMetaAccessor) SetAnnotation(key string, val string) {
|
||||
anno := m.obj.GetAnnotations()
|
||||
if val == "" {
|
||||
if anno != nil {
|
||||
@ -148,7 +150,7 @@ func (m *grafanaMetaAccessor) SetUpdatedTimestampMillis(v int64) {
|
||||
t := time.UnixMilli(v)
|
||||
m.SetUpdatedTimestamp(&t)
|
||||
} else {
|
||||
m.set(AnnoKeyUpdatedTimestamp, "") // will clear the annotation
|
||||
m.SetAnnotation(AnnoKeyUpdatedTimestamp, "") // will clear the annotation
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +159,7 @@ func (m *grafanaMetaAccessor) SetUpdatedTimestamp(v *time.Time) {
|
||||
if v != nil && v.Unix() != 0 {
|
||||
txt = v.UTC().Format(time.RFC3339)
|
||||
}
|
||||
m.set(AnnoKeyUpdatedTimestamp, txt)
|
||||
m.SetAnnotation(AnnoKeyUpdatedTimestamp, txt)
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) GetCreatedBy() string {
|
||||
@ -165,7 +167,7 @@ func (m *grafanaMetaAccessor) GetCreatedBy() string {
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) SetCreatedBy(user string) {
|
||||
m.set(AnnoKeyCreatedBy, user)
|
||||
m.SetAnnotation(AnnoKeyCreatedBy, user)
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) GetUpdatedBy() string {
|
||||
@ -173,7 +175,7 @@ func (m *grafanaMetaAccessor) GetUpdatedBy() string {
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) SetUpdatedBy(user string) {
|
||||
m.set(AnnoKeyUpdatedBy, user)
|
||||
m.SetAnnotation(AnnoKeyUpdatedBy, user)
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) GetFolder() string {
|
||||
@ -181,7 +183,7 @@ func (m *grafanaMetaAccessor) GetFolder() string {
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) SetFolder(uid string) {
|
||||
m.set(AnnoKeyFolder, uid)
|
||||
m.SetAnnotation(AnnoKeyFolder, uid)
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) GetSlug() string {
|
||||
@ -189,7 +191,7 @@ func (m *grafanaMetaAccessor) GetSlug() string {
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) SetSlug(v string) {
|
||||
m.set(AnnoKeySlug, v)
|
||||
m.SetAnnotation(AnnoKeySlug, v)
|
||||
}
|
||||
|
||||
func (m *grafanaMetaAccessor) SetOriginInfo(info *ResourceOriginInfo) {
|
||||
|
@ -1,9 +1,8 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
context "context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
@ -20,23 +19,16 @@ type WriteEvent struct {
|
||||
// NOTE, this is never mutated, only parsed and validated
|
||||
Value json.RawMessage
|
||||
|
||||
// Access the raw metadata values
|
||||
Object utils.GrafanaMetaAccessor
|
||||
OldObject utils.GrafanaMetaAccessor
|
||||
|
||||
// Change metadata
|
||||
// Optionally link to a
|
||||
Blob *LinkBlob
|
||||
|
||||
// Change metadata (useful?)
|
||||
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
|
||||
}
|
||||
// A function to write events
|
||||
type EventAppender = func(context.Context, *WriteEvent) (int64, error)
|
||||
|
131
pkg/storage/unified/resource/mem.go
Normal file
131
pkg/storage/unified/resource/mem.go
Normal file
@ -0,0 +1,131 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
context "context"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
type MemoryStore interface {
|
||||
Read(context.Context, *ReadRequest) (*ReadResponse, error)
|
||||
WriteEvent(context.Context, *WriteEvent) (int64, error)
|
||||
}
|
||||
|
||||
func NewMemoryStore() MemoryStore {
|
||||
return &memoryStore{
|
||||
store: make(map[string]*namespacedResources),
|
||||
}
|
||||
}
|
||||
|
||||
type memoryStore struct {
|
||||
counter atomic.Int64
|
||||
mutex sync.RWMutex
|
||||
|
||||
// Key is group+resource
|
||||
store map[string]*namespacedResources
|
||||
}
|
||||
|
||||
type namespacedResources struct {
|
||||
// Lookup by resource name
|
||||
namespace map[string]*resourceInfo
|
||||
}
|
||||
|
||||
type resourceInfo struct {
|
||||
history []resourceValue
|
||||
}
|
||||
|
||||
type resourceValue struct {
|
||||
rv int64
|
||||
event WriteEvent // saves the whole thing for now
|
||||
blobHash string
|
||||
}
|
||||
|
||||
func (s *memoryStore) get(key *ResourceKey) *resourceValue {
|
||||
s.mutex.RLock()
|
||||
defer s.mutex.RUnlock()
|
||||
|
||||
found, ok := s.store[key.Group+"/"+key.Resource]
|
||||
if !ok || found.namespace == nil {
|
||||
return nil
|
||||
}
|
||||
resource, ok := found.namespace[key.Namespace]
|
||||
if !ok || len(resource.history) < 1 {
|
||||
return nil
|
||||
}
|
||||
if key.ResourceVersion > 0 {
|
||||
for idx, v := range resource.history {
|
||||
if v.rv == key.ResourceVersion {
|
||||
return &resource.history[idx]
|
||||
}
|
||||
}
|
||||
}
|
||||
latest := resource.history[0]
|
||||
if latest.event.Operation == ResourceOperation_DELETED {
|
||||
return nil
|
||||
}
|
||||
return &latest // the first one
|
||||
}
|
||||
|
||||
func (s *memoryStore) Read(_ context.Context, req *ReadRequest) (*ReadResponse, error) {
|
||||
val := s.get(req.Key)
|
||||
if val == nil {
|
||||
return &ReadResponse{
|
||||
Status: &StatusResult{
|
||||
Status: "Failure",
|
||||
Reason: "not found",
|
||||
Code: 404,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
rsp := &ReadResponse{
|
||||
ResourceVersion: val.rv,
|
||||
Value: val.event.Value,
|
||||
}
|
||||
if val.event.Blob != nil {
|
||||
rsp.BlobUrl = "#blob"
|
||||
}
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
func (s *memoryStore) WriteEvent(_ context.Context, req *WriteEvent) (int64, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
val := resourceValue{
|
||||
rv: s.counter.Add(1),
|
||||
event: *req,
|
||||
}
|
||||
if req.Blob != nil {
|
||||
hasher := sha1.New()
|
||||
_, err := hasher.Write(req.Blob.Value)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
val.blobHash = base64.URLEncoding.EncodeToString(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
// Now append the value
|
||||
key := req.Key
|
||||
found, ok := s.store[key.Group+"/"+key.Resource]
|
||||
if !ok {
|
||||
found = &namespacedResources{}
|
||||
s.store[key.Group+"/"+key.Resource] = found
|
||||
}
|
||||
if found.namespace == nil {
|
||||
found.namespace = make(map[string]*resourceInfo)
|
||||
}
|
||||
|
||||
resource, ok := found.namespace[key.Namespace]
|
||||
if !ok {
|
||||
resource = &resourceInfo{}
|
||||
found.namespace[key.Namespace] = resource
|
||||
}
|
||||
if resource.history == nil {
|
||||
resource.history = []resourceValue{val}
|
||||
} else {
|
||||
resource.history = append([]resourceValue{val}, resource.history...)
|
||||
}
|
||||
return val.rv, nil
|
||||
}
|
41
pkg/storage/unified/resource/metrics.go
Normal file
41
pkg/storage/unified/resource/metrics.go
Normal file
@ -0,0 +1,41 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
StorageServerMetrics *StorageApiMetrics
|
||||
)
|
||||
|
||||
type StorageApiMetrics struct {
|
||||
OptimisticLockFailed *prometheus.CounterVec
|
||||
}
|
||||
|
||||
func NewStorageMetrics() *StorageApiMetrics {
|
||||
once.Do(func() {
|
||||
StorageServerMetrics = &StorageApiMetrics{
|
||||
OptimisticLockFailed: prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Namespace: "resource_storage",
|
||||
Name: "optimistic_lock_failed",
|
||||
Help: "count of optimistic locks failed",
|
||||
},
|
||||
[]string{"action"},
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
return StorageServerMetrics
|
||||
}
|
||||
|
||||
func (s *StorageApiMetrics) Collect(ch chan<- prometheus.Metric) {
|
||||
s.OptimisticLockFailed.Collect(ch)
|
||||
}
|
||||
|
||||
func (s *StorageApiMetrics) Describe(ch chan<- *prometheus.Desc) {
|
||||
s.OptimisticLockFailed.Describe(ch)
|
||||
}
|
@ -1091,7 +1091,7 @@ func (x *DeleteResponse) GetResourceVersion() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
type GetResourceRequest struct {
|
||||
type ReadRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
@ -1101,8 +1101,8 @@ type GetResourceRequest struct {
|
||||
IgnoreBlob bool `protobuf:"varint,2,opt,name=ignore_blob,json=ignoreBlob,proto3" json:"ignore_blob,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetResourceRequest) Reset() {
|
||||
*x = GetResourceRequest{}
|
||||
func (x *ReadRequest) Reset() {
|
||||
*x = ReadRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_resource_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -1110,13 +1110,13 @@ func (x *GetResourceRequest) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetResourceRequest) String() string {
|
||||
func (x *ReadRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetResourceRequest) ProtoMessage() {}
|
||||
func (*ReadRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetResourceRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *ReadRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_resource_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -1128,26 +1128,26 @@ func (x *GetResourceRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetResourceRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetResourceRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use ReadRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
||||
return file_resource_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *GetResourceRequest) GetKey() *ResourceKey {
|
||||
func (x *ReadRequest) GetKey() *ResourceKey {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetResourceRequest) GetIgnoreBlob() bool {
|
||||
func (x *ReadRequest) GetIgnoreBlob() bool {
|
||||
if x != nil {
|
||||
return x.IgnoreBlob
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type GetResourceResponse struct {
|
||||
type ReadResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
@ -1163,8 +1163,8 @@ type GetResourceResponse struct {
|
||||
BlobUrl string `protobuf:"bytes,4,opt,name=blob_url,json=blobUrl,proto3" json:"blob_url,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetResourceResponse) Reset() {
|
||||
*x = GetResourceResponse{}
|
||||
func (x *ReadResponse) Reset() {
|
||||
*x = ReadResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_resource_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -1172,13 +1172,13 @@ func (x *GetResourceResponse) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetResourceResponse) String() string {
|
||||
func (x *ReadResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetResourceResponse) ProtoMessage() {}
|
||||
func (*ReadResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetResourceResponse) ProtoReflect() protoreflect.Message {
|
||||
func (x *ReadResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_resource_proto_msgTypes[13]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -1190,33 +1190,33 @@ func (x *GetResourceResponse) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetResourceResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetResourceResponse) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use ReadResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
||||
return file_resource_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
func (x *GetResourceResponse) GetStatus() *StatusResult {
|
||||
func (x *ReadResponse) GetStatus() *StatusResult {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetResourceResponse) GetResourceVersion() int64 {
|
||||
func (x *ReadResponse) GetResourceVersion() int64 {
|
||||
if x != nil {
|
||||
return x.ResourceVersion
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GetResourceResponse) GetValue() []byte {
|
||||
func (x *ReadResponse) GetValue() []byte {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *GetResourceResponse) GetBlobUrl() string {
|
||||
func (x *ReadResponse) GetBlobUrl() string {
|
||||
if x != nil {
|
||||
return x.BlobUrl
|
||||
}
|
||||
@ -2421,221 +2421,228 @@ var file_resource_proto_rawDesc = []byte{
|
||||
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, 0x5e, 0x0a, 0x12, 0x47, 0x65, 0x74,
|
||||
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f,
|
||||
0x72, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69,
|
||||
0x67, 0x6e, 0x6f, 0x72, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x22, 0xa1, 0x01, 0x0a, 0x13, 0x47, 0x65,
|
||||
0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x39, 0x0a,
|
||||
0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x7f, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42,
|
||||
0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x73,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73,
|
||||
0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x69,
|
||||
0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 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, 0x64,
|
||||
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, 0x2a, 0x0a, 0x05,
|
||||
0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xc2, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52,
|
||||
0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65,
|
||||
0x6c, 0x73, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x8a, 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, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x12, 0x22, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x0e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f, 0x72, 0x74,
|
||||
0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x22, 0xc4, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 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, 0xe2, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a,
|
||||
0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,
|
||||
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x9b, 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, 0x35, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x35, 0x0a, 0x08, 0x70, 0x72, 0x65,
|
||||
0x76, 0x69, 0x6f, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x9a, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,
|
||||
0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x57, 0x0a, 0x0b, 0x52, 0x65, 0x61,
|
||||
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x62,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x42, 0x6c,
|
||||
0x6f, 0x62, 0x22, 0x9a, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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,
|
||||
0x39, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,
|
||||
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x92, 0x01,
|
||||
0x0a, 0x0f, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x2c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x8e, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xe5, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 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, 0x97, 0x01, 0x0a, 0x0e,
|
||||
0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32,
|
||||
0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
|
||||
0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x7f, 0x0a, 0x0f, 0x47, 0x65,
|
||||
0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a,
|
||||
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
|
||||
0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x26, 0x0a,
|
||||
0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x64, 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, 0x2a,
|
||||
0x0a, 0x05, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xc2, 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, 0x27, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79,
|
||||
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18,
|
||||
0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x2e, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x6c, 0x61,
|
||||
0x62, 0x65, 0x6c, 0x73, 0x12, 0x2d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x8a, 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, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x53, 0x6f,
|
||||
0x72, 0x74, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x22, 0xc4, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x05, 0x69, 0x74, 0x65,
|
||||
0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 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,
|
||||
0xe2, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
|
||||
0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x9b, 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, 0x35, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 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, 0x35, 0x0a, 0x08, 0x70,
|
||||
0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xab, 0x01, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68,
|
||||
0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a,
|
||||
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x8c, 0x05, 0x0a, 0x0d, 0x52,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x4a, 0x0a, 0x0b,
|
||||
0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12,
|
||||
0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x08, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x22, 0x9a, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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,
|
||||
0x92, 0x01, 0x0a, 0x0f, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x8e, 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, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xe5, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 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, 0x97, 0x01,
|
||||
0x0a, 0x0e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x32, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xab, 0x01, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c,
|
||||
0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x2b, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0xba, 0x03, 0x0a,
|
||||
0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35,
|
||||
0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12,
|
||||
0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65,
|
||||
0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x35, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16,
|
||||
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12,
|
||||
0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x30, 0x01, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x18, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x18, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x17, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x3b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
|
||||
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
|
||||
0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12,
|
||||
0x48, 0x0a, 0x09, 0x49, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x1c, 0x2e, 0x72,
|
||||
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68,
|
||||
0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x65, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63,
|
||||
0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x39, 0x5a, 0x37, 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, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2f, 0x72, 0x65, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xce, 0x02, 0x0a, 0x0e, 0x52, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x35, 0x0a, 0x04,
|
||||
0x52, 0x65, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
|
||||
0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x18,
|
||||
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f,
|
||||
0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x18,
|
||||
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x12, 0x17, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x2e, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x48, 0x0a, 0x09, 0x49, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x1c, 0x2e,
|
||||
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43,
|
||||
0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65,
|
||||
0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x39, 0x5a, 0x37, 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, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2f, 0x72, 0x65, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -2669,8 +2676,8 @@ var file_resource_proto_goTypes = []interface{}{
|
||||
(*UpdateResponse)(nil), // 13: resource.UpdateResponse
|
||||
(*DeleteRequest)(nil), // 14: resource.DeleteRequest
|
||||
(*DeleteResponse)(nil), // 15: resource.DeleteResponse
|
||||
(*GetResourceRequest)(nil), // 16: resource.GetResourceRequest
|
||||
(*GetResourceResponse)(nil), // 17: resource.GetResourceResponse
|
||||
(*ReadRequest)(nil), // 16: resource.ReadRequest
|
||||
(*ReadResponse)(nil), // 17: resource.ReadResponse
|
||||
(*GetBlobRequest)(nil), // 18: resource.GetBlobRequest
|
||||
(*GetBlobResponse)(nil), // 19: resource.GetBlobResponse
|
||||
(*Requirement)(nil), // 20: resource.Requirement
|
||||
@ -2699,8 +2706,8 @@ var file_resource_proto_depIdxs = []int32{
|
||||
8, // 7: resource.UpdateResponse.status:type_name -> resource.StatusResult
|
||||
4, // 8: resource.DeleteRequest.key:type_name -> resource.ResourceKey
|
||||
8, // 9: resource.DeleteResponse.status:type_name -> resource.StatusResult
|
||||
4, // 10: resource.GetResourceRequest.key:type_name -> resource.ResourceKey
|
||||
8, // 11: resource.GetResourceResponse.status:type_name -> resource.StatusResult
|
||||
4, // 10: resource.ReadRequest.key:type_name -> resource.ResourceKey
|
||||
8, // 11: resource.ReadResponse.status:type_name -> resource.StatusResult
|
||||
4, // 12: resource.GetBlobRequest.key:type_name -> resource.ResourceKey
|
||||
8, // 13: resource.GetBlobResponse.status:type_name -> resource.StatusResult
|
||||
7, // 14: resource.GetBlobResponse.info:type_name -> resource.BlobInfo
|
||||
@ -2721,28 +2728,32 @@ var file_resource_proto_depIdxs = []int32{
|
||||
4, // 29: resource.ResourceOriginInfo.key:type_name -> resource.ResourceKey
|
||||
30, // 30: resource.OriginResponse.items:type_name -> resource.ResourceOriginInfo
|
||||
3, // 31: resource.HealthCheckResponse.status:type_name -> resource.HealthCheckResponse.ServingStatus
|
||||
16, // 32: resource.ResourceStore.GetResource:input_type -> resource.GetResourceRequest
|
||||
16, // 32: resource.ResourceStore.Read:input_type -> resource.ReadRequest
|
||||
10, // 33: resource.ResourceStore.Create:input_type -> resource.CreateRequest
|
||||
12, // 34: resource.ResourceStore.Update:input_type -> resource.UpdateRequest
|
||||
14, // 35: resource.ResourceStore.Delete:input_type -> resource.DeleteRequest
|
||||
23, // 36: resource.ResourceStore.List:input_type -> resource.ListRequest
|
||||
25, // 37: resource.ResourceStore.Watch:input_type -> resource.WatchRequest
|
||||
18, // 38: resource.ResourceStore.GetBlob:input_type -> resource.GetBlobRequest
|
||||
27, // 39: resource.ResourceStore.History:input_type -> resource.HistoryRequest
|
||||
29, // 40: resource.ResourceStore.Origin:input_type -> resource.OriginRequest
|
||||
32, // 41: resource.ResourceStore.IsHealthy:input_type -> resource.HealthCheckRequest
|
||||
17, // 42: resource.ResourceStore.GetResource:output_type -> resource.GetResourceResponse
|
||||
11, // 43: resource.ResourceStore.Create:output_type -> resource.CreateResponse
|
||||
13, // 44: resource.ResourceStore.Update:output_type -> resource.UpdateResponse
|
||||
15, // 45: resource.ResourceStore.Delete:output_type -> resource.DeleteResponse
|
||||
24, // 46: resource.ResourceStore.List:output_type -> resource.ListResponse
|
||||
26, // 47: resource.ResourceStore.Watch:output_type -> resource.WatchResponse
|
||||
19, // 48: resource.ResourceStore.GetBlob:output_type -> resource.GetBlobResponse
|
||||
28, // 49: resource.ResourceStore.History:output_type -> resource.HistoryResponse
|
||||
31, // 50: resource.ResourceStore.Origin:output_type -> resource.OriginResponse
|
||||
33, // 51: resource.ResourceStore.IsHealthy:output_type -> resource.HealthCheckResponse
|
||||
42, // [42:52] is the sub-list for method output_type
|
||||
32, // [32:42] is the sub-list for method input_type
|
||||
32, // 38: resource.ResourceStore.IsHealthy:input_type -> resource.HealthCheckRequest
|
||||
16, // 39: resource.ResourceSearch.Read:input_type -> resource.ReadRequest
|
||||
18, // 40: resource.ResourceSearch.GetBlob:input_type -> resource.GetBlobRequest
|
||||
27, // 41: resource.ResourceSearch.History:input_type -> resource.HistoryRequest
|
||||
29, // 42: resource.ResourceSearch.Origin:input_type -> resource.OriginRequest
|
||||
32, // 43: resource.ResourceSearch.IsHealthy:input_type -> resource.HealthCheckRequest
|
||||
17, // 44: resource.ResourceStore.Read:output_type -> resource.ReadResponse
|
||||
11, // 45: resource.ResourceStore.Create:output_type -> resource.CreateResponse
|
||||
13, // 46: resource.ResourceStore.Update:output_type -> resource.UpdateResponse
|
||||
15, // 47: resource.ResourceStore.Delete:output_type -> resource.DeleteResponse
|
||||
24, // 48: resource.ResourceStore.List:output_type -> resource.ListResponse
|
||||
26, // 49: resource.ResourceStore.Watch:output_type -> resource.WatchResponse
|
||||
33, // 50: resource.ResourceStore.IsHealthy:output_type -> resource.HealthCheckResponse
|
||||
17, // 51: resource.ResourceSearch.Read:output_type -> resource.ReadResponse
|
||||
19, // 52: resource.ResourceSearch.GetBlob:output_type -> resource.GetBlobResponse
|
||||
28, // 53: resource.ResourceSearch.History:output_type -> resource.HistoryResponse
|
||||
31, // 54: resource.ResourceSearch.Origin:output_type -> resource.OriginResponse
|
||||
33, // 55: resource.ResourceSearch.IsHealthy:output_type -> resource.HealthCheckResponse
|
||||
44, // [44:56] is the sub-list for method output_type
|
||||
32, // [32:44] 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
|
||||
@ -2899,7 +2910,7 @@ func file_resource_proto_init() {
|
||||
}
|
||||
}
|
||||
file_resource_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetResourceRequest); i {
|
||||
switch v := v.(*ReadRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -2911,7 +2922,7 @@ func file_resource_proto_init() {
|
||||
}
|
||||
}
|
||||
file_resource_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetResourceResponse); i {
|
||||
switch v := v.(*ReadResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -3123,7 +3134,7 @@ func file_resource_proto_init() {
|
||||
NumEnums: 4,
|
||||
NumMessages: 30,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
NumServices: 2,
|
||||
},
|
||||
GoTypes: file_resource_proto_goTypes,
|
||||
DependencyIndexes: file_resource_proto_depIdxs,
|
||||
|
@ -186,14 +186,14 @@ message DeleteResponse {
|
||||
int64 resource_version = 2;
|
||||
}
|
||||
|
||||
message GetResourceRequest {
|
||||
message ReadRequest {
|
||||
ResourceKey key = 1;
|
||||
|
||||
// Do not include any blob details
|
||||
bool ignore_blob = 2;
|
||||
}
|
||||
|
||||
message GetResourceResponse {
|
||||
message ReadResponse {
|
||||
// Status code
|
||||
StatusResult status = 1;
|
||||
|
||||
@ -408,14 +408,24 @@ message HealthCheckResponse {
|
||||
ServingStatus status = 1;
|
||||
}
|
||||
|
||||
// The entity store provides a basic CRUD+watch for any resource
|
||||
// This provides the CRUD+List+Watch support needed for a k8s apiserver
|
||||
// The semantics and behaviors of this service are constrained by kubernetes
|
||||
// This does not understand the resource schemas, only deals with json bytes
|
||||
// Clients should not use this interface directly; it is for use in API Servers
|
||||
service ResourceStore {
|
||||
rpc GetResource(GetResourceRequest) returns (GetResourceResponse);
|
||||
rpc Read(ReadRequest) returns (ReadResponse);
|
||||
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);
|
||||
rpc IsHealthy(HealthCheckRequest) returns (HealthCheckResponse);
|
||||
}
|
||||
|
||||
// Unlike ResourceStore, this service does not have strict read after write guarantees
|
||||
// Clients can use this service directly
|
||||
service ResourceSearch {
|
||||
rpc Read(ReadRequest) returns (ReadResponse); // Duplicated -- for client read only usage
|
||||
|
||||
// Get the raw blob bytes and metadata
|
||||
rpc GetBlob(GetBlobRequest) returns (GetBlobResponse);
|
||||
|
@ -19,37 +19,30 @@ import (
|
||||
const _ = grpc.SupportPackageIsVersion8
|
||||
|
||||
const (
|
||||
ResourceStore_GetResource_FullMethodName = "/resource.ResourceStore/GetResource"
|
||||
ResourceStore_Create_FullMethodName = "/resource.ResourceStore/Create"
|
||||
ResourceStore_Update_FullMethodName = "/resource.ResourceStore/Update"
|
||||
ResourceStore_Delete_FullMethodName = "/resource.ResourceStore/Delete"
|
||||
ResourceStore_List_FullMethodName = "/resource.ResourceStore/List"
|
||||
ResourceStore_Watch_FullMethodName = "/resource.ResourceStore/Watch"
|
||||
ResourceStore_GetBlob_FullMethodName = "/resource.ResourceStore/GetBlob"
|
||||
ResourceStore_History_FullMethodName = "/resource.ResourceStore/History"
|
||||
ResourceStore_Origin_FullMethodName = "/resource.ResourceStore/Origin"
|
||||
ResourceStore_IsHealthy_FullMethodName = "/resource.ResourceStore/IsHealthy"
|
||||
ResourceStore_Read_FullMethodName = "/resource.ResourceStore/Read"
|
||||
ResourceStore_Create_FullMethodName = "/resource.ResourceStore/Create"
|
||||
ResourceStore_Update_FullMethodName = "/resource.ResourceStore/Update"
|
||||
ResourceStore_Delete_FullMethodName = "/resource.ResourceStore/Delete"
|
||||
ResourceStore_List_FullMethodName = "/resource.ResourceStore/List"
|
||||
ResourceStore_Watch_FullMethodName = "/resource.ResourceStore/Watch"
|
||||
ResourceStore_IsHealthy_FullMethodName = "/resource.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
|
||||
// This provides the CRUD+List+Watch support needed for a k8s apiserver
|
||||
// The semantics and behaviors of this service are constrained by kubernetes
|
||||
// This does not understand the resource schemas, only deals with json bytes
|
||||
// Clients should not use this interface directly; it is for use in API Servers
|
||||
type ResourceStoreClient interface {
|
||||
GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error)
|
||||
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, 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)
|
||||
}
|
||||
|
||||
@ -61,10 +54,10 @@ func NewResourceStoreClient(cc grpc.ClientConnInterface) ResourceStoreClient {
|
||||
return &resourceStoreClient{cc}
|
||||
}
|
||||
|
||||
func (c *resourceStoreClient) GetResource(ctx context.Context, in *GetResourceRequest, opts ...grpc.CallOption) (*GetResourceResponse, error) {
|
||||
func (c *resourceStoreClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(GetResourceResponse)
|
||||
err := c.cc.Invoke(ctx, ResourceStore_GetResource_FullMethodName, in, out, cOpts...)
|
||||
out := new(ReadResponse)
|
||||
err := c.cc.Invoke(ctx, ResourceStore_Read_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -144,36 +137,6 @@ func (x *resourceStoreWatchClient) Recv() (*WatchResponse, error) {
|
||||
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)
|
||||
@ -188,21 +151,17 @@ func (c *resourceStoreClient) IsHealthy(ctx context.Context, in *HealthCheckRequ
|
||||
// All implementations should embed UnimplementedResourceStoreServer
|
||||
// for forward compatibility
|
||||
//
|
||||
// The entity store provides a basic CRUD+watch for any resource
|
||||
// This provides the CRUD+List+Watch support needed for a k8s apiserver
|
||||
// The semantics and behaviors of this service are constrained by kubernetes
|
||||
// This does not understand the resource schemas, only deals with json bytes
|
||||
// Clients should not use this interface directly; it is for use in API Servers
|
||||
type ResourceStoreServer interface {
|
||||
GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error)
|
||||
Read(context.Context, *ReadRequest) (*ReadResponse, 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)
|
||||
}
|
||||
|
||||
@ -210,8 +169,8 @@ type ResourceStoreServer interface {
|
||||
type UnimplementedResourceStoreServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedResourceStoreServer) GetResource(context.Context, *GetResourceRequest) (*GetResourceResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetResource not implemented")
|
||||
func (UnimplementedResourceStoreServer) Read(context.Context, *ReadRequest) (*ReadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
|
||||
}
|
||||
func (UnimplementedResourceStoreServer) Create(context.Context, *CreateRequest) (*CreateResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
|
||||
@ -228,15 +187,6 @@ func (UnimplementedResourceStoreServer) List(context.Context, *ListRequest) (*Li
|
||||
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")
|
||||
}
|
||||
@ -252,20 +202,20 @@ func RegisterResourceStoreServer(s grpc.ServiceRegistrar, srv ResourceStoreServe
|
||||
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)
|
||||
func _ResourceStore_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ResourceStoreServer).GetResource(ctx, in)
|
||||
return srv.(ResourceStoreServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResourceStore_GetResource_FullMethodName,
|
||||
FullMethod: ResourceStore_Read_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResourceStoreServer).GetResource(ctx, req.(*GetResourceRequest))
|
||||
return srv.(ResourceStoreServer).Read(ctx, req.(*ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@ -363,60 +313,6 @@ 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 {
|
||||
@ -443,8 +339,8 @@ var ResourceStore_ServiceDesc = grpc.ServiceDesc{
|
||||
HandlerType: (*ResourceStoreServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetResource",
|
||||
Handler: _ResourceStore_GetResource_Handler,
|
||||
MethodName: "Read",
|
||||
Handler: _ResourceStore_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Create",
|
||||
@ -462,18 +358,6 @@ var ResourceStore_ServiceDesc = grpc.ServiceDesc{
|
||||
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,
|
||||
@ -488,3 +372,258 @@ var ResourceStore_ServiceDesc = grpc.ServiceDesc{
|
||||
},
|
||||
Metadata: "resource.proto",
|
||||
}
|
||||
|
||||
const (
|
||||
ResourceSearch_Read_FullMethodName = "/resource.ResourceSearch/Read"
|
||||
ResourceSearch_GetBlob_FullMethodName = "/resource.ResourceSearch/GetBlob"
|
||||
ResourceSearch_History_FullMethodName = "/resource.ResourceSearch/History"
|
||||
ResourceSearch_Origin_FullMethodName = "/resource.ResourceSearch/Origin"
|
||||
ResourceSearch_IsHealthy_FullMethodName = "/resource.ResourceSearch/IsHealthy"
|
||||
)
|
||||
|
||||
// ResourceSearchClient is the client API for ResourceSearch 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.
|
||||
//
|
||||
// Unlike ResourceStore, this service does not have strict read after write guarantees
|
||||
// Clients can use this service directly
|
||||
type ResourceSearchClient interface {
|
||||
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, 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 resourceSearchClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewResourceSearchClient(cc grpc.ClientConnInterface) ResourceSearchClient {
|
||||
return &resourceSearchClient{cc}
|
||||
}
|
||||
|
||||
func (c *resourceSearchClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ReadResponse)
|
||||
err := c.cc.Invoke(ctx, ResourceSearch_Read_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *resourceSearchClient) 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, ResourceSearch_GetBlob_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *resourceSearchClient) 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, ResourceSearch_History_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *resourceSearchClient) 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, ResourceSearch_Origin_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *resourceSearchClient) 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, ResourceSearch_IsHealthy_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ResourceSearchServer is the server API for ResourceSearch service.
|
||||
// All implementations should embed UnimplementedResourceSearchServer
|
||||
// for forward compatibility
|
||||
//
|
||||
// Unlike ResourceStore, this service does not have strict read after write guarantees
|
||||
// Clients can use this service directly
|
||||
type ResourceSearchServer interface {
|
||||
Read(context.Context, *ReadRequest) (*ReadResponse, 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)
|
||||
}
|
||||
|
||||
// UnimplementedResourceSearchServer should be embedded to have forward compatible implementations.
|
||||
type UnimplementedResourceSearchServer struct {
|
||||
}
|
||||
|
||||
func (UnimplementedResourceSearchServer) Read(context.Context, *ReadRequest) (*ReadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
|
||||
}
|
||||
func (UnimplementedResourceSearchServer) GetBlob(context.Context, *GetBlobRequest) (*GetBlobResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBlob not implemented")
|
||||
}
|
||||
func (UnimplementedResourceSearchServer) History(context.Context, *HistoryRequest) (*HistoryResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method History not implemented")
|
||||
}
|
||||
func (UnimplementedResourceSearchServer) Origin(context.Context, *OriginRequest) (*OriginResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Origin not implemented")
|
||||
}
|
||||
func (UnimplementedResourceSearchServer) IsHealthy(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method IsHealthy not implemented")
|
||||
}
|
||||
|
||||
// UnsafeResourceSearchServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ResourceSearchServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeResourceSearchServer interface {
|
||||
mustEmbedUnimplementedResourceSearchServer()
|
||||
}
|
||||
|
||||
func RegisterResourceSearchServer(s grpc.ServiceRegistrar, srv ResourceSearchServer) {
|
||||
s.RegisterService(&ResourceSearch_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _ResourceSearch_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ResourceSearchServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResourceSearch_Read_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResourceSearchServer).Read(ctx, req.(*ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ResourceSearch_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.(ResourceSearchServer).GetBlob(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResourceSearch_GetBlob_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResourceSearchServer).GetBlob(ctx, req.(*GetBlobRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ResourceSearch_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.(ResourceSearchServer).History(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResourceSearch_History_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResourceSearchServer).History(ctx, req.(*HistoryRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ResourceSearch_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.(ResourceSearchServer).Origin(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResourceSearch_Origin_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResourceSearchServer).Origin(ctx, req.(*OriginRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ResourceSearch_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.(ResourceSearchServer).IsHealthy(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResourceSearch_IsHealthy_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResourceSearchServer).IsHealthy(ctx, req.(*HealthCheckRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// ResourceSearch_ServiceDesc is the grpc.ServiceDesc for ResourceSearch service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var ResourceSearch_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "resource.ResourceSearch",
|
||||
HandlerType: (*ResourceSearchServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _ResourceSearch_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBlob",
|
||||
Handler: _ResourceSearch_GetBlob_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "History",
|
||||
Handler: _ResourceSearch_History_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Origin",
|
||||
Handler: _ResourceSearch_Origin_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "IsHealthy",
|
||||
Handler: _ResourceSearch_IsHealthy_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "resource.proto",
|
||||
}
|
||||
|
@ -1,256 +0,0 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
|
||||
// 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 *GetResourceResponse) (*WriteEvent, error)
|
||||
PrepareDelete(ctx context.Context, req *DeleteRequest, current *GetResourceResponse) (*WriteEvent, error)
|
||||
}
|
||||
|
||||
type EventValidatorOptions struct {
|
||||
// When running in a cluster, each node should have a different ID
|
||||
// This is used for snowflake generation and log identification
|
||||
NodeID int64
|
||||
|
||||
// Get the next EventID. When not set, this will be a snowflake ID
|
||||
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 {
|
||||
rvGenerationNode, err := snowflake.NewNode(opts.NodeID)
|
||||
if err == nil {
|
||||
opts.NextEventID = func() int64 {
|
||||
return rvGenerationNode.Generate().Int64()
|
||||
}
|
||||
} else {
|
||||
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 = identity.GetRequester(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")
|
||||
}
|
||||
gvk := obj.GetGroupVersionKind()
|
||||
if gvk.Kind == "" {
|
||||
return event.BadRequest(nil, "expecting resources with a kind in the body")
|
||||
}
|
||||
if gvk.Version == "" {
|
||||
return event.BadRequest(nil, "expecting resources with an apiVersion")
|
||||
}
|
||||
if gvk.Group != "" && gvk.Group != key.Group {
|
||||
return event.BadRequest(nil, "group in key does not match group in the body (%s != %s)", key.Group, gvk.Group)
|
||||
}
|
||||
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 *GetResourceResponse) (*WriteEvent, error) {
|
||||
event := v.newEvent(ctx, req.Key, req.Value, current.Value)
|
||||
event.Operation = ResourceOperation_UPDATED
|
||||
event.PreviousRV = current.ResourceVersion
|
||||
if current.Value == nil {
|
||||
return event.BadRequest(nil, "current value does not exist"), nil
|
||||
}
|
||||
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, "updated by annotation does not match: metadata.annotations#"+utils.AnnoKeyUpdatedBy), nil
|
||||
}
|
||||
|
||||
return event, nil
|
||||
}
|
||||
|
||||
func (v *eventValidator) PrepareDelete(ctx context.Context, req *DeleteRequest, current *GetResourceResponse) (*WriteEvent, error) {
|
||||
now := metav1.NewTime(time.Now())
|
||||
var err error
|
||||
event := &WriteEvent{
|
||||
EventID: v.opts.NextEventID(),
|
||||
Key: req.Key,
|
||||
Operation: ResourceOperation_DELETED,
|
||||
PreviousRV: current.ResourceVersion,
|
||||
}
|
||||
if event.PreviousRV != req.Key.ResourceVersion {
|
||||
return event.BadRequest(err, "deletion request does not match current revision (%d != %d)", req.Key.ResourceVersion, event.PreviousRV), nil
|
||||
}
|
||||
event.Requester, err = identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return event.BadRequest(err, "unable to get user"), nil
|
||||
}
|
||||
marker := &DeletedMarker{}
|
||||
err = json.Unmarshal(current.Value, marker)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read previous object, %w", err)
|
||||
}
|
||||
event.Object, err = utils.MetaAccessor(marker)
|
||||
if err != nil {
|
||||
return event.BadRequest(err, "unable to read marker object"), nil
|
||||
}
|
||||
event.Object.SetDeletionTimestamp(&now)
|
||||
event.Object.SetUpdatedTimestamp(&now.Time)
|
||||
event.Object.SetManagedFields(nil)
|
||||
event.Object.SetFinalizers(nil)
|
||||
event.Object.SetUpdatedBy(event.Requester.GetUID().String())
|
||||
marker.TypeMeta = metav1.TypeMeta{
|
||||
Kind: "DeletedMarker",
|
||||
APIVersion: "storage.grafana.app/v0alpha1", // ?? or can we stick this in common?
|
||||
}
|
||||
marker.Annotations["RestoreResourceVersion"] = fmt.Sprintf("%d", event.PreviousRV)
|
||||
event.Value, err = json.Marshal(marker)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable creating deletion marker, %w", err)
|
||||
}
|
||||
return event, nil
|
||||
}
|
330
pkg/storage/unified/resource/writer.go
Normal file
330
pkg/storage/unified/resource/writer.go
Normal file
@ -0,0 +1,330 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
|
||||
// Package-level errors.
|
||||
var (
|
||||
ErrNotFound = errors.New("entity not found")
|
||||
ErrOptimisticLockingFailed = errors.New("optimistic locking failed")
|
||||
ErrUserNotFoundInContext = errors.New("user not found in context")
|
||||
ErrUnableToReadResourceJSON = errors.New("unable to read resource json")
|
||||
ErrNextPageTokenNotSupported = errors.New("nextPageToken not yet supported")
|
||||
ErrLimitNotSupported = errors.New("limit not yet supported")
|
||||
ErrNotImplementedYet = errors.New("not implemented yet")
|
||||
)
|
||||
|
||||
// Resource writer support
|
||||
type ResourceWriter interface {
|
||||
Create(context.Context, *CreateRequest) (*CreateResponse, error)
|
||||
Update(context.Context, *UpdateRequest) (*UpdateResponse, error)
|
||||
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
|
||||
}
|
||||
|
||||
type WriterOptions struct {
|
||||
// OTel tracer
|
||||
Tracer trace.Tracer
|
||||
|
||||
// When running in a cluster, each node should have a different ID
|
||||
// This is used for snowflake generation and log identification
|
||||
NodeID int64
|
||||
|
||||
// Read an individual item
|
||||
Reader func(context.Context, *ReadRequest) (*ReadResponse, error)
|
||||
|
||||
// Add a validated write event
|
||||
Appender EventAppender
|
||||
|
||||
// Get the next EventID. When not set, this will default to snowflake IDs
|
||||
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
|
||||
}
|
||||
|
||||
func NewResourceWriter(opts WriterOptions) (ResourceWriter, error) {
|
||||
log := slog.Default().With("logger", "resource-writer")
|
||||
if err := prometheus.Register(NewStorageMetrics()); err != nil {
|
||||
log.Warn("error registering storage server metrics", "error", err)
|
||||
}
|
||||
if opts.NextEventID == nil {
|
||||
eventNode, err := snowflake.NewNode(opts.NodeID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error initializing snowflake id generator :: %w", err)
|
||||
}
|
||||
opts.NextEventID = func() int64 {
|
||||
return eventNode.Generate().Int64()
|
||||
}
|
||||
}
|
||||
return &writeServer{
|
||||
log: log,
|
||||
opts: opts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Internal object with just Type+ObjectMeta
|
||||
type dummyObject struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type writeServer struct {
|
||||
log *slog.Logger
|
||||
opts WriterOptions
|
||||
}
|
||||
|
||||
func (s *writeServer) newEvent(ctx context.Context, key *ResourceKey, value, oldValue []byte) (*WriteEvent, error) {
|
||||
var err error
|
||||
event := &WriteEvent{
|
||||
EventID: s.opts.NextEventID(),
|
||||
Key: key,
|
||||
Value: value,
|
||||
}
|
||||
event.Requester, err = identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, ErrUserNotFoundInContext
|
||||
}
|
||||
|
||||
dummy := &dummyObject{}
|
||||
err = json.Unmarshal(value, dummy)
|
||||
if err != nil {
|
||||
return nil, ErrUnableToReadResourceJSON
|
||||
}
|
||||
|
||||
obj, err := utils.MetaAccessor(dummy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid object in json")
|
||||
}
|
||||
if obj.GetUID() == "" {
|
||||
return nil, fmt.Errorf("the UID must be set")
|
||||
}
|
||||
if obj.GetGenerateName() != "" {
|
||||
return nil, fmt.Errorf("can not save value with generate name")
|
||||
}
|
||||
gvk := obj.GetGroupVersionKind()
|
||||
if gvk.Kind == "" {
|
||||
return nil, fmt.Errorf("expecting resources with a kind in the body")
|
||||
}
|
||||
if gvk.Version == "" {
|
||||
return nil, fmt.Errorf("expecting resources with an apiVersion")
|
||||
}
|
||||
if gvk.Group != "" && gvk.Group != key.Group {
|
||||
return nil, fmt.Errorf("group in key does not match group in the body (%s != %s)", key.Group, gvk.Group)
|
||||
}
|
||||
if obj.GetName() != key.Name {
|
||||
return nil, fmt.Errorf("key name does not match the name in the body")
|
||||
}
|
||||
if obj.GetNamespace() != key.Namespace {
|
||||
return nil, fmt.Errorf("key namespace does not match the namespace in the body")
|
||||
}
|
||||
folder := obj.GetFolder()
|
||||
if folder != "" {
|
||||
if s.opts.FolderAccess == nil {
|
||||
return nil, fmt.Errorf("folders are not supported")
|
||||
} else if !s.opts.FolderAccess(ctx, event.Requester, folder) {
|
||||
return nil, fmt.Errorf("unable to add resource to folder") // 403?
|
||||
}
|
||||
}
|
||||
origin, err := obj.GetOriginInfo()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid origin info")
|
||||
}
|
||||
if origin != nil && s.opts.OriginAccess != nil {
|
||||
if !s.opts.OriginAccess(ctx, event.Requester, origin.Name) {
|
||||
return nil, fmt.Errorf("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 nil, fmt.Errorf("error reading old json value")
|
||||
}
|
||||
old, err := utils.MetaAccessor(dummy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid object inside old json")
|
||||
}
|
||||
if key.Name != old.GetName() {
|
||||
return nil, fmt.Errorf("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 nil, fmt.Errorf("can not change the created by metadata (%s != %s)", obj.GetCreatedBy(), old.GetCreatedBy())
|
||||
}
|
||||
if obj.GetCreationTimestamp() != old.GetCreationTimestamp() {
|
||||
return nil, fmt.Errorf("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, nil
|
||||
}
|
||||
|
||||
func (s *writeServer) Create(ctx context.Context, req *CreateRequest) (*CreateResponse, error) {
|
||||
ctx, span := s.opts.Tracer.Start(ctx, "storage_server.Create")
|
||||
defer span.End()
|
||||
|
||||
if req.Key.ResourceVersion > 0 {
|
||||
return nil, fmt.Errorf("can not update a specific resource version")
|
||||
}
|
||||
|
||||
event, err := s.newEvent(ctx, req.Key, req.Value, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
event.Operation = ResourceOperation_CREATED
|
||||
event.Blob = req.Blob
|
||||
|
||||
rsp := &CreateResponse{}
|
||||
// Make sure the created by user is accurate
|
||||
//----------------------------------------
|
||||
val := event.Object.GetCreatedBy()
|
||||
if val != "" && val != event.Requester.GetUID().String() {
|
||||
return nil, fmt.Errorf("created by annotation does not match: metadata.annotations#" + utils.AnnoKeyCreatedBy)
|
||||
}
|
||||
|
||||
// Create can not have updated properties
|
||||
//----------------------------------------
|
||||
if event.Object.GetUpdatedBy() != "" {
|
||||
return nil, fmt.Errorf("unexpected metadata.annotations#" + utils.AnnoKeyCreatedBy)
|
||||
}
|
||||
|
||||
ts, err := event.Object.GetUpdatedTimestamp()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(fmt.Sprintf("invalid timestamp: %s", err))
|
||||
}
|
||||
if ts != nil {
|
||||
return nil, fmt.Errorf("unexpected metadata.annotations#" + utils.AnnoKeyUpdatedTimestamp)
|
||||
}
|
||||
|
||||
// Append and set the resource version
|
||||
rsp.ResourceVersion, err = s.opts.Appender(ctx, event)
|
||||
// ?? convert the error to status?
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
func (s *writeServer) Update(ctx context.Context, req *UpdateRequest) (*UpdateResponse, error) {
|
||||
ctx, span := s.opts.Tracer.Start(ctx, "storage_server.Update")
|
||||
defer span.End()
|
||||
|
||||
rsp := &UpdateResponse{}
|
||||
if req.Key.ResourceVersion < 0 {
|
||||
return nil, fmt.Errorf("update must include the previous version")
|
||||
}
|
||||
|
||||
latest, err := s.opts.Reader(ctx, &ReadRequest{
|
||||
Key: req.Key.WithoutResourceVersion(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if latest.Value == nil {
|
||||
return nil, fmt.Errorf("current value does not exist")
|
||||
}
|
||||
|
||||
event, err := s.newEvent(ctx, req.Key, req.Value, latest.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
event.Operation = ResourceOperation_UPDATED
|
||||
event.PreviousRV = latest.ResourceVersion
|
||||
|
||||
// Make sure the update user is accurate
|
||||
//----------------------------------------
|
||||
val := event.Object.GetUpdatedBy()
|
||||
if val != "" && val != event.Requester.GetUID().String() {
|
||||
return nil, fmt.Errorf("updated by annotation does not match: metadata.annotations#" + utils.AnnoKeyUpdatedBy)
|
||||
}
|
||||
|
||||
rsp.ResourceVersion, err = s.opts.Appender(ctx, event)
|
||||
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
func (s *writeServer) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) {
|
||||
ctx, span := s.opts.Tracer.Start(ctx, "storage_server.Delete")
|
||||
defer span.End()
|
||||
|
||||
rsp := &DeleteResponse{}
|
||||
if req.Key.ResourceVersion < 0 {
|
||||
return nil, fmt.Errorf("update must include the previous version")
|
||||
}
|
||||
|
||||
latest, err := s.opts.Reader(ctx, &ReadRequest{
|
||||
Key: req.Key.WithoutResourceVersion(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if latest.ResourceVersion != req.Key.ResourceVersion {
|
||||
return nil, fmt.Errorf("deletion request does not match current revision (%d != %d)", req.Key.ResourceVersion, latest.ResourceVersion)
|
||||
}
|
||||
|
||||
now := metav1.NewTime(time.Now())
|
||||
event := &WriteEvent{
|
||||
EventID: s.opts.NextEventID(),
|
||||
Key: req.Key,
|
||||
Operation: ResourceOperation_DELETED,
|
||||
PreviousRV: latest.ResourceVersion,
|
||||
}
|
||||
event.Requester, err = identity.GetRequester(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get user")
|
||||
}
|
||||
marker := &DeletedMarker{}
|
||||
err = json.Unmarshal(latest.Value, marker)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read previous object, %w", err)
|
||||
}
|
||||
event.Object, err = utils.MetaAccessor(marker)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
event.Object.SetDeletionTimestamp(&now)
|
||||
event.Object.SetUpdatedTimestamp(&now.Time)
|
||||
event.Object.SetManagedFields(nil)
|
||||
event.Object.SetFinalizers(nil)
|
||||
event.Object.SetUpdatedBy(event.Requester.GetUID().String())
|
||||
marker.TypeMeta = metav1.TypeMeta{
|
||||
Kind: "DeletedMarker",
|
||||
APIVersion: "storage.grafana.app/v0alpha1", // ?? or can we stick this in common?
|
||||
}
|
||||
marker.Annotations["RestoreResourceVersion"] = fmt.Sprintf("%d", event.PreviousRV)
|
||||
event.Value, err = json.Marshal(marker)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable creating deletion marker, %w", err)
|
||||
}
|
||||
|
||||
rsp.ResourceVersion, err = s.opts.Appender(ctx, event)
|
||||
|
||||
return rsp, err
|
||||
}
|
103
pkg/storage/unified/resource/writer_test.go
Normal file
103
pkg/storage/unified/resource/writer_test.go
Normal file
@ -0,0 +1,103 @@
|
||||
package resource
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
)
|
||||
|
||||
func TestWriter(t *testing.T) {
|
||||
tracer := noop.NewTracerProvider().Tracer("testing")
|
||||
testUserA := &user.SignedInUser{
|
||||
UserID: 123,
|
||||
UserUID: "u123",
|
||||
OrgRole: identity.RoleAdmin,
|
||||
}
|
||||
ctx := appcontext.WithUser(context.Background(), testUserA)
|
||||
|
||||
store := NewMemoryStore()
|
||||
writer, err := NewResourceWriter(WriterOptions{
|
||||
Tracer: tracer,
|
||||
Reader: store.Read,
|
||||
Appender: store.WriteEvent,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("playlist happy CRUD paths", func(t *testing.T) {
|
||||
raw := testdata(t, "01_create_playlist.json")
|
||||
key := &ResourceKey{
|
||||
Group: "playlist.grafana.app",
|
||||
Resource: "rrrr", // can be anything :(
|
||||
Namespace: "default",
|
||||
Name: "fdgsv37qslr0ga",
|
||||
}
|
||||
created, err := writer.Create(ctx, &CreateRequest{
|
||||
Value: raw,
|
||||
Key: key,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.True(t, created.ResourceVersion > 0)
|
||||
|
||||
// The key does not include resource version
|
||||
found, err := store.Read(ctx, &ReadRequest{Key: key})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, created.ResourceVersion, found.ResourceVersion)
|
||||
|
||||
// Now update the value
|
||||
tmp := &unstructured.Unstructured{}
|
||||
err = json.Unmarshal(raw, tmp)
|
||||
require.NoError(t, err)
|
||||
|
||||
now := time.Now().UnixMilli()
|
||||
obj, err := utils.MetaAccessor(tmp)
|
||||
require.NoError(t, err)
|
||||
obj.SetAnnotation("test", "hello")
|
||||
obj.SetUpdatedTimestampMillis(now)
|
||||
obj.SetUpdatedBy(testUserA.GetUID().String())
|
||||
raw, err = json.Marshal(tmp)
|
||||
require.NoError(t, err)
|
||||
|
||||
key.ResourceVersion = created.ResourceVersion
|
||||
updated, err := writer.Update(ctx, &UpdateRequest{Key: key, Value: raw})
|
||||
require.NoError(t, err)
|
||||
require.True(t, updated.ResourceVersion > created.ResourceVersion)
|
||||
|
||||
// We should still get the latest
|
||||
key.ResourceVersion = 0
|
||||
found, err = store.Read(ctx, &ReadRequest{Key: key})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, updated.ResourceVersion, found.ResourceVersion)
|
||||
|
||||
key.ResourceVersion = updated.ResourceVersion
|
||||
deleted, err := writer.Delete(ctx, &DeleteRequest{Key: key})
|
||||
require.NoError(t, err)
|
||||
require.True(t, deleted.ResourceVersion > updated.ResourceVersion)
|
||||
|
||||
// We should get not found when trying to read the latest value
|
||||
key.ResourceVersion = 0
|
||||
found, _ = store.Read(ctx, &ReadRequest{Key: key})
|
||||
require.Equal(t, int32(404), found.Status.Code)
|
||||
require.Nil(t, found.Value)
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed testdata/*
|
||||
var testdataFS embed.FS
|
||||
|
||||
func testdata(t *testing.T, filename string) []byte {
|
||||
t.Helper()
|
||||
b, err := testdataFS.ReadFile(`testdata/` + filename)
|
||||
require.NoError(t, err)
|
||||
return b
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package sqlstash
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
playlist "github.com/grafana/grafana/pkg/apis/playlist/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/infra/appcontext"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
)
|
||||
|
||||
func TestSQLCommands(t *testing.T) {
|
||||
ctx := appcontext.WithUser(context.Background(), &user.SignedInUser{
|
||||
UserID: 123,
|
||||
UserUID: "u123",
|
||||
OrgRole: identity.RoleAdmin,
|
||||
})
|
||||
validator := resource.NewEventValidator(resource.EventValidatorOptions{
|
||||
// no folders for now
|
||||
})
|
||||
|
||||
t.Run("insert playlist SQL", func(t *testing.T) {
|
||||
input := testdataFromJSON(t, "01_create_playlist.json", &playlist.Playlist{})
|
||||
key, err := resource.ResourceKeyFor(playlist.PlaylistResourceInfo.GroupResource(), input)
|
||||
require.NoError(t, err)
|
||||
|
||||
req := &resource.CreateRequest{Key: key, Message: "test commit"}
|
||||
req.Value, err = json.Marshal(input)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "default/playlist.grafana.app/playlists/fdgsv37qslr0ga", key.NamespacedPath())
|
||||
|
||||
evt, err := validator.PrepareCreate(ctx, req)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, evt.Error)
|
||||
require.Nil(t, evt.Error)
|
||||
})
|
||||
}
|
||||
|
||||
//go:embed testdata/*
|
||||
var testdataFS embed.FS
|
||||
|
||||
func testdata(t *testing.T, filename string) []byte {
|
||||
t.Helper()
|
||||
b, err := testdataFS.ReadFile(`testdata/` + filename)
|
||||
require.NoError(t, err)
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func testdataFromJSON[T any](t *testing.T, filename string, dest T) T {
|
||||
t.Helper()
|
||||
b := testdata(t, filename)
|
||||
err := json.Unmarshal(b, dest)
|
||||
require.NoError(t, err)
|
||||
return dest
|
||||
}
|
@ -21,9 +21,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
)
|
||||
|
||||
const resoruceTable = "resource"
|
||||
const resourceVersionTable = "resource_version"
|
||||
|
||||
// Package-level errors.
|
||||
var (
|
||||
ErrNotFound = errors.New("entity not found")
|
||||
@ -34,8 +31,9 @@ var (
|
||||
ErrNotImplementedYet = errors.New("not implemented yet")
|
||||
)
|
||||
|
||||
// Make sure we implement correct interfaces
|
||||
// Make sure we implement both store and search
|
||||
var _ resource.ResourceStoreServer = &sqlResourceServer{}
|
||||
var _ resource.ResourceSearchServer = &sqlResourceServer{}
|
||||
|
||||
func ProvideSQLResourceServer(db db.EntityDBInterface, tracer tracing.Tracer) (SqlResourceServer, error) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@ -72,7 +70,7 @@ type sqlResourceServer struct {
|
||||
cancel context.CancelFunc
|
||||
stream chan *resource.WatchResponse
|
||||
tracer trace.Tracer
|
||||
validator resource.EventValidator
|
||||
writer resource.ResourceWriter
|
||||
|
||||
once sync.Once
|
||||
initErr error
|
||||
@ -138,9 +136,15 @@ func (s *sqlResourceServer) init() error {
|
||||
|
||||
s.sess = sess
|
||||
s.dialect = migrator.NewDialect(engine.DriverName())
|
||||
s.validator = resource.NewEventValidator(resource.EventValidatorOptions{
|
||||
// use snowflake IDs
|
||||
s.writer, err = resource.NewResourceWriter(resource.WriterOptions{
|
||||
NodeID: 10,
|
||||
Tracer: s.tracer,
|
||||
Reader: s.Read,
|
||||
Appender: s.append,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set up the broadcaster
|
||||
s.broadcaster, err = sqlstash.NewBroadcaster(s.ctx, func(stream chan *resource.WatchResponse) error {
|
||||
@ -176,8 +180,15 @@ func (s *sqlResourceServer) Stop() {
|
||||
s.cancel()
|
||||
}
|
||||
|
||||
func (s *sqlResourceServer) GetResource(ctx context.Context, req *resource.GetResourceRequest) (*resource.GetResourceResponse, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "storage_server.GetResource")
|
||||
func (s *sqlResourceServer) append(ctx context.Context, event *resource.WriteEvent) (int64, error) {
|
||||
_, span := s.tracer.Start(ctx, "storage_server.WriteEvent")
|
||||
defer span.End()
|
||||
|
||||
return 0, ErrNotImplementedYet
|
||||
}
|
||||
|
||||
func (s *sqlResourceServer) Read(ctx context.Context, req *resource.ReadRequest) (*resource.ReadResponse, error) {
|
||||
_, span := s.tracer.Start(ctx, "storage_server.GetResource")
|
||||
defer span.End()
|
||||
|
||||
if err := s.Init(); err != nil {
|
||||
@ -185,10 +196,10 @@ func (s *sqlResourceServer) GetResource(ctx context.Context, req *resource.GetRe
|
||||
}
|
||||
|
||||
if req.Key.Group == "" {
|
||||
return &resource.GetResourceResponse{Status: badRequest("missing group")}, nil
|
||||
return &resource.ReadResponse{Status: badRequest("missing group")}, nil
|
||||
}
|
||||
if req.Key.Resource == "" {
|
||||
return &resource.GetResourceResponse{Status: badRequest("missing resource")}, nil
|
||||
return &resource.ReadResponse{Status: badRequest("missing resource")}, nil
|
||||
}
|
||||
|
||||
fmt.Printf("TODO, GET: %+v", req.Key)
|
||||
@ -197,96 +208,39 @@ func (s *sqlResourceServer) GetResource(ctx context.Context, req *resource.GetRe
|
||||
}
|
||||
|
||||
func (s *sqlResourceServer) Create(ctx context.Context, req *resource.CreateRequest) (*resource.CreateResponse, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "storage_server.Create")
|
||||
defer span.End()
|
||||
|
||||
if req.Key.ResourceVersion > 0 {
|
||||
return &resource.CreateResponse{
|
||||
Status: badRequest("can not update a specific resource version"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if err := s.Init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
event, err := s.validator.PrepareCreate(ctx, req)
|
||||
rsp, err := s.writer.Create(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
s.log.Info("create", "error", err)
|
||||
rsp.Status = &resource.StatusResult{
|
||||
Status: "Failure",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
if event.Status != nil {
|
||||
return &resource.CreateResponse{Status: event.Status}, nil
|
||||
}
|
||||
|
||||
fmt.Printf("TODO, CREATE: %v", event)
|
||||
|
||||
return nil, ErrNotImplementedYet
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
func (s *sqlResourceServer) Update(ctx context.Context, req *resource.UpdateRequest) (*resource.UpdateResponse, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "storage_server.Update")
|
||||
defer span.End()
|
||||
|
||||
if req.Key.ResourceVersion < 0 {
|
||||
return &resource.UpdateResponse{
|
||||
Status: badRequest("update must include the previous version"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if err := s.Init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
latest, err := s.GetResource(ctx, &resource.GetResourceRequest{
|
||||
Key: req.Key.WithoutResourceVersion(),
|
||||
})
|
||||
rsp, err := s.writer.Update(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
s.log.Info("create", "error", err)
|
||||
rsp.Status = &resource.StatusResult{
|
||||
Status: "Failure",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
event, err := s.validator.PrepareUpdate(ctx, req, latest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if event.Status != nil {
|
||||
return &resource.UpdateResponse{Status: event.Status}, nil
|
||||
}
|
||||
|
||||
fmt.Printf("TODO, UPDATE: %v", event)
|
||||
|
||||
return nil, ErrNotImplementedYet
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
func (s *sqlResourceServer) Delete(ctx context.Context, req *resource.DeleteRequest) (*resource.DeleteResponse, error) {
|
||||
ctx, span := s.tracer.Start(ctx, "storage_server.Delete")
|
||||
defer span.End()
|
||||
|
||||
if req.Key.ResourceVersion < 0 {
|
||||
return &resource.DeleteResponse{
|
||||
Status: badRequest("update must include the previous version"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if err := s.Init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
latest, err := s.GetResource(ctx, &resource.GetResourceRequest{
|
||||
Key: req.Key.WithoutResourceVersion(),
|
||||
})
|
||||
rsp, err := s.writer.Delete(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
s.log.Info("create", "error", err)
|
||||
rsp.Status = &resource.StatusResult{
|
||||
Status: "Failure",
|
||||
Message: err.Error(),
|
||||
}
|
||||
}
|
||||
event, err := s.validator.PrepareDelete(ctx, req, latest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if event.Status != nil {
|
||||
return &resource.DeleteResponse{Status: event.Status}, nil
|
||||
}
|
||||
|
||||
fmt.Printf("TODO, DELETE: %+v ", req.Key)
|
||||
|
||||
return nil, ErrNotImplementedYet
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
func (s *sqlResourceServer) List(ctx context.Context, req *resource.ListRequest) (*resource.ListResponse, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user