diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index 854cc570f49d6..c7f976a90f00e 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -654,6 +654,10 @@ "ImportPath": "k8s.io/apimachinery/pkg/api/meta", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apimachinery/pkg/api/meta/table", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apimachinery/pkg/api/resource", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -754,6 +758,10 @@ "ImportPath": "k8s.io/apimachinery/pkg/util/diff", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/duration", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apimachinery/pkg/util/errors", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/BUILD b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/BUILD index 6a982a5a3d88e..0a1a0a0cb86d9 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/BUILD +++ b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/BUILD @@ -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", diff --git a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go index f94bbf91f69d9..57fee68103ab9 100644 --- a/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go +++ b/staging/src/k8s.io/kube-aggregator/pkg/registry/apiservice/etcd/etcd.go @@ -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" @@ -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 {