Add a method for getting supported resources on a server

pull/6/head
Brendan Burns 2015-10-12 14:23:35 -07:00
parent b9c7cf43b2
commit 5afbf578b0
3 changed files with 173 additions and 0 deletions

View File

@ -52,6 +52,7 @@ type Interface interface {
ComponentStatusesInterface
SwaggerSchemaInterface
Extensions() ExtensionsInterface
ResourcesInterface
}
func (c *Client) ReplicationControllers(namespace string) ReplicationControllerInterface {
@ -119,6 +120,12 @@ type VersionInterface interface {
ServerAPIVersions() (*unversioned.APIVersions, error)
}
// ResourcesInterface has methods for obtaining supported resources on the API server
type ResourcesInterface interface {
SupportedResourcesForGroupVersion(groupVersion string) (*api.APIResourceList, error)
SupportedResources() (map[string]*api.APIResourceList, error)
}
// APIStatus is exposed by errors that can be converted to an api.Status object
// for finer grained details.
type APIStatus interface {
@ -145,6 +152,42 @@ func (c *Client) ServerVersion() (*version.Info, error) {
return &info, nil
}
// SupportedResourcesForGroupVersion retrieves the list of resources supported by the API server for a group version.
func (c *Client) SupportedResourcesForGroupVersion(groupVersion string) (*api.APIResourceList, error) {
var prefix string
if groupVersion == "v1" {
prefix = "/api"
} else {
prefix = "/apis"
}
body, err := c.Get().AbsPath(prefix, groupVersion).Do().Raw()
if err != nil {
return nil, err
}
resources := api.APIResourceList{}
if err := json.Unmarshal(body, &resources); err != nil {
return nil, err
}
return &resources, nil
}
// SupportedResources gets all supported resources for all group versions. The key in the map is an API groupVersion.
func (c *Client) SupportedResources() (map[string]*api.APIResourceList, error) {
apis, err := c.ServerAPIVersions()
if err != nil {
return nil, err
}
result := map[string]*api.APIResourceList{}
for _, groupVersion := range apis.Versions {
resources, err := c.SupportedResourcesForGroupVersion(groupVersion)
if err != nil {
return nil, err
}
result[groupVersion] = resources
}
return result, nil
}
// ServerAPIVersions retrieves and parses the list of API versions the server supports.
func (c *Client) ServerAPIVersions() (*unversioned.APIVersions, error) {
body, err := c.Get().UnversionedPath("").Do().Raw()

View File

@ -271,6 +271,105 @@ func TestGetServerVersion(t *testing.T) {
}
}
func TestGetServerResources(t *testing.T) {
stable := api.APIResourceList{
GroupVersion: "v1",
APIResources: []api.APIResource{
{"pods", true},
{"services", true},
{"namespaces", false},
},
}
beta := api.APIResourceList{
GroupVersion: "extensions/v1",
APIResources: []api.APIResource{
{"deployments", true},
{"ingress", true},
{"jobs", true},
},
}
tests := []struct {
resourcesList *api.APIResourceList
path string
request string
expectErr bool
}{
{
resourcesList: &stable,
path: "/api/v1",
request: "v1",
expectErr: false,
},
{
resourcesList: &beta,
path: "/apis/extensions/v1beta1",
request: "extensions/v1beta1",
expectErr: false,
},
{
resourcesList: &stable,
path: "/api/v1",
request: "foobar",
expectErr: true,
},
}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
var list interface{}
switch req.URL.Path {
case "/api/v1":
list = &stable
case "/apis/extensions/v1beta1":
list = &beta
case "/api":
list = &api.APIVersions{
Versions: []string{
"v1",
"extensions/v1beta1",
},
}
default:
t.Logf("unexpected request: %s", req.URL.Path)
w.WriteHeader(http.StatusNotFound)
return
}
output, err := json.Marshal(list)
if err != nil {
t.Errorf("unexpected encoding error: %v", err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(output)
}))
client := NewOrDie(&Config{Host: server.URL})
for _, test := range tests {
got, err := client.SupportedResourcesForGroupVersion(test.request)
if test.expectErr {
if err == nil {
t.Error("unexpected non-error")
}
continue
}
if err != nil {
t.Errorf("unexpected error: %v", err)
continue
}
if !reflect.DeepEqual(got, test.resourcesList) {
t.Errorf("expected:\n%v\ngot:\n%v\n", test.resourcesList, got)
}
}
resourceMap, err := client.SupportedResources()
if err != nil {
t.Errorf("unexpected error: %v", err)
}
for _, api := range []string{"v1", "extensions/v1beta1"} {
if _, found := resourceMap[api]; !found {
t.Errorf("missing expected api: %s", api)
}
}
}
func TestGetServerAPIVersions(t *testing.T) {
versions := []string{"v1", "v2", "v3"}
expect := unversioned.APIVersions{Versions: versions}

View File

@ -60,6 +60,8 @@ type Fake struct {
WatchReactionChain []WatchReactor
// ProxyReactionChain is the list of proxy reactors that will be attempted for every request in the order they are tried
ProxyReactionChain []ProxyReactor
Resources []api.APIResourceList
}
// Reactor is an interface to allow the composition of reaction functions.
@ -272,6 +274,35 @@ func (c *Fake) Extensions() client.ExtensionsInterface {
return &FakeExperimental{c}
}
func (c *Fake) SupportedResources() (map[string]*api.APIResourceList, error) {
action := ActionImpl{
Verb: "get",
Resource: "resources",
}
c.Invokes(action, nil)
result := map[string]*api.APIResourceList{}
for _, resource := range c.Resources {
result[resource.GroupVersion] = &api.APIResourceList{
APIResources: resource.APIResources,
}
}
return result, nil
}
func (c *Fake) SupportedResourcesForGroupVersion(version string) (*api.APIResourceList, error) {
action := ActionImpl{
Verb: "get",
Resource: "resource",
}
c.Invokes(action, nil)
for _, resource := range c.Resources {
if resource.GroupVersion == version {
return &resource, nil
}
}
return nil, nil
}
func (c *Fake) ServerVersion() (*version.Info, error) {
action := ActionImpl{}
action.Verb = "get"