Skip to content

Commit 7953338

Browse files
committed
Add kind to APIResource
1 parent 7ca0fa4 commit 7953338

File tree

6 files changed

+39
-8
lines changed

6 files changed

+39
-8
lines changed

pkg/api/rest/rest.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ type Storage interface {
5555
New() runtime.Object
5656
}
5757

58+
// KindProvider specifies a different kind for its API than for its internal storage. This is necessary for external
59+
// objects that are not compiled into the api server. For such objects, there is no in-memory representation for
60+
// the object, so they must be represented as generic objects (e.g. RawJSON), but when we present the object as part of
61+
// API discovery we want to present the specific kind, not the generic internal representation.
62+
type KindProvider interface {
63+
Kind() string
64+
}
65+
5866
// Lister is an object that can retrieve resources that match the provided field and label criteria.
5967
type Lister interface {
6068
// NewList returns an empty object that can be used with the List call.

pkg/api/unversioned/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ type APIResource struct {
339339
Name string `json:"name"`
340340
// namespaced indicates if a resource is namespaced or not.
341341
Namespaced bool `json:"namespaced"`
342+
// kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')
343+
Kind string `json:"kind"`
342344
}
343345

344346
// APIResourceList is a list of APIResource, it is used to expose the name of the

pkg/api/unversioned/types_swagger_doc_generated.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var map_APIResource = map[string]string{
5151
"": "APIResource specifies the name of a resource and whether it is namespaced.",
5252
"name": "name is the name of the resource.",
5353
"namespaced": "namespaced indicates if a resource is namespaced or not.",
54+
"kind": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
5455
}
5556

5657
func (APIResource) SwaggerDoc() map[string]string {

pkg/apiserver/api_installer.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
144144
}
145145
}
146146

147+
kind := fqKindToRegister.Kind
148+
147149
if fqKindToRegister.IsEmpty() {
148150
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)
149151
}
150-
kind := fqKindToRegister.Kind
151152

152153
versionedPtr, err := a.group.Creater.New(a.group.GroupVersion.WithKind(kind))
153154
if err != nil {
@@ -323,6 +324,14 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
323324
params := []*restful.Parameter{}
324325
actions := []action{}
325326

327+
var resourceKind string
328+
kindProvider, ok := storage.(rest.KindProvider)
329+
if ok {
330+
resourceKind = kindProvider.Kind()
331+
} else {
332+
resourceKind = fqKindToRegister.Kind
333+
}
334+
326335
var apiResource unversioned.APIResource
327336
// Get the list of actions for the given scope.
328337
switch scope.Name() {
@@ -340,6 +349,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
340349
}
341350
apiResource.Name = path
342351
apiResource.Namespaced = false
352+
apiResource.Kind = resourceKind
343353
namer := rootScopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath)}
344354

345355
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
@@ -382,6 +392,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
382392
}
383393
apiResource.Name = path
384394
apiResource.Namespaced = true
395+
apiResource.Kind = resourceKind
385396
namer := scopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath), false}
386397

387398
actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)

pkg/client/unversioned/client_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,17 @@ func TestGetServerResources(t *testing.T) {
131131
stable := unversioned.APIResourceList{
132132
GroupVersion: "v1",
133133
APIResources: []unversioned.APIResource{
134-
{"pods", true},
135-
{"services", true},
136-
{"namespaces", false},
134+
{"pods", true, "Pod"},
135+
{"services", true, "Service"},
136+
{"namespaces", false, "Namespace"},
137137
},
138138
}
139139
beta := unversioned.APIResourceList{
140140
GroupVersion: "extensions/v1",
141141
APIResources: []unversioned.APIResource{
142-
{"deployments", true},
143-
{"ingresses", true},
144-
{"jobs", true},
142+
{"deployments", true, "Deployment"},
143+
{"ingresses", true, "Ingress"},
144+
{"jobs", true, "Job"},
145145
},
146146
}
147147
tests := []struct {

pkg/registry/thirdpartyresourcedata/etcd/etcd.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
// REST implements a RESTStorage for ThirdPartyResourceDatas against etcd
3434
type REST struct {
3535
*etcdgeneric.Etcd
36+
kind string
3637
}
3738

3839
// 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
6465
Storage: storageInterface,
6566
}
6667

67-
return &REST{store}
68+
return &REST{
69+
Etcd: store,
70+
kind: kind,
71+
}
72+
}
73+
74+
// Implements the rest.KindProvider interface
75+
func (r *REST) Kind() string {
76+
return r.kind
6877
}

0 commit comments

Comments
 (0)