mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			794 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Protocol Buffer
		
	
	
	
			
		
		
	
	
			794 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Protocol Buffer
		
	
	
	
| syntax = "proto3";
 | |
| package resource;
 | |
| 
 | |
| option go_package = "github.com/grafana/grafana/pkg/storage/unified/resource";
 | |
| 
 | |
| message ResourceKey {
 | |
|   // Namespace (tenant)
 | |
|   string namespace = 2;
 | |
|   // Resource Group
 | |
|   string group = 1;
 | |
|   // The resource type
 | |
|   string resource = 3;
 | |
|   // Resource identifier (unique within namespace+group+resource)
 | |
|   string name = 4;
 | |
| }
 | |
| 
 | |
| message ResourceWrapper {
 | |
|   // The resource version
 | |
|   int64 resource_version = 1;
 | |
| 
 | |
|   // Full kubernetes json bytes (although the resource version may not be accurate)
 | |
|   bytes value = 2;
 | |
| }
 | |
| 
 | |
| // Status structure is copied from:
 | |
| // https://github.com/kubernetes/apimachinery/blob/v0.30.1/pkg/apis/meta/v1/generated.proto#L979
 | |
| // However, this is only used for error handling, never for succesful results
 | |
| message ErrorResult {
 | |
|   // A human-readable description of the status of this operation.
 | |
|   // +optional
 | |
|   string message = 1;
 | |
| 
 | |
|   // A machine-readable description of why this operation is in the
 | |
|   // "Failure" status. If this value is empty there
 | |
|   // is no information available. A Reason clarifies an HTTP status
 | |
|   // code but does not override it.
 | |
|   // +optional
 | |
|   string reason = 2;
 | |
| 
 | |
|   // Extended data associated with the reason.  Each reason may define its
 | |
|   // own extended details. This field is optional and the data returned
 | |
|   // is not guaranteed to conform to any schema except that defined by
 | |
|   // the reason type.
 | |
|   // +optional
 | |
|   // +listType=atomic
 | |
|   ErrorDetails details = 3;
 | |
| 
 | |
|   // Suggested HTTP return code for this status, 0 if not set.
 | |
|   // +optional
 | |
|   int32 code = 4;
 | |
| }
 | |
| 
 | |
| // ErrorDetails is a set of additional properties that MAY be set by the
 | |
| // server to provide additional information about a response. The Reason
 | |
| // field of a Status object defines what attributes will be set. Clients
 | |
| // must ignore fields that do not match the defined type of each attribute,
 | |
| // and should assume that any attribute may be empty, invalid, or under
 | |
| // defined.
 | |
| message ErrorDetails {
 | |
|   // The name attribute of the resource associated with the status StatusReason
 | |
|   // (when there is a single name which can be described).
 | |
|   // +optional
 | |
|   string name = 1;
 | |
| 
 | |
|   // The group attribute of the resource associated with the status StatusReason.
 | |
|   // +optional
 | |
|   string group = 2;
 | |
| 
 | |
|   // The kind attribute of the resource associated with the status StatusReason.
 | |
|   // On some operations may differ from the requested resource Kind.
 | |
|   // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
 | |
|   // +optional
 | |
|   string kind = 3;
 | |
| 
 | |
|   // UID of the resource.
 | |
|   // (when there is a single resource which can be described).
 | |
|   // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids
 | |
|   // +optional
 | |
|   string uid = 6;
 | |
| 
 | |
|   // The Causes array includes more details associated with the StatusReason
 | |
|   // failure. Not all StatusReasons may provide detailed causes.
 | |
|   // +optional
 | |
|   // +listType=atomic
 | |
|   repeated ErrorCause causes = 4;
 | |
| 
 | |
|   // If specified, the time in seconds before the operation should be retried. Some errors may indicate
 | |
|   // the client must take an alternate action - for those errors this field may indicate how long to wait
 | |
|   // before taking the alternate action.
 | |
|   // +optional
 | |
|   int32 retryAfterSeconds = 5;
 | |
| }
 | |
| 
 | |
