Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
dedc0b4
backend: Sortby slice to string
wilhelmguo Nov 29, 2018
5fb93f0
backend: base api pageSize and pageNo must bigger than zero
wilhelmguo Nov 29, 2018
50ca792
backend: add kubernetes resource dataselector for backend paging
wilhelmguo Nov 29, 2018
5c26fcd
backend: add kubernetes deployment list
wilhelmguo Nov 29, 2018
2d9c02b
backend: abstraction base controller
wilhelmguo Nov 30, 2018
2f75143
Merge branch 'master' of github.com:Qihoo360/wayne into feature/add_k…
wilhelmguo Nov 30, 2018
7277e57
backend: remove deployment debug logs
wilhelmguo Nov 30, 2018
8da44cd
Merge branch 'master' of github.com:Qihoo360/wayne into feature/add_k…
wilhelmguo Nov 30, 2018
e9176a7
backend: update auditlog model Action size 255 to 256
wilhelmguo Dec 5, 2018
f33fe16
backend: update kubernetes deployment cluster & namespace param to path
wilhelmguo Dec 5, 2018
451ebe4
backend: add get kube deployment api
wilhelmguo Dec 5, 2018
d601685
backend: get kubernetes list return DeploymentList Object
wilhelmguo Dec 5, 2018
03cb40e
frontend: move tpl-detail to shared
wilhelmguo Dec 5, 2018
699621f
frontend: add kubernetes deployment management
wilhelmguo Dec 5, 2018
c847355
merge master
wilhelmguo Dec 5, 2018
a6db772
backend: update kubernetes deployment createOrUpdate strategy
wilhelmguo Dec 5, 2018
de1bfa4
frontend: update deployment tpl generate rules
wilhelmguo Dec 5, 2018
42e4b03
frontend: move tpl-detail to shared
wilhelmguo Dec 5, 2018
4fe613b
backend: deal with Resources already exist error.
wilhelmguo Dec 6, 2018
319f604
frontend: add kubernetes deployment migration
wilhelmguo Dec 6, 2018
b84aed2
frontend: update lib version
wilhelmguo Dec 6, 2018
95b5bb9
frontend: migration deployment showcolumns key to lower case
wilhelmguo Dec 6, 2018
453de6b
Merge branch 'master' of github.com:Qihoo360/wayne into feature/add_k…
wilhelmguo Dec 6, 2018
de6e641
Merge branch 'master' into feature/add_kubernetes_deployment_migration
Dec 6, 2018
42dedf4
backend: remove unused newline
wilhelmguo Dec 6, 2018
07c8c93
Merge branch 'feature/add_kubernetes_deployment_migration' of https:/…
wilhelmguo Dec 6, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
frontend: add kubernetes deployment migration
  • Loading branch information
wilhelmguo committed Dec 6, 2018
commit 319f604ce144964c5ca79478c6faa34798c66d13
3 changes: 3 additions & 0 deletions src/frontend/src/app/admin/admin.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ export class AdminComponent implements OnInit {
'/admin/kubernetes/persistentvolume': {
i18nKey: 'MENU.PV',
},
'/admin/kubernetes/deployment': {
i18nKey: 'MENU.DEPLOYMENT',
},
};

constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="table-search">
<div class="table-search-left">
<wayne-filter-box (confirm)="confirmEvent()" (cancel)="cancelEvent()">
<wayne-checkbox-group [(ngModel)]="showList">
<wayne-checkbox value="Name">名称</wayne-checkbox>
<wayne-checkbox value="Label">Label</wayne-checkbox>
<wayne-checkbox value="Containers">镜像</wayne-checkbox>
<wayne-checkbox value="Status">容器状态</wayne-checkbox>
<wayne-checkbox value="Age">Age</wayne-checkbox>
</wayne-checkbox-group>
</wayne-filter-box>
</div>
</div>
<kube-list-deployment
[deployments]="changedDeployments"
[page]="pageState.page"
(detail)="detail($event)"
(migration)="migration($event)"
[showState]="showState"
(paginate)="retrieve($event)"></kube-list-deployment>
</div>
</div>
<kube-migration-deployment></kube-migration-deployment>

