mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 15:42:06 +08:00
152 lines
5.8 KiB
Go
152 lines
5.8 KiB
Go
package storage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"k8s.io/apimachinery/pkg/api/meta"
|
|
metatable "k8s.io/apimachinery/pkg/api/meta/table"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apiserver/pkg/registry/generic"
|
|
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
|
|
"k8s.io/apiserver/pkg/registry/rest"
|
|
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
|
|
|
"github.com/grafana/grafana/pkg/aggregator/apis/aggregation"
|
|
"github.com/grafana/grafana/pkg/aggregator/registry/dataplaneservice"
|
|
)
|
|
|
|
// REST implements a RESTStorage for Data Plane services.
|
|
type REST struct {
|
|
*genericregistry.Store
|
|
}
|
|
|
|
// NewREST returns a RESTStorage object that will work against Data Plane services.
|
|
func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST {
|
|
strategy := dataplaneservice.NewStrategy(scheme)
|
|
store := &genericregistry.Store{
|
|
NewFunc: func() runtime.Object { return &aggregation.DataPlaneService{} },
|
|
NewListFunc: func() runtime.Object { return &aggregation.DataPlaneServiceList{} },
|
|
PredicateFunc: dataplaneservice.MatchDataPlaneService,
|
|
DefaultQualifiedResource: aggregation.Resource("dataplaneservices"),
|
|
SingularQualifiedResource: aggregation.Resource("dataplaneservice"),
|
|
|
|
CreateStrategy: strategy,
|
|
UpdateStrategy: strategy,
|
|
DeleteStrategy: strategy,
|
|
ResetFieldsStrategy: strategy,
|
|
|
|
TableConvertor: rest.NewDefaultTableConvertor(aggregation.Resource("dataplaneservices")),
|
|
}
|
|
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: dataplaneservice.GetAttrs}
|
|
if err := store.CompleteWithOptions(options); err != nil {
|
|
panic(err) // TODO: Propagate error up
|
|
}
|
|
return &REST{store}
|
|
}
|
|
|
|
// Implement CategoriesProvider
|
|
var _ rest.CategoriesProvider = &REST{}
|
|
|
|
// Categories implements the CategoriesProvider interface. Returns a list of categories a resource is part of.
|
|
func (c *REST) Categories() []string {
|
|
return []string{"dataplane"}
|
|
}
|
|
|
|
var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
|
|
|
|
// ConvertToTable implements the TableConvertor interface for REST.
|
|
func (c *REST) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
|
table := &metav1.Table{
|
|
ColumnDefinitions: []metav1.TableColumnDefinition{
|
|
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
|
|
{Name: "Available", Type: "string", Description: "Whether this service is available."},
|
|
{Name: "Age", Type: "string", Description: swaggerMetadataDescriptions["creationTimestamp"]},
|
|
},
|
|
}
|
|
if m, err := meta.ListAccessor(obj); err == nil {
|
|
table.ResourceVersion = m.GetResourceVersion()
|
|
table.Continue = m.GetContinue()
|
|
table.RemainingItemCount = m.GetRemainingItemCount()
|
|
} else {
|
|
if m, err := meta.CommonAccessor(obj); err == nil {
|
|
table.ResourceVersion = m.GetResourceVersion()
|
|
}
|
|
}
|
|
|
|
var err error
|
|
table.Rows, err = metatable.MetaToTableRow(obj, func(obj runtime.Object, m metav1.Object, name, age string) ([]interface{}, error) {
|
|
svc := obj.(*aggregation.DataPlaneService)
|
|
status := string(aggregation.ConditionUnknown)
|
|
if condition := getCondition(svc.Status.Conditions, "Available"); condition != nil {
|
|
switch {
|
|
case condition.Status == aggregation.ConditionTrue:
|
|
status = string(condition.Status)
|
|
case len(condition.Reason) > 0:
|
|
status = fmt.Sprintf("%s (%s)", condition.Status, condition.Reason)
|
|
default:
|
|
status = string(condition.Status)
|
|
}
|
|
}
|
|
return []interface{}{name, status, age}, nil
|
|
})
|
|
return table, err
|
|
}
|
|
|
|
func getCondition(conditions []aggregation.DataPlaneServiceCondition, conditionType aggregation.DataPlaneServiceConditionType) *aggregation.DataPlaneServiceCondition {
|
|
for i, condition := range conditions {
|
|
if condition.Type == conditionType {
|
|
return &conditions[i]
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// NewStatusREST makes a RESTStorage for status that has more limited options.
|
|
// It is based on the original REST so that we can share the same underlying store
|
|
func NewStatusREST(scheme *runtime.Scheme, rest *REST) *StatusREST {
|
|
strategy := dataplaneservice.NewStatusStrategy(scheme)
|
|
statusStore := *rest.Store
|
|
statusStore.CreateStrategy = nil
|
|
statusStore.DeleteStrategy = nil
|
|
statusStore.UpdateStrategy = strategy
|
|
statusStore.ResetFieldsStrategy = strategy
|
|
return &StatusREST{store: &statusStore}
|
|
}
|
|
|
|
// StatusREST implements the REST endpoint for changing the status of an DataPlaneService.
|
|
type StatusREST struct {
|
|
store *genericregistry.Store
|
|
}
|
|
|
|
var _ = rest.Patcher(&StatusREST{})
|
|
|
|
// New creates a new DataPlaneService object.
|
|
func (r *StatusREST) New() runtime.Object {
|
|
return &aggregation.DataPlaneService{}
|
|
}
|
|
|
|
// Destroy cleans up resources on shutdown.
|
|
func (r *StatusREST) Destroy() {
|
|
// Given that underlying store is shared with REST,
|
|
// we don't destroy it here explicitly.
|
|
}
|
|
|
|
// Get retrieves the object from the storage. It is required to support Patch.
|
|
func (r *StatusREST) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
|
return r.store.Get(ctx, name, options)
|
|
}
|
|
|
|
// Update alters the status subset of an object.
|
|
func (r *StatusREST) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
|
|
// We are explicitly setting forceAllowCreate to false in the call to the underlying storage because
|
|
// subresources should never allow create on update.
|
|
return r.store.Update(ctx, name, objInfo, createValidation, updateValidation, false, options)
|
|
}
|
|
|
|
// GetResetFields implements rest.ResetFieldsStrategy
|
|
func (r *StatusREST) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Set {
|
|
return r.store.GetResetFields()
|
|
}
|