| message ErrorCause {
 | |
|   // A machine-readable description of the cause of the error. If this value is
 | |
|   // empty there is no information available.
 | |
|   string reason = 1;
 | |
|   // A human-readable description of the cause of the error.  This field may be
 | |
|   // presented as-is to a reader.
 | |
|   // +optional
 | |
|   string message = 2;
 | |
|   // The field of the resource that has caused this error, as named by its JSON
 | |
|   // serialization. May include dot and postfix notation for nested attributes.
 | |
|   // Arrays are zero-indexed.  Fields may appear more than once in an array of
 | |
|   // causes due to fields having multiple errors.
 | |
|   // Optional.
 | |
|   //
 | |
|   // Examples:
 | |
|   //   "name" - the field "name" on the current resource
 | |
|   //   "items[0].name" - the field "name" on the first array entry in "items"
 | |
|   // +optional
 | |
|   string field = 3;
 | |
| }
 | |
| 
 | |
| // ----------------------------------
 | |
| // CRUD Objects
 | |
| // ----------------------------------
 | |
| 
 | |
| message CreateRequest {
 | |
|   // Requires group+resource to be configuired
 | |
|   // If name is not set, a unique name will be generated
 | |
|   // The resourceVersion should not be set
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // The resource JSON.
 | |
|   bytes value = 2;
 | |
| }
 | |
| 
 | |
| message CreateResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // The updated resource version
 | |
|   int64 resource_version = 2;
 | |
| }
 | |
| 
 | |
| message UpdateRequest {
 | |
|   // Full key must be set
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // The current resource version
 | |
|   int64 resource_version = 2;
 | |
| 
 | |
|   // The resource JSON.
 | |
|   bytes value = 3;
 | |
| }
 | |
| 
 | |
| message UpdateResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // The updated resource version
 | |
|   int64 resource_version = 2;
 | |
| }
 | |
| 
 | |
| message DeleteRequest {
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // The current resource version
 | |
|   int64 resource_version = 2;
 | |
| 
 | |
|   // Preconditions: make sure the uid matches the current saved value
 | |
|   // +optional
 | |
|   string uid = 3;
 | |
| }
 | |
| 
 | |
| message DeleteResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // The resource version for the deletion marker
 | |
|   int64 resource_version = 2;
 | |
| }
 | |
| 
 | |
| message ReadRequest {
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // Optionally pick an explicit resource version
 | |
|   int64 resource_version = 2;
 | |
|   // Optionally decide to return the latest RV if deleted
 | |
|   bool include_deleted = 3;
 | |
| }
 | |
| 
 | |
| message ReadResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // The new resource version
 | |
|   int64 resource_version = 2;
 | |
| 
 | |
|   // The properties
 | |
|   bytes value = 3;
 | |
| }
 | |
| 
 | |
| // ----------------------------------
 | |
| // List Request/Response
 | |
| // ----------------------------------
 | |
| 
 | |
| // The label filtering requirements:
 | |
| // https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/labels/selector.go#L141
 | |
| message Requirement {
 | |
|   string key = 1;
 | |
|   string operator = 2; // See https://github.com/kubernetes/kubernetes/blob/v1.30.1/staging/src/k8s.io/apimachinery/pkg/selection/operator.go#L21
 | |
|   repeated string values = 3; // typically one value, but depends on the operator
 | |
| }
 | |
| 
 | |
| message ListOptions {
 | |
|   // Group+Namespace+Resource (not name)
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // (best effort) Match label
 | |
|   // Allowed to send more results than actually match because the filter will be applied
 | |
|   // to the results again in the client.  That time with the full field selector
 | |
|   repeated Requirement labels = 2;
 | |
| 
 | |
|   // (best effort) fields matcher
 | |
|   // Allowed to send more results than actually match because the filter will be applied
 | |
|   // to the results again in the client.  That time with the full field selector
 | |
|   repeated Requirement fields = 3;
 | |
| }
 | |
| 
 | |
| enum ResourceVersionMatch {
 | |
|   NotOlderThan = 0;
 | |
|   Exact = 1;
 | |
| }
 | |
| 
 | |
