Skip to content

Commit

Permalink
Add kind to APIResource
Browse files Browse the repository at this point in the history
  • Loading branch information
brendandburns committed Jan 8, 2016
1 parent 7ca0fa4 commit 7953338
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 8 deletions.
8 changes: 8 additions & 0 deletions pkg/api/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ type Storage interface {
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.
type Lister interface {
// NewList returns an empty object that can be used with the List call.
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/unversioned/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ type APIResource struct {
Name string `json:"name"`
// namespaced indicates if a resource is namespaced or not.
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
Expand Down
1 change: 1 addition & 0 deletions pkg/api/unversioned/types_swagger_doc_generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var map_APIResource = map[string]string{
"": "APIResource specifies the name of a resource and whether it is namespaced.",
"name": "name is the name of the resource.",
"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 {
Expand Down
13 changes: 12 additions & 1 deletion pkg/apiserver/api_installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
}

kind := fqKindToRegister.Kind

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)
}
kind := fqKindToRegister.Kind

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

var resourceKind string
kindProvider, ok := storage.(rest.KindProvider)
if ok {
resourceKind = kindProvider.Kind()
} else {
resourceKind = fqKindToRegister.Kind
}

var apiResource unversioned.APIResource
// Get the list of actions for the given scope.
switch scope.Name() {
Expand All @@ -340,6 +349,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
}
apiResource.Name = path
apiResource.Namespaced = false
apiResource.Kind = resourceKind
namer := rootScopeNaming{scope, a.group.Linker, gpath.Join(a.prefix, itemPath)}

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

actions = appendIf(actions, action{"LIST", resourcePath, resourceParams, namer}, isLister)
Expand Down
12 changes: 6 additions & 6 deletions pkg/client/unversioned/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,17 @@ func TestGetServerResources(t *testing.T) {
stable := unversioned.APIResourceList{
GroupVersion: "v1",
APIResources: []unversioned.APIResource{
{"pods", true},
{"services", true},
{"namespaces", false},
{"pods", true, "Pod"},
{"services", true, "Service"},
{"namespaces", false, "Namespace"},
},
}
beta := unversioned.APIResourceList{
GroupVersion: "extensions/v1",
APIResources: []unversioned.APIResource{
{"deployments", true},
{"ingresses", true},
{"jobs", true},
{"deployments", true, "Deployment"},
{"ingresses", true, "Ingress"},
{"jobs", true, "Job"},
},
}
tests := []struct {
Expand Down
11 changes: 10 additions & 1 deletion pkg/registry/thirdpartyresourcedata/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
// REST implements a RESTStorage for ThirdPartyResourceDatas against etcd
type REST struct {
*etcdgeneric.Etcd
kind string
}

// NewREST returns a registry which will store ThirdPartyResourceData in the given helper
Expand Down Expand Up @@ -64,5 +65,13 @@ func NewREST(s storage.Interface, storageDecorator generic.StorageDecorator, gro
Storage: storageInterface,
}

return &REST{store}
return &REST{
Etcd: store,
kind: kind,
}
}

// Implements the rest.KindProvider interface
func (r *REST) Kind() string {
return r.kind
}

0 comments on commit 7953338

Please sign in to comment.