Unified storage: Add quotas app to apiserver (#114425)

* initial generation

* went through doc to add new resource

* added dummy kind so grafana will run

* added dummy handler and custom route

* fix app name

* gets custom route working - still a dummy route

* adds groupOverride to manifest

* adds quotas to grpc client and server

* WIP - trying to get api recognized - not working

* Gets route working

* fixes group and resource vars

* expects group and resource as separate params

* set content-type header on response

* removes Quotas kind and regens

* Update grafana-app-sdk to v0.48.5

* Update codegen

* updates manifest

* formatting

* updates grafana-app-sdk version to 0.48.5

* regen ResourceClient mocks

* adds tests

* remove commented code

* uncomment go mod tidy

* fix tests and make update workspace

* adds quotas app to codeowners

* formatting

* make gen-apps

* deletes temp file

* fix generated folder code

* make gofmt

* make gen-go

* make update-workspace

* add COPY apps/quotas to Dockerfile

* fix test mock

* fixes undefined NewFolderStatus()

* make gen-apps, and add func for NewFolderStatus

* make gen-apps again

* make update-workspace

* regen folder_object_gen.go

* gofmt

* fix linting

* apps/folder make update-workspace

* make gen-apps

* make gen-apps

* fixes enterprise_imports.go

* go get testcontainers

* adds feature toggle

* make update-workspace

* fix go mod

* fix another client mock

---------

Co-authored-by: Steve Simpson <steve@grafana.com>
This commit is contained in:
owensmallwood
2025-12-09 09:40:34 -06:00
committed by GitHub
co-authored by Steve Simpson
parent 297e886e1b
commit a3daf0e39d
47 changed files with 1758 additions and 149 deletions
+2 -1
View File
@@ -56,7 +56,8 @@ import (
_ "github.com/grafana/e2e"
_ "github.com/grafana/gofpdf"
_ "github.com/grafana/gomemcache/memcache"
_ "github.com/grafana/tempo/pkg/traceql"
_ "github.com/grafana/grafana/apps/alerting/alertenrichment/pkg/apis/alertenrichment/v1beta1"
_ "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1"
_ "github.com/grafana/tempo/pkg/traceql"
)
@@ -95,3 +95,7 @@ func (d *directResourceClient) BulkProcess(ctx context.Context, opts ...grpc.Cal
func (b *directResourceClient) RebuildIndexes(ctx context.Context, req *resourcepb.RebuildIndexesRequest, opts ...grpc.CallOption) (*resourcepb.RebuildIndexesResponse, error) {
return nil, fmt.Errorf("not implemented")
}
func (b *directResourceClient) GetQuotaUsage(ctx context.Context, req *resourcepb.QuotaUsageRequest, opts ...grpc.CallOption) (*resourcepb.QuotaUsageResponse, error) {
return nil, fmt.Errorf("not implemented")
}
@@ -1103,3 +1103,7 @@ func (m *MockClient) BulkProcess(ctx context.Context, opts ...grpc.CallOption) (
func (m *MockClient) UpdateIndex(ctx context.Context, reason string) error {
return nil
}
func (m *MockClient) GetQuotaUsage(ctx context.Context, req *resourcepb.QuotaUsageRequest, opts ...grpc.CallOption) (*resourcepb.QuotaUsageResponse, error) {
return nil, nil
}
@@ -284,3 +284,6 @@ func (m *MockClient) BulkProcess(ctx context.Context, opts ...grpc.CallOption) (
func (m *MockClient) UpdateIndex(ctx context.Context, reason string) error {
return nil
}
func (m *MockClient) GetQuotaUsage(ctx context.Context, in *resourcepb.QuotaUsageRequest, opts ...grpc.CallOption) (*resourcepb.QuotaUsageResponse, error) {
return nil, nil
}
+7
View File
@@ -3,6 +3,8 @@ package appregistry
import (
"context"
"github.com/grafana/grafana/pkg/registry/apps/quotas"
"github.com/open-feature/go-sdk/openfeature"
"k8s.io/client-go/rest"
"github.com/grafana/grafana-app-sdk/app"
@@ -44,12 +46,17 @@ func ProvideAppInstallers(
exampleAppInstaller *example.ExampleAppInstaller,
advisorAppInstaller *advisor.AdvisorAppInstaller,
alertingHistorianAppInstaller *historian.AlertingHistorianAppInstaller,
quotasAppInstaller *quotas.QuotasAppInstaller,
) []appsdkapiserver.AppInstaller {
featureClient := openfeature.NewDefaultClient()
installers := []appsdkapiserver.AppInstaller{
playlistAppInstaller,
pluginsApplInstaller,
exampleAppInstaller,
}
if featureClient.Boolean(context.Background(), featuremgmt.FlagKubernetesUnifiedStorageQuotas, false, openfeature.TransactionContext(context.Background())) {
installers = append(installers, quotasAppInstaller)
}
//nolint:staticcheck // not yet migrated to OpenFeature
if features.IsEnabledGlobally(featuremgmt.FlagKubernetesShortURLs) {
installers = append(installers, shorturlAppInstaller)
+3 -1
View File
@@ -3,6 +3,7 @@ package appregistry
import (
"testing"
"github.com/grafana/grafana/pkg/registry/apps/quotas"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/registry/apps/advisor"
@@ -27,6 +28,7 @@ func TestProvideAppInstallers_Table(t *testing.T) {
exampleAppInstaller := &example.ExampleAppInstaller{}
advisorAppInstaller := &advisor.AdvisorAppInstaller{}
historianAppInstaller := &historian.AlertingHistorianAppInstaller{}
quotasAppInstaller := &quotas.QuotasAppInstaller{}
tests := []struct {
name string
@@ -43,7 +45,7 @@ func TestProvideAppInstallers_Table(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
features := featuremgmt.WithFeatures(tt.flags...)
got := ProvideAppInstallers(features, playlistInstaller, pluginsInstaller, nil, tt.rulesInst, correlationsAppInstaller, notificationsAppInstaller, nil, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller, historianAppInstaller)
got := ProvideAppInstallers(features, playlistInstaller, pluginsInstaller, nil, tt.rulesInst, correlationsAppInstaller, notificationsAppInstaller, nil, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller, historianAppInstaller, quotasAppInstaller)
if tt.expectRulesApp {
require.Contains(t, got, tt.rulesInst)
} else {
+50
View File
@@ -0,0 +1,50 @@
package quotas
import (
"github.com/grafana/grafana/apps/quotas/pkg/apis"
"github.com/grafana/grafana/pkg/storage/unified/resource"
restclient "k8s.io/client-go/rest"
"github.com/grafana/grafana-app-sdk/app"
appsdkapiserver "github.com/grafana/grafana-app-sdk/k8s/apiserver"
"github.com/grafana/grafana-app-sdk/simple"
quotasapp "github.com/grafana/grafana/apps/quotas/pkg/app"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
)
var (
_ appsdkapiserver.AppInstaller = (*QuotasAppInstaller)(nil)
)
type QuotasAppInstaller struct {
appsdkapiserver.AppInstaller
cfg *setting.Cfg
}
func RegisterAppInstaller(
cfg *setting.Cfg,
features featuremgmt.FeatureToggles,
resourceClient resource.ResourceClient,
) (*QuotasAppInstaller, error) {
installer := &QuotasAppInstaller{
cfg: cfg,
}
specificConfig := &quotasapp.QuotasAppConfig{
ResourceClient: resourceClient,
}
provider := simple.NewAppProvider(apis.LocalManifest(), specificConfig, quotasapp.New)
appConfig := app.Config{
KubeConfig: restclient.Config{}, // this will be overridden by the installer's InitializeApp method
ManifestData: *apis.LocalManifest().ManifestData,
SpecificConfig: specificConfig,
}
i, err := appsdkapiserver.NewDefaultAppInstaller(provider, appConfig, apis.NewGoTypeAssociator())
if err != nil {
return nil, err
}
installer.AppInstaller = i
return installer, nil
}
+2
View File
@@ -2,6 +2,7 @@ package appregistry
import (
"github.com/google/wire"
"github.com/grafana/grafana/pkg/registry/apps/quotas"
"github.com/grafana/grafana/pkg/registry/apps/alerting/historian"
"github.com/grafana/grafana/pkg/registry/apps/alerting/notifications"
@@ -29,5 +30,6 @@ var WireSet = wire.NewSet(
historian.RegisterAppInstaller,
logsdrilldown.RegisterAppInstaller,
annotation.RegisterAppInstaller,
quotas.RegisterAppInstaller,
example.RegisterAppInstaller,
)
+11 -2
View File
@@ -89,6 +89,7 @@ import (
"github.com/grafana/grafana/pkg/registry/apps/logsdrilldown"
"github.com/grafana/grafana/pkg/registry/apps/playlist"
"github.com/grafana/grafana/pkg/registry/apps/plugins"
"github.com/grafana/grafana/pkg/registry/apps/quotas"
"github.com/grafana/grafana/pkg/registry/apps/shorturl"
"github.com/grafana/grafana/pkg/registry/backgroundsvcs"
"github.com/grafana/grafana/pkg/registry/usagestatssvcs"
@@ -824,7 +825,11 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
if err != nil {
return nil, err
}
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, appInstaller, shortURLAppInstaller, alertingRulesAppInstaller, correlationsAppInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller, alertingHistorianAppInstaller)
quotasAppInstaller, err := quotas.RegisterAppInstaller(cfg, featureToggles, resourceClient)
if err != nil {
return nil, err
}
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, appInstaller, shortURLAppInstaller, alertingRulesAppInstaller, correlationsAppInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller, alertingHistorianAppInstaller, quotasAppInstaller)
builderMetrics := builder.ProvideBuilderMetrics(registerer)
apiserverService, err := apiserver.ProvideService(cfg, featureToggles, routeRegisterImpl, tracingService, serverLockService, sqlStore, kvStore, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, pluginstoreService, dualwriteService, resourceClient, inlineSecureValueSupport, eventualRestConfigProvider, v, eventualRestConfigProvider, registerer, aggregatorRunner, v2, builderMetrics)
if err != nil {
@@ -1477,7 +1482,11 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
if err != nil {
return nil, err
}
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, appInstaller, shortURLAppInstaller, alertingRulesAppInstaller, correlationsAppInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller, alertingHistorianAppInstaller)
quotasAppInstaller, err := quotas.RegisterAppInstaller(cfg, featureToggles, resourceClient)
if err != nil {
return nil, err
}
v2 := appregistry.ProvideAppInstallers(featureToggles, playlistAppInstaller, appInstaller, shortURLAppInstaller, alertingRulesAppInstaller, correlationsAppInstaller, alertingNotificationsAppInstaller, logsDrilldownAppInstaller, annotationAppInstaller, exampleAppInstaller, advisorAppInstaller, alertingHistorianAppInstaller, quotasAppInstaller)
builderMetrics := builder.ProvideBuilderMetrics(registerer)
apiserverService, err := apiserver.ProvideService(cfg, featureToggles, routeRegisterImpl, tracingService, serverLockService, sqlStore, kvStore, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, pluginstoreService, dualwriteService, resourceClient, inlineSecureValueSupport, eventualRestConfigProvider, v, eventualRestConfigProvider, registerer, aggregatorRunner, v2, builderMetrics)
if err != nil {
+7
View File
@@ -414,6 +414,13 @@ var (
Owner: grafanaDataProSquad,
RequiresRestart: true,
},
{
Name: "kubernetesUnifiedStorageQuotas",
Description: "Adds support for Kubernetes unified storage quotas",
Stage: FeatureStageExperimental,
Owner: grafanaSearchAndStorageSquad,
RequiresRestart: true,
},
{
Name: "kubernetesLogsDrilldown",
Description: "Adds support for Kubernetes logs drilldown",
+1
View File
@@ -56,6 +56,7 @@ kubernetesShortURLs,experimental,@grafana/grafana-app-platform-squad,false,true,
useKubernetesShortURLsAPI,experimental,@grafana/sharing-squad,false,false,true
kubernetesAlertingRules,experimental,@grafana/alerting-squad,false,true,false
kubernetesCorrelations,experimental,@grafana/datapro,false,true,false
kubernetesUnifiedStorageQuotas,experimental,@grafana/search-and-storage,false,true,false
kubernetesLogsDrilldown,experimental,@grafana/observability-logs,false,true,false
kubernetesQueryCaching,experimental,@grafana/grafana-operator-experience-squad,false,true,false
dashboardDisableSchemaValidationV1,experimental,@grafana/grafana-app-platform-squad,false,false,false
1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
56 useKubernetesShortURLsAPI experimental @grafana/sharing-squad false false true
57 kubernetesAlertingRules experimental @grafana/alerting-squad false true false
58 kubernetesCorrelations experimental @grafana/datapro false true false
59 kubernetesUnifiedStorageQuotas experimental @grafana/search-and-storage false true false
60 kubernetesLogsDrilldown experimental @grafana/observability-logs false true false
61 kubernetesQueryCaching experimental @grafana/grafana-operator-experience-squad false true false
62 dashboardDisableSchemaValidationV1 experimental @grafana/grafana-app-platform-squad false false false
+4
View File
@@ -183,6 +183,10 @@ const (
// Adds support for Kubernetes correlations
FlagKubernetesCorrelations = "kubernetesCorrelations"
// FlagKubernetesUnifiedStorageQuotas
// Adds support for Kubernetes unified storage quotas
FlagKubernetesUnifiedStorageQuotas = "kubernetesUnifiedStorageQuotas"
// FlagKubernetesLogsDrilldown
// Adds support for Kubernetes logs drilldown
FlagKubernetesLogsDrilldown = "kubernetesLogsDrilldown"
+13
View File
@@ -2039,6 +2039,19 @@
"requiresRestart": true
}
},
{
"metadata": {
"name": "kubernetesUnifiedStorageQuotas",
"resourceVersion": "1764965198011",
"creationTimestamp": "2025-12-05T20:06:38Z"
},
"spec": {
"description": "Adds support for Kubernetes unified storage quotas",
"stage": "experimental",
"codeowner": "@grafana/search-and-storage",
"requiresRestart": true
}
},
{
"metadata": {
"name": "localeFormatPreference",
@@ -166,6 +166,7 @@ type resourceClientMock struct {
resourcepb.BulkStoreClient
resourcepb.BlobStoreClient
resourcepb.DiagnosticsClient
resourcepb.QuotasClient
}
// always return GRPC Unauthenticated code
+21
View File
@@ -587,6 +587,22 @@ message ResourceTableRow {
bytes object = 4;
}
message QuotaUsageRequest {
// Namespace (tenant)
ResourceKey key = 1;
}
message QuotaUsageResponse {
// Error details
ErrorResult error = 1;
// Current usage
int64 usage = 2;
// Current limit
int64 limit = 3;
}
// 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
@@ -631,3 +647,8 @@ service Diagnostics {
// Check if the service is healthy
rpc IsHealthy(HealthCheckRequest) returns (HealthCheckResponse);
}
service Quotas {
// Get current quota usage and limits
rpc GetQuotaUsage(QuotaUsageRequest) returns (QuotaUsageResponse);
}
+4
View File
@@ -39,6 +39,7 @@ type ResourceClient interface {
resourcepb.BulkStoreClient
resourcepb.BlobStoreClient
resourcepb.DiagnosticsClient
resourcepb.QuotasClient
}
// Internal implementation
@@ -49,6 +50,7 @@ type resourceClient struct {
resourcepb.BulkStoreClient
resourcepb.BlobStoreClient
resourcepb.DiagnosticsClient
resourcepb.QuotasClient
}
func NewResourceClient(conn, indexConn grpc.ClientConnInterface, cfg *setting.Cfg, features featuremgmt.FeatureToggles, tracer trace.Tracer) (ResourceClient, error) {
@@ -76,6 +78,7 @@ func newResourceClient(storageCc grpc.ClientConnInterface, indexCc grpc.ClientCo
BulkStoreClient: resourcepb.NewBulkStoreClient(storageCc),
BlobStoreClient: resourcepb.NewBlobStoreClient(storageCc),
DiagnosticsClient: resourcepb.NewDiagnosticsClient(storageCc),
QuotasClient: resourcepb.NewQuotasClient(storageCc),
}
}
@@ -102,6 +105,7 @@ func NewLocalResourceClient(server ResourceServer) ResourceClient {
&resourcepb.BlobStore_ServiceDesc,
&resourcepb.BulkStore_ServiceDesc,
&resourcepb.Diagnostics_ServiceDesc,
&resourcepb.Quotas_ServiceDesc,
} {
channel.RegisterService(
grpchan.InterceptServer(
@@ -394,6 +394,80 @@ func (_c *MockResourceClient_GetBlob_Call) RunAndReturn(run func(context.Context
return _c
}
// GetQuotaUsage provides a mock function with given fields: ctx, in, opts
func (_m *MockResourceClient) GetQuotaUsage(ctx context.Context, in *resourcepb.QuotaUsageRequest, opts ...grpc.CallOption) (*resourcepb.QuotaUsageResponse, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for GetQuotaUsage")
}
var r0 *resourcepb.QuotaUsageResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *resourcepb.QuotaUsageRequest, ...grpc.CallOption) (*resourcepb.QuotaUsageResponse, error)); ok {
return rf(ctx, in, opts...)
}
if rf, ok := ret.Get(0).(func(context.Context, *resourcepb.QuotaUsageRequest, ...grpc.CallOption) *resourcepb.QuotaUsageResponse); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*resourcepb.QuotaUsageResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *resourcepb.QuotaUsageRequest, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockResourceClient_GetQuotaUsage_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetQuotaUsage'
type MockResourceClient_GetQuotaUsage_Call struct {
*mock.Call
}
// GetQuotaUsage is a helper method to define mock.On call
// - ctx context.Context
// - in *resourcepb.QuotaUsageRequest
// - opts ...grpc.CallOption
func (_e *MockResourceClient_Expecter) GetQuotaUsage(ctx interface{}, in interface{}, opts ...interface{}) *MockResourceClient_GetQuotaUsage_Call {
return &MockResourceClient_GetQuotaUsage_Call{Call: _e.mock.On("GetQuotaUsage",
append([]interface{}{ctx, in}, opts...)...)}
}
func (_c *MockResourceClient_GetQuotaUsage_Call) Run(run func(ctx context.Context, in *resourcepb.QuotaUsageRequest, opts ...grpc.CallOption)) *MockResourceClient_GetQuotaUsage_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]grpc.CallOption, len(args)-2)
for i, a := range args[2:] {
if a != nil {
variadicArgs[i] = a.(grpc.CallOption)
}
}
run(args[0].(context.Context), args[1].(*resourcepb.QuotaUsageRequest), variadicArgs...)
})
return _c
}
func (_c *MockResourceClient_GetQuotaUsage_Call) Return(_a0 *resourcepb.QuotaUsageResponse, _a1 error) *MockResourceClient_GetQuotaUsage_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockResourceClient_GetQuotaUsage_Call) RunAndReturn(run func(context.Context, *resourcepb.QuotaUsageRequest, ...grpc.CallOption) (*resourcepb.QuotaUsageResponse, error)) *MockResourceClient_GetQuotaUsage_Call {
_c.Call.Return(run)
return _c
}
// GetStats provides a mock function with given fields: ctx, in, opts
func (_m *MockResourceClient) GetStats(ctx context.Context, in *resourcepb.ResourceStatsRequest, opts ...grpc.CallOption) (*resourcepb.ResourceStatsResponse, error) {
_va := make([]interface{}, len(opts))
+33
View File
@@ -41,6 +41,7 @@ type ResourceServer interface {
resourcepb.ManagedObjectIndexServer
resourcepb.BlobStoreServer
resourcepb.DiagnosticsServer
resourcepb.QuotasServer
}
type ListIterator interface {
@@ -1466,6 +1467,38 @@ func (s *server) PutBlob(ctx context.Context, req *resourcepb.PutBlobRequest) (*
return rsp, nil
}
func (s *server) GetQuotaUsage(ctx context.Context, req *resourcepb.QuotaUsageRequest) (*resourcepb.QuotaUsageResponse, error) {
if s.overridesService == nil {
return &resourcepb.QuotaUsageResponse{Error: &resourcepb.ErrorResult{
Message: "overrides service not configured on resource server",
Code: http.StatusNotImplemented,
}}, nil
}
nsr := NamespacedResource{
Namespace: req.Key.Namespace,
Group: req.Key.Group,
Resource: req.Key.Resource,
}
usage, err := s.backend.GetResourceStats(ctx, nsr, 0)
if err != nil {
return &resourcepb.QuotaUsageResponse{Error: AsErrorResult(err)}, nil
}
limit, err := s.overridesService.GetQuota(ctx, nsr)
if err != nil {
return &resourcepb.QuotaUsageResponse{Error: AsErrorResult(err)}, nil
}
// handle case where no resources exist yet - very unlikely but possible
rsp := &resourcepb.QuotaUsageResponse{Limit: int64(limit.Limit)}
if len(usage) <= 0 {
rsp.Usage = 0
} else {
rsp.Usage = usage[0].Count
}
return rsp, nil
}
func (s *server) getPartialObject(ctx context.Context, key *resourcepb.ResourceKey, rv int64) (utils.GrafanaMetaAccessor, *resourcepb.ErrorResult) {
if r := verifyRequestKey(key); r != nil {
return nil, r
@@ -5,6 +5,8 @@ import (
"encoding/json"
"errors"
"net/http"
"os"
"path/filepath"
"strings"
"sync"
"testing"
@@ -22,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
"github.com/grafana/grafana/pkg/util/scheduler"
)
@@ -614,3 +617,70 @@ func TestArtificialDelayAfterSuccessfulOperation(t *testing.T) {
check(t, false, &resourcepb.UpdateResponse{Error: AsErrorResult(errors.New("some error"))}, nil)
check(t, false, &resourcepb.DeleteResponse{Error: AsErrorResult(errors.New("some error"))}, nil)
}
func TestGetQuotaUsage(t *testing.T) {
ctx := context.Background()
t.Run("returns error when overrides service is not configured", func(t *testing.T) {
s := &server{
overridesService: nil,
log: log.NewNopLogger(),
}
resp, err := s.GetQuotaUsage(ctx, &resourcepb.QuotaUsageRequest{
Key: &resourcepb.ResourceKey{
Namespace: "stacks-123",
Group: "dashboard.grafana.app",
Resource: "dashboards",
},
})
require.NoError(t, err)
require.NotNil(t, resp.Error)
assert.Equal(t, int32(http.StatusNotImplemented), resp.Error.Code)
assert.Equal(t, "overrides service not configured on resource server", resp.Error.Message)
})
t.Run("returns usage and limit successfully", func(t *testing.T) {
// Create a temporary overrides config file
tmpFile := filepath.Join(t.TempDir(), "overrides.yaml")
content := `"123":
quotas:
dashboard.grafana.app/dashboards:
limit: 500
`
require.NoError(t, os.WriteFile(tmpFile, []byte(content), 0644))
// Create a real OverridesService with the temp file
overridesService, err := NewOverridesService(ctx, log.NewNopLogger(), prometheus.NewRegistry(), tracing.NewNoopTracerService(), ReloadOptions{
FilePath: tmpFile,
})
require.NoError(t, err)
require.NoError(t, overridesService.init(ctx))
defer func() {
_ = overridesService.stop(ctx)
}()
// Create a mock backend that returns resource stats (reusing mockStorageBackend from search_test.go)
mockBackend := &mockStorageBackend{
resourceStats: []ResourceStats{{Count: 42}},
}
s := &server{
backend: mockBackend,
overridesService: overridesService,
log: log.NewNopLogger(),
}
resp, err := s.GetQuotaUsage(ctx, &resourcepb.QuotaUsageRequest{
Key: &resourcepb.ResourceKey{
Namespace: "stacks-123",
Group: "dashboard.grafana.app",
Resource: "dashboards",
},
})
require.NoError(t, err)
require.Nil(t, resp.Error)
assert.Equal(t, int64(42), resp.Usage)
assert.Equal(t, int64(500), resp.Limit)
})
}
+249 -118
View File
@@ -2484,6 +2484,114 @@ func (x *ResourceTableRow) GetObject() []byte {
return nil
}
type QuotaUsageRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Namespace (tenant)
Key *ResourceKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *QuotaUsageRequest) Reset() {
*x = QuotaUsageRequest{}
mi := &file_resource_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *QuotaUsageRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*QuotaUsageRequest) ProtoMessage() {}
func (x *QuotaUsageRequest) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[30]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use QuotaUsageRequest.ProtoReflect.Descriptor instead.
func (*QuotaUsageRequest) Descriptor() ([]byte, []int) {
return file_resource_proto_rawDescGZIP(), []int{30}
}
func (x *QuotaUsageRequest) GetKey() *ResourceKey {
if x != nil {
return x.Key
}
return nil
}
type QuotaUsageResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Error details
Error *ErrorResult `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
// Current usage
Usage int64 `protobuf:"varint,2,opt,name=usage,proto3" json:"usage,omitempty"`
// Current limit
Limit int64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *QuotaUsageResponse) Reset() {
*x = QuotaUsageResponse{}
mi := &file_resource_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *QuotaUsageResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*QuotaUsageResponse) ProtoMessage() {}
func (x *QuotaUsageResponse) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[31]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use QuotaUsageResponse.ProtoReflect.Descriptor instead.
func (*QuotaUsageResponse) Descriptor() ([]byte, []int) {
return file_resource_proto_rawDescGZIP(), []int{31}
}
func (x *QuotaUsageResponse) GetError() *ErrorResult {
if x != nil {
return x.Error
}
return nil
}
func (x *QuotaUsageResponse) GetUsage() int64 {
if x != nil {
return x.Usage
}
return 0
}
func (x *QuotaUsageResponse) GetLimit() int64 {
if x != nil {
return x.Limit
}
return 0
}
type WatchEvent_Resource struct {
state protoimpl.MessageState `protogen:"open.v1"`
Version int64 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
@@ -2494,7 +2602,7 @@ type WatchEvent_Resource struct {
func (x *WatchEvent_Resource) Reset() {
*x = WatchEvent_Resource{}
mi := &file_resource_proto_msgTypes[30]
mi := &file_resource_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2506,7 +2614,7 @@ func (x *WatchEvent_Resource) String() string {
func (*WatchEvent_Resource) ProtoMessage() {}
func (x *WatchEvent_Resource) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[30]
mi := &file_resource_proto_msgTypes[32]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2553,7 +2661,7 @@ type BulkResponse_Summary struct {
func (x *BulkResponse_Summary) Reset() {
*x = BulkResponse_Summary{}
mi := &file_resource_proto_msgTypes[31]
mi := &file_resource_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2565,7 +2673,7 @@ func (x *BulkResponse_Summary) String() string {
func (*BulkResponse_Summary) ProtoMessage() {}
func (x *BulkResponse_Summary) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[31]
mi := &file_resource_proto_msgTypes[33]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2649,7 +2757,7 @@ type BulkResponse_Rejected struct {
func (x *BulkResponse_Rejected) Reset() {
*x = BulkResponse_Rejected{}
mi := &file_resource_proto_msgTypes[32]
mi := &file_resource_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2661,7 +2769,7 @@ func (x *BulkResponse_Rejected) String() string {
func (*BulkResponse_Rejected) ProtoMessage() {}
func (x *BulkResponse_Rejected) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[32]
mi := &file_resource_proto_msgTypes[34]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2718,7 +2826,7 @@ type ListManagedObjectsResponse_Item struct {
func (x *ListManagedObjectsResponse_Item) Reset() {
*x = ListManagedObjectsResponse_Item{}
mi := &file_resource_proto_msgTypes[33]
mi := &file_resource_proto_msgTypes[35]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2730,7 +2838,7 @@ func (x *ListManagedObjectsResponse_Item) String() string {
func (*ListManagedObjectsResponse_Item) ProtoMessage() {}
func (x *ListManagedObjectsResponse_Item) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[33]
mi := &file_resource_proto_msgTypes[35]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2801,7 +2909,7 @@ type CountManagedObjectsResponse_ResourceCount struct {
func (x *CountManagedObjectsResponse_ResourceCount) Reset() {
*x = CountManagedObjectsResponse_ResourceCount{}
mi := &file_resource_proto_msgTypes[34]
mi := &file_resource_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2813,7 +2921,7 @@ func (x *CountManagedObjectsResponse_ResourceCount) String() string {
func (*CountManagedObjectsResponse_ResourceCount) ProtoMessage() {}
func (x *CountManagedObjectsResponse_ResourceCount) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[34]
mi := &file_resource_proto_msgTypes[36]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -2886,7 +2994,7 @@ type ResourceTableColumnDefinition_Properties struct {
func (x *ResourceTableColumnDefinition_Properties) Reset() {
*x = ResourceTableColumnDefinition_Properties{}
mi := &file_resource_proto_msgTypes[35]
mi := &file_resource_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -2898,7 +3006,7 @@ func (x *ResourceTableColumnDefinition_Properties) String() string {
func (*ResourceTableColumnDefinition_Properties) ProtoMessage() {}
func (x *ResourceTableColumnDefinition_Properties) ProtoReflect() protoreflect.Message {
mi := &file_resource_proto_msgTypes[35]
mi := &file_resource_proto_msgTypes[37]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -3320,68 +3428,85 @@ var file_resource_proto_rawDesc = string([]byte{
0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2a, 0x49,
0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43,
0x41, 0x54, 0x45, 0x44, 0x5f, 0x4e, 0x6f, 0x74, 0x4f, 0x6c, 0x64, 0x65, 0x72, 0x54, 0x68, 0x61,
0x6e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45,
0x44, 0x5f, 0x45, 0x78, 0x61, 0x63, 0x74, 0x10, 0x01, 0x2a, 0x4d, 0x0a, 0x16, 0x52, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63,
0x68, 0x56, 0x32, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00,
0x12, 0x09, 0x0a, 0x05, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45,
0x78, 0x61, 0x63, 0x74, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x4f, 0x6c, 0x64,
0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x10, 0x03, 0x32, 0xed, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x52, 0x65,
0x61, 0x64, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65,
0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3b, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b,
0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74,
0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x37, 0x0a, 0x05, 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x14, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63,
0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x32, 0x4b, 0x0a, 0x09, 0x42, 0x75, 0x6c, 0x6b,
0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x72, 0x6f,
0x63, 0x65, 0x73, 0x73, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x28, 0x01, 0x32, 0xd9, 0x01, 0x0a, 0x12, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x62, 0x0a, 0x13,
0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43,
0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63,
0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65,
0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x5f, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a,
0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67,
0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x32, 0x57, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73,
0x12, 0x48, 0x0a, 0x09, 0x49, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x1c, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43,
0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65,
0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61,
0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x74, 0x6f,
0x72, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2f, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3c,
0x0a, 0x11, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x6d, 0x0a, 0x12,
0x51, 0x75, 0x6f, 0x74, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72,
0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12,
0x14, 0x0a, 0x05, 0x75, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
0x75, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03,
0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x2a, 0x49, 0x0a, 0x14, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61,
0x74, 0x63, 0x68, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45,
0x44, 0x5f, 0x4e, 0x6f, 0x74, 0x4f, 0x6c, 0x64, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x10, 0x00,
0x12, 0x14, 0x0a, 0x10, 0x44, 0x45, 0x50, 0x52, 0x45, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x45,
0x78, 0x61, 0x63, 0x74, 0x10, 0x01, 0x2a, 0x4d, 0x0a, 0x16, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x56, 0x32,
0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a,
0x05, 0x55, 0x6e, 0x73, 0x65, 0x74, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x78, 0x61, 0x63,
0x74, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x4f, 0x6c, 0x64, 0x65, 0x72, 0x54,
0x68, 0x61, 0x6e, 0x10, 0x03, 0x32, 0xed, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12,
0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b,
0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65,
0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x05,
0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76,
0x65, 0x6e, 0x74, 0x30, 0x01, 0x32, 0x4b, 0x0a, 0x09, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x6f,
0x72, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73,
0x73, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x6c,
0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x28, 0x01, 0x32, 0xd9, 0x01, 0x0a, 0x12, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x62, 0x0a, 0x13, 0x43, 0x6f, 0x75,
0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73,
0x12, 0x24, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e,
0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62,
0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a,
0x12, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65,
0x63, 0x74, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c,
0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f,
0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x57,
0x0a, 0x0b, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x48, 0x0a,
0x09, 0x49, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x1c, 0x2e, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63,
0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x54, 0x0a, 0x06, 0x51, 0x75, 0x6f, 0x74, 0x61,
0x73, 0x12, 0x4a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x55, 0x73, 0x61,
0x67, 0x65, 0x12, 0x1b, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x51, 0x75,
0x6f, 0x74, 0x61, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x1c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x51, 0x75, 0x6f, 0x74, 0x61,
0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3b, 0x5a,
0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66,
0x61, 0x6e, 0x61, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2f,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
})
var (
@@ -3397,7 +3522,7 @@ func file_resource_proto_rawDescGZIP() []byte {
}
var file_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 7)
var file_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 36)
var file_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 38)
var file_resource_proto_goTypes = []any{
(ResourceVersionMatch)(0), // 0: resource.ResourceVersionMatch
(ResourceVersionMatchV2)(0), // 1: resource.ResourceVersionMatchV2
@@ -3436,12 +3561,14 @@ var file_resource_proto_goTypes = []any{
(*ResourceTable)(nil), // 34: resource.ResourceTable
(*ResourceTableColumnDefinition)(nil), // 35: resource.ResourceTableColumnDefinition
(*ResourceTableRow)(nil), // 36: resource.ResourceTableRow
(*WatchEvent_Resource)(nil), // 37: resource.WatchEvent.Resource
(*BulkResponse_Summary)(nil), // 38: resource.BulkResponse.Summary
(*BulkResponse_Rejected)(nil), // 39: resource.BulkResponse.Rejected
(*ListManagedObjectsResponse_Item)(nil), // 40: resource.ListManagedObjectsResponse.Item
(*CountManagedObjectsResponse_ResourceCount)(nil), // 41: resource.CountManagedObjectsResponse.ResourceCount
(*ResourceTableColumnDefinition_Properties)(nil), // 42: resource.ResourceTableColumnDefinition.Properties
(*QuotaUsageRequest)(nil), // 37: resource.QuotaUsageRequest
(*QuotaUsageResponse)(nil), // 38: resource.QuotaUsageResponse
(*WatchEvent_Resource)(nil), // 39: resource.WatchEvent.Resource
(*BulkResponse_Summary)(nil), // 40: resource.BulkResponse.Summary
(*BulkResponse_Rejected)(nil), // 41: resource.BulkResponse.Rejected
(*ListManagedObjectsResponse_Item)(nil), // 42: resource.ListManagedObjectsResponse.Item
(*CountManagedObjectsResponse_ResourceCount)(nil), // 43: resource.CountManagedObjectsResponse.ResourceCount
(*ResourceTableColumnDefinition_Properties)(nil), // 44: resource.ResourceTableColumnDefinition.Properties
}
var file_resource_proto_depIdxs = []int32{
10, // 0: resource.ErrorResult.details:type_name -> resource.ErrorDetails
@@ -3465,51 +3592,55 @@ var file_resource_proto_depIdxs = []int32{
9, // 18: resource.ListResponse.error:type_name -> resource.ErrorResult
21, // 19: resource.WatchRequest.options:type_name -> resource.ListOptions
3, // 20: resource.WatchEvent.type:type_name -> resource.WatchEvent.Type
37, // 21: resource.WatchEvent.resource:type_name -> resource.WatchEvent.Resource
37, // 22: resource.WatchEvent.previous:type_name -> resource.WatchEvent.Resource
39, // 21: resource.WatchEvent.resource:type_name -> resource.WatchEvent.Resource
39, // 22: resource.WatchEvent.previous:type_name -> resource.WatchEvent.Resource
7, // 23: resource.BulkRequest.key:type_name -> resource.ResourceKey
4, // 24: resource.BulkRequest.action:type_name -> resource.BulkRequest.Action
9, // 25: resource.BulkResponse.error:type_name -> resource.ErrorResult
38, // 26: resource.BulkResponse.summary:type_name -> resource.BulkResponse.Summary
39, // 27: resource.BulkResponse.rejected:type_name -> resource.BulkResponse.Rejected
40, // 28: resource.ListManagedObjectsResponse.items:type_name -> resource.ListManagedObjectsResponse.Item
40, // 26: resource.BulkResponse.summary:type_name -> resource.BulkResponse.Summary
41, // 27: resource.BulkResponse.rejected:type_name -> resource.BulkResponse.Rejected
42, // 28: resource.ListManagedObjectsResponse.items:type_name -> resource.ListManagedObjectsResponse.Item
9, // 29: resource.ListManagedObjectsResponse.error:type_name -> resource.ErrorResult
41, // 30: resource.CountManagedObjectsResponse.items:type_name -> resource.CountManagedObjectsResponse.ResourceCount
43, // 30: resource.CountManagedObjectsResponse.items:type_name -> resource.CountManagedObjectsResponse.ResourceCount
9, // 31: resource.CountManagedObjectsResponse.error:type_name -> resource.ErrorResult
5, // 32: resource.HealthCheckResponse.status:type_name -> resource.HealthCheckResponse.ServingStatus
35, // 33: resource.ResourceTable.columns:type_name -> resource.ResourceTableColumnDefinition
36, // 34: resource.ResourceTable.rows:type_name -> resource.ResourceTableRow
6, // 35: resource.ResourceTableColumnDefinition.type:type_name -> resource.ResourceTableColumnDefinition.ColumnType
42, // 36: resource.ResourceTableColumnDefinition.properties:type_name -> resource.ResourceTableColumnDefinition.Properties
44, // 36: resource.ResourceTableColumnDefinition.properties:type_name -> resource.ResourceTableColumnDefinition.Properties
7, // 37: resource.ResourceTableRow.key:type_name -> resource.ResourceKey
7, // 38: resource.BulkResponse.Rejected.key:type_name -> resource.ResourceKey
4, // 39: resource.BulkResponse.Rejected.action:type_name -> resource.BulkRequest.Action
7, // 40: resource.ListManagedObjectsResponse.Item.object:type_name -> resource.ResourceKey
18, // 41: resource.ResourceStore.Read:input_type -> resource.ReadRequest
12, // 42: resource.ResourceStore.Create:input_type -> resource.CreateRequest
14, // 43: resource.ResourceStore.Update:input_type -> resource.UpdateRequest
16, // 44: resource.ResourceStore.Delete:input_type -> resource.DeleteRequest
22, // 45: resource.ResourceStore.List:input_type -> resource.ListRequest
24, // 46: resource.ResourceStore.Watch:input_type -> resource.WatchRequest
26, // 47: resource.BulkStore.BulkProcess:input_type -> resource.BulkRequest
30, // 48: resource.ManagedObjectIndex.CountManagedObjects:input_type -> resource.CountManagedObjectsRequest
28, // 49: resource.ManagedObjectIndex.ListManagedObjects:input_type -> resource.ListManagedObjectsRequest
32, // 50: resource.Diagnostics.IsHealthy:input_type -> resource.HealthCheckRequest
19, // 51: resource.ResourceStore.Read:output_type -> resource.ReadResponse
13, // 52: resource.ResourceStore.Create:output_type -> resource.CreateResponse
15, // 53: resource.ResourceStore.Update:output_type -> resource.UpdateResponse
17, // 54: resource.ResourceStore.Delete:output_type -> resource.DeleteResponse
23, // 55: resource.ResourceStore.List:output_type -> resource.ListResponse
25, // 56: resource.ResourceStore.Watch:output_type -> resource.WatchEvent
27, // 57: resource.BulkStore.BulkProcess:output_type -> resource.BulkResponse
31, // 58: resource.ManagedObjectIndex.CountManagedObjects:output_type -> resource.CountManagedObjectsResponse
29, // 59: resource.ManagedObjectIndex.ListManagedObjects:output_type -> resource.ListManagedObjectsResponse
33, // 60: resource.Diagnostics.IsHealthy:output_type -> resource.HealthCheckResponse
51, // [51:61] is the sub-list for method output_type
41, // [41:51] is the sub-list for method input_type
41, // [41:41] is the sub-list for extension type_name
41, // [41:41] is the sub-list for extension extendee
0, // [0:41] is the sub-list for field type_name
7, // 38: resource.QuotaUsageRequest.key:type_name -> resource.ResourceKey
9, // 39: resource.QuotaUsageResponse.error:type_name -> resource.ErrorResult
7, // 40: resource.BulkResponse.Rejected.key:type_name -> resource.ResourceKey
4, // 41: resource.BulkResponse.Rejected.action:type_name -> resource.BulkRequest.Action
7, // 42: resource.ListManagedObjectsResponse.Item.object:type_name -> resource.ResourceKey
18, // 43: resource.ResourceStore.Read:input_type -> resource.ReadRequest
12, // 44: resource.ResourceStore.Create:input_type -> resource.CreateRequest
14, // 45: resource.ResourceStore.Update:input_type -> resource.UpdateRequest
16, // 46: resource.ResourceStore.Delete:input_type -> resource.DeleteRequest
22, // 47: resource.ResourceStore.List:input_type -> resource.ListRequest
24, // 48: resource.ResourceStore.Watch:input_type -> resource.WatchRequest
26, // 49: resource.BulkStore.BulkProcess:input_type -> resource.BulkRequest
30, // 50: resource.ManagedObjectIndex.CountManagedObjects:input_type -> resource.CountManagedObjectsRequest
28, // 51: resource.ManagedObjectIndex.ListManagedObjects:input_type -> resource.ListManagedObjectsRequest
32, // 52: resource.Diagnostics.IsHealthy:input_type -> resource.HealthCheckRequest
37, // 53: resource.Quotas.GetQuotaUsage:input_type -> resource.QuotaUsageRequest
19, // 54: resource.ResourceStore.Read:output_type -> resource.ReadResponse
13, // 55: resource.ResourceStore.Create:output_type -> resource.CreateResponse
15, // 56: resource.ResourceStore.Update:output_type -> resource.UpdateResponse
17, // 57: resource.ResourceStore.Delete:output_type -> resource.DeleteResponse
23, // 58: resource.ResourceStore.List:output_type -> resource.ListResponse
25, // 59: resource.ResourceStore.Watch:output_type -> resource.WatchEvent
27, // 60: resource.BulkStore.BulkProcess:output_type -> resource.BulkResponse
31, // 61: resource.ManagedObjectIndex.CountManagedObjects:output_type -> resource.CountManagedObjectsResponse
29, // 62: resource.ManagedObjectIndex.ListManagedObjects:output_type -> resource.ListManagedObjectsResponse
33, // 63: resource.Diagnostics.IsHealthy:output_type -> resource.HealthCheckResponse
38, // 64: resource.Quotas.GetQuotaUsage:output_type -> resource.QuotaUsageResponse
54, // [54:65] is the sub-list for method output_type
43, // [43:54] is the sub-list for method input_type
43, // [43:43] is the sub-list for extension type_name
43, // [43:43] is the sub-list for extension extendee
0, // [0:43] is the sub-list for field type_name
}
func init() { file_resource_proto_init() }
@@ -3524,9 +3655,9 @@ func file_resource_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_resource_proto_rawDesc), len(file_resource_proto_rawDesc)),
NumEnums: 7,
NumMessages: 36,
NumMessages: 38,
NumExtensions: 0,
NumServices: 4,
NumServices: 5,
},
GoTypes: file_resource_proto_goTypes,
DependencyIndexes: file_resource_proto_depIdxs,
@@ -709,3 +709,94 @@ var Diagnostics_ServiceDesc = grpc.ServiceDesc{
Streams: []grpc.StreamDesc{},
Metadata: "resource.proto",
}
const (
Quotas_GetQuotaUsage_FullMethodName = "/resource.Quotas/GetQuotaUsage"
)
// QuotasClient is the client API for Quotas service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type QuotasClient interface {
// Get current quota usage and limits
GetQuotaUsage(ctx context.Context, in *QuotaUsageRequest, opts ...grpc.CallOption) (*QuotaUsageResponse, error)
}
type quotasClient struct {
cc grpc.ClientConnInterface
}
func NewQuotasClient(cc grpc.ClientConnInterface) QuotasClient {
return &quotasClient{cc}
}
func (c *quotasClient) GetQuotaUsage(ctx context.Context, in *QuotaUsageRequest, opts ...grpc.CallOption) (*QuotaUsageResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(QuotaUsageResponse)
err := c.cc.Invoke(ctx, Quotas_GetQuotaUsage_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// QuotasServer is the server API for Quotas service.
// All implementations should embed UnimplementedQuotasServer
// for forward compatibility
type QuotasServer interface {
// Get current quota usage and limits
GetQuotaUsage(context.Context, *QuotaUsageRequest) (*QuotaUsageResponse, error)
}
// UnimplementedQuotasServer should be embedded to have forward compatible implementations.
type UnimplementedQuotasServer struct {
}
func (UnimplementedQuotasServer) GetQuotaUsage(context.Context, *QuotaUsageRequest) (*QuotaUsageResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetQuotaUsage not implemented")
}
// UnsafeQuotasServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to QuotasServer will
// result in compilation errors.
type UnsafeQuotasServer interface {
mustEmbedUnimplementedQuotasServer()
}
func RegisterQuotasServer(s grpc.ServiceRegistrar, srv QuotasServer) {
s.RegisterService(&Quotas_ServiceDesc, srv)
}
func _Quotas_GetQuotaUsage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QuotaUsageRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QuotasServer).GetQuotaUsage(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Quotas_GetQuotaUsage_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QuotasServer).GetQuotaUsage(ctx, req.(*QuotaUsageRequest))
}
return interceptor(ctx, in, info, handler)
}
// Quotas_ServiceDesc is the grpc.ServiceDesc for Quotas service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Quotas_ServiceDesc = grpc.ServiceDesc{
ServiceName: "resource.Quotas",
HandlerType: (*QuotasServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetQuotaUsage",
Handler: _Quotas_GetQuotaUsage_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "resource.proto",
}
+1
View File
@@ -312,6 +312,7 @@ func (s *service) starting(ctx context.Context) error {
resourcepb.RegisterManagedObjectIndexServer(srv, server)
resourcepb.RegisterBlobStoreServer(srv, server)
resourcepb.RegisterDiagnosticsServer(srv, server)
resourcepb.RegisterQuotasServer(srv, server)
grpc_health_v1.RegisterHealthServer(srv, healthService)
// register reflection service