| message ListRequest {
 | |
|   enum Source {
 | |
|     STORE = 0; // the standard place
 | |
|     HISTORY = 1;
 | |
|     TRASH = 2;
 | |
|   }
 | |
| 
 | |
|   // Starting from the requested page (other query parameters must match!)
 | |
|   string next_page_token = 1;
 | |
| 
 | |
|   // The resource version
 | |
|   int64 resource_version = 2;
 | |
| 
 | |
|   // List options
 | |
|   ResourceVersionMatch version_match = 3;
 | |
| 
 | |
|   // Maximum number of items to return
 | |
|   // NOTE responses will also be limited by the response payload size
 | |
|   int64 limit = 4;
 | |
| 
 | |
|   // Filtering
 | |
|   ListOptions options = 5;
 | |
| 
 | |
|   // Select values from history or trash
 | |
|   Source source = 6;
 | |
| }
 | |
| 
 | |
| message ListResponse {
 | |
|   repeated ResourceWrapper items = 1;
 | |
| 
 | |
|   // When more results exist, pass this in the next request
 | |
|   string next_page_token = 2;
 | |
| 
 | |
|   // ResourceVersion of the list response
 | |
|   int64 resource_version = 3;
 | |
| 
 | |
|   // remainingItemCount is the number of subsequent items in the list which are not included in this
 | |
|   // list response. If the list request contained label or field selectors, then the number of
 | |
|   // remaining items is unknown and the field will be left unset and omitted during serialization.
 | |
|   // If the list is complete (either because it is not chunking or because this is the last chunk),
 | |
|   // then there are no more remaining items and this field will be left unset and omitted during
 | |
|   // serialization.
 | |
|   //
 | |
|   // The intended use of the remainingItemCount is *estimating* the size of a collection. Clients
 | |
|   // should not rely on the remainingItemCount to be set or to be exact.
 | |
|   // +optional
 | |
|   int64 remaining_item_count = 4; // 0 won't be set either (no next page token)
 | |
| 
 | |
|   // Error details
 | |
|   ErrorResult error = 5;
 | |
| }
 | |
| 
 | |
| message WatchRequest {
 | |
|   // ResourceVersion of last changes. Empty will default to full history
 | |
|   int64 since = 1;
 | |
| 
 | |
|   // Additional options
 | |
|   ListOptions options = 3;
 | |
| 
 | |
|   // Return initial events
 | |
|   bool send_initial_events = 4;
 | |
| 
 | |
|   // When done with initial events, send a bookmark event
 | |
|   bool allow_watch_bookmarks = 5;
 | |
| }
 | |
| 
 | |
| message WatchEvent {
 | |
|   enum Type {
 | |
|     UNKNOWN = 0;
 | |
|     ADDED = 1;
 | |
|     MODIFIED = 2;
 | |
|     DELETED = 3;
 | |
|     BOOKMARK = 4;
 | |
|     ERROR = 5;
 | |
|   }
 | |
| 
 | |
|   message Resource {
 | |
|     int64 version = 1;
 | |
|     bytes value = 2;
 | |
|   }
 | |
| 
 | |
|   // Timestamp the event was sent
 | |
|   int64 timestamp = 1;
 | |
| 
 | |
|   // Timestamp the event was sent
 | |
|   Type type = 2;
 | |
| 
 | |
|   // Resource version for the object
 | |
|   Resource resource = 3;
 | |
| 
 | |
|   // Previous resource version (for update+delete)
 | |
|   Resource previous = 4;
 | |
| }
 | |
| 
 | |
| // Get statistics across multiple resources
 | |
| // For these queries, we do not need authorization to see the actual values
 | |
| message ResourceStatsRequest {
 | |
|   // Namespace (tenant)
 | |
|   string namespace = 1;
 | |
| 
 | |
|   // An optional list of group/resource identifiers
 | |
|   // when empty, we assume searching across everything
 | |
|   // NOTE, this query may need to federate across a few storage instances
 | |
|   repeated string kinds = 2;
 | |
| 
 | |
|   // Limit the stats within a folder (not recursive!)
 | |
|   string folder = 3;
 | |
| }
 | |
| 
 | |
| message ResourceStatsResponse {
 | |
|   message Stats {
 | |
|     // Resource group
 | |
|     string group = 1;
 | |
|     // Resource name
 | |
|     string resource = 2;
 | |
|     // Number of items
 | |
|     int64 count = 3;
 | |
|   }
 | |
| 
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // All results exist within this key
 | |
|   repeated Stats stats = 2;
 | |
| }
 | |
| 
 | |
