mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
Merge pull request #19380 from brendandburns/apiresource
Auto commit by PR queue bot
This commit is contained in:
commit
5914deeac8
@ -55,6 +55,14 @@ type Storage interface {
|
|||||||
New() runtime.Object
|
New() runtime.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KindProvider specifies a different kind for its API than for its internal storage. This is necessary for external
|
||||||
|
// objects that are not compiled into the api server. For such objects, there is no in-memory representation for
|
||||||
|
// the object, so they must be represented as generic objects (e.g. RawJSON), but when we present the object as part of
|
||||||
|
// API discovery we want to present the specific kind, not the generic internal representation.
|
||||||
|
type KindProvider interface {
|
||||||
|
Kind() string
|
||||||
|
}
|
||||||
|
|
||||||
// Lister is an object that can retrieve resources that match the provided field and label criteria.
|
// Lister is an object that can retrieve resources that match the provided field and label criteria.
|
||||||
type Lister interface {
|
type Lister interface {
|
||||||
// NewList returns an empty object that can be used with the List call.
|
// NewList returns an empty object that can be used with the List call.
|
||||||
|
@ -339,6 +339,8 @@ type APIResource struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
// namespaced indicates if a resource is namespaced or not.
|
// namespaced indicates if a resource is namespaced or not.
|
||||||
Namespaced bool `json:"namespaced"`
|
Namespaced bool `json:"namespaced"`
|
||||||
|
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
|
||||||
|
Kind string `json:"kind"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
// APIResourceList is a list of APIResource, it is used to expose the name of the
|
||||||
|
@ -51,6 +51,7 @@ var map_APIResource = map[string]string{
|
|||||||
"": "APIResource specifies the name of a resource and whether it is namespaced.",
|
"": "APIResource specifies the name of a resource and whether it is namespaced.",
|
||||||
"name": "name is the name of the resource.",
|
"name": "name is the name of the resource.",
|
||||||
"namespaced": "namespaced indicates if a resource is namespaced or not.",
|
"namespaced": "namespaced indicates if a resource is namespaced or not.",
|
||||||
|
"kind": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (APIResource) SwaggerDoc() map[string]string {
|
func (APIResource) SwaggerDoc() map[string]string {
|
||||||
|
@ -152,10 +152,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kind := fqKindToRegister.Kind
|
||||||
|
|
||||||
if fqKindToRegister.IsEmpty() {
|
if fqKindToRegister.IsEmpty() {
|
||||||
return nil, fmt.Errorf("unable to locate fully qualified kind for %v: found %v when registering for %v", reflect.TypeOf(object), fqKinds, a.group.GroupVersion)
|
return nil, fmt.Errorf("unable to locate fully qualified kind for %v: found %v when registering for %v", reflect.TypeOf(object), fqKinds, a.group.GroupVersion)
|
||||||
}
|
}
|
||||||
kind := fqKindToRegister.Kind
|
|
||||||
|
|
||||||
versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(kind))
|
versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(kind))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -322,6 +323,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
params := []*restful.Parameter{}
|
params := []*restful.Parameter{}
|
||||||
actions := []action{}
|
actions := []action{}
|
||||||
|
|
||||||
|
var resourceKind string
|
||||||
|
kindProvider, ok := storage.(rest.KindProvider)
|
||||||
|
if ok {
|
||||||
|
resourceKind = kindProvider.Kind()
|
||||||
|
} else {
|
||||||
|
resourceKind = fqKindToRegister.Kind
|
||||||
|
}
|
||||||
|
|
||||||
var apiResource unversioned.APIResource
|
var apiResource unversioned.APIResource
|
||||||
// Get the list of actions for the given scope.
|
// Get the list of actions for the given scope.
|
||||||
switch scope.Name() {
|
switch scope.Name() {
|
||||||
@ -339,6 +348,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
}
|
}
|
||||||
apiResource.Name = path
|
apiResource.Name = path
|
||||||
apiResource.Namespaced = false
|
apiResource.Namespaced = false
|
||||||
|
apiResource.Kind = resourceKind
|
||||||
namer := rootScopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath)}
|
namer := rootScopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath)}
|
||||||
|
|
||||||
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
|
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
|
||||||
@ -381,6 +391,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
}
|
}
|
||||||
apiResource.Name = path
|
apiResource.Name = path
|
||||||
apiResource.Namespaced = true
|
apiResource.Namespaced = true
|
||||||
|
apiResource.Kind = resourceKind
|
||||||
namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false}
|
namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false}
|
||||||
|
|
||||||
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)
|
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)
|
||||||
|
@ -137,17 +137,17 @@ func TestGetServerResources(t *testing.T) {
|
|||||||
stable := unversioned.APIResourceList{
|
stable := unversioned.APIResourceList{
|
||||||
GroupVersion: "v1",
|
GroupVersion: "v1",
|
||||||
APIResources: []unversioned.APIResource{
|
APIResources: []unversioned.APIResource{
|
||||||
{"pods", true},
|
{"pods", true, "Pod"},
|
||||||
{"services", true},
|
{"services", true, "Service"},
|
||||||
{"namespaces", false},
|
{"namespaces", false, "Namespace"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
beta := unversioned.APIResourceList{
|
beta := unversioned.APIResourceList{
|
||||||
GroupVersion: "extensions/v1",
|
GroupVersion: "extensions/v1",
|
||||||
APIResources: []unversioned.APIResource{
|
APIResources: []unversioned.APIResource{
|
||||||
{"deployments", true},
|
{"deployments", true, "Deployment"},
|
||||||
{"ingresses", true},
|
{"ingresses", true, "Ingress"},
|
||||||
{"jobs", true},
|
{"jobs", true, "Job"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
// REST implements a RESTStorage for ThirdPartyResourceDatas against etcd
|
// REST implements a RESTStorage for ThirdPartyResourceDatas against etcd
|
||||||
type REST struct {
|
type REST struct {
|
||||||
*etcdgeneric.Etcd
|
*etcdgeneric.Etcd
|
||||||
|
kind string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewREST returns a registry which will store ThirdPartyResourceData in the given helper
|
// NewREST returns a registry which will store ThirdPartyResourceData in the given helper
|
||||||
@ -64,5 +65,13 @@ func NewREST(s storage.Interface, storageDecorator generic.StorageDecorator, gro
|
|||||||
Storage: storageInterface,
|
Storage: storageInterface,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &REST{store}
|
return &REST{
|
||||||
|
Etcd: store,
|
||||||
|
kind: kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements the rest.KindProvider interface
|
||||||
|
func (r *REST) Kind() string {
|
||||||
|
return r.kind
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user