syntax = "proto3"; package object; option go_package = "./;object"; 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 string UID = 4; } // The canonical object/document data -- this represents the raw bytes and storage level metadata message RawObject { // Object identifier GRN GRN = 1; // Time in epoch milliseconds that the object was created int64 created_at = 2; // Time in epoch milliseconds that the object was updated int64 updated_at = 3; // Who created the object string created_by = 4; // Who updated the object string updated_by = 5; // Content Length int64 size = 6; // MD5 digest of the body string ETag = 7; // Raw bytes of the storage object. The kind will determine what is a valid payload bytes body = 8; // 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; // External location info ObjectOriginInfo origin = 10; } message ObjectOriginInfo { // NOTE: currently managed by the dashboard_provisioning table string source = 1; // Time in epoch milliseconds that the object was last synced with an external system (provisioning/git) int64 time = 2; } // Report error while working with objects // NOTE: real systems at scale will contain errors. message ObjectErrorInfo { // Match an error code registry? int64 code = 1; // Simple error display string message = 2; // Details encoded in JSON bytes details_json = 3; } // This is a subset of RawObject that does not include body or sync info message ObjectVersionInfo { // The version will change when the object is saved. It is not necessarily sortable string version = 1; // Time in epoch milliseconds that the object was updated int64 updated_at = 2; // Who updated the object string updated_by = 3; // Content Length int64 size = 4; // MD5 digest of the body string ETag = 5; // optional "save" or "commit" message // // NOTE: currently managed by the dashboard_version table, and will be returned from a "history" command string comment = 6; } //----------------------------------------------- // Get request/response //----------------------------------------------- message ReadObjectRequest { // Object identifier GRN GRN = 1; // Fetch an explicit version string version = 2; // Include the full body bytes bool with_body = 3; // Include derived summary metadata bool with_summary = 4; } message ReadObjectResponse { // Object details with the body removed RawObject object = 1; // Object summary as JSON bytes summary_json = 2; } //------------------------------------------------------ // Make many read requests at once (by Kind+ID+version) //------------------------------------------------------ message BatchReadObjectRequest { repeated ReadObjectRequest batch = 1; } message BatchReadObjectResponse { repeated ReadObjectResponse results = 1; } //----------------------------------------------- // Write request/response //----------------------------------------------- message WriteObjectRequest { // Object identifier GRN GRN = 1; // The raw object body bytes body = 2; // Message that can be seen when exploring object history string comment = 3; // Used for optimistic locking. If missing, the previous version will be replaced regardless string previous_version = 4; } // This operation is useful when syncing a resource from external sources // that have more accurate metadata information (git, or an archive). // This process can bypass the forced checks that message AdminWriteObjectRequest { // Object identifier GRN GRN = 1; // The raw object body bytes body = 2; // Message that can be seen when exploring object history string comment = 3; // Time in epoch milliseconds that the object was created // Optional, if 0 it will use the current time int64 created_at = 4; // Time in epoch milliseconds that the object was updated // Optional, if empty it will use the current user int64 updated_at = 5; // Who created the object // Optional, if 0 it will use the current time string created_by = 6; // Who updated the object // Optional, if empty it will use the current user string updated_by = 7; // An explicit version identifier // Optional, if set, this will overwrite/define an explicit version string version = 8; // 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; // 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; // Optionally define where the object came from string origin = 11; } message WriteObjectResponse { // Error info -- if exists, the save did not happen ObjectErrorInfo error = 1; // Object identifier GRN GRN = 2; // Object details with the body removed ObjectVersionInfo object = 3; // Object summary as JSON bytes summary_json = 4; // Status code Status status = 5; // Status enumeration enum Status { ERROR = 0; CREATED = 1; UPDATED = 2; UNCHANGED = 3; } } //----------------------------------------------- // Delete request/response //----------------------------------------------- message DeleteObjectRequest { // Object identifier GRN GRN = 1; // Used for optimistic locking. If missing, the previous version will be replaced regardless string previous_version = 3; } message DeleteObjectResponse { bool OK = 1; } //----------------------------------------------- // History request/response //----------------------------------------------- message ObjectHistoryRequest { // Object identifier GRN GRN = 1; // Maximum number of items to return int64 limit = 3; // Starting from the requested page string next_page_token = 5; } message ObjectHistoryResponse { // Object identifier GRN GRN = 1; // Object metadata without the raw bytes repeated ObjectVersionInfo versions = 2; // More results exist... pass this in the next request string next_page_token = 3; } //----------------------------------------------- // List request/response //----------------------------------------------- message ObjectSearchRequest { // Starting from the requested page (other query parameters must match!) string next_page_token = 1; // Maximum number of items to return int64 limit = 2; // Free text query string -- mileage may vary :) string query = 3; // limit to a specific kind (empty is all) repeated string kind = 4; // Limit results to items in a specific folder string folder = 5; // Must match all labels map labels = 6; // Sorting instructions `field ASC/DESC` repeated string sort = 7; // Return the full body in each payload bool with_body = 8; // Return the full body in each payload bool with_labels = 9; // Return the full body in each payload bool with_fields = 10; } // Search result metadata for each object message ObjectSearchResult { // Object identifier GRN GRN = 1; // The current veresion of this object string version = 2; // Content Length int64 size = 3; // Time in epoch milliseconds that the object was updated int64 updated_at = 4; // Who updated the object string updated_by = 5; // Optionally include the full object body bytes body = 6; //---------------------------------------- // Derived from body in the summary //---------------------------------------- // Always included string name = 7; // Always included string description = 8; // The structured labels map labels = 9; // Optionally include extracted JSON bytes fields_json = 10; // ObjectErrorInfo in json bytes error_json = 11; } message ObjectSearchResponse { repeated ObjectSearchResult results = 1; // More results exist... pass this in the next request string next_page_token = 2; } //----------------------------------------------- // Storage interface //----------------------------------------------- // The object store provides a basic CRUD (+watch eventually) interface for generic objects service ObjectStore { rpc Read(ReadObjectRequest) returns (ReadObjectResponse); rpc BatchRead(BatchReadObjectRequest) returns (BatchReadObjectResponse); rpc Write(WriteObjectRequest) returns (WriteObjectResponse); rpc Delete(DeleteObjectRequest) returns (DeleteObjectResponse); rpc History(ObjectHistoryRequest) returns (ObjectHistoryResponse); rpc Search(ObjectSearchRequest) returns (ObjectSearchResponse); // Ideally an additional search endpoint with more flexibility to limit what you actually care about // https://github.com/grafana/grafana-plugin-sdk-go/blob/main/proto/backend.proto#L129 // rpc SearchEX(ObjectSearchRequest) returns (DataResponse); // TEMPORARY... while we split this into a new service (see below) rpc AdminWrite(AdminWriteObjectRequest) returns (WriteObjectResponse); } // The admin service extends the basic object store interface, but provides // more explicit control that can support bulk operations like efficient git sync service ObjectStoreAdmin { rpc AdminWrite(AdminWriteObjectRequest) returns (WriteObjectResponse); }