| // Search within a single resource
 | |
| message ResourceSearchRequest {
 | |
|   message Sort {
 | |
|     string field = 1;
 | |
|     bool desc = 2; // defaults to ascending
 | |
|   }
 | |
| 
 | |
|   message Facet {
 | |
|     string field = 1;
 | |
|     int64 limit = 2;
 | |
|     // For now, only term queries, eventually?
 | |
|     // numeric queries
 | |
|     // date queries
 | |
|   }
 | |
| 
 | |
|   // The key must include namespace + group + resource
 | |
|   ListOptions options = 1;
 | |
| 
 | |
|   // To search additional resource types, add additional keys to this list
 | |
|   // NOTE: queries will only support federation across kinds with common fields
 | |
|   repeated ResourceKey federated = 2;
 | |
| 
 | |
|   // When a query exists, it is parsed and used to influence
 | |
|   // query string for chosen implementation (currently just bleve)
 | |
|   // The score is only relevant when a query exists
 | |
|   string query = 3;
 | |
| 
 | |
|   // max results
 | |
|   int64 limit = 4;
 | |
| 
 | |
|   // where to start the query (eg, From)
 | |
|   int64 offset = 5;
 | |
| 
 | |
|   // sorting
 | |
|   repeated Sort sortBy = 6;
 | |
| 
 | |
|   // calculate field statistics
 | |
|   map<string,Facet> facet = 7;
 | |
| 
 | |
|   // the return fields (empty will return everything)
 | |
|   repeated string fields = 8;
 | |
| 
 | |
|   // explain each result (added to the each row)
 | |
|   bool explain = 9;
 | |
| 
 | |
|   bool is_deleted = 10;
 | |
| 
 | |
|   int64 page = 11;
 | |
| }
 | |
| 
 | |
| message ResourceSearchResponse {
 | |
|   message Facet {
 | |
|     string field = 1;
 | |
|     // The distinct terms
 | |
|     int64 total = 2;
 | |
|     // The number of documents that do *not* have this field
 | |
|     int64 missing = 3;
 | |
|     // Top term stats
 | |
|     repeated TermFacet terms = 4;
 | |
|     // numeric range
 | |
|     // date range facets
 | |
|   }
 | |
| 
 | |
|   message TermFacet {
 | |
|     string term = 1;
 | |
|     int64 count = 2;
 | |
|   }
 | |
| 
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // All results exist within this key
 | |
|   ResourceKey key = 2;
 | |
| 
 | |
|   // Query results
 | |
|   ResourceTable results = 3;
 | |
| 
 | |
|   // The total hit count
 | |
|   int64 total_hits = 4;
 | |
| 
 | |
|   // indicates how expensive was the query with respect to bytes read
 | |
|   double query_cost = 5;
 | |
| 
 | |
|   // maximum score across all fields
 | |
|   double max_score = 6;
 | |
| 
 | |
|   // Facet results
 | |
|   map<string,Facet> facet = 7;
 | |
| }
 | |
| 
 | |
| // List items within a resource type & repository name
 | |
| // Access control is managed above this request
 | |
| message ListRepositoryObjectsRequest {
 | |
|   // Starting from the requested page (other query parameters must match!)
 | |
|   string next_page_token = 1;
 | |
| 
 | |
|   // Namespace (tenant)
 | |
|   string namespace = 2;
 | |
| 
 | |
|   // The name of the repository
 | |
|   string name = 3;
 | |
| }
 | |
| 
 | |
| message ListRepositoryObjectsResponse {
 | |
|   message Item {
 | |
|     // The resource object key
 | |
|     ResourceKey object = 1;
 | |
| 
 | |
|     // Hash for the resource
 | |
|     string path = 2;
 | |
| 
 | |
|     // Verification hash from the origin
 | |
|     string hash = 3;
 | |
| 
 | |
|     // Change time from the origin
 | |
|     int64 time = 5;
 | |
| 
 | |
|     // Title inside the payload
 | |
|     string title = 6;
 | |
| 
 | |
|     // The name of the folder in metadata
 | |
|     string folder = 7;
 | |
|   }
 | |
| 
 | |
|   // Item iterator
 | |
|   repeated Item items = 1;
 | |
| 
 | |
|   // More results exist... pass this in the next request
 | |
|   string next_page_token = 2;
 | |
| 
 | |
|   // Error details
 | |
|   ErrorResult error = 3;
 | |
| }
 | |