<wayne-float-window value="{{cluster}}">
<wayne-float-window-item *ngFor="let cluster of clusters" [value]="cluster"
(click)="jumpTo(cluster)"></wayne-float-window-item>
</wayne-float-window>

Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ import { DeploymentList } from '../../../shared/model/v1/deployment-list';
import { AdminDefaultApiId } from '../../../shared/shared.const';
import { AceEditorMsg } from '../../../shared/ace-editor/ace-editor';
import { AceEditorService } from '../../../shared/ace-editor/ace-editor.service';
import { KubeMigrationDeploymentComponent } from './migration/kube-migration-deployment.component';

const showState = {
'名称': {hidden: false},
'总量': {hidden: false},
'回收策略': {hidden: true},
'访问模式': {hidden: false},
'状态': {hidden: false},
'已绑定PVC': {hidden: false},
'原因': {hidden: true},
'开始时间': {hidden: false},
'Name': {hidden: false},
Comment thread
wilhelmguo marked this conversation as resolved.
Outdated
'Label': {hidden: false},
'Containers': {hidden: false},
'Status': {hidden: false},
'Age': {hidden: false}
};

@Component({
Expand All @@ -31,6 +29,8 @@ const showState = {
export class KubeDeploymentComponent implements OnInit {
@ViewChild(KubeListDeploymentComponent)
listDeployment: KubeListDeploymentComponent;
@ViewChild(KubeMigrationDeploymentComponent)
migrationDeployment: KubeMigrationDeploymentComponent;

namespace = 'default';
cluster: string;
Expand Down Expand Up @@ -60,6 +60,20 @@ export class KubeDeploymentComponent implements OnInit {
});
}

confirmEvent() {
Object.keys(this.showState).forEach(key => {
if (this.showList.indexOf(key) > -1) {
this.showState[key] = {hidden: false};
} else {
this.showState[key] = {hidden: true};
}
});
}

cancelEvent() {
this.initShow();
}

ngOnInit() {
this.initShow();
let cluster = this.route.snapshot.params['cluster'];
Expand Down Expand Up @@ -95,6 +109,17 @@ export class KubeDeploymentComponent implements OnInit {
);
}

migration(deploymentList: DeploymentList) {
this.deploymentClient.get(AdminDefaultApiId, this.cluster, deploymentList.objectMeta.namespace, deploymentList.objectMeta.name)
.subscribe(
response => {
const data = response.data;
this.migrationDeployment.openModal(this.cluster, data);
},
error => this.messageHandlerService.handleError(error)
);
}

retrieve(state?: State): void {
if (state) {
this.pageState = PageState.fromState(state, {totalPage: this.pageState.page.totalPage, totalCount: this.pageState.page.totalCount});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { KubeDeploymentComponent } from './kube-deployment.component';
import { ReactiveFormsModule } from '@angular/forms';
import { DeploymentClient } from '../../../shared/client/v1/kubernetes/deployment';
import { KubeListDeploymentComponent } from './list/kube-list-deployment.component';
import { KubeMigrationDeploymentComponent } from './migration/kube-migration-deployment.component';

@NgModule({
imports: [
Expand All @@ -16,10 +17,12 @@ import { KubeListDeploymentComponent } from './list/kube-list-deployment.compone
exports: [
KubeDeploymentComponent,
KubeListDeploymentComponent,
KubeMigrationDeploymentComponent
],
declarations: [
KubeDeploymentComponent,
KubeListDeploymentComponent
KubeListDeploymentComponent,
KubeMigrationDeploymentComponent
]
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
<clr-datagrid (clrDgRefresh)="refresh($event)">
<clr-dg-column [clrDgField]="'name'">
<ng-container *clrDgHideableColumn="{hidden: false}">
<ng-container *clrDgHideableColumn="showState['Name']">
名称
</ng-container>
</clr-dg-column>
<clr-dg-column class="col-version">
<ng-container *clrDgHideableColumn="{hidden: false}">
<ng-container *clrDgHideableColumn="showState['Label']">
Label
</ng-container>
</clr-dg-column>
<clr-dg-column class="col-version">
<ng-container *clrDgHideableColumn="{hidden: false}">
<ng-container *clrDgHideableColumn="showState['Containers']">
镜像
</ng-container>
</clr-dg-column>
<clr-dg-column>
<ng-container *clrDgHideableColumn="{hidden: false}">
容器组
<ng-container *clrDgHideableColumn="showState['Status']">
容器状态
</ng-container>
</clr-dg-column>
<clr-dg-column class="col-time">
<ng-container *clrDgHideableColumn="{hidden: false}">
<ng-container *clrDgHideableColumn="showState['Age']">
Age
</ng-container>
</clr-dg-column>
Expand All @@ -29,7 +29,7 @@
<clr-dg-row *ngFor="let deployment of deployments" [clrDgItem]="deployment">
<clr-dg-action-overflow>
<button class="action-item" (click)="detailDeployment(deployment)">详情</button>
<button class="action-item" (click)="detailDeployment(deployment)">迁移</button>
<button class="action-item" (click)="migrationDeployment(deployment)">迁移</button>
</clr-dg-action-overflow>
<clr-dg-cell>{{deployment.objectMeta.name}}</clr-dg-cell>
<clr-dg-cell class="col-version">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ export class KubeListDeploymentComponent implements OnInit {

@Input() deployments: DeploymentList[];
@Input() page: Page;
@Input() showState: object;
currentPage = 1;
state: State;

@Output() paginate = new EventEmitter<State>();
@Output() detail = new EventEmitter<DeploymentList>();
@Output() migration = new EventEmitter<DeploymentList>();

constructor(
private breadcrumbService: BreadcrumbService,
Expand Down Expand Up @@ -48,4 +50,8 @@ export class KubeListDeploymentComponent implements OnInit {
detailDeployment(obj: DeploymentList) {
this.detail.emit(obj);
}

migrationDeployment(obj: DeploymentList) {
this.migration.emit(obj);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<clr-modal [(clrModalOpen)]="modalOpened" [clrModalSize]="'xl'" #modal>
<h3 class="modal-title">迁移部署到机房: [{{cluster}}]
<wayne-modal-operate [modal]="modal" *ngIf="modalOpened"></wayne-modal-operate>
</h3>
<div class="modal-body">
<div class="alert alert-warning" *ngIf="warningMsg">
<div class="alert-items">
<div class="alert-item static">
<div class="alert-icon-wrapper">
<clr-icon class="alert-icon" shape="exclamation-circle"></clr-icon>
</div>
<span class="alert-text">
{{warningMsg}}
</span>
</div>
</div>
</div>
<form #ngForm="ngForm">
<section class="form-block">
<div class="form-group" style="padding-left: 135px;">
<label for="deployment_app" class="col-md-3 form-group-label-override required">应用</label>
<div class="select form-control">
<select [(ngModel)]="selectedApp"
id="deployment_app"
name="deployment_app">
<option *ngFor="let app of apps" [ngValue]="app">{{app.name}}
</option>
</select>
</div>
</div>
<div class="form-group" style="padding-left: 135px;">
<label for="deployment_metadata" class="col-md-3 form-group-label-override">部署模版</label>
<wayne-ace-editor-box id="deployment_metadata"></wayne-ace-editor-box>

</div>
</section>
</form>
<div class="modal-footer">

<button type="button" class="btn btn-outline" (click)="onCancel()">{{'BUTTON.CANCEL' | translate}}</button>
<button type="button" class="btn btn-primary" [disabled]="!isValid"
(click)="onSubmit()">{{'BUTTON.SUBMIT' | translate}}</button>
</div>
</div>
</clr-modal>
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
import { NgForm } from '@angular/forms';
import { AceEditorBoxComponent } from '../../../../shared/ace-editor/ace-editor-box/ace-editor-box.component';
import { App } from '../../../../shared/model/v1/app';
import { DeploymentService } from '../../../../shared/client/v1/deployment.service';
import { AppService } from '../../../../shared/client/v1/app.service';
import { AceEditorService } from '../../../../shared/ace-editor/ace-editor.service';
import { MessageHandlerService } from '../../../../shared/message-handler/message-handler.service';
import { AceEditorMsg } from '../../../../shared/ace-editor/ace-editor';
import { isUndefined } from 'util';
import { KubeDeployment } from '../../../../shared/model/v1/kubernetes/deployment';
import { defaultDeployment } from '../../../../shared/default-models/deployment.const';
import { AuthService } from '../../../../shared/auth/auth.service';
import { Deployment, DeploymentMetaData } from '../../../../shared/model/v1/deployment';
import { DeploymentTplService } from '../../../../shared/client/v1/deploymenttpl.service';
import { DeploymentTpl } from '../../../../shared/model/v1/deploymenttpl';

@Component({
selector: 'kube-migration-deployment',
templateUrl: 'kube-migration-deployment.component.html'
})
export class KubeMigrationDeploymentComponent implements OnInit {

@Output() create = new EventEmitter<boolean>();
modalOpened: boolean;

@ViewChild('ngForm')
currentForm: NgForm;

@ViewChild(AceEditorBoxComponent)
aceBox: any;

deployment: KubeDeployment;
isSubmitOnGoing = false;

warningMsg: string;
cluster: string;

apps: App[];
selectedApp: App;

constructor(private deploymentService: DeploymentService,
private deploymentTplService: DeploymentTplService,
private appService: AppService,
public authService: AuthService,
private aceEditorService: AceEditorService,
private messageHandlerService: MessageHandlerService) {

}

ngOnInit(): void {
this.appService
.getNames()
.subscribe(
response => {
this.apps = response.data;
},
error => this.messageHandlerService.handleError(error)
);

}

openModal(cluster: string, deployment: KubeDeployment) {
this.modalOpened = true;
this.isSubmitOnGoing = false;
this.warningMsg = '';
this.cluster = cluster;

Comment thread
wilhelmguo marked this conversation as resolved.
this.deployment = JSON.parse(defaultDeployment);
this.deployment.metadata.name = deployment.metadata.name;
this.deployment.metadata.labels = deployment.metadata.labels;
this.deployment.metadata.annotations = deployment.metadata.annotations;
this.deployment.spec = deployment.spec;
this.validLabel(deployment);
this.initJsonEditor();
}

initJsonEditor(): void {
this.aceEditorService.announceMessage(AceEditorMsg.Instance(this.deployment));
}

validLabel(deployment: KubeDeployment) {
const app = deployment.spec.selector.matchLabels['app'];
if (!app) {
this.warningMsg = '.spec.selector.matchLabels 没有app标签,直接发布可能会导致游离的rs!';
}
if (app !== deployment.metadata.name) {
this.warningMsg = '.spec.selector.matchLabels app标签和部署名称不一致,直接发布可能会导致游离的rs!';
}
}

onCancel() {
this.modalOpened = false;
this.currentForm.reset();
}

onSubmit() {

Comment thread
wilhelmguo marked this conversation as resolved.
Outdated
if (this.isSubmitOnGoing) {
return;
}
this.isSubmitOnGoing = true;
const deployment = new Deployment();
deployment.name = this.deployment.metadata.name;
deployment.appId = this.selectedApp.id;
const metaData = new DeploymentMetaData();
metaData.replicas = {[this.cluster]: this.deployment.spec.replicas};
deployment.metaData = JSON.stringify(metaData);
this.deploymentService.create(deployment).subscribe(
resp => {
const data = resp.data;
const deploymentTpl = new DeploymentTpl();
deploymentTpl.name = this.deployment.metadata.name;
deploymentTpl.deploymentId = data.id;
deploymentTpl.template = JSON.stringify(this.deployment);
deploymentTpl.description = 'migration from kubernetes. ';
this.deploymentTplService.create(deploymentTpl, this.selectedApp.id).subscribe(
() => {
this.messageHandlerService.showSuccess('创建部署和部署模版成功!请前往前台手动发布部署到相应机房!');
},
error => {
this.messageHandlerService.handleError(error);
});
},
error => {
this.messageHandlerService.handleError(error);
}
);
this.modalOpened = false;
}

public get isValid(): boolean {
return this.currentForm &&
this.currentForm.valid &&
!this.isSubmitOnGoing &&
!isUndefined(this.selectedApp);
}

}
Loading