Skip to content

Commit

Permalink
Give APIServer pretty column output
Browse files Browse the repository at this point in the history
Simple server side render that prints the implementing service (if any)
and the available condition.

```
$ kubectl get apiservice
NAME                                   SERVICE                      AVAILABLE                 AGE
v1.                                    Local                        True                      10m
v1.apps                                Local                        True                      10m
v1.authentication.k8s.io               Local                        True                      10m
v2beta1.autoscaling                    Local                        True                      10m
v1beta1.metrics                        kube-system/metrics-server   False (DiscoveryFailed)   10m
```
  • Loading branch information
smarterclayton committed Aug 23, 2018
1 parent 5a16163 commit b06d4b7
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
8 changes: 8 additions & 0 deletions staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd",
importpath = "k8s.io/kube-aggregator/pkg/registry/apiservice/etcd",
deps = [
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ package etcd

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"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/generic"
genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
Expand Down Expand Up @@ -53,6 +57,60 @@ func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) *REST
return &REST{store}
}

var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()

func (c *REST) ConvertToTable(ctx context.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1beta1.Table, error) {
table := &metav1beta1.Table{
ColumnDefinitions: []metav1beta1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
{Name: "Service", Type: "string", Description: "The reference to the service that hosts this API endpoint."},
{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.SelfLink = m.GetSelfLink()
table.Continue = m.GetContinue()
} else {
if m, err := meta.CommonAccessor(obj); err == nil {
table.ResourceVersion = m.GetResourceVersion()
table.SelfLink = m.GetSelfLink()
}
}

var err error
table.Rows, err = metatable.MetaToTableRow(obj, func(obj runtime.Object, m metav1.Object, name, age string) ([]interface{}, error) {
svc := obj.(*apiregistration.APIService)
service := "Local"
if svc.Spec.Service != nil {
service = fmt.Sprintf("%s/%s", svc.Spec.Service.Namespace, svc.Spec.Service.Name)
}
status := string(apiregistration.ConditionUnknown)
if condition := getCondition(svc.Status.Conditions, "Available"); condition != nil {
switch {
case condition.Status == apiregistration.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, service, status, age}, nil
})
return table, err
}

func getCondition(conditions []apiregistration.APIServiceCondition, conditionType apiregistration.APIServiceConditionType) *apiregistration.APIServiceCondition {
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 {
Expand Down

0 comments on commit b06d4b7

Please sign in to comment.