| 
 | |
| // Count the items that exist with
 | |
| message CountRepositoryObjectsRequest {
 | |
|   // Namespace (tenant)
 | |
|   string namespace = 1;
 | |
| 
 | |
|   // The name of the repository
 | |
|   // empty to count across all repositories
 | |
|   string name = 2;
 | |
| }
 | |
| 
 | |
| // Count the items that exist with
 | |
| message CountRepositoryObjectsResponse {
 | |
|   message ResourceCount {
 | |
|     string repository = 1;
 | |
|     string group = 2;
 | |
|     string resource = 3;
 | |
|     int64 count = 4;
 | |
|   }
 | |
| 
 | |
|   // Resource counts
 | |
|   repeated ResourceCount items = 1;
 | |
| 
 | |
|   // Error details
 | |
|   ErrorResult error = 2;
 | |
| }
 | |
| 
 | |
| message HealthCheckRequest {
 | |
|   string service = 1;
 | |
| }
 | |
| 
 | |
| message HealthCheckResponse {
 | |
|   enum ServingStatus {
 | |
|     UNKNOWN = 0;
 | |
|     SERVING = 1;
 | |
|     NOT_SERVING = 2;
 | |
|     SERVICE_UNKNOWN = 3;  // Used only by the Watch method.
 | |
|   }
 | |
|   ServingStatus status = 1;
 | |
| }
 | |
| 
 | |
| // ResourceTable is a protobuf variation of the kubernetes Table object.
 | |
| // This format allows specifying a flexible set of columns related to a given resource
 | |
| message ResourceTable {
 | |
|   // Columns describes each column in the returned items array. The number of cells per row
 | |
|   // will always match the number of column definitions.
 | |
|   repeated ResourceTableColumnDefinition columns = 1;
 | |
| 
 | |
|   // rows is the list of items in the table.
 | |
|   repeated ResourceTableRow rows = 2;
 | |
| 
 | |
|   // When more results exist, pass this in the next request
 | |
|   string next_page_token = 3;
 | |
| 
 | |
|   // ResourceVersion of the list response
 | |
|   // +optional
 | |
|   int64 resource_version = 4;
 | |
| 
 | |
|   // remainingItemCount is the number of subsequent items in the list which are not included in this
 | |
|   // list response. If the list request contained label or field selectors, then the number of
 | |
|   // remaining items is unknown and the field will be left unset and omitted during serialization.
 | |
|   // If the list is complete (either because it is not chunking or because this is the last chunk),
 | |
|   // then there are no more remaining items and this field will be left unset and omitted during
 | |
|   // serialization.
 | |
|   //
 | |
|   // The intended use of the remainingItemCount is *estimating* the size of a collection. Clients
 | |
|   // should not rely on the remainingItemCount to be set or to be exact.
 | |
|   // +optional
 | |
|   int64 remaining_item_count = 5;
 | |
| }
 | |
| 
 | |
| // TableColumnDefinition contains information about a column returned in the Table.
 | |
