Skip to content

Commit

Permalink
Merge pull request #254 from wilhelmguo/feature/add_kubernetes_pod_re…
Browse files Browse the repository at this point in the history
…source

Feature/add kubernetes pod resource
  • Loading branch information
wilhelmguo authored Feb 2, 2019
2 parents c61e09c + 21c6782 commit 971fbae
Show file tree
Hide file tree
Showing 30 changed files with 3,563 additions and 118 deletions.
79 changes: 54 additions & 25 deletions src/backend/controllers/base/parambuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,8 @@ type ParamBuilderController struct {
ResultHandlerController
}

// TODO: 需要重构成独立的Controller,参考Django的generic views设计
func (c *ParamBuilderController) BuildQueryParam() *common.QueryParam {
pageNo := c.Input().Get("pageNo")
pageSize := c.Input().Get("pageSize")
if pageNo == "" {
pageNo = strconv.Itoa(defaultPageNo)
}

if pageSize == "" {
pageSize = strconv.Itoa(defaultPageSize)
}

no, err := strconv.ParseInt(pageNo, 10, 64)
// pageNo must bigger than zero.
if err != nil || no < 1 {
c.AbortBadRequest("Invalid pageNo in query.")
}
// pageSize must bigger than zero.
size, err := strconv.ParseInt(pageSize, 10, 64)
if err != nil || size < 1 {
c.AbortBadRequest("Invalid pageSize in query.")
}
no, size := c.buildPageParam()

qmap := map[string]interface{}{}
deletedStr := c.Input().Get("deleted")
Expand Down Expand Up @@ -73,12 +53,61 @@ func (c *ParamBuilderController) BuildQueryParam() *common.QueryParam {
relate = c.Input().Get("relate")
}

return &common.QueryParam{PageNo: no,
return &common.QueryParam{
PageNo: no,
PageSize: size,
Query: qmap,
Sortby: snaker.CamelToSnake(c.Input().Get("sortby")),
Relate: relate}
}

func (c *ParamBuilderController) BuildKubernetesQueryParam() *common.QueryParam {
no, size := c.buildPageParam()

qmap := map[string]interface{}{}

filter := c.Input().Get("filter")
if filter != "" {
filters := strings.Split(filter, ",")
for _, param := range filters {
params := strings.Split(param, "=")
if len(params) != 2 {
continue
}
qmap[params[0]] = params[1]
}
}

return &common.QueryParam{
PageNo: no,
PageSize: size,
Query: qmap,
Sortby: snaker.CamelToSnake(c.Input().Get("sortby")),
Relate: relate,
LabelSelector: c.Input().Get("filter")}
Sortby: c.Input().Get("sortby"),
LabelSelector: c.Input().Get("labelSelector")}
}

func (c *ParamBuilderController) buildPageParam() (no int64, size int64) {
pageNo := c.Input().Get("pageNo")
pageSize := c.Input().Get("pageSize")
if pageNo == "" {
pageNo = strconv.Itoa(defaultPageNo)
}

if pageSize == "" {
pageSize = strconv.Itoa(defaultPageSize)
}

no, err := strconv.ParseInt(pageNo, 10, 64)
// pageNo must bigger than zero.
if err != nil || no < 1 {
c.AbortBadRequest("Invalid pageNo in query.")
}
// pageSize must bigger than zero.
size, err = strconv.ParseInt(pageSize, 10, 64)
if err != nil || size < 1 {
c.AbortBadRequest("Invalid pageSize in query.")
}
return
}

