From 708af7c626299b4f2212136fac4dbcf47cf50fb1 Mon Sep 17 00:00:00 2001 From: chengyumeng <792400644@qq.com> Date: Mon, 24 Dec 2018 15:12:21 +0800 Subject: [PATCH 1/4] frontend:add page and filter in kubernetes namespace on backend --- .../deployment/kube-deployment.component.ts | 2 +- .../namespace/kube-namespace.component.html | 2 ++ .../namespace/kube-namespace.component.ts | 10 +------ .../list-namespace.component.html | 15 +++++++--- .../list-namespace.component.ts | 8 ++--- .../kubernetes/kubernetes-list-resource.ts | 30 +++++++++++++++++++ .../base/kubernetes/kubernetes-resource.ts | 15 ++++++++-- .../shared/client/v1/kubernetes/namespace.ts | 14 ++++++++- 8 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 src/frontend/src/app/shared/base/kubernetes/kubernetes-list-resource.ts diff --git a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts index 670b6ee80..8a61e2323 100644 --- a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts +++ b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts @@ -95,7 +95,7 @@ export class KubeDeploymentComponent implements OnInit { if (cluster) { this.namespaceClient.list(cluster).subscribe( resp => { - this.namespaces = resp.data; + this.namespaces = resp.data.list; this.jumpTo(cluster); }, error => this.messageHandlerService.handleError(error) diff --git a/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.html b/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.html index 4c3cf3201..de0982eb4 100644 --- a/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.html +++ b/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.html @@ -19,6 +19,8 @@ (delete)="onDeleteResourceEvent($event)" (detail)="onEditResourceEvent($event)" (edit)="onEditResourceEvent($event)" + [page]="pageState.page" + (paginate)="retrieveResource($event)" > diff --git a/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.ts b/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.ts index 80685490e..b16121739 100644 --- a/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.ts +++ b/src/frontend/src/app/admin/kubernetes/namespace/kube-namespace.component.ts @@ -53,15 +53,7 @@ export class KubeNamespaceComponent extends KubernetesResource implements OnInit this.jumpToHref(data[0].name); return; } - if (this.cluster) { - this.namespaceClient.list(this.cluster).subscribe( - resp => { - this.resources = resp.data; - this.jumpToHref(this.cluster); - }, - error => this.messageHandlerService.handleError(error) - ); - } + this.retrieveResource(); }, error => this.messageHandlerService.handleError(error) ); diff --git a/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.html b/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.html index 42ec049e0..c54029793 100644 --- a/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.html +++ b/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.html @@ -1,15 +1,15 @@ - + 名称 - + 状态 - + 创建时间 @@ -23,5 +23,12 @@ {{namespace.objectMeta.name}} {{ namespace.status }} {{namespace.objectMeta.creationTimestamp | relativeTime}} - + + + + diff --git a/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.ts b/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.ts index 95a2ae2c4..f2706eb7a 100644 --- a/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.ts +++ b/src/frontend/src/app/admin/kubernetes/namespace/list-namespace/list-namespace.component.ts @@ -1,5 +1,6 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { NamespaceList } from '../../../../shared/model/v1/namespace-list'; +import { KubernetesListResource } from '../../../../shared/base/kubernetes/kubernetes-list-resource'; @Component({ @@ -8,13 +9,14 @@ import { NamespaceList } from '../../../../shared/model/v1/namespace-list'; styleUrls: ['./list-namespace.component.scss'] }) -export class ListNamespaceComponent implements OnInit, OnDestroy { +export class ListNamespaceComponent extends KubernetesListResource implements OnInit, OnDestroy { @Input() resources: NamespaceList[]; @Input() showState: object; @Output() detail = new EventEmitter(); constructor() { + super(); } ngOnInit() { @@ -23,7 +25,5 @@ export class ListNamespaceComponent implements OnInit, OnDestroy { ngOnDestroy() { } - onDetailEvent(obj: any) { - this.detail.emit(obj); - } + } diff --git a/src/frontend/src/app/shared/base/kubernetes/kubernetes-list-resource.ts b/src/frontend/src/app/shared/base/kubernetes/kubernetes-list-resource.ts new file mode 100644 index 000000000..824bf3c89 --- /dev/null +++ b/src/frontend/src/app/shared/base/kubernetes/kubernetes-list-resource.ts @@ -0,0 +1,30 @@ +import { EventEmitter, Input, Output } from '@angular/core'; +import { State } from '@clr/angular'; +import { NamespaceList } from '../../model/v1/namespace-list'; +import { Page } from '../../page/page-state'; + +export class KubernetesListResource { + state: State; + currentPage = 1; + + @Input() page: Page; + + @Output() paginate = new EventEmitter(); + @Output() detail = new EventEmitter(); + + onDetailEvent(obj: any) { + this.detail.emit(obj); + } + + refresh(state: State) { + this.state = state; + this.paginate.emit(state); + } + + pageSizeChange(pageSize: number) { + this.state.page.to = pageSize - 1; + this.state.page.size = pageSize; + this.currentPage = 1; + this.paginate.emit(this.state); + } +} diff --git a/src/frontend/src/app/shared/base/kubernetes/kubernetes-resource.ts b/src/frontend/src/app/shared/base/kubernetes/kubernetes-resource.ts index d4896f1df..e326b3818 100644 --- a/src/frontend/src/app/shared/base/kubernetes/kubernetes-resource.ts +++ b/src/frontend/src/app/shared/base/kubernetes/kubernetes-resource.ts @@ -5,12 +5,15 @@ import { AceEditorComponent } from '../../ace-editor/ace-editor.component'; import { AuthService } from '../../auth/auth.service'; import { ActivatedRoute, Router } from '@angular/router'; import { ClusterService } from '../../client/v1/cluster.service'; +import {PageState} from '../../page/page-state'; +import {State} from '@clr/angular'; export class KubernetesResource { listResourceComponent: any; aceEditorModal: AceEditorComponent; showState: object; + pageState: PageState = new PageState(); cluster: string; clusters: Array; @@ -67,12 +70,18 @@ export class KubernetesResource { } } - retrieveResource(): void { + retrieveResource(state?: State): void { + if (state) { + this.pageState = PageState.fromState(state, {totalPage: this.pageState.page.totalPage, totalCount: this.pageState.page.totalCount}); + } if (this.cluster) { - this.resourceClient.list(this.cluster) + this.resourceClient.listPage(this.pageState, this.cluster) .subscribe( response => { - this.resources = response.data; + const data = response.data; + this.resources = data.list; + this.pageState.page.totalPage = data.totalPage; + this.pageState.page.totalCount = data.totalCount; }, error => this.messageHandlerService.handleError(error) ); diff --git a/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts b/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts index 0735c2689..4b6cdeb8f 100644 --- a/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts +++ b/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts @@ -2,6 +2,8 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { HttpClient, HttpParams } from '@angular/common/http'; import { KubeNamespace } from '../../../model/v1/kubernetes/namespace'; +import {PageState} from '../../../page/page-state'; +import {BaseClient} from './base-client'; @Injectable() export class NamespaceClient { @@ -9,8 +11,18 @@ export class NamespaceClient { } list(cluster: string): Observable { + // for list all in one page + let params = new HttpParams(); + params = params.set('pageSize', 102410241024 + ''); + return this.http + .get(`/api/v1/kubernetes/namespaces/clusters/${cluster}`, {params: params}) + .catch(error => Observable.throw(error)); + } + + listPage(pageState: PageState, cluster: string): Observable { + const params = BaseClient.buildParam(pageState); return this.http - .get(`/api/v1/kubernetes/namespaces/clusters/${cluster}`) + .get(`/api/v1/kubernetes/namespaces/clusters/${cluster}`, {params: params}) .catch(error => Observable.throw(error)); } From 15269b45f35d13c4755eb6496e700dd764a4e2c7 Mon Sep 17 00:00:00 2001 From: chengyumeng <792400644@qq.com> Date: Mon, 24 Dec 2018 15:44:10 +0800 Subject: [PATCH 2/4] backend:list k8s namespace by page --- .../kubernetes/namespace/namespace.go | 3 ++- src/backend/resources/namespace/common.go | 17 +++++++++++++++++ src/backend/resources/namespace/list.go | 13 +++++++++++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/backend/controllers/kubernetes/namespace/namespace.go b/src/backend/controllers/kubernetes/namespace/namespace.go index d442da6da..8a887c1be 100644 --- a/src/backend/controllers/kubernetes/namespace/namespace.go +++ b/src/backend/controllers/kubernetes/namespace/namespace.go @@ -37,11 +37,12 @@ func (c *KubeNamespaceController) Prepare() { // @Success 200 {object} common.Page success // @router /clusters/:cluster [get] func (c *KubeNamespaceController) List() { + param := c.BuildQueryParam() cluster := c.Ctx.Input.Param(":cluster") cli, err := client.Client(cluster) if err == nil { - result, err := namespace.GetNamespaceList(cli) + result, err := namespace.GetNamespacePage(cli, param) if err != nil { logs.Error("list kubernetes namespaces error.", cluster, err) c.HandleError(err) diff --git a/src/backend/resources/namespace/common.go b/src/backend/resources/namespace/common.go index 4445e8497..0bfcc69f9 100644 --- a/src/backend/resources/namespace/common.go +++ b/src/backend/resources/namespace/common.go @@ -2,6 +2,7 @@ package namespace import ( "github.com/Qihoo360/wayne/src/backend/resources/common" + "github.com/Qihoo360/wayne/src/backend/resources/dataselector" "k8s.io/api/core/v1" ) @@ -18,3 +19,19 @@ func toNamespace(namespace *v1.Namespace) *Namespace { return result } + +type NamespaceCell Namespace + +func (cell NamespaceCell) GetProperty(name dataselector.PropertyName) dataselector.ComparableValue { + switch name { + case dataselector.NameProperty: + return dataselector.StdComparableString(cell.ObjectMeta.Name) + case dataselector.CreationTimestampProperty: + return dataselector.StdComparableTime(cell.ObjectMeta.CreationTimestamp.Time) + case dataselector.NamespaceProperty: + return dataselector.StdComparableString(cell.ObjectMeta.Namespace) + default: + // if name is not supported then just return a constant dummy value, sort will have no effect. + return nil + } +} diff --git a/src/backend/resources/namespace/list.go b/src/backend/resources/namespace/list.go index 3a07f595a..b8840904c 100644 --- a/src/backend/resources/namespace/list.go +++ b/src/backend/resources/namespace/list.go @@ -1,12 +1,14 @@ package namespace import ( + "github.com/Qihoo360/wayne/src/backend/common" + "github.com/Qihoo360/wayne/src/backend/resources/dataselector" "k8s.io/api/core/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) -func GetNamespaceList(cli *kubernetes.Clientset) ([]Namespace, error) { +func GetNamespacePage(cli *kubernetes.Clientset, q *common.QueryParam) (*common.Page, error) { kubeNamespaces, err := cli.CoreV1().Namespaces().List(metaV1.ListOptions{}) if err != nil { return nil, err @@ -17,8 +19,15 @@ func GetNamespaceList(cli *kubernetes.Clientset) ([]Namespace, error) { for i := 0; i < len(kubeNamespaces.Items); i++ { namespaces = append(namespaces, *toNamespace(&kubeNamespaces.Items[i])) } + return dataselector.DataSelectPage(toCells(namespaces), q), nil +} - return namespaces, nil +func toCells(ns []Namespace) []dataselector.DataCell { + cells := make([]dataselector.DataCell, len(ns)) + for i := range ns { + cells[i] = NamespaceCell(ns[i]) + } + return cells } func GetNamespace(cli *kubernetes.Clientset, namespace string) (*v1.Namespace, error) { From bd774af0b4457cf55278a49ff5b7c4c3e6d6d14e Mon Sep 17 00:00:00 2001 From: chengyumeng <792400644@qq.com> Date: Thu, 27 Dec 2018 17:21:35 +0800 Subject: [PATCH 3/4] backend: add list namespace name API --- .../kubernetes/namespace/namespace.go | 25 ++++++++++++++++++- src/backend/resources/namespace/list.go | 14 +++++++++++ ...Router_controllers_kubernetes_namespace.go | 8 ++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/backend/controllers/kubernetes/namespace/namespace.go b/src/backend/controllers/kubernetes/namespace/namespace.go index 8a887c1be..dd514752c 100644 --- a/src/backend/controllers/kubernetes/namespace/namespace.go +++ b/src/backend/controllers/kubernetes/namespace/namespace.go @@ -24,6 +24,7 @@ type KubeNamespaceController struct { func (c *KubeNamespaceController) URLMapping() { c.Mapping("Resources", c.Resources) c.Mapping("List", c.List) + c.Mapping("GetNames", c.GetNames) } func (c *KubeNamespaceController) Prepare() { @@ -32,7 +33,7 @@ func (c *KubeNamespaceController) Prepare() { } // @Title List namespace -// @Description get all namespace +// @Description get all namespace by page // @Param cluster path string true "the cluster name" // @Success 200 {object} common.Page success // @router /clusters/:cluster [get] @@ -54,6 +55,28 @@ func (c *KubeNamespaceController) List() { } } +// @Title List all namespace name +// @Description get all namespace name +// @Param cluster path string true "the cluster name" +// @router /clusters/:cluster/names [get] +func (c *KubeNamespaceController) GetNames() { + cluster := c.Ctx.Input.Param(":cluster") + + cli, err := client.Client(cluster) + if err == nil { + result, err := namespace.GetAllNamespaceName(cli) + if err != nil { + logs.Error("list all kubernetes namespace names error.", cluster, err) + c.HandleError(err) + return + } + c.Success(result) + } else { + c.AbortBadRequestFormat("Cluster") + } + +} + // @Title Get namespace info // @Description get one namespace detail // @Param cluster path string true "the cluster name" diff --git a/src/backend/resources/namespace/list.go b/src/backend/resources/namespace/list.go index b8840904c..6b3eb2d3c 100644 --- a/src/backend/resources/namespace/list.go +++ b/src/backend/resources/namespace/list.go @@ -22,6 +22,20 @@ func GetNamespacePage(cli *kubernetes.Clientset, q *common.QueryParam) (*common. return dataselector.DataSelectPage(toCells(namespaces), q), nil } +func GetAllNamespaceName(cli *kubernetes.Clientset) ([]string, error) { + kubeNamespaces, err := cli.CoreV1().Namespaces().List(metaV1.ListOptions{}) + if err != nil { + return nil, err + } + + namespaces := make([]string, 0) + + for _, ns := range kubeNamespaces.Items { + namespaces = append(namespaces, ns.Name) + } + return namespaces, nil +} + func toCells(ns []Namespace) []dataselector.DataCell { cells := make([]dataselector.DataCell, len(ns)) for i := range ns { diff --git a/src/backend/routers/commentsRouter_controllers_kubernetes_namespace.go b/src/backend/routers/commentsRouter_controllers_kubernetes_namespace.go index e87f3044e..4cda43704 100644 --- a/src/backend/routers/commentsRouter_controllers_kubernetes_namespace.go +++ b/src/backend/routers/commentsRouter_controllers_kubernetes_namespace.go @@ -55,4 +55,12 @@ func init() { MethodParams: param.Make(), Params: nil}) + beego.GlobalControllerRouter["github.com/Qihoo360/wayne/src/backend/controllers/kubernetes/namespace:KubeNamespaceController"] = append(beego.GlobalControllerRouter["github.com/Qihoo360/wayne/src/backend/controllers/kubernetes/namespace:KubeNamespaceController"], + beego.ControllerComments{ + Method: "GetNames", + Router: `/clusters/:cluster/names`, + AllowHTTPMethods: []string{"get"}, + MethodParams: param.Make(), + Params: nil}) + } From a27a5972a661605be516823b6482c48ddf1cc4af Mon Sep 17 00:00:00 2001 From: chengyumeng <792400644@qq.com> Date: Thu, 27 Dec 2018 17:22:59 +0800 Subject: [PATCH 4/4] frontend:list namespace names no pageSize --- .../deployment/kube-deployment.component.html | 4 ++-- .../deployment/kube-deployment.component.ts | 6 +++--- .../src/app/shared/client/v1/kubernetes/namespace.ts | 11 ++++------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.html b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.html index aa3d0c67f..03f8859c1 100644 --- a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.html +++ b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.html @@ -20,8 +20,8 @@ [(ngModel)]="namespace" name="namespace_name" (change)="retrieve()"> - diff --git a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts index 8a61e2323..d52a9bb19 100644 --- a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts +++ b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.component.ts @@ -46,7 +46,7 @@ export class KubeDeploymentComponent implements OnInit { showList: any[] = Array(); showState: object = showState; - namespaces: any; + namespaces: string[]; constructor(private breadcrumbService: BreadcrumbService, private deploymentClient: DeploymentClient, @@ -93,9 +93,9 @@ export class KubeDeploymentComponent implements OnInit { return; } if (cluster) { - this.namespaceClient.list(cluster).subscribe( + this.namespaceClient.getNames(cluster).subscribe( resp => { - this.namespaces = resp.data.list; + this.namespaces = resp.data; this.jumpTo(cluster); }, error => this.messageHandlerService.handleError(error) diff --git a/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts b/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts index 4b6cdeb8f..6bee83b6c 100644 --- a/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts +++ b/src/frontend/src/app/shared/client/v1/kubernetes/namespace.ts @@ -2,20 +2,17 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { HttpClient, HttpParams } from '@angular/common/http'; import { KubeNamespace } from '../../../model/v1/kubernetes/namespace'; -import {PageState} from '../../../page/page-state'; -import {BaseClient} from './base-client'; +import { PageState } from '../../../page/page-state'; +import { BaseClient } from './base-client'; @Injectable() export class NamespaceClient { constructor(private http: HttpClient) { } - list(cluster: string): Observable { - // for list all in one page - let params = new HttpParams(); - params = params.set('pageSize', 102410241024 + ''); + getNames(cluster: string): Observable { return this.http - .get(`/api/v1/kubernetes/namespaces/clusters/${cluster}`, {params: params}) + .get(`/api/v1/kubernetes/namespaces/clusters/${cluster}/names`) .catch(error => Observable.throw(error)); }