| message ResourceTableColumnDefinition {
 | |
|   // See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types for more.
 | |
|   // When converted to a k8s Table, this will become two fields: type and format
 | |
|   enum ColumnType {
 | |
|     UNKNOWN_TYPE = 0;
 | |
|     STRING = 1;
 | |
|     BOOLEAN = 2;
 | |
|     INT32 = 3;
 | |
|     INT64 = 4;
 | |
|     FLOAT = 5;
 | |
|     DOUBLE = 6;
 | |
|     DATE = 7;
 | |
|     DATE_TIME = 8;
 | |
|     BINARY = 9;
 | |
|     OBJECT = 10; // map[string]any
 | |
|   }
 | |
| 
 | |
|   // These values are not part of standard k8s format
 | |
|   // however these are useful when indexing and analyzing results
 | |
|   message Properties {
 | |
|     // All values in this columns should be unique
 | |
|     bool unique_values = 1;
 | |
| 
 | |
|     // The string value is free text; using text analyzers is appropriate
 | |
|     bool free_text = 2;
 | |
| 
 | |
|     // The value(s) are reasonable to use for search refinement
 | |
|     // When indexing, these values would be good to add to an index
 | |
|     bool filterable = 3;
 | |
| 
 | |
|     // When true, every value should exist
 | |
|     // not_null with a nil default_value should be an error
 | |
|     bool not_null = 4;
 | |
| 
 | |
|     // When missing, this value can be used
 | |
|     bytes default_value = 5;
 | |
|   }
 | |
| 
 | |
|   // name is a human readable name for the column.
 | |
|   string name = 1;
 | |
| 
 | |
|   // Defines the column type.  In k8s, this will resolve into both the type and format fields
 | |
|   ColumnType type = 2;
 | |
| 
 | |
|   // The value is an array of given type
 | |
|   bool is_array = 3;
 | |
| 
 | |
|   // description is a human readable description of this column.
 | |
|   string description = 4;
 | |
| 
 | |
|   // Properties about this column (helpful for indexing and search)
 | |
|   Properties properties = 5;
 | |
| 
 | |
|   // priority is an integer defining the relative importance of this column compared to others. Lower
 | |
|   // numbers are considered higher priority. Columns that may be omitted in limited space scenarios
 | |
|   // should be given a higher priority.
 | |
|   int32 priority = 6;
 | |
| }
 | |
| 
 | |
| // TableRow is an individual row in a table.
 | |
| message ResourceTableRow {
 | |
|   // The resource referenced by this row
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // The resource version for the given values
 | |
|   int64 resource_version = 2;
 | |
| 
 | |
|   // Cells will be as wide as the column definitions array
 | |
|   // Numeric values will be encoded using big endian bytes
 | |
|   // All arrays will be JSON encoded
 | |
|   repeated bytes cells = 3;
 | |
| 
 | |
|   // This field may contains the additional information about each object based on the request.
 | |
|   // The value will be at least a partial object metadata, and perhaps the full object metadata.
 | |
|   // When this value exists, it should include both the key and the resource_version otherwise
 | |
|   // they may be lost in the conversion to k8s resource
 | |
|   // +optional
 | |
|   bytes object = 4;
 | |
| }
 | |
| 
 | |
| //----------------------------
 | |
| // Restore Support
 | |
| //----------------------------
 | |
| 
 | |
| message RestoreRequest {
 | |
|   // Full key must be set
 | |
|   ResourceKey key = 1;
 | |
| 
 | |
|   // The resource version to restore
 | |
|   int64 resource_version = 2;
 | |
| }
 | |
| 
 | |
| message RestoreResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // The updated resource version
 | |
|   int64 resource_version = 2;
 | |
| }
 | |
| 
 | |
| //----------------------------
 | |
| // Blob Support
 | |
| //----------------------------
 | |
| 
 | |
| message PutBlobRequest {
 | |
|   enum Method {
 | |
|     // Use the inline raw []byte
 | |
|     GRPC = 0;
 | |
| 
 | |
|     // Get a signed URL and PUT the value
 | |
|     HTTP = 1;
 | |
|   }
 | |
| 
 | |
|   // The resource that will use this blob
 | |
|   // NOTE: the name may not yet exist, but group+resource are required
 | |
|   ResourceKey resource = 1;
 | |
| 
 | |
|   // How to upload
 | |
|   Method method = 2;
 | |
| 
 | |
|   // Content type header
 | |
|   string content_type = 3;
 | |
| 
 | |
|   // Raw value to write
 | |
|   // Not valid when method == HTTP
 | |
|   bytes value = 4;
 | |
| }
 | |
| 
 | |
| message PutBlobResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // The blob uid.  This must be saved into the resource to support access
 | |
|   string uid = 2;
 | |
| 
 | |
|   // The URL where this value can be PUT
 | |
|   string url = 3;
 | |
| 
 | |
|   // Size of the uploaded blob
 | |
|   int64 size = 4;
 | |
| 
 | |
|   // Content hash used for an etag
 | |
|   string hash = 5;
 | |
| 
 | |
|   // Validated mimetype (from content_type)
 | |
|   string mime_type = 6;
 | |
| 
 | |
|   // Validated charset (from content_type)
 | |
|   string charset = 7;
 | |
| }
 | |
| 
 | |