func (c *ParamBuilderController) GetIDFromURL() int64 {
Expand Down
25 changes: 18 additions & 7 deletions src/backend/controllers/kubernetes/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package proxy

import (
"encoding/json"
"strconv"

meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -100,7 +101,7 @@ func (c *KubeProxyController) GetNames() {
// @Success 200 {object} success
// @router / [get]
func (c *KubeProxyController) List() {
param := c.BuildQueryParam()
param := c.BuildKubernetesQueryParam()
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
kind := c.Ctx.Input.Param(":kind")
Expand Down Expand Up @@ -179,21 +180,31 @@ func (c *KubeProxyController) Update() {
// @Param kind path string true "the resource kind"
// @Param namespace path string true "the namespace want to delete"
// @Param name path string true "the name want to delete"
// @Param deleteOptions body string false "the kubernetes delete options"
// @Param force query bool false "force to delete the resource from etcd."
// @Success 200 {string} delete success!
// @router /:name [delete]
func (c *KubeProxyController) Delete() {
cluster := c.Ctx.Input.Param(":cluster")
namespace := c.Ctx.Input.Param(":namespace")
name := c.Ctx.Input.Param(":name")
kind := c.Ctx.Input.Param(":kind")
var deleteOptions meta_v1.DeleteOptions
err := json.Unmarshal(c.Ctx.Input.RequestBody, &deleteOptions)
if err != nil {
c.AbortBadRequestFormat("deleteOptions")
force := c.Input().Get("force")
defaultPropagationPolicy := meta_v1.DeletePropagationBackground
defaultDeleteOptions := meta_v1.DeleteOptions{
PropagationPolicy: &defaultPropagationPolicy,
}
if force != "" {
forceBool, err := strconv.ParseBool(force)
if err != nil {
c.AbortBadRequestFormat("force")
}
if forceBool {
var gracePeriodSeconds int64 = 0
defaultDeleteOptions.GracePeriodSeconds = &gracePeriodSeconds
}
}
kubeClient := c.KubeClient(cluster)
err = kubeClient.Delete(kind, namespace, name, &deleteOptions)
err := kubeClient.Delete(kind, namespace, name, &defaultDeleteOptions)
if err != nil {
logs.Error("Delete kubernetes resource (%s:%s:%s) from cluster (%s) error. %v", kind, namespace, name, cluster, err)
c.HandleError(err)
Expand Down
11 changes: 11 additions & 0 deletions src/backend/resources/proxy/proxy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package proxy

import (
"sort"

"k8s.io/apimachinery/pkg/util/json"

"github.com/Qihoo360/wayne/src/backend/client"
Expand Down Expand Up @@ -28,6 +30,10 @@ func GetPage(kubeClient client.ResourceHandler, kind string, namespace string, q
commonObjs = append(commonObjs, commonObj)
}

sort.Slice(commonObjs, func(i, j int) bool {
return commonObjs[j].GetProperty(dataselector.NameProperty).Compare(commonObjs[i].GetProperty(dataselector.NameProperty)) == 1
})

return dataselector.DataSelectPage(commonObjs, q), nil
}

Expand All @@ -36,6 +42,7 @@ func GetNames(kubeClient client.ResourceHandler, kind string, namespace string)
if err != nil {
return nil, err
}

commonObjs := make([]response.NamesObject, 0)
for _, obj := range objs {
objByte, err := json.Marshal(obj)
Expand All @@ -52,5 +59,9 @@ func GetNames(kubeClient client.ResourceHandler, kind string, namespace string)
})
}

sort.Slice(commonObjs, func(i, j int) bool {
return commonObjs[i].Name < commonObjs[j].Name
})

return commonObjs, nil
}
3 changes: 3 additions & 0 deletions src/frontend/src/app/admin/admin-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import { AutoscaleComponent } from './autoscale/autoscale.component';
import { TrashAutoscaleComponent } from './autoscale/trash-autoscale/trash-autoscale.component';
import { AutoscaletplComponent } from './autoscaletpl/autoscaletpl.component';
import { TrashAutoscaletplComponent } from './autoscaletpl/trash-autoscaletpl/trash-autoscaletpl.component';
import { KubePodComponent } from './kubernetes/pod/kube-pod.component';


const routes: Routes = [
Expand Down Expand Up @@ -148,6 +149,8 @@ const routes: Routes = [
{path: 'kubernetes/deployment/:cluster', component: KubeDeploymentComponent},
{path: 'kubernetes/namespace', component: KubeNamespaceComponent},
{path: 'kubernetes/namespace/:cluster', component: KubeNamespaceComponent},
{path: 'kubernetes/pod', component: KubePodComponent},
{path: 'kubernetes/pod/:cluster', component: KubePodComponent},
...ADMINROUTES
]
}
Expand Down
4 changes: 3 additions & 1 deletion src/frontend/src/app/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { CreateEditAutoscaletplComponent } from './autoscaletpl/create-edit-auto
import { ListAutoscaletplComponent } from './autoscaletpl/list-autoscaletpl/list-autoscaletpl.component';
import { TrashAutoscaletplComponent } from './autoscaletpl/trash-autoscaletpl/trash-autoscaletpl.component';
import { SidenavModule } from './sidenav/sidenav.module';
import { KubePodModule } from './kubernetes/pod/kube-pod.module';

@NgModule({
imports: [
Expand Down Expand Up @@ -88,7 +89,8 @@ import { SidenavModule } from './sidenav/sidenav.module';
IngressTplModule,
KubeDeploymentModule,
TplDetailModule,
SidenavModule
SidenavModule,
KubePodModule,
],
providers: [
AdminAuthCheckGuard,
Expand Down
49 changes: 49 additions & 0 deletions src/frontend/src/app/admin/kubernetes/pod/kube-pod.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<div class="clr-row">
<div class="clr-col-lg-12 clr-col-md-12 clr-col-sm-12 clr-col-xs-12">
<div class="table-search">
<div class="table-search-left">
<button class="wayne-button normal" (click)="createResource()">
{{'ADMIN.KUBERNETES.POD.CREATE' | translate}}
</button>
<button class="wayne-button normal" (click)="retrieveResource()">
{{'ADMIN.KUBERNETES.ACTION.REFRESH' | translate}}
</button>
<wayne-filter-box (confirm)="onConfirmEvent()" (cancel)="onCancelEvent()">
<wayne-checkbox-group [(ngModel)]="showList">
<wayne-checkbox value="name">{{'ADMIN.KUBERNETES.POD.LIST.NAME' | translate}}</wayne-checkbox>
<wayne-checkbox value="label">{{'ADMIN.KUBERNETES.POD.LIST.LABEL' | translate}}</wayne-checkbox>
<wayne-checkbox value="images">{{'ADMIN.KUBERNETES.POD.LIST.IMAGES' | translate}}</wayne-checkbox>
<wayne-checkbox value="status"> {{'ADMIN.KUBERNETES.POD.LIST.STATUS' | translate}}</wayne-checkbox>
<wayne-checkbox value="podIP">{{'ADMIN.KUBERNETES.POD.LIST.PODIP' | translate}}</wayne-checkbox>
<wayne-checkbox value="node">{{'ADMIN.KUBERNETES.POD.LIST.NODE' | translate}}</wayne-checkbox>
<wayne-checkbox value="restartCount">{{'ADMIN.KUBERNETES.POD.LIST.RESTARTCOUNT' | translate}}</wayne-checkbox>
<wayne-checkbox value="age">{{'ADMIN.KUBERNETES.POD.LIST.AGE' | translate}}</wayne-checkbox>
</wayne-checkbox-group>
</wayne-filter-box>
<label for="namespace_name" class="clr-col-md-3">{{'ADMIN.KUBERNETES.LABEL.NAMESPACE' | translate}}</label>
<wayne-select [(ngModel)]="namespace" (change)="retrieveResource()"
searchable
name="namespace_name"
[placeholder]="'PLACEHOLDER.CHOOSE' | translate"
style="margin-left: 12px;">
<wayne-option *ngFor="let ns of namespaces" [value]="ns">{{ns}}</wayne-option>
</wayne-select>
</div>
</div>

<wayne-list-pod
[resources]="resources"
[showState]="showState"
(delete)="onDeleteResourceEvent($event)"
(edit)="onEditResourceEvent($event)"
[page]="pageState.page"
(paginate)="retrieveResource($event)">
</wayne-list-pod>
</div>
</div>
<deletion-dialog (outputObj)="confirmDeleteEvent($event)"></deletion-dialog>
<wayne-ace-editor (createOutputObj)="onCreateResourceEvent($event)" (outputObj)="onSaveResourceEvent($event)"></wayne-ace-editor>
<wayne-float-window value="{{ cluster }}">
<wayne-float-window-item *ngFor="let cluster of clusters" [value]="cluster"
(click)="jumpToHref(cluster)"></wayne-float-window-item>
</wayne-float-window>
63 changes: 63 additions & 0 deletions src/frontend/src/app/admin/kubernetes/pod/kube-pod.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfirmationDialogService } from '../../../shared/confirmation-dialog/confirmation-dialog.service';
import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service';
import { ClusterService } from '../../../shared/client/v1/cluster.service';
import { AuthService } from '../../../shared/auth/auth.service';
import { AceEditorComponent } from '../../../shared/ace-editor/ace-editor.component';
import { ListPodComponent } from './list-pod/list-pod.component';
import { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes';
import { KubeResourcePod } from '../../../shared/shared.const';
import { KubernetesNamespacedResource } from '../../../shared/base/kubernetes-namespaced/kubernetes-namespaced-resource';
import { DeletionDialogComponent } from '../../../shared/deletion-dialog/deletion-dialog.component';

const showState = {
'name': {hidden: false},
'label': {hidden: false},
'images': {hidden: false},
'status': {hidden: false},
'podIP': {hidden: false},
'node': {hidden: false},
'restartCount': {hidden: false},
'age': {hidden: false},
};

@Component({
selector: 'wayne-kube-pod',
templateUrl: './kube-pod.component.html'
})

export class KubePodComponent extends KubernetesNamespacedResource implements OnInit, OnDestroy {
@ViewChild(ListPodComponent)
listResourceComponent: ListPodComponent;

@ViewChild(AceEditorComponent)
aceEditorModal: AceEditorComponent;

@ViewChild(DeletionDialogComponent)
deletionDialogComponent: DeletionDialogComponent;

constructor(public kubernetesClient: KubernetesClient,
public route: ActivatedRoute,
public router: Router,
public clusterService: ClusterService,
public authService: AuthService,
public messageHandlerService: MessageHandlerService) {
super(kubernetesClient, route, router, clusterService, authService, messageHandlerService);
super.registResourceType('pod');
super.registKubeResource(KubeResourcePod);
super.registShowSate(showState);
}

ngOnInit() {
super.ngOnInit();
}

ngOnDestroy(): void {
super.ngOnDestroy();
}




}
29 changes: 29 additions & 0 deletions src/frontend/src/app/admin/kubernetes/pod/kube-pod.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { NgModule } from '@angular/core';
import { SharedModule } from '../../../shared/shared.module';
import { ReactiveFormsModule } from '@angular/forms';
import { KubePodComponent } from './kube-pod.component';
import { ListPodComponent } from './list-pod/list-pod.component';
import { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes';
import { DeletionDialogModule } from '../../../shared/deletion-dialog/deletion-dialog.module';

@NgModule({
imports: [
SharedModule,
ReactiveFormsModule,
DeletionDialogModule
],
providers: [
KubernetesClient
],
exports: [
KubePodComponent,
ListPodComponent
],
declarations: [
KubePodComponent,
ListPodComponent
]
})

export class KubePodModule {
}
Loading

0 comments on commit 971fbae

Please sign in to comment.