mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ObjectStore: Replace path model with folder, uid, and slug model (#59452)
This commit is contained in:
parent
5f3291be03
commit
b4b843be66
@ -125,9 +125,8 @@ func (e *objectStoreJob) start(ctx context.Context) {
|
||||
|
||||
_, err = e.store.AdminWrite(ctx, &object.AdminWriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: dash.UID,
|
||||
Kind: models.StandardKindDashboard,
|
||||
UID: dash.UID,
|
||||
Kind: models.StandardKindDashboard,
|
||||
},
|
||||
ClearHistory: true,
|
||||
Version: fmt.Sprintf("%d", dash.Version),
|
||||
@ -135,9 +134,11 @@ func (e *objectStoreJob) start(ctx context.Context) {
|
||||
UpdatedAt: dash.Updated.UnixMilli(),
|
||||
UpdatedBy: fmt.Sprintf("user:%d", dash.UpdatedBy),
|
||||
CreatedBy: fmt.Sprintf("user:%d", dash.CreatedBy),
|
||||
Origin: "export-from-sql",
|
||||
Body: dash.Data,
|
||||
Comment: "(exported from SQL)",
|
||||
Origin: &object.ObjectOriginInfo{
|
||||
Source: "export-from-sql",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
e.status.Status = "error: " + err.Error()
|
||||
@ -175,9 +176,8 @@ func (e *objectStoreJob) start(ctx context.Context) {
|
||||
|
||||
_, err = e.store.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: playlist.Uid,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
UID: playlist.Uid,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
},
|
||||
Body: prettyJSON(playlist),
|
||||
Comment: "export from playlists",
|
||||
@ -240,9 +240,8 @@ func (e *objectStoreJob) start(ctx context.Context) {
|
||||
|
||||
_, err = e.store.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: dto.Key,
|
||||
Kind: models.StandardKindSnapshot,
|
||||
UID: dto.Key,
|
||||
Kind: models.StandardKindSnapshot,
|
||||
},
|
||||
Body: prettyJSON(m),
|
||||
Comment: "export from snapshtts",
|
||||
|
@ -60,7 +60,6 @@ func (s *objectStoreImpl) sync() {
|
||||
TenantId: info.OrgID,
|
||||
UID: info.UID,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
},
|
||||
Body: body,
|
||||
})
|
||||
@ -76,9 +75,8 @@ func (s *objectStoreImpl) Create(ctx context.Context, cmd *playlist.CreatePlayli
|
||||
}
|
||||
_, err = s.objectstore.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
UID: rsp.UID,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
UID: rsp.UID,
|
||||
},
|
||||
Body: body,
|
||||
})
|
||||
@ -98,9 +96,8 @@ func (s *objectStoreImpl) Update(ctx context.Context, cmd *playlist.UpdatePlayli
|
||||
}
|
||||
_, err = s.objectstore.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
UID: rsp.Uid,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: rsp.Uid,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
},
|
||||
Body: body,
|
||||
})
|
||||
@ -116,9 +113,8 @@ func (s *objectStoreImpl) Delete(ctx context.Context, cmd *playlist.DeletePlayli
|
||||
if err == nil {
|
||||
_, err = s.objectstore.Delete(ctx, &object.DeleteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
UID: cmd.UID,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: cmd.UID,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
@ -148,9 +144,8 @@ func (s *objectStoreImpl) GetWithoutItems(ctx context.Context, q *playlist.GetPl
|
||||
func (s *objectStoreImpl) Get(ctx context.Context, q *playlist.GetPlaylistByUidQuery) (*playlist.PlaylistDTO, error) {
|
||||
rsp, err := s.objectstore.Read(ctx, &object.ReadObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
UID: q.UID,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: q.UID,
|
||||
Kind: models.StandardKindPlaylist,
|
||||
},
|
||||
WithBody: true,
|
||||
})
|
||||
|
@ -8,33 +8,34 @@ import (
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func getKeyColumn(name string, isPrimaryKey bool) *migrator.Column {
|
||||
func getLatinPathColumn(name string) *migrator.Column {
|
||||
return &migrator.Column{
|
||||
Name: name,
|
||||
Type: migrator.DB_NVarchar,
|
||||
Length: 1024,
|
||||
Nullable: false,
|
||||
IsPrimaryKey: isPrimaryKey,
|
||||
IsLatin: true, // only used in MySQL
|
||||
Name: name,
|
||||
Type: migrator.DB_NVarchar,
|
||||
Length: 1024,
|
||||
Nullable: false,
|
||||
IsLatin: true, // only used in MySQL
|
||||
}
|
||||
}
|
||||
|
||||
func addObjectStorageMigrations(mg *migrator.Migrator) {
|
||||
grnLength := 256 // len(tenant)~8 + len(kind)!16 + len(kind)~128 = 256
|
||||
tables := []migrator.Table{}
|
||||
tables = append(tables, migrator.Table{
|
||||
Name: "object",
|
||||
Name: "entity",
|
||||
Columns: []*migrator.Column{
|
||||
// Object path contains everything required to make it unique across all instances
|
||||
// orgId + scope + kind + uid
|
||||
getKeyColumn("path", true),
|
||||
// Object ID (OID) will be unique across all objects/instances
|
||||
// uuid5( tenant_id, kind + uid )
|
||||
{Name: "grn", Type: migrator.DB_NVarchar, Length: grnLength, Nullable: false, IsPrimaryKey: true},
|
||||
|
||||
// This is an optimization for listing everything at the same level in the object store
|
||||
getKeyColumn("parent_folder_path", false),
|
||||
|
||||
// The object type
|
||||
// The entity identifier
|
||||
{Name: "tenant_id", Type: migrator.DB_BigInt, Nullable: false},
|
||||
{Name: "kind", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
|
||||
{Name: "uid", Type: migrator.DB_NVarchar, Length: 40, Nullable: false},
|
||||
{Name: "folder", Type: migrator.DB_NVarchar, Length: 40, Nullable: false},
|
||||
{Name: "slug", Type: migrator.DB_NVarchar, Length: 189, Nullable: false}, // from title
|
||||
|
||||
// The raw object body (any byte array)
|
||||
// The raw entity body (any byte array)
|
||||
{Name: "body", Type: migrator.DB_LongBlob, Nullable: false},
|
||||
{Name: "size", Type: migrator.DB_BigInt, Nullable: false},
|
||||
{Name: "etag", Type: migrator.DB_NVarchar, Length: 32, Nullable: false, IsLatin: true}, // md5(body)
|
||||
@ -47,7 +48,8 @@ func addObjectStorageMigrations(mg *migrator.Migrator) {
|
||||
{Name: "created_by", Type: migrator.DB_NVarchar, Length: 190, Nullable: false},
|
||||
|
||||
// Mark objects with origin metadata
|
||||
{Name: "origin", Type: migrator.DB_Text, Nullable: true},
|
||||
{Name: "origin", Type: migrator.DB_NVarchar, Length: 40, Nullable: false},
|
||||
getLatinPathColumn("origin_key"), // index with length 1024
|
||||
{Name: "origin_ts", Type: migrator.DB_BigInt, Nullable: false},
|
||||
|
||||
// Summary data (always extracted from the `body` column)
|
||||
@ -58,28 +60,46 @@ func addObjectStorageMigrations(mg *migrator.Migrator) {
|
||||
{Name: "errors", Type: migrator.DB_Text, Nullable: true}, // JSON object
|
||||
},
|
||||
Indices: []*migrator.Index{
|
||||
{Cols: []string{"parent_folder_path"}}, // list in folder
|
||||
{Cols: []string{"kind"}}, // filter by type
|
||||
{Cols: []string{"kind"}},
|
||||
{Cols: []string{"folder"}},
|
||||
{Cols: []string{"uid"}},
|
||||
|
||||
{Cols: []string{"tenant_id", "kind", "uid"}, Type: migrator.UniqueIndex},
|
||||
// {Cols: []string{"tenant_id", "folder", "slug"}, Type: migrator.UniqueIndex},
|
||||
},
|
||||
})
|
||||
|
||||
// when saving a folder, keep a path version cached
|
||||
tables = append(tables, migrator.Table{
|
||||
Name: "entity_folder",
|
||||
Columns: []*migrator.Column{
|
||||
{Name: "grn", Type: migrator.DB_NVarchar, Length: grnLength, Nullable: false},
|
||||
getLatinPathColumn("path"), // slug/slug/slug/...
|
||||
{Name: "depth", Type: migrator.DB_Int, Nullable: false},
|
||||
{Name: "tree", Type: migrator.DB_Text, Nullable: false}, // JSON array from root
|
||||
},
|
||||
Indices: []*migrator.Index{
|
||||
{Cols: []string{"path"}, Type: migrator.UniqueIndex},
|
||||
},
|
||||
})
|
||||
|
||||
tables = append(tables, migrator.Table{
|
||||
Name: "object_labels",
|
||||
Name: "entity_labels",
|
||||
Columns: []*migrator.Column{
|
||||
getKeyColumn("path", false),
|
||||
{Name: "grn", Type: migrator.DB_NVarchar, Length: grnLength, Nullable: false},
|
||||
{Name: "label", Type: migrator.DB_NVarchar, Length: 191, Nullable: false},
|
||||
{Name: "value", Type: migrator.DB_NVarchar, Length: 1024, Nullable: false},
|
||||
},
|
||||
Indices: []*migrator.Index{
|
||||
{Cols: []string{"path", "label"}, Type: migrator.UniqueIndex},
|
||||
{Cols: []string{"grn", "label"}, Type: migrator.UniqueIndex},
|
||||
},
|
||||
})
|
||||
|
||||
tables = append(tables, migrator.Table{
|
||||
Name: "object_ref",
|
||||
Name: "entity_ref",
|
||||
Columns: []*migrator.Column{
|
||||
// Source:
|
||||
getKeyColumn("path", false),
|
||||
{Name: "grn", Type: migrator.DB_NVarchar, Length: grnLength, Nullable: false},
|
||||
|
||||
// Address (defined in the body, not resolved, may be invalid and change)
|
||||
{Name: "kind", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
|
||||
@ -88,21 +108,21 @@ func addObjectStorageMigrations(mg *migrator.Migrator) {
|
||||
|
||||
// Runtime calcs (will depend on the system state)
|
||||
{Name: "resolved_ok", Type: migrator.DB_Bool, Nullable: false},
|
||||
getKeyColumn("resolved_to", false),
|
||||
{Name: "resolved_to", Type: migrator.DB_NVarchar, Length: 40, Nullable: false},
|
||||
{Name: "resolved_warning", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
|
||||
{Name: "resolved_time", Type: migrator.DB_DateTime, Nullable: false}, // resolution cache timestamp
|
||||
},
|
||||
Indices: []*migrator.Index{
|
||||
{Cols: []string{"path"}, Type: migrator.IndexType},
|
||||
{Cols: []string{"grn"}, Type: migrator.IndexType},
|
||||
{Cols: []string{"kind"}, Type: migrator.IndexType},
|
||||
{Cols: []string{"resolved_to"}, Type: migrator.IndexType},
|
||||
},
|
||||
})
|
||||
|
||||
tables = append(tables, migrator.Table{
|
||||
Name: "object_history",
|
||||
Name: "entity_history",
|
||||
Columns: []*migrator.Column{
|
||||
getKeyColumn("path", false),
|
||||
{Name: "grn", Type: migrator.DB_NVarchar, Length: grnLength, Nullable: false},
|
||||
{Name: "version", Type: migrator.DB_NVarchar, Length: 128, Nullable: false},
|
||||
|
||||
// Raw bytes
|
||||
@ -118,7 +138,7 @@ func addObjectStorageMigrations(mg *migrator.Migrator) {
|
||||
{Name: "message", Type: migrator.DB_Text, Nullable: false}, // defaults to empty string
|
||||
},
|
||||
Indices: []*migrator.Index{
|
||||
{Cols: []string{"path", "version"}, Type: migrator.UniqueIndex},
|
||||
{Cols: []string{"grn", "version"}, Type: migrator.UniqueIndex},
|
||||
{Cols: []string{"updated_by"}, Type: migrator.IndexType},
|
||||
},
|
||||
})
|
||||
@ -134,25 +154,28 @@ func addObjectStorageMigrations(mg *migrator.Migrator) {
|
||||
// Migration cleanups: given that this is a complex setup
|
||||
// that requires a lot of testing before we are ready to push out of dev
|
||||
// this script lets us easy wipe previous changes and initialize clean tables
|
||||
suffix := " (v5)" // change this when we want to wipe and reset the object tables
|
||||
mg.AddMigration("ObjectStore init: cleanup"+suffix, migrator.NewRawSQLMigration(strings.TrimSpace(`
|
||||
suffix := " (v8)" // change this when we want to wipe and reset the object tables
|
||||
mg.AddMigration("EntityStore init: cleanup"+suffix, migrator.NewRawSQLMigration(strings.TrimSpace(`
|
||||
DELETE FROM migration_log WHERE migration_id LIKE 'EntityStore init%';
|
||||
`)))
|
||||
// for a while this was called "ObjectStore"... this can be removed before we remove the dev only flags
|
||||
mg.AddMigration("EntityStore init: object cleanup"+suffix, migrator.NewRawSQLMigration(strings.TrimSpace(`
|
||||
DELETE FROM migration_log WHERE migration_id LIKE 'ObjectStore init%';
|
||||
`)))
|
||||
|
||||
// Initialize all tables
|
||||
for t := range tables {
|
||||
mg.AddMigration("ObjectStore init: drop "+tables[t].Name+suffix, migrator.NewRawSQLMigration(
|
||||
mg.AddMigration("EntityStore init: drop "+tables[t].Name+suffix, migrator.NewRawSQLMigration(
|
||||
fmt.Sprintf("DROP TABLE IF EXISTS %s", tables[t].Name),
|
||||
))
|
||||
mg.AddMigration("ObjectStore init: table "+tables[t].Name+suffix, migrator.NewAddTableMigration(tables[t]))
|
||||
mg.AddMigration("EntityStore init: table "+tables[t].Name+suffix, migrator.NewAddTableMigration(tables[t]))
|
||||
for i := range tables[t].Indices {
|
||||
mg.AddMigration(fmt.Sprintf("ObjectStore init: index %s[%d]"+suffix, tables[t].Name, i), migrator.NewAddIndexMigration(tables[t], tables[t].Indices[i]))
|
||||
mg.AddMigration(fmt.Sprintf("EntityStore init: index %s[%d]"+suffix, tables[t].Name, i), migrator.NewAddIndexMigration(tables[t], tables[t].Indices[i]))
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add collation support to `migrator.Column`
|
||||
mg.AddMigration("ObjectStore init: set path collation in object tables"+suffix, migrator.NewRawSQLMigration("").
|
||||
mg.AddMigration("EntityStore init: set path collation in entity tables"+suffix, migrator.NewRawSQLMigration("").
|
||||
// MySQL `utf8mb4_unicode_ci` collation is set in `mysql_dialect.go`
|
||||
// SQLite uses a `BINARY` collation by default
|
||||
Postgres("ALTER TABLE object ALTER COLUMN path TYPE VARCHAR(1024) COLLATE \"C\";")) // Collate C - sorting done based on character code byte values
|
||||
Postgres("ALTER TABLE entity_folder ALTER COLUMN path TYPE VARCHAR(1024) COLLATE \"C\";")) // Collate C - sorting done based on character code byte values
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Check if the two GRNs reference to the same object
|
||||
// we can not use simple `*x == *b` because of the internal settings
|
||||
func (x *GRN) Equals(b *GRN) bool {
|
||||
@ -7,9 +11,11 @@ func (x *GRN) Equals(b *GRN) bool {
|
||||
return false
|
||||
}
|
||||
return x == b || (x.TenantId == b.TenantId &&
|
||||
x.Scope == b.Scope &&
|
||||
x.Kind == b.Kind &&
|
||||
x.UID == b.UID)
|
||||
}
|
||||
|
||||
// TODO: this should interpoerate with the GRN string flavor
|
||||
// Set an OID based on the GRN
|
||||
func (x *GRN) ToGRNString() string {
|
||||
return fmt.Sprintf("grn:%d/%s/%s", x.TenantId, x.Kind, x.UID)
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/services/store/kind"
|
||||
"github.com/grafana/grafana/pkg/services/store/object"
|
||||
"github.com/grafana/grafana/pkg/services/store/router"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
|
||||
@ -27,18 +26,16 @@ type HTTPObjectStore interface {
|
||||
}
|
||||
|
||||
type httpObjectStore struct {
|
||||
store object.ObjectStoreServer
|
||||
log log.Logger
|
||||
kinds kind.KindRegistry
|
||||
router router.ObjectStoreRouter
|
||||
store object.ObjectStoreServer
|
||||
log log.Logger
|
||||
kinds kind.KindRegistry
|
||||
}
|
||||
|
||||
func ProvideHTTPObjectStore(store object.ObjectStoreServer, kinds kind.KindRegistry) HTTPObjectStore {
|
||||
return &httpObjectStore{
|
||||
store: store,
|
||||
log: log.New("http-object-store"),
|
||||
kinds: kinds,
|
||||
router: router.NewObjectStoreRouter(kinds),
|
||||
store: store,
|
||||
log: log.New("http-object-store"),
|
||||
kinds: kinds,
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,16 +45,16 @@ func (s *httpObjectStore) RegisterHTTPRoutes(route routing.RouteRegister) {
|
||||
reqGrafanaAdmin := middleware.ReqSignedIn //.ReqGrafanaAdmin
|
||||
|
||||
// Every * must parse to a GRN (uid+kind)
|
||||
route.Get("/store/*", reqGrafanaAdmin, routing.Wrap(s.doGetObject))
|
||||
route.Post("/store/*", reqGrafanaAdmin, routing.Wrap(s.doWriteObject))
|
||||
route.Delete("/store/*", reqGrafanaAdmin, routing.Wrap(s.doDeleteObject))
|
||||
route.Get("/raw/*", reqGrafanaAdmin, routing.Wrap(s.doGetRawObject))
|
||||
route.Get("/history/*", reqGrafanaAdmin, routing.Wrap(s.doGetHistory))
|
||||
route.Get("/list/*", reqGrafanaAdmin, routing.Wrap(s.doListFolder)) // Simplified version of search -- path is prefix
|
||||
route.Get("/store/:kind/:uid", reqGrafanaAdmin, routing.Wrap(s.doGetObject))
|
||||
route.Post("/store/:kind/:uid", reqGrafanaAdmin, routing.Wrap(s.doWriteObject))
|
||||
route.Delete("/store/:kind/:uid", reqGrafanaAdmin, routing.Wrap(s.doDeleteObject))
|
||||
route.Get("/raw/:kind/:uid", reqGrafanaAdmin, routing.Wrap(s.doGetRawObject))
|
||||
route.Get("/history/:kind/:uid", reqGrafanaAdmin, routing.Wrap(s.doGetHistory))
|
||||
route.Get("/list/:uid", reqGrafanaAdmin, routing.Wrap(s.doListFolder)) // Simplified version of search -- path is prefix
|
||||
route.Get("/search", reqGrafanaAdmin, routing.Wrap(s.doSearch))
|
||||
|
||||
// File upload
|
||||
route.Post("/upload/:scope", reqGrafanaAdmin, routing.Wrap(s.doUpload))
|
||||
route.Post("/upload", reqGrafanaAdmin, routing.Wrap(s.doUpload))
|
||||
}
|
||||
|
||||
// This function will extract UID+Kind from the requested path "*" in our router
|
||||
@ -65,12 +62,6 @@ func (s *httpObjectStore) RegisterHTTPRoutes(route routing.RouteRegister) {
|
||||
// This will quickly be revisited as we explore how to encode UID+Kind in a "GRN" format
|
||||
func (s *httpObjectStore) getGRNFromRequest(c *models.ReqContext) (*object.GRN, map[string]string, error) {
|
||||
params := web.Params(c.Req)
|
||||
info, err := s.router.RouteFromKey(c.Req.Context(),
|
||||
fmt.Sprintf("%d/%s", c.OrgID, params["*"]))
|
||||
if err != nil {
|
||||
return nil, params, err
|
||||
}
|
||||
|
||||
// Read parameters that are encoded in the URL
|
||||
vals := c.Req.URL.Query()
|
||||
for k, v := range vals {
|
||||
@ -78,7 +69,11 @@ func (s *httpObjectStore) getGRNFromRequest(c *models.ReqContext) (*object.GRN,
|
||||
params[k] = v[0]
|
||||
}
|
||||
}
|
||||
return info.GRN, params, nil
|
||||
return &object.GRN{
|
||||
TenantId: c.OrgID,
|
||||
Kind: params[":kind"],
|
||||
UID: params[":uid"],
|
||||
}, params, nil
|
||||
}
|
||||
|
||||
func (s *httpObjectStore) doGetObject(c *models.ReqContext) response.Response {
|
||||
@ -182,6 +177,7 @@ func (s *httpObjectStore) doWriteObject(c *models.ReqContext) response.Response
|
||||
rsp, err := s.store.Write(c.Req.Context(), &object.WriteObjectRequest{
|
||||
GRN: grn,
|
||||
Body: b,
|
||||
Folder: params["folder"],
|
||||
Comment: params["comment"],
|
||||
PreviousVersion: params["previousVersion"],
|
||||
})
|
||||
@ -233,10 +229,6 @@ func (s *httpObjectStore) doUpload(c *models.ReqContext) response.Response {
|
||||
if len(fileinfo) < 1 {
|
||||
return response.Error(400, "missing files", nil)
|
||||
}
|
||||
scope := web.Params(c.Req)[":scope"]
|
||||
if scope == "" {
|
||||
return response.Error(400, "invalid scope", nil)
|
||||
}
|
||||
|
||||
var rsp []*object.WriteObjectResponse
|
||||
|
||||
@ -257,12 +249,7 @@ func (s *httpObjectStore) doUpload(c *models.ReqContext) response.Response {
|
||||
if err != nil || kind.ID == "" {
|
||||
return response.Error(400, "Unsupported kind: "+fileHeader.Filename, err)
|
||||
}
|
||||
uid := folder
|
||||
if uid != "" {
|
||||
uid = uid + "/" + fileHeader.Filename[:idx]
|
||||
} else {
|
||||
uid = fileHeader.Filename[:idx]
|
||||
}
|
||||
uid := fileHeader.Filename[:idx]
|
||||
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
@ -278,9 +265,9 @@ func (s *httpObjectStore) doUpload(c *models.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
grn := &object.GRN{
|
||||
Scope: scope,
|
||||
UID: uid,
|
||||
Kind: kind.ID,
|
||||
UID: uid,
|
||||
Kind: kind.ID,
|
||||
TenantId: c.OrgID,
|
||||
}
|
||||
|
||||
if !overwriteExistingFile {
|
||||
@ -301,6 +288,7 @@ func (s *httpObjectStore) doUpload(c *models.ReqContext) response.Response {
|
||||
GRN: grn,
|
||||
Body: data,
|
||||
Comment: message,
|
||||
Folder: folder,
|
||||
// PreviousVersion: params["previousVersion"],
|
||||
})
|
||||
|
||||
|
@ -96,6 +96,16 @@ func (codec *rawObjectCodec) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream)
|
||||
stream.WriteObjectField("etag")
|
||||
stream.WriteString(obj.ETag)
|
||||
}
|
||||
if obj.Folder != "" {
|
||||
stream.WriteMore()
|
||||
stream.WriteObjectField("folder")
|
||||
stream.WriteString(obj.Folder)
|
||||
}
|
||||
if obj.Slug != "" {
|
||||
stream.WriteMore()
|
||||
stream.WriteObjectField("slug")
|
||||
stream.WriteString(obj.Slug)
|
||||
}
|
||||
if obj.Size > 0 {
|
||||
stream.WriteMore()
|
||||
stream.WriteObjectField("size")
|
||||
@ -135,6 +145,10 @@ func readRawObject(iter *jsoniter.Iterator, raw *RawObject) {
|
||||
raw.Size = iter.ReadInt64()
|
||||
case "etag":
|
||||
raw.ETag = iter.ReadString()
|
||||
case "folder":
|
||||
raw.Folder = iter.ReadString()
|
||||
case "slug":
|
||||
raw.Slug = iter.ReadString()
|
||||
case "version":
|
||||
raw.Version = iter.ReadString()
|
||||
case "origin":
|
||||
|
@ -80,15 +80,11 @@ type GRN struct {
|
||||
|
||||
// the tenant/org id
|
||||
TenantId int64 `protobuf:"varint,1,opt,name=tenant_id,json=tenantId,proto3" json:"tenant_id,omitempty"`
|
||||
// mabybe "namespace"? valid values include
|
||||
// * entity
|
||||
// * drive
|
||||
// * service/xyz
|
||||
Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"`
|
||||
// Identify the object kind. This kind will be used to apply a schema to the body and
|
||||
// will trigger additional indexing behavior.
|
||||
Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"`
|
||||
// Unique ID
|
||||
// less then 40, no slashes or other special characters
|
||||
UID string `protobuf:"bytes,4,opt,name=UID,proto3" json:"UID,omitempty"`
|
||||
}
|
||||
|
||||
@ -131,13 +127,6 @@ func (x *GRN) GetTenantId() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GRN) GetScope() string {
|
||||
if x != nil {
|
||||
return x.Scope
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *GRN) GetKind() string {
|
||||
if x != nil {
|
||||
return x.Kind
|
||||
@ -174,12 +163,16 @@ type RawObject struct {
|
||||
ETag string `protobuf:"bytes,7,opt,name=ETag,proto3" json:"ETag,omitempty"`
|
||||
// Raw bytes of the storage object. The kind will determine what is a valid payload
|
||||
Body []byte `protobuf:"bytes,8,opt,name=body,proto3" json:"body,omitempty"`
|
||||
// Folder UID
|
||||
Folder string `protobuf:"bytes,9,opt,name=folder,proto3" json:"folder,omitempty"`
|
||||
// Unique slug within folder (may be UID)
|
||||
Slug string `protobuf:"bytes,10,opt,name=slug,proto3" json:"slug,omitempty"`
|
||||
// The version will change when the object is saved. It is not necessarily sortable
|
||||
//
|
||||
// NOTE: currently managed by the dashboard+dashboard_version tables
|
||||
Version string `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"`
|
||||
Version string `protobuf:"bytes,11,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// External location info
|
||||
Origin *ObjectOriginInfo `protobuf:"bytes,10,opt,name=origin,proto3" json:"origin,omitempty"`
|
||||
Origin *ObjectOriginInfo `protobuf:"bytes,12,opt,name=origin,proto3" json:"origin,omitempty"`
|
||||
}
|
||||
|
||||
func (x *RawObject) Reset() {
|
||||
@ -270,6 +263,20 @@ func (x *RawObject) GetBody() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *RawObject) GetFolder() string {
|
||||
if x != nil {
|
||||
return x.Folder
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RawObject) GetSlug() string {
|
||||
if x != nil {
|
||||
return x.Slug
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RawObject) GetVersion() string {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
@ -291,8 +298,10 @@ type ObjectOriginInfo struct {
|
||||
|
||||
// NOTE: currently managed by the dashboard_provisioning table
|
||||
Source string `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"`
|
||||
// Key in the upstream system
|
||||
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"`
|
||||
// Time in epoch milliseconds that the object was last synced with an external system (provisioning/git)
|
||||
Time int64 `protobuf:"varint,2,opt,name=time,proto3" json:"time,omitempty"`
|
||||
Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ObjectOriginInfo) Reset() {
|
||||
@ -334,6 +343,13 @@ func (x *ObjectOriginInfo) GetSource() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ObjectOriginInfo) GetKey() string {
|
||||
if x != nil {
|
||||
return x.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ObjectOriginInfo) GetTime() int64 {
|
||||
if x != nil {
|
||||
return x.Time
|
||||
@ -738,12 +754,14 @@ type WriteObjectRequest struct {
|
||||
|
||||
// Object identifier
|
||||
GRN *GRN `protobuf:"bytes,1,opt,name=GRN,proto3" json:"GRN,omitempty"`
|
||||
// Where to save the object (empty will leave it unchanged)
|
||||
Folder string `protobuf:"bytes,2,opt,name=folder,proto3" json:"folder,omitempty"`
|
||||
// The raw object body
|
||||
Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
|
||||
Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
|
||||
// Message that can be seen when exploring object history
|
||||
Comment string `protobuf:"bytes,3,opt,name=comment,proto3" json:"comment,omitempty"`
|
||||
Comment string `protobuf:"bytes,4,opt,name=comment,proto3" json:"comment,omitempty"`
|
||||
// Used for optimistic locking. If missing, the previous version will be replaced regardless
|
||||
PreviousVersion string `protobuf:"bytes,4,opt,name=previous_version,json=previousVersion,proto3" json:"previous_version,omitempty"`
|
||||
PreviousVersion string `protobuf:"bytes,5,opt,name=previous_version,json=previousVersion,proto3" json:"previous_version,omitempty"`
|
||||
}
|
||||
|
||||
func (x *WriteObjectRequest) Reset() {
|
||||
@ -785,6 +803,13 @@ func (x *WriteObjectRequest) GetGRN() *GRN {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *WriteObjectRequest) GetFolder() string {
|
||||
if x != nil {
|
||||
return x.Folder
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *WriteObjectRequest) GetBody() []byte {
|
||||
if x != nil {
|
||||
return x.Body
|
||||
@ -816,33 +841,35 @@ type AdminWriteObjectRequest struct {
|
||||
|
||||
// Object identifier
|
||||
GRN *GRN `protobuf:"bytes,1,opt,name=GRN,proto3" json:"GRN,omitempty"`
|
||||
// Where to save the object (empty will leave it unchanged)
|
||||
Folder string `protobuf:"bytes,2,opt,name=folder,proto3" json:"folder,omitempty"`
|
||||
// The raw object body
|
||||
Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
|
||||
Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
|
||||
// Message that can be seen when exploring object history
|
||||
Comment string `protobuf:"bytes,3,opt,name=comment,proto3" json:"comment,omitempty"`
|
||||
Comment string `protobuf:"bytes,4,opt,name=comment,proto3" json:"comment,omitempty"`
|
||||
// Time in epoch milliseconds that the object was created
|
||||
// Optional, if 0 it will use the current time
|
||||
CreatedAt int64 `protobuf:"varint,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
CreatedAt int64 `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
// Time in epoch milliseconds that the object was updated
|
||||
// Optional, if empty it will use the current user
|
||||
UpdatedAt int64 `protobuf:"varint,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||
UpdatedAt int64 `protobuf:"varint,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
|
||||
// Who created the object
|
||||
// Optional, if 0 it will use the current time
|
||||
CreatedBy string `protobuf:"bytes,6,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
|
||||
CreatedBy string `protobuf:"bytes,7,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
|
||||
// Who updated the object
|
||||
// Optional, if empty it will use the current user
|
||||
UpdatedBy string `protobuf:"bytes,7,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"`
|
||||
UpdatedBy string `protobuf:"bytes,8,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"`
|
||||
// An explicit version identifier
|
||||
// Optional, if set, this will overwrite/define an explicit version
|
||||
Version string `protobuf:"bytes,8,opt,name=version,proto3" json:"version,omitempty"`
|
||||
Version string `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// Used for optimistic locking. If missing, the previous version will be replaced regardless
|
||||
// This may not be used along with an explicit version in the request
|
||||
PreviousVersion string `protobuf:"bytes,9,opt,name=previous_version,json=previousVersion,proto3" json:"previous_version,omitempty"`
|
||||
PreviousVersion string `protobuf:"bytes,10,opt,name=previous_version,json=previousVersion,proto3" json:"previous_version,omitempty"`
|
||||
// Request that all previous versions are removed from the history
|
||||
// This will make sense for systems that manage history explicitly externallay
|
||||
ClearHistory bool `protobuf:"varint,10,opt,name=clear_history,json=clearHistory,proto3" json:"clear_history,omitempty"`
|
||||
ClearHistory bool `protobuf:"varint,11,opt,name=clear_history,json=clearHistory,proto3" json:"clear_history,omitempty"`
|
||||
// Optionally define where the object came from
|
||||
Origin string `protobuf:"bytes,11,opt,name=origin,proto3" json:"origin,omitempty"`
|
||||
Origin *ObjectOriginInfo `protobuf:"bytes,12,opt,name=origin,proto3" json:"origin,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AdminWriteObjectRequest) Reset() {
|
||||
@ -884,6 +911,13 @@ func (x *AdminWriteObjectRequest) GetGRN() *GRN {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *AdminWriteObjectRequest) GetFolder() string {
|
||||
if x != nil {
|
||||
return x.Folder
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AdminWriteObjectRequest) GetBody() []byte {
|
||||
if x != nil {
|
||||
return x.Body
|
||||
@ -947,11 +981,11 @@ func (x *AdminWriteObjectRequest) GetClearHistory() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AdminWriteObjectRequest) GetOrigin() string {
|
||||
func (x *AdminWriteObjectRequest) GetOrigin() *ObjectOriginInfo {
|
||||
if x != nil {
|
||||
return x.Origin
|
||||
}
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteObjectResponse struct {
|
||||
@ -1427,10 +1461,14 @@ type ObjectSearchResult struct {
|
||||
Description string `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"`
|
||||
// The structured labels
|
||||
Labels map[string]string `protobuf:"bytes,9,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
// Folder UID
|
||||
Folder string `protobuf:"bytes,10,opt,name=folder,proto3" json:"folder,omitempty"`
|
||||
// Slugified name
|
||||
Slug string `protobuf:"bytes,11,opt,name=slug,proto3" json:"slug,omitempty"`
|
||||
// Optionally include extracted JSON
|
||||
FieldsJson []byte `protobuf:"bytes,10,opt,name=fields_json,json=fieldsJson,proto3" json:"fields_json,omitempty"`
|
||||
FieldsJson []byte `protobuf:"bytes,12,opt,name=fields_json,json=fieldsJson,proto3" json:"fields_json,omitempty"`
|
||||
// ObjectErrorInfo in json
|
||||
ErrorJson []byte `protobuf:"bytes,11,opt,name=error_json,json=errorJson,proto3" json:"error_json,omitempty"`
|
||||
ErrorJson []byte `protobuf:"bytes,13,opt,name=error_json,json=errorJson,proto3" json:"error_json,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ObjectSearchResult) Reset() {
|
||||
@ -1528,6 +1566,20 @@ func (x *ObjectSearchResult) GetLabels() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ObjectSearchResult) GetFolder() string {
|
||||
if x != nil {
|
||||
return x.Folder
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ObjectSearchResult) GetSlug() string {
|
||||
if x != nil {
|
||||
return x.Slug
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ObjectSearchResult) GetFieldsJson() []byte {
|
||||
if x != nil {
|
||||
return x.FieldsJson
|
||||
@ -1602,252 +1654,261 @@ var File_object_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_object_proto_rawDesc = []byte{
|
||||
0x0a, 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x5e, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x1b, 0x0a,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x48, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x1b, 0x0a,
|
||||
0x09, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x63,
|
||||
0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6b, 0x69, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x03, 0x55, 0x49, 0x44, 0x22, 0xae, 0x02, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x4f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03,
|
||||
0x47, 0x52, 0x4e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x45, 0x54, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x45, 0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18,
|
||||
0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18,
|
||||
0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52,
|
||||
0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0x3e, 0x0a, 0x10, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x62, 0x0a, 0x0f, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f,
|
||||
0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x74, 0x61,
|
||||
0x69, 0x6c, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b,
|
||||
0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x11,
|
||||
0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x75,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x52, 0x08, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69,
|
||||
0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x55, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x49, 0x44,
|
||||
0x22, 0xda, 0x02, 0x0a, 0x09, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1d,
|
||||
0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x1d, 0x0a,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a,
|
||||
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x45, 0x54, 0x61, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x54, 0x61,
|
||||
0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x11,
|
||||
0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b,
|
||||
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69,
|
||||
0x74, 0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77,
|
||||
0x69, 0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x69, 0x74, 0x68, 0x5f,
|
||||
0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77,
|
||||
0x69, 0x74, 0x68, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x62, 0x0a, 0x12, 0x52, 0x65,
|
||||
0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x29, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x11, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73,
|
||||
0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x49,
|
||||
0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63,
|
||||
0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x22, 0x4f, 0x0a, 0x17, 0x42, 0x61, 0x74,
|
||||
0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52,
|
||||
0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x8c, 0x01, 0x0a, 0x12, 0x57,
|
||||
0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b,
|
||||
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04,
|
||||
0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x45, 0x54, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x54, 0x61,
|
||||
0x67, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x73, 0x6c, 0x75, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6c, 0x75,
|
||||
0x67, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x06, 0x6f,
|
||||
0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x72, 0x69, 0x67, 0x69,
|
||||
0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x22, 0x50, 0x0a,
|
||||
0x10, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22,
|
||||
0x62, 0x0a, 0x0f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x4a,
|
||||
0x73, 0x6f, 0x6e, 0x22, 0xad, 0x01, 0x0a, 0x11, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
|
||||
0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42,
|
||||
0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x45, 0x54, 0x61, 0x67, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x45, 0x54, 0x61, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69, 0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x53, 0x75, 0x6d, 0x6d, 0x61,
|
||||
0x72, 0x79, 0x22, 0x62, 0x0a, 0x12, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x2e, 0x52, 0x61, 0x77, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x06, 0x6f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a,
|
||||
0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61,
|
||||
0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x22, 0x49, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52,
|
||||
0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x2f, 0x0a, 0x05, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x05, 0x62, 0x61, 0x74, 0x63,
|
||||
0x68, 0x22, 0x4f, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07,
|
||||
0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x12, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64,
|
||||
0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04,
|
||||
0x62, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x29,
|
||||
0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x29,
|
||||
0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xe4, 0x02, 0x0a, 0x17, 0x41, 0x64,
|
||||
0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x96, 0x03, 0x0a, 0x17, 0x41, 0x64,
|
||||
0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52,
|
||||
0x03, 0x47, 0x52, 0x4e, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74,
|
||||
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41,
|
||||
0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x07, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76,
|
||||
0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x56, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x5f, 0x68, 0x69, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x6c, 0x65, 0x61,
|
||||
0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67,
|
||||
0x69, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e,
|
||||
0x22, 0xb3, 0x02, 0x0a, 0x13, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f,
|
||||
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e, 0x66, 0x6f,
|
||||
0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52,
|
||||
0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x75, 0x6d,
|
||||
0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x3a, 0x0a, 0x06,
|
||||
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x6f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 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, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x43, 0x48, 0x41,
|
||||
0x4e, 0x47, 0x45, 0x44, 0x10, 0x03, 0x22, 0x5f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
|
||||
0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a,
|
||||
0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x29, 0x0a, 0x10,
|
||||
0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73,
|
||||
0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74,
|
||||
0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x4f, 0x4b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x4f, 0x4b, 0x22,
|
||||
0x73, 0x0a, 0x14, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52,
|
||||
0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x26, 0x0a, 0x0f,
|
||||
0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x95, 0x01, 0x0a, 0x15, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48,
|
||||
0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
|
||||
0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x35, 0x0a,
|
||||
0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67,
|
||||
0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e,
|
||||
0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x84, 0x03, 0x0a,
|
||||
0x13, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 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, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64,
|
||||
0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f,
|
||||
0x6c, 0x64, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x06,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c,
|
||||
0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x69, 0x74,
|
||||
0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x77, 0x69,
|
||||
0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x6c,
|
||||
0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69, 0x74,
|
||||
0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68, 0x5f,
|
||||
0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77, 0x69,
|
||||
0x74, 0x68, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65,
|
||||
0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
|
||||
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
|
||||
0x02, 0x38, 0x01, 0x22, 0xa4, 0x03, 0x0a, 0x12, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65,
|
||||
0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52,
|
||||
0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
0x64, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x06, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x3e, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x26, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53,
|
||||
0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65,
|
||||
0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x4a, 0x73, 0x6f, 0x6e,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x1a,
|
||||
0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
|
||||
0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x74, 0x0a, 0x14, 0x4f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52,
|
||||
0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 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,
|
||||
0x32, 0xfa, 0x03, 0x0a, 0x0b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65,
|
||||
0x12, 0x3d, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61,
|
||||
0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x4c, 0x0a, 0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x6f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a,
|
||||
0x05, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74,
|
||||
0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x43, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12,
|
||||
0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48,
|
||||
0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x06,
|
||||
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x03, 0x47, 0x52, 0x4e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x29, 0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76,
|
||||
0x69, 0x6f, 0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x63,
|
||||
0x6c, 0x65, 0x61, 0x72, 0x5f, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x0c, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79,
|
||||
0x12, 0x30, 0x0a, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x18, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x72, 0x69, 0x67,
|
||||
0x69, 0x6e, 0x22, 0xb3, 0x02, 0x0a, 0x13, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x05, 0x65, 0x72,
|
||||
0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x73,
|
||||
0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x3a,
|
||||
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22,
|
||||
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3c, 0x0a, 0x06, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 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, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x43,
|
||||
0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x03, 0x22, 0x5f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x29,
|
||||
0x0a, 0x10, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f,
|
||||
0x75, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x26, 0x0a, 0x14, 0x44, 0x65, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x4b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x02, 0x4f,
|
||||
0x4b, 0x22, 0x73, 0x0a, 0x14, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69,
|
||||
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x26,
|
||||
0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67,
|
||||
0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x95, 0x01, 0x0a, 0x15, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x1d, 0x0a, 0x03, 0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12,
|
||||
0x35, 0x0a, 0x08, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70,
|
||||
0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x84,
|
||||
0x03, 0x0a, 0x13, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 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, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69,
|
||||
0x6e, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73,
|
||||
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x4a, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12,
|
||||
0x1f, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72,
|
||||
0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52,
|
||||
0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x18,
|
||||
0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x77,
|
||||
0x69, 0x74, 0x68, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
|
||||
0x77, 0x69, 0x74, 0x68, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74, 0x68,
|
||||
0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x77,
|
||||
0x69, 0x74, 0x68, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x77, 0x69, 0x74,
|
||||
0x68, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a,
|
||||
0x77, 0x69, 0x74, 0x68, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61,
|
||||
0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xd0, 0x03, 0x0a, 0x12, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1d, 0x0a, 0x03,
|
||||
0x47, 0x52, 0x4e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x6f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x2e, 0x47, 0x52, 0x4e, 0x52, 0x03, 0x47, 0x52, 0x4e, 0x12, 0x18, 0x0a, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64,
|
||||
0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75,
|
||||
0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x3e, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4c, 0x61,
|
||||
0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c,
|
||||
0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c, 0x75,
|
||||
0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x12, 0x1f, 0x0a,
|
||||
0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x1a, 0x39, 0x0a,
|
||||
0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x74, 0x0a, 0x14, 0x4f, 0x62, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72,
|
||||
0x65, 0x73, 0x75, 0x6c, 0x74, 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, 0x32, 0xfa,
|
||||
0x03, 0x0a, 0x0b, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3d,
|
||||
0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x19, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e,
|
||||
0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a,
|
||||
0x09, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x12, 0x1e, 0x2e, 0x6f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x05, 0x57,
|
||||
0x72, 0x69, 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72,
|
||||
0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x5e, 0x0a,
|
||||
0x10, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6d, 0x69,
|
||||
0x6e, 0x12, 0x4a, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12,
|
||||
0x1f, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72,
|
||||
0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0b, 0x5a,
|
||||
0x09, 0x2e, 0x2f, 0x3b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a,
|
||||
0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
|
||||
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x44, 0x65,
|
||||
0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x2e,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x53, 0x65,
|
||||
0x61, 0x72, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1c, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x4a, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1f, 0x2e,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74,
|
||||
0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
|
||||
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x5e, 0x0a, 0x10, 0x4f,
|
||||
0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12,
|
||||
0x4a, 0x0a, 0x0a, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x12, 0x1f, 0x2e,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x57, 0x72, 0x69, 0x74,
|
||||
0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
|
||||
0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0b, 0x5a, 0x09, 0x2e,
|
||||
0x2f, 0x3b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -1897,39 +1958,40 @@ var file_object_proto_depIdxs = []int32{
|
||||
7, // 5: object.BatchReadObjectResponse.results:type_name -> object.ReadObjectResponse
|
||||
1, // 6: object.WriteObjectRequest.GRN:type_name -> object.GRN
|
||||
1, // 7: object.AdminWriteObjectRequest.GRN:type_name -> object.GRN
|
||||
4, // 8: object.WriteObjectResponse.error:type_name -> object.ObjectErrorInfo
|
||||
1, // 9: object.WriteObjectResponse.GRN:type_name -> object.GRN
|
||||
5, // 10: object.WriteObjectResponse.object:type_name -> object.ObjectVersionInfo
|
||||
0, // 11: object.WriteObjectResponse.status:type_name -> object.WriteObjectResponse.Status
|
||||
1, // 12: object.DeleteObjectRequest.GRN:type_name -> object.GRN
|
||||
1, // 13: object.ObjectHistoryRequest.GRN:type_name -> object.GRN
|
||||
1, // 14: object.ObjectHistoryResponse.GRN:type_name -> object.GRN
|
||||
5, // 15: object.ObjectHistoryResponse.versions:type_name -> object.ObjectVersionInfo
|
||||
20, // 16: object.ObjectSearchRequest.labels:type_name -> object.ObjectSearchRequest.LabelsEntry
|
||||
1, // 17: object.ObjectSearchResult.GRN:type_name -> object.GRN
|
||||
21, // 18: object.ObjectSearchResult.labels:type_name -> object.ObjectSearchResult.LabelsEntry
|
||||
18, // 19: object.ObjectSearchResponse.results:type_name -> object.ObjectSearchResult
|
||||
6, // 20: object.ObjectStore.Read:input_type -> object.ReadObjectRequest
|
||||
8, // 21: object.ObjectStore.BatchRead:input_type -> object.BatchReadObjectRequest
|
||||
10, // 22: object.ObjectStore.Write:input_type -> object.WriteObjectRequest
|
||||
13, // 23: object.ObjectStore.Delete:input_type -> object.DeleteObjectRequest
|
||||
15, // 24: object.ObjectStore.History:input_type -> object.ObjectHistoryRequest
|
||||
17, // 25: object.ObjectStore.Search:input_type -> object.ObjectSearchRequest
|
||||
11, // 26: object.ObjectStore.AdminWrite:input_type -> object.AdminWriteObjectRequest
|
||||
11, // 27: object.ObjectStoreAdmin.AdminWrite:input_type -> object.AdminWriteObjectRequest
|
||||
7, // 28: object.ObjectStore.Read:output_type -> object.ReadObjectResponse
|
||||
9, // 29: object.ObjectStore.BatchRead:output_type -> object.BatchReadObjectResponse
|
||||
12, // 30: object.ObjectStore.Write:output_type -> object.WriteObjectResponse
|
||||
14, // 31: object.ObjectStore.Delete:output_type -> object.DeleteObjectResponse
|
||||
16, // 32: object.ObjectStore.History:output_type -> object.ObjectHistoryResponse
|
||||
19, // 33: object.ObjectStore.Search:output_type -> object.ObjectSearchResponse
|
||||
12, // 34: object.ObjectStore.AdminWrite:output_type -> object.WriteObjectResponse
|
||||
12, // 35: object.ObjectStoreAdmin.AdminWrite:output_type -> object.WriteObjectResponse
|
||||
28, // [28:36] is the sub-list for method output_type
|
||||
20, // [20:28] is the sub-list for method input_type
|
||||
20, // [20:20] is the sub-list for extension type_name
|
||||
20, // [20:20] is the sub-list for extension extendee
|
||||
0, // [0:20] is the sub-list for field type_name
|
||||
3, // 8: object.AdminWriteObjectRequest.origin:type_name -> object.ObjectOriginInfo
|
||||
4, // 9: object.WriteObjectResponse.error:type_name -> object.ObjectErrorInfo
|
||||
1, // 10: object.WriteObjectResponse.GRN:type_name -> object.GRN
|
||||
5, // 11: object.WriteObjectResponse.object:type_name -> object.ObjectVersionInfo
|
||||
0, // 12: object.WriteObjectResponse.status:type_name -> object.WriteObjectResponse.Status
|
||||
1, // 13: object.DeleteObjectRequest.GRN:type_name -> object.GRN
|
||||
1, // 14: object.ObjectHistoryRequest.GRN:type_name -> object.GRN
|
||||
1, // 15: object.ObjectHistoryResponse.GRN:type_name -> object.GRN
|
||||
5, // 16: object.ObjectHistoryResponse.versions:type_name -> object.ObjectVersionInfo
|
||||
20, // 17: object.ObjectSearchRequest.labels:type_name -> object.ObjectSearchRequest.LabelsEntry
|
||||
1, // 18: object.ObjectSearchResult.GRN:type_name -> object.GRN
|
||||
21, // 19: object.ObjectSearchResult.labels:type_name -> object.ObjectSearchResult.LabelsEntry
|
||||
18, // 20: object.ObjectSearchResponse.results:type_name -> object.ObjectSearchResult
|
||||
6, // 21: object.ObjectStore.Read:input_type -> object.ReadObjectRequest
|
||||
8, // 22: object.ObjectStore.BatchRead:input_type -> object.BatchReadObjectRequest
|
||||
10, // 23: object.ObjectStore.Write:input_type -> object.WriteObjectRequest
|
||||
13, // 24: object.ObjectStore.Delete:input_type -> object.DeleteObjectRequest
|
||||
15, // 25: object.ObjectStore.History:input_type -> object.ObjectHistoryRequest
|
||||
17, // 26: object.ObjectStore.Search:input_type -> object.ObjectSearchRequest
|
||||
11, // 27: object.ObjectStore.AdminWrite:input_type -> object.AdminWriteObjectRequest
|
||||
11, // 28: object.ObjectStoreAdmin.AdminWrite:input_type -> object.AdminWriteObjectRequest
|
||||
7, // 29: object.ObjectStore.Read:output_type -> object.ReadObjectResponse
|
||||
9, // 30: object.ObjectStore.BatchRead:output_type -> object.BatchReadObjectResponse
|
||||
12, // 31: object.ObjectStore.Write:output_type -> object.WriteObjectResponse
|
||||
14, // 32: object.ObjectStore.Delete:output_type -> object.DeleteObjectResponse
|
||||
16, // 33: object.ObjectStore.History:output_type -> object.ObjectHistoryResponse
|
||||
19, // 34: object.ObjectStore.Search:output_type -> object.ObjectSearchResponse
|
||||
12, // 35: object.ObjectStore.AdminWrite:output_type -> object.WriteObjectResponse
|
||||
12, // 36: object.ObjectStoreAdmin.AdminWrite:output_type -> object.WriteObjectResponse
|
||||
29, // [29:37] is the sub-list for method output_type
|
||||
21, // [21:29] is the sub-list for method input_type
|
||||
21, // [21:21] is the sub-list for extension type_name
|
||||
21, // [21:21] is the sub-list for extension extendee
|
||||
0, // [0:21] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_object_proto_init() }
|
||||
|
@ -7,17 +7,12 @@ message GRN {
|
||||
// the tenant/org id
|
||||
int64 tenant_id = 1;
|
||||
|
||||
// mabybe "namespace"? valid values include
|
||||
// * entity
|
||||
// * drive
|
||||
// * service/xyz
|
||||
string scope = 2;
|
||||
|
||||
// Identify the object kind. This kind will be used to apply a schema to the body and
|
||||
// will trigger additional indexing behavior.
|
||||
string kind = 3;
|
||||
|
||||
// Unique ID
|
||||
// 40 characters or less, no slashes or other special characters
|
||||
string UID = 4;
|
||||
}
|
||||
|
||||
@ -47,21 +42,30 @@ message RawObject {
|
||||
// Raw bytes of the storage object. The kind will determine what is a valid payload
|
||||
bytes body = 8;
|
||||
|
||||
// Folder UID
|
||||
string folder = 9;
|
||||
|
||||
// Unique slug within folder (may be UID)
|
||||
string slug = 10;
|
||||
|
||||
// The version will change when the object is saved. It is not necessarily sortable
|
||||
//
|
||||
// NOTE: currently managed by the dashboard+dashboard_version tables
|
||||
string version = 9;
|
||||
string version = 11;
|
||||
|
||||
// External location info
|
||||
ObjectOriginInfo origin = 10;
|
||||
ObjectOriginInfo origin = 12;
|
||||
}
|
||||
|
||||
message ObjectOriginInfo {
|
||||
// NOTE: currently managed by the dashboard_provisioning table
|
||||
string source = 1;
|
||||
|
||||
// Key in the upstream system
|
||||
string key = 2;
|
||||
|
||||
// Time in epoch milliseconds that the object was last synced with an external system (provisioning/git)
|
||||
int64 time = 2;
|
||||
int64 time = 3;
|
||||
}
|
||||
|
||||
// Report error while working with objects
|
||||
@ -146,14 +150,17 @@ message WriteObjectRequest {
|
||||
// Object identifier
|
||||
GRN GRN = 1;
|
||||
|
||||
// Where to save the object (empty will leave it unchanged)
|
||||
string folder = 2;
|
||||
|
||||
// The raw object body
|
||||
bytes body = 2;
|
||||
bytes body = 3;
|
||||
|
||||
// Message that can be seen when exploring object history
|
||||
string comment = 3;
|
||||
string comment = 4;
|
||||
|
||||
// Used for optimistic locking. If missing, the previous version will be replaced regardless
|
||||
string previous_version = 4;
|
||||
string previous_version = 5;
|
||||
}
|
||||
|
||||
// This operation is useful when syncing a resource from external sources
|
||||
@ -163,42 +170,45 @@ message AdminWriteObjectRequest {
|
||||
// Object identifier
|
||||
GRN GRN = 1;
|
||||
|
||||
// Where to save the object (empty will leave it unchanged)
|
||||
string folder = 2;
|
||||
|
||||
// The raw object body
|
||||
bytes body = 2;
|
||||
bytes body = 3;
|
||||
|
||||
// Message that can be seen when exploring object history
|
||||
string comment = 3;
|
||||
string comment = 4;
|
||||
|
||||
// Time in epoch milliseconds that the object was created
|
||||
// Optional, if 0 it will use the current time
|
||||
int64 created_at = 4;
|
||||
int64 created_at = 5;
|
||||
|
||||
// Time in epoch milliseconds that the object was updated
|
||||
// Optional, if empty it will use the current user
|
||||
int64 updated_at = 5;
|
||||
int64 updated_at = 6;
|
||||
|
||||
// Who created the object
|
||||
// Optional, if 0 it will use the current time
|
||||
string created_by = 6;
|
||||
string created_by = 7;
|
||||
|
||||
// Who updated the object
|
||||
// Optional, if empty it will use the current user
|
||||
string updated_by = 7;
|
||||
string updated_by = 8;
|
||||
|
||||
// An explicit version identifier
|
||||
// Optional, if set, this will overwrite/define an explicit version
|
||||
string version = 8;
|
||||
string version = 9;
|
||||
|
||||
// Used for optimistic locking. If missing, the previous version will be replaced regardless
|
||||
// This may not be used along with an explicit version in the request
|
||||
string previous_version = 9;
|
||||
string previous_version = 10;
|
||||
|
||||
// Request that all previous versions are removed from the history
|
||||
// This will make sense for systems that manage history explicitly externallay
|
||||
bool clear_history = 10;
|
||||
bool clear_history = 11;
|
||||
|
||||
// Optionally define where the object came from
|
||||
string origin = 11;
|
||||
ObjectOriginInfo origin = 12;
|
||||
}
|
||||
|
||||
message WriteObjectResponse {
|
||||
@ -338,11 +348,17 @@ message ObjectSearchResult {
|
||||
// The structured labels
|
||||
map<string,string> labels = 9;
|
||||
|
||||
// Folder UID
|
||||
string folder = 10;
|
||||
|
||||
// Slugified name
|
||||
string slug = 11;
|
||||
|
||||
// Optionally include extracted JSON
|
||||
bytes fields_json = 10;
|
||||
bytes fields_json = 12;
|
||||
|
||||
// ObjectErrorInfo in json
|
||||
bytes error_json = 11;
|
||||
bytes error_json = 13;
|
||||
}
|
||||
|
||||
message ObjectSearchResponse {
|
||||
|
@ -12,7 +12,7 @@ type selectQuery struct {
|
||||
args []interface{}
|
||||
}
|
||||
|
||||
func (q *selectQuery) addWhere(f string, val string) {
|
||||
func (q *selectQuery) addWhere(f string, val interface{}) {
|
||||
q.args = append(q.args, val)
|
||||
q.where = append(q.where, f+"=?")
|
||||
}
|
||||
@ -37,11 +37,6 @@ func (q *selectQuery) addWhereIn(f string, vals []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (q *selectQuery) addWherePrefix(f string, v string) {
|
||||
q.args = append(q.args, v+"%")
|
||||
q.where = append(q.where, f+" LIKE ?")
|
||||
}
|
||||
|
||||
func (q *selectQuery) toQuery() (string, []interface{}) {
|
||||
args := q.args
|
||||
sb := strings.Builder{}
|
||||
|
@ -11,15 +11,12 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/grpcserver"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/session"
|
||||
"github.com/grafana/grafana/pkg/services/store"
|
||||
"github.com/grafana/grafana/pkg/services/store/kind"
|
||||
"github.com/grafana/grafana/pkg/services/store/kind/folder"
|
||||
"github.com/grafana/grafana/pkg/services/store/object"
|
||||
"github.com/grafana/grafana/pkg/services/store/resolver"
|
||||
"github.com/grafana/grafana/pkg/services/store/router"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@ -33,7 +30,6 @@ func ProvideSQLObjectServer(db db.DB, cfg *setting.Cfg, grpcServerProvider grpcs
|
||||
log: log.New("sql-object-server"),
|
||||
kinds: kinds,
|
||||
resolver: resolver,
|
||||
router: router.NewObjectStoreRouter(kinds),
|
||||
}
|
||||
object.RegisterObjectStoreServer(grpcServerProvider.GetServer(), objectServer)
|
||||
return objectServer
|
||||
@ -44,16 +40,16 @@ type sqlObjectServer struct {
|
||||
sess *session.SessionDB
|
||||
kinds kind.KindRegistry
|
||||
resolver resolver.ObjectReferenceResolver
|
||||
router router.ObjectStoreRouter
|
||||
}
|
||||
|
||||
func getReadSelect(r *object.ReadObjectRequest) string {
|
||||
fields := []string{
|
||||
"path", "kind", "version",
|
||||
"tenant_id", "kind", "uid", // The PK
|
||||
"version", "slug", "folder",
|
||||
"size", "etag", "errors", // errors are always returned
|
||||
"created_at", "created_by",
|
||||
"updated_at", "updated_by",
|
||||
"origin", "origin_ts"}
|
||||
"origin", "origin_key", "origin_ts"}
|
||||
|
||||
if r.WithBody {
|
||||
fields = append(fields, `body`)
|
||||
@ -61,24 +57,24 @@ func getReadSelect(r *object.ReadObjectRequest) string {
|
||||
if r.WithSummary {
|
||||
fields = append(fields, `name`, `description`, `labels`, `fields`)
|
||||
}
|
||||
return "SELECT " + strings.Join(fields, ",") + " FROM object WHERE "
|
||||
return "SELECT " + strings.Join(fields, ",") + " FROM entity WHERE "
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) rowToReadObjectResponse(ctx context.Context, rows *sql.Rows, r *object.ReadObjectRequest) (*object.ReadObjectResponse, error) {
|
||||
path := "" // string (extract UID?)
|
||||
var origin sql.NullString
|
||||
originTime := int64(0)
|
||||
raw := &object.RawObject{
|
||||
GRN: &object.GRN{},
|
||||
GRN: &object.GRN{},
|
||||
Origin: &object.ObjectOriginInfo{},
|
||||
}
|
||||
slug := ""
|
||||
|
||||
summaryjson := &summarySupport{}
|
||||
args := []interface{}{
|
||||
&path, &raw.GRN.Kind, &raw.Version,
|
||||
&raw.GRN.TenantId, &raw.GRN.Kind, &raw.GRN.UID,
|
||||
&raw.Version, &slug, &raw.Folder,
|
||||
&raw.Size, &raw.ETag, &summaryjson.errors,
|
||||
&raw.CreatedAt, &raw.CreatedBy,
|
||||
&raw.UpdatedAt, &raw.UpdatedBy,
|
||||
&origin, &originTime,
|
||||
&raw.Origin.Source, &raw.Origin.Key, &raw.Origin.Time,
|
||||
}
|
||||
if r.WithBody {
|
||||
args = append(args, &raw.Body)
|
||||
@ -92,17 +88,8 @@ func (s *sqlObjectServer) rowToReadObjectResponse(ctx context.Context, rows *sql
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if origin.Valid {
|
||||
raw.Origin = &object.ObjectOriginInfo{
|
||||
Source: origin.String,
|
||||
Time: originTime,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the GRN from key. TODO? save each part as a column?
|
||||
info, _ := s.router.RouteFromKey(ctx, path)
|
||||
if info.GRN != nil {
|
||||
raw.GRN = info.GRN
|
||||
if raw.Origin.Source == "" {
|
||||
raw.Origin = nil
|
||||
}
|
||||
|
||||
rsp := &object.ReadObjectResponse{
|
||||
@ -124,35 +111,43 @@ func (s *sqlObjectServer) rowToReadObjectResponse(ctx context.Context, rows *sql
|
||||
return rsp, nil
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) getObjectKey(ctx context.Context, grn *object.GRN) (router.ResourceRouteInfo, error) {
|
||||
func (s *sqlObjectServer) validateGRN(ctx context.Context, grn *object.GRN) (*object.GRN, error) {
|
||||
if grn == nil {
|
||||
return router.ResourceRouteInfo{}, fmt.Errorf("missing grn")
|
||||
return nil, fmt.Errorf("missing GRN")
|
||||
}
|
||||
user := store.UserFromContext(ctx)
|
||||
if user == nil {
|
||||
return router.ResourceRouteInfo{}, fmt.Errorf("can not find user in context")
|
||||
}
|
||||
if user.OrgID != grn.TenantId {
|
||||
if grn.TenantId > 0 {
|
||||
return router.ResourceRouteInfo{}, fmt.Errorf("invalid user (wrong tenant id)")
|
||||
}
|
||||
if grn.TenantId == 0 {
|
||||
grn.TenantId = user.OrgID
|
||||
} else if grn.TenantId != user.OrgID {
|
||||
return nil, fmt.Errorf("tenant ID does not match userID")
|
||||
}
|
||||
return s.router.Route(ctx, grn)
|
||||
|
||||
if grn.Kind == "" {
|
||||
return nil, fmt.Errorf("GRN missing kind")
|
||||
}
|
||||
if grn.UID == "" {
|
||||
return nil, fmt.Errorf("GRN missing UID")
|
||||
}
|
||||
if len(grn.UID) > 40 {
|
||||
return nil, fmt.Errorf("GRN UID is too long (>40)")
|
||||
}
|
||||
if strings.ContainsAny(grn.UID, "/#$@?") {
|
||||
return nil, fmt.Errorf("invalid character in GRN")
|
||||
}
|
||||
return grn, nil
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) Read(ctx context.Context, r *object.ReadObjectRequest) (*object.ReadObjectResponse, error) {
|
||||
if r.Version != "" {
|
||||
return s.readFromHistory(ctx, r)
|
||||
}
|
||||
|
||||
route, err := s.getObjectKey(ctx, r.GRN)
|
||||
grn, err := s.validateGRN(ctx, r.GRN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args := []interface{}{route.Key}
|
||||
where := "path=?"
|
||||
args := []interface{}{grn.ToGRNString()}
|
||||
where := "grn=?"
|
||||
|
||||
rows, err := s.sess.Query(ctx, getReadSelect(r)+where, args...)
|
||||
if err != nil {
|
||||
@ -168,10 +163,11 @@ func (s *sqlObjectServer) Read(ctx context.Context, r *object.ReadObjectRequest)
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) readFromHistory(ctx context.Context, r *object.ReadObjectRequest) (*object.ReadObjectResponse, error) {
|
||||
route, err := s.getObjectKey(ctx, r.GRN)
|
||||
grn, err := s.validateGRN(ctx, r.GRN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oid := grn.ToGRNString()
|
||||
|
||||
fields := []string{
|
||||
"body", "size", "etag",
|
||||
@ -180,7 +176,7 @@ func (s *sqlObjectServer) readFromHistory(ctx context.Context, r *object.ReadObj
|
||||
|
||||
rows, err := s.sess.Query(ctx,
|
||||
"SELECT "+strings.Join(fields, ",")+
|
||||
" FROM object_history WHERE path=? AND version=?", route.Key, r.Version)
|
||||
" FROM entity_history WHERE grn=? AND version=?", oid, r.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -243,13 +239,13 @@ func (s *sqlObjectServer) BatchRead(ctx context.Context, b *object.BatchReadObje
|
||||
return nil, fmt.Errorf("requests must want the same things")
|
||||
}
|
||||
|
||||
route, err := s.getObjectKey(ctx, r.GRN)
|
||||
grn, err := s.validateGRN(ctx, r.GRN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
where := "path=?"
|
||||
args = append(args, route.Key)
|
||||
where := "grn=?"
|
||||
args = append(args, grn.ToGRNString())
|
||||
if r.Version != "" {
|
||||
return nil, fmt.Errorf("version not supported for batch read (yet?)")
|
||||
}
|
||||
@ -282,14 +278,11 @@ func (s *sqlObjectServer) Write(ctx context.Context, r *object.WriteObjectReques
|
||||
|
||||
//nolint:gocyclo
|
||||
func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteObjectRequest) (*object.WriteObjectResponse, error) {
|
||||
route, err := s.getObjectKey(ctx, r.GRN)
|
||||
grn, err := s.validateGRN(ctx, r.GRN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
grn := route.GRN
|
||||
if grn == nil {
|
||||
return nil, fmt.Errorf("invalid grn")
|
||||
}
|
||||
oid := grn.ToGRNString()
|
||||
|
||||
timestamp := time.Now().UnixMilli()
|
||||
createdAt := r.CreatedAt
|
||||
@ -312,20 +305,15 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slug := slugifyTitle(summary.name, r.GRN.UID)
|
||||
etag := createContentsHash(body)
|
||||
path := route.Key
|
||||
|
||||
rsp := &object.WriteObjectResponse{
|
||||
GRN: grn,
|
||||
Status: object.WriteObjectResponse_CREATED, // Will be changed if not true
|
||||
}
|
||||
|
||||
// Make sure all parent folders exist
|
||||
if grn.Scope == models.ObjectStoreScopeDrive {
|
||||
err = s.ensureFolders(ctx, grn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
origin := r.Origin
|
||||
if origin == nil {
|
||||
origin = &object.ObjectOriginInfo{}
|
||||
}
|
||||
|
||||
err = s.sess.WithTransaction(ctx, func(tx *session.SessionTx) error {
|
||||
@ -334,18 +322,18 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
if r.ClearHistory {
|
||||
// Optionally keep the original creation time information
|
||||
if createdAt < 1000 || createdBy == "" {
|
||||
err = s.fillCreationInfo(ctx, tx, path, &createdAt, &createdBy)
|
||||
err = s.fillCreationInfo(ctx, tx, oid, &createdAt, &createdBy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_, err = doDelete(ctx, tx, path)
|
||||
_, err = doDelete(ctx, tx, oid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
versionInfo = &object.ObjectVersionInfo{}
|
||||
} else {
|
||||
versionInfo, err = s.selectForUpdate(ctx, tx, path)
|
||||
versionInfo, err = s.selectForUpdate(ctx, tx, oid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -385,25 +373,25 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
|
||||
if isUpdate {
|
||||
// Clear the labels+refs
|
||||
if _, err := tx.Exec(ctx, "DELETE FROM object_labels WHERE path=?", path); err != nil {
|
||||
if _, err := tx.Exec(ctx, "DELETE FROM entity_labels WHERE grn=?", oid); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.Exec(ctx, "DELETE FROM object_ref WHERE path=?", path); err != nil {
|
||||
if _, err := tx.Exec(ctx, "DELETE FROM entity_ref WHERE grn=?", oid); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Add the `object_history` values
|
||||
// 1. Add the `entity_history` values
|
||||
versionInfo.Size = int64(len(body))
|
||||
versionInfo.ETag = etag
|
||||
versionInfo.UpdatedAt = updatedAt
|
||||
versionInfo.UpdatedBy = updatedBy
|
||||
_, err = tx.Exec(ctx, `INSERT INTO object_history (`+
|
||||
"path, version, message, "+
|
||||
_, err = tx.Exec(ctx, `INSERT INTO entity_history (`+
|
||||
"grn, version, message, "+
|
||||
"size, body, etag, "+
|
||||
"updated_at, updated_by) "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
path, versionInfo.Version, versionInfo.Comment,
|
||||
oid, versionInfo.Version, versionInfo.Comment,
|
||||
versionInfo.Size, body, versionInfo.ETag,
|
||||
updatedAt, versionInfo.UpdatedBy,
|
||||
)
|
||||
@ -414,10 +402,10 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
// 2. Add the labels rows
|
||||
for k, v := range summary.model.Labels {
|
||||
_, err = tx.Exec(ctx,
|
||||
`INSERT INTO object_labels `+
|
||||
"(path, label, value) "+
|
||||
`INSERT INTO entity_labels `+
|
||||
"(grn, label, value) "+
|
||||
`VALUES (?, ?, ?)`,
|
||||
path, k, v,
|
||||
oid, k, v,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -430,11 +418,11 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = tx.Exec(ctx, `INSERT INTO object_ref (`+
|
||||
"path, kind, type, uid, "+
|
||||
_, err = tx.Exec(ctx, `INSERT INTO entity_ref (`+
|
||||
"grn, kind, type, uid, "+
|
||||
"resolved_ok, resolved_to, resolved_warning, resolved_time) "+
|
||||
`VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
path, ref.Kind, ref.Type, ref.UID,
|
||||
oid, ref.Kind, ref.Type, ref.UID,
|
||||
resolved.OK, resolved.Key, resolved.Warning, resolved.Timestamp,
|
||||
)
|
||||
if err != nil {
|
||||
@ -446,19 +434,19 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
rsp.Object = versionInfo
|
||||
if isUpdate {
|
||||
rsp.Status = object.WriteObjectResponse_UPDATED
|
||||
_, err = tx.Exec(ctx, "UPDATE object SET "+
|
||||
_, err = tx.Exec(ctx, "UPDATE entity SET "+
|
||||
"body=?, size=?, etag=?, version=?, "+
|
||||
"updated_at=?, updated_by=?,"+
|
||||
"name=?, description=?,"+
|
||||
"labels=?, fields=?, errors=?, "+
|
||||
"origin=?, origin_ts=? "+
|
||||
"WHERE path=?",
|
||||
"origin=?, origin_key=?, origin_ts=? "+
|
||||
"WHERE grn=?",
|
||||
body, versionInfo.Size, etag, versionInfo.Version,
|
||||
updatedAt, versionInfo.UpdatedBy,
|
||||
summary.model.Name, summary.model.Description,
|
||||
summary.labels, summary.fields, summary.errors,
|
||||
r.Origin, timestamp,
|
||||
path,
|
||||
origin.Source, origin.Key, timestamp,
|
||||
oid,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@ -470,16 +458,25 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
createdBy = updatedBy
|
||||
}
|
||||
|
||||
_, err = tx.Exec(ctx, "INSERT INTO object ("+
|
||||
"path, parent_folder_path, kind, size, body, etag, version, "+
|
||||
_, err = tx.Exec(ctx, "INSERT INTO entity ("+
|
||||
"grn, tenant_id, kind, uid, folder, "+
|
||||
"size, body, etag, version, "+
|
||||
"updated_at, updated_by, created_at, created_by, "+
|
||||
"name, description, origin, origin_ts, "+
|
||||
"labels, fields, errors) "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
path, getParentFolderPath(grn.Kind, path), grn.Kind, versionInfo.Size, body, etag, versionInfo.Version,
|
||||
"name, description, slug, "+
|
||||
"labels, fields, errors, "+
|
||||
"origin, origin_key, origin_ts) "+
|
||||
"VALUES (?, ?, ?, ?, ?, "+
|
||||
" ?, ?, ?, ?, "+
|
||||
" ?, ?, ?, ?, "+
|
||||
" ?, ?, ?, "+
|
||||
" ?, ?, ?, "+
|
||||
" ?, ?, ?)",
|
||||
oid, grn.TenantId, grn.Kind, grn.UID, r.Folder,
|
||||
versionInfo.Size, body, etag, versionInfo.Version,
|
||||
updatedAt, createdBy, createdAt, createdBy, // created + updated are the same
|
||||
summary.model.Name, summary.model.Description, r.Origin, timestamp,
|
||||
summary.model.Name, summary.model.Description, slug,
|
||||
summary.labels, summary.fields, summary.errors,
|
||||
origin.Source, origin.Key, origin.Time,
|
||||
)
|
||||
return err
|
||||
})
|
||||
@ -490,7 +487,7 @@ func (s *sqlObjectServer) AdminWrite(ctx context.Context, r *object.AdminWriteOb
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) fillCreationInfo(ctx context.Context, tx *session.SessionTx, path string, createdAt *int64, createdBy *string) error {
|
||||
func (s *sqlObjectServer) fillCreationInfo(ctx context.Context, tx *session.SessionTx, grn string, createdAt *int64, createdBy *string) error {
|
||||
if *createdAt > 1000 {
|
||||
ignore := int64(0)
|
||||
createdAt = &ignore
|
||||
@ -500,7 +497,7 @@ func (s *sqlObjectServer) fillCreationInfo(ctx context.Context, tx *session.Sess
|
||||
createdBy = &ignore
|
||||
}
|
||||
|
||||
rows, err := tx.Query(ctx, "SELECT created_at,created_by FROM object WHERE path=?", path)
|
||||
rows, err := tx.Query(ctx, "SELECT created_at,created_by FROM entity WHERE grn=?", grn)
|
||||
if err == nil {
|
||||
if rows.Next() {
|
||||
err = rows.Scan(&createdAt, &createdBy)
|
||||
@ -512,12 +509,12 @@ func (s *sqlObjectServer) fillCreationInfo(ctx context.Context, tx *session.Sess
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) selectForUpdate(ctx context.Context, tx *session.SessionTx, path string) (*object.ObjectVersionInfo, error) {
|
||||
q := "SELECT etag,version,updated_at,size FROM object WHERE path=?"
|
||||
func (s *sqlObjectServer) selectForUpdate(ctx context.Context, tx *session.SessionTx, grn string) (*object.ObjectVersionInfo, error) {
|
||||
q := "SELECT etag,version,updated_at,size FROM entity WHERE grn=?"
|
||||
if false { // TODO, MYSQL/PosgreSQL can lock the row " FOR UPDATE"
|
||||
q += " FOR UPDATE"
|
||||
}
|
||||
rows, err := tx.Query(ctx, q, path)
|
||||
rows, err := tx.Query(ctx, q, grn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -551,22 +548,21 @@ func (s *sqlObjectServer) prepare(ctx context.Context, r *object.AdminWriteObjec
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) Delete(ctx context.Context, r *object.DeleteObjectRequest) (*object.DeleteObjectResponse, error) {
|
||||
route, err := s.getObjectKey(ctx, r.GRN)
|
||||
grn, err := s.validateGRN(ctx, r.GRN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := route.Key
|
||||
|
||||
rsp := &object.DeleteObjectResponse{}
|
||||
err = s.sess.WithTransaction(ctx, func(tx *session.SessionTx) error {
|
||||
rsp.OK, err = doDelete(ctx, tx, path)
|
||||
rsp.OK, err = doDelete(ctx, tx, grn.ToGRNString())
|
||||
return err
|
||||
})
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
func doDelete(ctx context.Context, tx *session.SessionTx, path string) (bool, error) {
|
||||
results, err := tx.Exec(ctx, "DELETE FROM object WHERE path=?", path)
|
||||
func doDelete(ctx context.Context, tx *session.SessionTx, grn string) (bool, error) {
|
||||
results, err := tx.Exec(ctx, "DELETE FROM entity WHERE grn=?", grn)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -576,21 +572,21 @@ func doDelete(ctx context.Context, tx *session.SessionTx, path string) (bool, er
|
||||
}
|
||||
|
||||
// TODO: keep history? would need current version bump, and the "write" would have to get from history
|
||||
_, _ = tx.Exec(ctx, "DELETE FROM object_history WHERE path=?", path)
|
||||
_, _ = tx.Exec(ctx, "DELETE FROM object_labels WHERE path=?", path)
|
||||
_, _ = tx.Exec(ctx, "DELETE FROM object_ref WHERE path=?", path)
|
||||
_, _ = tx.Exec(ctx, "DELETE FROM entity_history WHERE grn=?", grn)
|
||||
_, _ = tx.Exec(ctx, "DELETE FROM entity_labels WHERE grn=?", grn)
|
||||
_, _ = tx.Exec(ctx, "DELETE FROM entity_ref WHERE grn=?", grn)
|
||||
return rows > 0, err
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) History(ctx context.Context, r *object.ObjectHistoryRequest) (*object.ObjectHistoryResponse, error) {
|
||||
route, err := s.getObjectKey(ctx, r.GRN)
|
||||
grn, err := s.validateGRN(ctx, r.GRN)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path := route.Key
|
||||
oid := grn.ToGRNString()
|
||||
|
||||
page := ""
|
||||
args := []interface{}{path}
|
||||
args := []interface{}{oid}
|
||||
if r.NextPageToken != "" {
|
||||
// args = append(args, r.NextPageToken) // TODO, need to get time from the version
|
||||
// page = "AND updated <= ?"
|
||||
@ -598,8 +594,8 @@ func (s *sqlObjectServer) History(ctx context.Context, r *object.ObjectHistoryRe
|
||||
}
|
||||
|
||||
query := "SELECT version,size,etag,updated_at,updated_by,message \n" +
|
||||
" FROM object_history \n" +
|
||||
" WHERE path=? " + page + "\n" +
|
||||
" FROM entity_history \n" +
|
||||
" WHERE grn=? " + page + "\n" +
|
||||
" ORDER BY updated_at DESC LIMIT 100"
|
||||
|
||||
rows, err := s.sess.Query(ctx, query, args...)
|
||||
@ -608,7 +604,7 @@ func (s *sqlObjectServer) History(ctx context.Context, r *object.ObjectHistoryRe
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
rsp := &object.ObjectHistoryResponse{
|
||||
GRN: route.GRN,
|
||||
GRN: r.GRN,
|
||||
}
|
||||
for rows.Next() {
|
||||
v := &object.ObjectVersionInfo{}
|
||||
@ -632,7 +628,8 @@ func (s *sqlObjectServer) Search(ctx context.Context, r *object.ObjectSearchRequ
|
||||
}
|
||||
|
||||
fields := []string{
|
||||
"path", "kind", "version", "errors", // errors are always returned
|
||||
"grn", "tenant_id", "kind", "uid",
|
||||
"version", "folder", "slug", "errors", // errors are always returned
|
||||
"size", "updated_at", "updated_by",
|
||||
"name", "description", // basic summary
|
||||
}
|
||||
@ -649,31 +646,20 @@ func (s *sqlObjectServer) Search(ctx context.Context, r *object.ObjectSearchRequ
|
||||
|
||||
selectQuery := selectQuery{
|
||||
fields: fields,
|
||||
from: "object", // the table
|
||||
from: "entity", // the table
|
||||
args: []interface{}{},
|
||||
limit: int(r.Limit),
|
||||
oneExtra: true, // request one more than the limit (and show next token if it exists)
|
||||
}
|
||||
selectQuery.addWhere("tenant_id", user.OrgID)
|
||||
|
||||
if len(r.Kind) > 0 {
|
||||
selectQuery.addWhereIn("kind", r.Kind)
|
||||
}
|
||||
|
||||
// Locked to a folder or prefix
|
||||
// Folder UID or OID?
|
||||
if r.Folder != "" {
|
||||
if strings.HasSuffix(r.Folder, "/") {
|
||||
return nil, fmt.Errorf("folder should not end with slash")
|
||||
}
|
||||
if strings.HasSuffix(r.Folder, "*") {
|
||||
keyPrefix := fmt.Sprintf("%d/%s", user.OrgID, strings.ReplaceAll(r.Folder, "*", ""))
|
||||
selectQuery.addWherePrefix("path", keyPrefix)
|
||||
} else {
|
||||
keyPrefix := fmt.Sprintf("%d/%s", user.OrgID, r.Folder)
|
||||
selectQuery.addWhere("parent_folder_path", keyPrefix)
|
||||
}
|
||||
} else {
|
||||
keyPrefix := fmt.Sprintf("%d/", user.OrgID)
|
||||
selectQuery.addWherePrefix("path", keyPrefix)
|
||||
selectQuery.addWhere("folder", r.Folder)
|
||||
}
|
||||
|
||||
query, args := selectQuery.toQuery()
|
||||
@ -688,7 +674,7 @@ func (s *sqlObjectServer) Search(ctx context.Context, r *object.ObjectSearchRequ
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
key := ""
|
||||
oid := ""
|
||||
rsp := &object.ObjectSearchResponse{}
|
||||
for rows.Next() {
|
||||
result := &object.ObjectSearchResult{
|
||||
@ -697,7 +683,8 @@ func (s *sqlObjectServer) Search(ctx context.Context, r *object.ObjectSearchRequ
|
||||
summaryjson := summarySupport{}
|
||||
|
||||
args := []interface{}{
|
||||
&key, &result.GRN.Kind, &result.Version, &summaryjson.errors,
|
||||
&oid, &result.GRN.TenantId, &result.GRN.Kind, &result.GRN.UID,
|
||||
&result.Version, &result.Folder, &result.Slug, &summaryjson.errors,
|
||||
&result.Size, &result.UpdatedAt, &result.UpdatedBy,
|
||||
&result.Name, &summaryjson.description,
|
||||
}
|
||||
@ -716,16 +703,10 @@ func (s *sqlObjectServer) Search(ctx context.Context, r *object.ObjectSearchRequ
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
info, err := s.router.RouteFromKey(ctx, key)
|
||||
if err != nil {
|
||||
return rsp, err
|
||||
}
|
||||
result.GRN = info.GRN
|
||||
|
||||
// found one more than requested
|
||||
if len(rsp.Results) >= selectQuery.limit {
|
||||
// TODO? should this encode start+offset?
|
||||
rsp.NextPageToken = key
|
||||
rsp.NextPageToken = oid
|
||||
break
|
||||
}
|
||||
|
||||
@ -753,54 +734,3 @@ func (s *sqlObjectServer) Search(ctx context.Context, r *object.ObjectSearchRequ
|
||||
}
|
||||
return rsp, err
|
||||
}
|
||||
|
||||
func (s *sqlObjectServer) ensureFolders(ctx context.Context, objectgrn *object.GRN) error {
|
||||
uid := objectgrn.UID
|
||||
idx := strings.LastIndex(uid, "/")
|
||||
var missing []*object.GRN
|
||||
|
||||
for idx > 0 {
|
||||
parent := uid[:idx]
|
||||
grn := &object.GRN{
|
||||
TenantId: objectgrn.TenantId,
|
||||
Scope: objectgrn.Scope,
|
||||
Kind: models.StandardKindFolder,
|
||||
UID: parent,
|
||||
}
|
||||
fr, err := s.router.Route(ctx, grn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Not super efficient, but maybe it is OK?
|
||||
results := []int64{}
|
||||
err = s.sess.Select(ctx, &results, "SELECT 1 from object WHERE path=?", fr.Key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(results) == 0 {
|
||||
missing = append([]*object.GRN{grn}, missing...)
|
||||
}
|
||||
idx = strings.LastIndex(parent, "/")
|
||||
}
|
||||
|
||||
// walk though each missing element
|
||||
for _, grn := range missing {
|
||||
f := &folder.Model{
|
||||
Name: store.GuessNameFromUID(grn.UID),
|
||||
}
|
||||
fmt.Printf("CREATE Folder: %s\n", grn.UID)
|
||||
body, err := json.Marshal(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = s.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: grn,
|
||||
Body: body,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -2,10 +2,11 @@ package sqlstash
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/gosimple/slug"
|
||||
)
|
||||
|
||||
func createContentsHash(contents []byte) string {
|
||||
@ -13,15 +14,20 @@ func createContentsHash(contents []byte) string {
|
||||
return hex.EncodeToString(hash[:])
|
||||
}
|
||||
|
||||
func getParentFolderPath(kind string, key string) string {
|
||||
idx := strings.LastIndex(key, "/")
|
||||
if idx < 0 {
|
||||
return "" // ?
|
||||
func slugifyTitle(title string, fallback string) string {
|
||||
if title == "" {
|
||||
title = fallback
|
||||
}
|
||||
|
||||
// folder should have a parent up one directory
|
||||
if kind == models.StandardKindFolder {
|
||||
idx = strings.LastIndex(key[:idx], "/")
|
||||
s := slug.Make(strings.ToLower(title))
|
||||
if s == "" {
|
||||
// If the dashboard name is only characters outside of the
|
||||
// sluggable characters, the slug creation will return an
|
||||
// empty string which will mess up URLs. This failsafe picks
|
||||
// that up and creates the slug as a base64 identifier instead.
|
||||
s = base64.RawURLEncoding.EncodeToString([]byte(title))
|
||||
if slug.MaxLength != 0 && len(s) > slug.MaxLength {
|
||||
s = s[:slug.MaxLength]
|
||||
}
|
||||
}
|
||||
return key[:idx]
|
||||
return s
|
||||
}
|
||||
|
@ -48,9 +48,6 @@ func requireObjectMatch(t *testing.T, obj *object.RawObject, m rawObjectMatcher)
|
||||
if m.grn.TenantId > 0 && m.grn.TenantId != obj.GRN.TenantId {
|
||||
mismatches += fmt.Sprintf("expected tenant: %d, actual: %d\n", m.grn.TenantId, obj.GRN.TenantId)
|
||||
}
|
||||
if m.grn.Scope != "" && m.grn.Scope != obj.GRN.Scope {
|
||||
mismatches += fmt.Sprintf("expected Scope: %s, actual: %s\n", m.grn.Scope, obj.GRN.Scope)
|
||||
}
|
||||
if m.grn.Kind != "" && m.grn.Kind != obj.GRN.Kind {
|
||||
mismatches += fmt.Sprintf("expected Kind: %s, actual: %s\n", m.grn.Kind, obj.GRN.Kind)
|
||||
}
|
||||
@ -125,9 +122,8 @@ func TestIntegrationObjectServer(t *testing.T) {
|
||||
firstVersion := "1"
|
||||
kind := models.StandardKindJSONObj
|
||||
grn := &object.GRN{
|
||||
Kind: kind,
|
||||
UID: "my-test-entity",
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
Kind: kind,
|
||||
UID: "my-test-entity",
|
||||
}
|
||||
body := []byte("{\"name\":\"John\"}")
|
||||
|
||||
@ -171,7 +167,6 @@ func TestIntegrationObjectServer(t *testing.T) {
|
||||
foundGRN := readResp.Object.GRN
|
||||
require.NotNil(t, foundGRN)
|
||||
require.Equal(t, testCtx.user.OrgID, foundGRN.TenantId) // orgId becomes the tenant id when not set
|
||||
require.Equal(t, grn.Scope, foundGRN.Scope)
|
||||
require.Equal(t, grn.Kind, foundGRN.Kind)
|
||||
require.Equal(t, grn.UID, foundGRN.UID)
|
||||
|
||||
@ -205,9 +200,8 @@ func TestIntegrationObjectServer(t *testing.T) {
|
||||
t.Run("should be able to update an object", func(t *testing.T) {
|
||||
before := time.Now()
|
||||
grn := &object.GRN{
|
||||
Kind: kind,
|
||||
UID: util.GenerateShortUID(),
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
Kind: kind,
|
||||
UID: util.GenerateShortUID(),
|
||||
}
|
||||
|
||||
writeReq1 := &object.WriteObjectRequest{
|
||||
@ -316,9 +310,8 @@ func TestIntegrationObjectServer(t *testing.T) {
|
||||
|
||||
w2, err := testCtx.client.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
UID: uid2,
|
||||
Kind: kind,
|
||||
Scope: grn.Scope,
|
||||
UID: uid2,
|
||||
Kind: kind,
|
||||
},
|
||||
Body: body,
|
||||
})
|
||||
@ -326,9 +319,8 @@ func TestIntegrationObjectServer(t *testing.T) {
|
||||
|
||||
w3, err := testCtx.client.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
UID: uid3,
|
||||
Kind: kind2,
|
||||
Scope: grn.Scope,
|
||||
UID: uid3,
|
||||
Kind: kind2,
|
||||
},
|
||||
Body: body,
|
||||
})
|
||||
@ -336,9 +328,8 @@ func TestIntegrationObjectServer(t *testing.T) {
|
||||
|
||||
w4, err := testCtx.client.Write(ctx, &object.WriteObjectRequest{
|
||||
GRN: &object.GRN{
|
||||
UID: uid4,
|
||||
Kind: kind2,
|
||||
Scope: grn.Scope,
|
||||
UID: uid4,
|
||||
Kind: kind2,
|
||||
},
|
||||
Body: body,
|
||||
})
|
||||
|
@ -5,6 +5,7 @@ func ToAdminWriteObjectRequest(req *WriteObjectRequest) *AdminWriteObjectRequest
|
||||
return &AdminWriteObjectRequest{
|
||||
GRN: req.GRN,
|
||||
Body: req.Body,
|
||||
Folder: req.Folder,
|
||||
Comment: req.Comment,
|
||||
PreviousVersion: req.PreviousVersion,
|
||||
}
|
||||
|
@ -1,173 +0,0 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/store/kind"
|
||||
"github.com/grafana/grafana/pkg/services/store/object"
|
||||
)
|
||||
|
||||
type ResourceRouteInfo struct {
|
||||
// The resource identifier
|
||||
GRN *object.GRN
|
||||
|
||||
// Raw key used in storage engine
|
||||
Key string
|
||||
}
|
||||
|
||||
type ObjectStoreRouter interface {
|
||||
// This will throw exceptions for unsupported
|
||||
Route(ctx context.Context, grn *object.GRN) (ResourceRouteInfo, error)
|
||||
|
||||
// Parse a key to get the GRN and storage information
|
||||
RouteFromKey(ctx context.Context, key string) (ResourceRouteInfo, error)
|
||||
}
|
||||
|
||||
type standardStoreRouter struct {
|
||||
kinds kind.KindRegistry
|
||||
}
|
||||
|
||||
func NewObjectStoreRouter(kinds kind.KindRegistry) ObjectStoreRouter {
|
||||
return &standardStoreRouter{kinds: kinds}
|
||||
}
|
||||
|
||||
var _ ObjectStoreRouter = &standardStoreRouter{}
|
||||
|
||||
func (r *standardStoreRouter) Route(ctx context.Context, grn *object.GRN) (ResourceRouteInfo, error) {
|
||||
info := ResourceRouteInfo{
|
||||
GRN: grn,
|
||||
}
|
||||
|
||||
if grn == nil {
|
||||
return info, fmt.Errorf("missing GRN")
|
||||
}
|
||||
|
||||
// Make sure the orgID is set
|
||||
if grn.TenantId < 1 {
|
||||
return info, fmt.Errorf("missing TenantId")
|
||||
}
|
||||
if grn.Kind == "" {
|
||||
return info, fmt.Errorf("missing Kind")
|
||||
}
|
||||
if grn.UID == "" {
|
||||
return info, fmt.Errorf("missing UID")
|
||||
}
|
||||
|
||||
kind, err := r.kinds.GetInfo(grn.Kind)
|
||||
if err != nil {
|
||||
return info, fmt.Errorf("unknown Kind: " + grn.Kind)
|
||||
}
|
||||
|
||||
if grn.Scope == "" {
|
||||
return info, fmt.Errorf("missing Scope")
|
||||
}
|
||||
|
||||
switch grn.Scope {
|
||||
case models.ObjectStoreScopeEntity:
|
||||
{
|
||||
info.Key = fmt.Sprintf("%d/%s/%s/%s", grn.TenantId, grn.Scope, grn.Kind, grn.UID)
|
||||
}
|
||||
case models.ObjectStoreScopeDrive:
|
||||
{
|
||||
// Special folder handling in drive
|
||||
if grn.Kind == models.StandardKindFolder {
|
||||
info.Key = fmt.Sprintf("%d/%s/%s/__folder.json", grn.TenantId, grn.Scope, grn.UID)
|
||||
return info, nil
|
||||
}
|
||||
if kind.FileExtension != "" {
|
||||
info.Key = fmt.Sprintf("%d/%s/%s.%s", grn.TenantId, grn.Scope, grn.UID, kind.FileExtension)
|
||||
} else {
|
||||
info.Key = fmt.Sprintf("%d/%s/%s-%s.json", grn.TenantId, grn.Scope, grn.UID, grn.Kind)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return info, fmt.Errorf("unsupported scope: " + grn.Scope)
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (r *standardStoreRouter) RouteFromKey(ctx context.Context, key string) (ResourceRouteInfo, error) {
|
||||
info := ResourceRouteInfo{
|
||||
Key: key,
|
||||
GRN: &object.GRN{},
|
||||
}
|
||||
// {orgID}/{scope}/....
|
||||
|
||||
idx := strings.Index(key, "/")
|
||||
if idx <= 0 {
|
||||
return info, fmt.Errorf("can not find orgID")
|
||||
}
|
||||
p0 := key[:idx]
|
||||
key = key[idx+1:]
|
||||
idx = strings.Index(key, "/")
|
||||
if idx <= 0 {
|
||||
return info, fmt.Errorf("can not find namespace")
|
||||
}
|
||||
p2 := key[:idx]
|
||||
key = key[idx+1:]
|
||||
|
||||
tenantID, err := strconv.ParseInt(p0, 10, 64)
|
||||
if err != nil {
|
||||
return info, fmt.Errorf("error parsing orgID")
|
||||
}
|
||||
info.GRN.TenantId = tenantID
|
||||
info.GRN.Scope = p2
|
||||
|
||||
switch info.GRN.Scope {
|
||||
case models.ObjectStoreScopeDrive:
|
||||
{
|
||||
idx := strings.LastIndex(key, ".")
|
||||
if idx > 0 {
|
||||
ext := key[idx+1:]
|
||||
if ext == "json" {
|
||||
sdx := strings.LastIndex(key, "/")
|
||||
idx = strings.LastIndex(key, "-")
|
||||
if idx > sdx {
|
||||
ddx := strings.LastIndex(key, ".") // .json
|
||||
info.GRN.UID = key[:idx]
|
||||
info.GRN.Kind = key[idx+1 : ddx]
|
||||
} else {
|
||||
switch key[sdx+1:] {
|
||||
case "__folder.json":
|
||||
{
|
||||
info.GRN.UID = key[:sdx]
|
||||
info.GRN.Kind = models.StandardKindFolder
|
||||
}
|
||||
default:
|
||||
return info, fmt.Errorf("unable to parse drive path")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info.GRN.UID = key[:idx]
|
||||
k, err := r.kinds.GetFromExtension(ext)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
info.GRN.Kind = k.ID
|
||||
}
|
||||
} else {
|
||||
idx = strings.Index(key, "/")
|
||||
|
||||
info.GRN.Kind = key[:idx]
|
||||
info.GRN.UID = key[idx+1:]
|
||||
}
|
||||
}
|
||||
|
||||
case models.ObjectStoreScopeEntity:
|
||||
{
|
||||
idx = strings.Index(key, "/")
|
||||
|
||||
info.GRN.Kind = key[:idx]
|
||||
info.GRN.UID = key[idx+1:]
|
||||
}
|
||||
|
||||
default:
|
||||
return info, fmt.Errorf("unsupported scope")
|
||||
}
|
||||
return info, nil
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/store/kind"
|
||||
"github.com/grafana/grafana/pkg/services/store/object"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSimpleRouter(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
router := &standardStoreRouter{
|
||||
kinds: kind.NewKindRegistry(),
|
||||
}
|
||||
info, err := router.Route(ctx, &object.GRN{
|
||||
UID: "path/to/file",
|
||||
})
|
||||
require.Error(t, err) // needs OrgID
|
||||
|
||||
type routeScenario struct {
|
||||
GRN *object.GRN
|
||||
Error string
|
||||
Key string
|
||||
}
|
||||
|
||||
scenarios := []routeScenario{{
|
||||
Error: "missing TenantId",
|
||||
GRN: &object.GRN{Scope: "x"},
|
||||
}, {
|
||||
Error: "unknown Kind: xyz",
|
||||
GRN: &object.GRN{
|
||||
TenantId: 11,
|
||||
Scope: models.ObjectStoreScopeDrive,
|
||||
UID: "path/to/file",
|
||||
Kind: "xyz",
|
||||
},
|
||||
}, {
|
||||
Key: "11/drive/path/to/file-dashboard.json",
|
||||
GRN: &object.GRN{
|
||||
TenantId: 11,
|
||||
Scope: models.ObjectStoreScopeDrive,
|
||||
UID: "path/to/file",
|
||||
Kind: "dashboard",
|
||||
},
|
||||
}, {
|
||||
Key: "11/drive/path/to/folder/__folder.json",
|
||||
GRN: &object.GRN{
|
||||
TenantId: 11,
|
||||
Scope: models.ObjectStoreScopeDrive,
|
||||
UID: "path/to/folder",
|
||||
Kind: "folder",
|
||||
},
|
||||
}, {
|
||||
Key: "10/drive/path/to/file.png",
|
||||
GRN: &object.GRN{
|
||||
TenantId: 10,
|
||||
Scope: models.ObjectStoreScopeDrive,
|
||||
UID: "path/to/file",
|
||||
Kind: "png",
|
||||
},
|
||||
}, {
|
||||
Key: "10/entity/playlist/aaaaa", // ?.json better or not?
|
||||
GRN: &object.GRN{
|
||||
TenantId: 10,
|
||||
Scope: models.ObjectStoreScopeEntity,
|
||||
UID: "aaaaa",
|
||||
Kind: "playlist",
|
||||
},
|
||||
}}
|
||||
|
||||
for idx, check := range scenarios {
|
||||
testID := fmt.Sprintf("[%d] %s", idx, check.Key)
|
||||
|
||||
// Read the key from the GRN
|
||||
info, err = router.Route(ctx, check.GRN)
|
||||
if check.Error == "" {
|
||||
require.NoError(t, err, testID)
|
||||
} else {
|
||||
require.Error(t, err, testID)
|
||||
require.Equal(t, check.Error, err.Error(), testID)
|
||||
continue
|
||||
}
|
||||
// Check that the key matched
|
||||
require.Equal(t, check.Key, info.Key, testID)
|
||||
|
||||
// Now try to parse the same key again
|
||||
out, err := router.RouteFromKey(ctx, info.Key)
|
||||
require.NoError(t, err, testID)
|
||||
require.Equal(t, check.GRN, out.GRN, testID)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user