| message GetBlobRequest {
 | |
|   ResourceKey resource = 1;
 | |
| 
 | |
|   // The new resource version
 | |
|   int64 resource_version = 2;
 | |
| 
 | |
|   // Do not return a pre-signed URL (when possible)
 | |
|   bool must_proxy_bytes = 3;
 | |
| }
 | |
| 
 | |
| message GetBlobResponse {
 | |
|   // Error details
 | |
|   ErrorResult error = 1;
 | |
| 
 | |
|   // (optional) When possible, the system will return a presigned URL
 | |
|   // that can be used to actually read the full blob+metadata
 | |
|   // When this is set, neither info nor value will be set
 | |
|   string url = 2;
 | |
| 
 | |
|   // Content type
 | |
|   string content_type = 3;
 | |
| 
 | |
|   // The raw object value
 | |
|   bytes value = 4;
 | |
| }
 | |
| 
 | |
| // This provides the CRUD+List+Watch support needed for a k8s apiserver
 | |
| // The semantics and behaviors of this service are constrained by kubernetes
 | |
| // This does not understand the resource schemas, only deals with json bytes
 | |
| // Clients should not use this interface directly; it is for use in API Servers
 | |
| service ResourceStore {
 | |
|   rpc Read(ReadRequest) returns (ReadResponse);
 | |
|   rpc Create(CreateRequest) returns (CreateResponse);
 | |
|   rpc Update(UpdateRequest) returns (UpdateResponse);
 | |
|   rpc Delete(DeleteRequest) returns (DeleteResponse);
 | |
|   rpc Restore(RestoreRequest) returns (RestoreResponse);
 | |
| 
 | |
|   // The results *may* include values that should not be returned to the user
 | |
|   // This will perform best-effort filtering to increase performace.
 | |
|   // NOTE: storage.Interface is ultimatly responsible for the final filtering
 | |
|   rpc List(ListRequest) returns (ListResponse);
 | |
| 
 | |
|   // The results *may* include values that should not be returned to the user
 | |
|   // This will perform best-effort filtering to increase performace.
 | |
|   // NOTE: storage.Interface is ultimatly responsible for the final filtering
 | |
|   rpc Watch(WatchRequest) returns (stream WatchEvent);
 | |
| }
 | |
| 
 | |
| // Unlike the ResourceStore, this service can be exposed to clients directly
 | |
| // It should be implemented with efficient indexes and does not need read-after-write semantics
 | |
| service ResourceIndex {
 | |
|   rpc Search(ResourceSearchRequest) returns (ResourceSearchResponse);
 | |
| 
 | |
|   // Get the resource stats
 | |
|   rpc GetStats(ResourceStatsRequest) returns (ResourceStatsResponse);
 | |
| }
 | |
| 
 | |
| // Query repository info from the search index.
 | |
| // Results access control is based on access to the repository *not* the items
 | |
| service RepositoryIndex {
 | |
|   // Describe how many resources of each type exist within a repository
 | |
|   rpc CountRepositoryObjects(CountRepositoryObjectsRequest) returns (CountRepositoryObjectsResponse);
 | |
| 
 | |
|   // List the resources of a specific kind within a repository
 | |
|   rpc ListRepositoryObjects(ListRepositoryObjectsRequest) returns (ListRepositoryObjectsResponse);
 | |
| }
 | |
| 
 | |
| service BlobStore {
 | |
|   // Upload a blob that will be saved in a resource
 | |
|   rpc PutBlob(PutBlobRequest) returns (PutBlobResponse);
 | |
| 
 | |
|   // Get blob contents.  When possible, this will return a signed URL
 | |
|   // For large payloads, signed URLs are required to avoid protobuf message size limits
 | |
|   rpc GetBlob(GetBlobRequest) returns (GetBlobResponse);
 | |
| 
 | |
|   // NOTE: there is no direct access to delete blobs
 | |
|   // >> cleanup will be managed via garbage collection or direct access to the underlying storage
 | |
| }
 | |
| 
 | |
| // Clients can use this service directly
 | |
| // NOTE: This is read only, and no read afer write guarantees
 | |
| service Diagnostics {
 | |
|   // Check if the service is healthy
 | |
|   rpc IsHealthy(HealthCheckRequest) returns (HealthCheckResponse);
 | |
| }
 |