diff --git a/src/backend/client/api/types.go b/src/backend/client/api/types.go index 99b5d7ebc..d4731a3f2 100644 --- a/src/backend/client/api/types.go +++ b/src/backend/client/api/types.go @@ -7,6 +7,7 @@ import ( batchv1beta1 "k8s.io/api/batch/v1beta1" corev1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -33,6 +34,11 @@ const ( ResourceNameStatefulSet ResourceName = "statefulsets" ResourceNameEndpoint ResourceName = "endpoints" ResourceNameStorageClass ResourceName = "storageclasses" + ResourceNameRole ResourceName = "roles" + ResourceNameRoleBinding ResourceName = "rolebindings" + ResourceNameClusterRole ResourceName = "clusterroles" + ResourceNameClusterRoleBinding ResourceName = "clusterrolebindings" + ResourceNameServiceAccount ResourceName = "serviceaccounts" ) type ResourceMap struct { @@ -194,4 +200,45 @@ var KindToResourceMap = map[string]ResourceMap{ }, Namespaced: false, }, + + ResourceNameRole: { + GroupVersionResource: schema.GroupVersionResource{ + Group: rbacv1.GroupName, + Version: rbacv1.SchemeGroupVersion.Version, + Resource: ResourceNameRole, + }, + Namespaced: true, + }, + ResourceNameRoleBinding: { + GroupVersionResource: schema.GroupVersionResource{ + Group: rbacv1.GroupName, + Version: rbacv1.SchemeGroupVersion.Version, + Resource: ResourceNameRoleBinding, + }, + Namespaced: true, + }, + ResourceNameClusterRole: { + GroupVersionResource: schema.GroupVersionResource{ + Group: rbacv1.GroupName, + Version: rbacv1.SchemeGroupVersion.Version, + Resource: ResourceNameClusterRole, + }, + Namespaced: false, + }, + ResourceNameClusterRoleBinding: { + GroupVersionResource: schema.GroupVersionResource{ + Group: rbacv1.GroupName, + Version: rbacv1.SchemeGroupVersion.Version, + Resource: ResourceNameClusterRoleBinding, + }, + Namespaced: false, + }, + ResourceNameServiceAccount: { + GroupVersionResource: schema.GroupVersionResource{ + Group: corev1.GroupName, + Version: corev1.SchemeGroupVersion.Version, + Resource: ResourceNameServiceAccount, + }, + Namespaced: true, + }, } diff --git a/src/backend/client/clientfactory.go b/src/backend/client/clientfactory.go index 0f3af68db..d21f66669 100644 --- a/src/backend/client/clientfactory.go +++ b/src/backend/client/clientfactory.go @@ -6,6 +6,7 @@ import ( batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" + rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/rest" @@ -29,6 +30,8 @@ func (h *resourceHandler) getClientByGroupVersion(groupVersion schema.GroupVersi return h.client.ExtensionsV1beta1().RESTClient() case storagev1.GroupName: return h.client.StorageV1().RESTClient() + case rbacv1.GroupName: + return h.client.RbacV1().RESTClient() default: return h.client.CoreV1().RESTClient() } diff --git a/src/backend/resources/common/common.go b/src/backend/resources/common/common.go index 2f4b5ad8e..1959fd3ac 100644 --- a/src/backend/resources/common/common.go +++ b/src/backend/resources/common/common.go @@ -11,6 +11,9 @@ type Object struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // for ServiceAccount + Secrets []v1.ObjectReference `json:"secrets,omitempty"` + // for StorageClass Provisioner string `json:"provisioner,omitempty"` ReclaimPolicy *v1.PersistentVolumeReclaimPolicy `json:"reclaimPolicy,omitempty"` diff --git a/src/frontend/src/app/admin/admin-routing.module.ts b/src/frontend/src/app/admin/admin-routing.module.ts index 891d9c1b1..9133aee09 100644 --- a/src/frontend/src/app/admin/admin-routing.module.ts +++ b/src/frontend/src/app/admin/admin-routing.module.ts @@ -82,6 +82,11 @@ import { KubePvcComponent } from './kubernetes/pvc/kube-pvc.component'; import { KubeReplicasetComponent } from './kubernetes/replicaset/kube-replicaset.component'; import { KubeStorageclassComponent } from './kubernetes/storageclass/kube-storageclass.component'; import { KubeHpaComponent } from './kubernetes/hpa/kube-hpa.component'; +import { KubeRoleComponent } from './kubernetes/role/kube-role.component'; +import { KubeRolebindingComponent } from './kubernetes/rolebinding/kube-rolebinding.component'; +import { KubeServiceaccountComponent } from './kubernetes/serviceaccount/kube-serviceaccount.component'; +import { KubeClusterroleComponent } from './kubernetes/clusterrole/kube-clusterrole.component'; +import { KubeClusterrolebindingComponent } from './kubernetes/clusterrolebinding/kube-clusterrolebinding.component'; const routes: Routes = [ @@ -190,6 +195,16 @@ const routes: Routes = [ {path: 'kubernetes/storageclass/:cluster', component: KubeStorageclassComponent}, {path: 'kubernetes/horizontalpodautoscaler', component: KubeHpaComponent}, {path: 'kubernetes/horizontalpodautoscaler/:cluster', component: KubeHpaComponent}, + {path: 'kubernetes/role', component: KubeRoleComponent}, + {path: 'kubernetes/role/:cluster', component: KubeRoleComponent}, + {path: 'kubernetes/rolebinding', component: KubeRolebindingComponent}, + {path: 'kubernetes/rolebinding/:cluster', component: KubeRolebindingComponent}, + {path: 'kubernetes/serviceaccount', component: KubeServiceaccountComponent}, + {path: 'kubernetes/serviceaccount/:cluster', component: KubeServiceaccountComponent}, + {path: 'kubernetes/clusterrole', component: KubeClusterroleComponent}, + {path: 'kubernetes/clusterrole/:cluster', component: KubeClusterroleComponent}, + {path: 'kubernetes/clusterrolebinding', component: KubeClusterrolebindingComponent}, + {path: 'kubernetes/clusterrolebinding/:cluster', component: KubeClusterrolebindingComponent}, ...ADMINROUTES ] } diff --git a/src/frontend/src/app/admin/admin.module.ts b/src/frontend/src/app/admin/admin.module.ts index f6cbfbabb..a38ac7707 100644 --- a/src/frontend/src/app/admin/admin.module.ts +++ b/src/frontend/src/app/admin/admin.module.ts @@ -62,6 +62,11 @@ import { KubeReplicasetModule } from './kubernetes/replicaset/kube-replicaset.mo import { KubePvcModule } from './kubernetes/pvc/kube-pvc.module'; import { KubeStorageclassModule } from './kubernetes/storageclass/kube-storageclass.module'; import { KubeHpaModule } from './kubernetes/hpa/kube-hpa.module'; +import { KubeRoleModule } from './kubernetes/role/kube-role.module'; +import { KubeRolebindingModule } from './kubernetes/rolebinding/kube-rolebinding.module'; +import { KubeServiceaccountModule } from './kubernetes/serviceaccount/kube-serviceaccount.module'; +import { KubeClusterroleModule } from './kubernetes/clusterrole/kube-clusterrole.module'; +import { KubeClusterrolebindingModule } from './kubernetes/clusterrolebinding/kube-clusterrolebinding.module'; @NgModule({ imports: [ @@ -117,7 +122,13 @@ import { KubeHpaModule } from './kubernetes/hpa/kube-hpa.module'; KubeJobModule, KubePvcModule, KubeStorageclassModule, - KubeHpaModule + KubeHpaModule, + KubeRoleModule, + KubeRolebindingModule, + KubeServiceaccountModule, + KubeClusterroleModule, + KubeClusterrolebindingModule, + KubeNamespaceModule ], providers: [ AdminAuthCheckGuard, diff --git a/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.component.html b/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.component.html new file mode 100644 index 000000000..650b8947d --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.component.html @@ -0,0 +1,37 @@ +
+
+ + + + +
+
+ + + + + diff --git a/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.component.ts b/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.component.ts new file mode 100644 index 000000000..bc8533621 --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.component.ts @@ -0,0 +1,54 @@ +import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +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 { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes'; +import { KubeResourceClusterRole } from '../../../shared/shared.const'; +import { DeletionDialogComponent } from '../../../shared/deletion-dialog/deletion-dialog.component'; +import { KubernetesUnNamespacedResource } from '../../../shared/base/kubernetes-namespaced/kubernetes-unnamespaced-resource'; +import { ListClusterroleComponent } from './list-clusterrole/list-clusterrole.component'; + +const showState = { + 'name': {hidden: false}, + 'label': {hidden: false}, + 'age': {hidden: false}, +}; + +@Component({ + selector: 'wayne-kube-clusterrole', + templateUrl: './kube-clusterrole.component.html' +}) + +export class KubeClusterroleComponent extends KubernetesUnNamespacedResource implements OnInit, OnDestroy { + @ViewChild(ListClusterroleComponent) + listResourceComponent: ListClusterroleComponent; + + @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('clusterrole'); + super.registKubeResource(KubeResourceClusterRole); + super.registShowSate(showState); + } + + ngOnInit() { + super.ngOnInit(); + } + + ngOnDestroy(): void { + super.ngOnDestroy(); + } + +} diff --git a/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.module.ts b/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.module.ts new file mode 100644 index 000000000..4fcf446db --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrole/kube-clusterrole.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../../shared/shared.module'; +import { ReactiveFormsModule } from '@angular/forms'; +import { KubeClusterroleComponent } from './kube-clusterrole.component'; +import { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes'; +import { DeletionDialogModule } from '../../../shared/deletion-dialog/deletion-dialog.module'; +import { ListClusterroleComponent } from './list-clusterrole/list-clusterrole.component'; + +@NgModule({ + imports: [ + SharedModule, + ReactiveFormsModule, + DeletionDialogModule + ], + providers: [ + KubernetesClient + ], + exports: [], + declarations: [ + KubeClusterroleComponent, + ListClusterroleComponent + ] +}) + +export class KubeClusterroleModule { +} diff --git a/src/frontend/src/app/admin/kubernetes/clusterrole/list-clusterrole/list-clusterrole.component.html b/src/frontend/src/app/admin/kubernetes/clusterrole/list-clusterrole/list-clusterrole.component.html new file mode 100644 index 000000000..a5717395b --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrole/list-clusterrole/list-clusterrole.component.html @@ -0,0 +1,40 @@ + + + + {{'ADMIN.KUBERNETES.CLUSTERROLE.LIST.NAME' | translate}} + + + + + {{'ADMIN.KUBERNETES.CLUSTERROLE.LIST.LABEL' | translate}} + + + + + {{'ADMIN.KUBERNETES.CLUSTERROLE.LIST.AGE' | translate}} + + + + + + + + + + {{ obj.metadata.name }} + + + + {{ obj.metadata.creationTimestamp | relativeTime}} + + + + + + diff --git a/src/frontend/src/app/admin/kubernetes/clusterrole/list-clusterrole/list-clusterrole.component.ts b/src/frontend/src/app/admin/kubernetes/clusterrole/list-clusterrole/list-clusterrole.component.ts new file mode 100644 index 000000000..aa254a345 --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrole/list-clusterrole/list-clusterrole.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; +import { KubernetesListResource } from '../../../../shared/base/kubernetes-namespaced/kubernetes-list-resource'; +import { TplDetailService } from '../../../../shared/tpl-detail/tpl-detail.service'; + +@Component({ + selector: 'wayne-list-clusterrole', + templateUrl: './list-clusterrole.component.html' +}) + +export class ListClusterroleComponent extends KubernetesListResource { + @Input() resources: any[]; + @Input() showState: object; + + constructor(public tplDetailService: TplDetailService) { + super(tplDetailService); + } + +} diff --git a/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.component.html b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.component.html new file mode 100644 index 000000000..aa8a99ccb --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.component.html @@ -0,0 +1,37 @@ +
+
+ + + + +
+
+ + + + + diff --git a/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.component.ts b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.component.ts new file mode 100644 index 000000000..d920a68f4 --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.component.ts @@ -0,0 +1,54 @@ +import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +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 { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes'; +import { KubeResourceClusterRoleBinding } from '../../../shared/shared.const'; +import { DeletionDialogComponent } from '../../../shared/deletion-dialog/deletion-dialog.component'; +import { KubernetesUnNamespacedResource } from '../../../shared/base/kubernetes-namespaced/kubernetes-unnamespaced-resource'; +import { ListClusterrolebindingComponent } from './list-clusterrolebinding/list-clusterrolebinding.component'; + +const showState = { + 'name': {hidden: false}, + 'label': {hidden: false}, + 'age': {hidden: false}, +}; + +@Component({ + selector: 'wayne-kube-clusterrolebinding', + templateUrl: './kube-clusterrolebinding.component.html' +}) + +export class KubeClusterrolebindingComponent extends KubernetesUnNamespacedResource implements OnInit, OnDestroy { + @ViewChild(ListClusterrolebindingComponent) + listResourceComponent: ListClusterrolebindingComponent; + + @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('clusterrolebinding'); + super.registKubeResource(KubeResourceClusterRoleBinding); + super.registShowSate(showState); + } + + ngOnInit() { + super.ngOnInit(); + } + + ngOnDestroy(): void { + super.ngOnDestroy(); + } + +} diff --git a/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.module.ts b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.module.ts new file mode 100644 index 000000000..57848d0b6 --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/kube-clusterrolebinding.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../../shared/shared.module'; +import { ReactiveFormsModule } from '@angular/forms'; +import { KubeClusterrolebindingComponent } from './kube-clusterrolebinding.component'; +import { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes'; +import { DeletionDialogModule } from '../../../shared/deletion-dialog/deletion-dialog.module'; +import { ListClusterrolebindingComponent } from './list-clusterrolebinding/list-clusterrolebinding.component'; + +@NgModule({ + imports: [ + SharedModule, + ReactiveFormsModule, + DeletionDialogModule + ], + providers: [ + KubernetesClient + ], + exports: [], + declarations: [ + KubeClusterrolebindingComponent, + ListClusterrolebindingComponent + ] +}) + +export class KubeClusterrolebindingModule { +} diff --git a/src/frontend/src/app/admin/kubernetes/clusterrolebinding/list-clusterrolebinding/list-clusterrolebinding.component.html b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/list-clusterrolebinding/list-clusterrolebinding.component.html new file mode 100644 index 000000000..07d142739 --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/list-clusterrolebinding/list-clusterrolebinding.component.html @@ -0,0 +1,40 @@ + + + + {{'ADMIN.KUBERNETES.CLUSTERROLEBINDING.LIST.NAME' | translate}} + + + + + {{'ADMIN.KUBERNETES.CLUSTERROLEBINDING.LIST.LABEL' | translate}} + + + + + {{'ADMIN.KUBERNETES.CLUSTERROLEBINDING.LIST.AGE' | translate}} + + + + + + + + + + {{ obj.metadata.name }} + + + + {{ obj.metadata.creationTimestamp | relativeTime}} + + + + + + diff --git a/src/frontend/src/app/admin/kubernetes/clusterrolebinding/list-clusterrolebinding/list-clusterrolebinding.component.ts b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/list-clusterrolebinding/list-clusterrolebinding.component.ts new file mode 100644 index 000000000..059e721bf --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/clusterrolebinding/list-clusterrolebinding/list-clusterrolebinding.component.ts @@ -0,0 +1,18 @@ +import { Component, Input } from '@angular/core'; +import { KubernetesListResource } from '../../../../shared/base/kubernetes-namespaced/kubernetes-list-resource'; +import { TplDetailService } from '../../../../shared/tpl-detail/tpl-detail.service'; + +@Component({ + selector: 'wayne-list-clusterrolebinding', + templateUrl: './list-clusterrolebinding.component.html' +}) + +export class ListClusterrolebindingComponent extends KubernetesListResource { + @Input() resources: any[]; + @Input() showState: object; + + constructor(public tplDetailService: TplDetailService) { + super(tplDetailService); + } + +} 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 1eb754758..f47486f44 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 @@ -2,44 +2,48 @@
- + (paginate)="retrieveResource($event)"> +
- - - - + + + + + (click)="jumpToHref(cluster)"> - 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 aea7088a4..26a458345 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 @@ -1,169 +1,65 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { ClrDatagridStateInterface } from '@clr/angular'; -import { Subscription } from 'rxjs/Subscription'; -import { DeploymentClient } from '../../../shared/client/v1/kubernetes/deployment'; -import { PageState } from '../../../shared/page/page-state'; -import { BreadcrumbService } from '../../../shared/client/v1/breadcrumb.service'; import { MessageHandlerService } from '../../../shared/message-handler/message-handler.service'; -import { KubeListDeploymentComponent } from './list/kube-list-deployment.component'; import { ClusterService } from '../../../shared/client/v1/cluster.service'; -import { DeploymentList } from '../../../shared/model/v1/deployment-list'; -import { AdminDefaultApiId } from '../../../shared/shared.const'; -import { AceEditorService } from '../../../shared/ace-editor/ace-editor.service'; -import { KubeMigrationDeploymentComponent } from './migration/kube-migration-deployment.component'; -import { NamespaceClient } from '../../../shared/client/v1/kubernetes/namespace'; +import { AuthService } from '../../../shared/auth/auth.service'; import { AceEditorComponent } from '../../../shared/ace-editor/ace-editor.component'; -import { KubeDeployment } from '../../../shared/model/v1/kubernetes/deployment'; +import { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes'; +import { KubeResourceDeployment } from '../../../shared/shared.const'; +import { KubernetesNamespacedResource } from '../../../shared/base/kubernetes-namespaced/kubernetes-namespaced-resource'; +import { DeletionDialogComponent } from '../../../shared/deletion-dialog/deletion-dialog.component'; +import { MigrationComponent } from './migration/migration.component'; +import { ListDeploymentComponent } from './list-deployment/list-deployment.component'; const showState = { 'name': {hidden: false}, 'label': {hidden: false}, 'containers': {hidden: false}, 'status': {hidden: false}, - 'age': {hidden: false} + 'age': {hidden: false}, }; @Component({ - selector: 'kubernetes-deployment', + selector: 'wayne-kube-deployment', templateUrl: './kube-deployment.component.html' }) -export class KubeDeploymentComponent implements OnInit { - @ViewChild(KubeListDeploymentComponent) - listDeployment: KubeListDeploymentComponent; - @ViewChild(KubeMigrationDeploymentComponent) - migrationDeployment: KubeMigrationDeploymentComponent; - @ViewChild(AceEditorComponent) - editModal: AceEditorComponent; - - namespace: string; - cluster: string; - clusters: Array; - changedDeployments: DeploymentList[]; - pageState: PageState = new PageState(); - subscription: Subscription; - - showList: any[] = Array(); - showState: object = showState; - - namespaces: string[]; - - constructor(private breadcrumbService: BreadcrumbService, - private deploymentClient: DeploymentClient, - private clusterService: ClusterService, - private namespaceClient: NamespaceClient, - private route: ActivatedRoute, - private router: Router, - private aceEditorService: AceEditorService, - private messageHandlerService: MessageHandlerService) { - } - - initShow() { - this.showList = []; - Object.keys(this.showState).forEach(key => { - if (!this.showState[key].hidden) { - this.showList.push(key); - } - }); - } - confirmEvent() { - Object.keys(this.showState).forEach(key => { - if (this.showList.indexOf(key) > -1) { - this.showState[key] = {hidden: false}; - } else { - this.showState[key] = {hidden: true}; - } - }); - } +export class KubeDeploymentComponent extends KubernetesNamespacedResource implements OnInit, OnDestroy { + @ViewChild(ListDeploymentComponent) + listResourceComponent: ListDeploymentComponent; - cancelEvent() { - this.initShow(); + @ViewChild(AceEditorComponent) + aceEditorModal: AceEditorComponent; + + @ViewChild(DeletionDialogComponent) + deletionDialogComponent: DeletionDialogComponent; + + @ViewChild(MigrationComponent) + migrationComponent: MigrationComponent; + + 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('deployment'); + super.registKubeResource(KubeResourceDeployment); + super.registShowSate(showState); } ngOnInit() { - this.initShow(); - const cluster = this.route.snapshot.params['cluster']; - this.clusterService.getNames().subscribe( - response => { - const data = response.data; - this.clusters = data.map(item => item.name); - if (data && data.length > 0 && !cluster) { - this.router.navigateByUrl(`admin/kubernetes/deployment/${data[0].name}`); - return; - } - if (cluster) { - this.jumpTo(cluster); - } - }, - error => this.messageHandlerService.handleError(error) - ); - } - - jumpTo(cluster: string) { - this.cluster = cluster; - this.router.navigateByUrl(`admin/kubernetes/deployment/${cluster}`); - this.namespaceClient.getNames(cluster).subscribe( - resp => { - this.namespaces = resp.data; - this.namespace = this.namespaces && this.namespaces.length > 0 ? this.namespaces[0] : 'default'; - this.retrieve(); - }, - error => this.messageHandlerService.handleError(error) - ); + super.ngOnInit(); } - detail(deploymentList: DeploymentList) { - this.deploymentClient.get(AdminDefaultApiId, this.cluster, deploymentList.objectMeta.namespace, deploymentList.objectMeta.name) - .subscribe( - response => { - const data = response.data; - this.editModal.openModal(data, '编辑节点', true); - }, - error => this.messageHandlerService.handleError(error) - ); + ngOnDestroy(): void { + super.ngOnDestroy(); } - 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) - ); - } - - save(obj: KubeDeployment) { - this.deploymentClient.update(AdminDefaultApiId, this.cluster, obj.metadata.namespace, obj.metadata.name, obj).subscribe( - resp => { - this.messageHandlerService.showSuccess('更新成功!'); - this.retrieve(); - }, - error => { - this.messageHandlerService.handleError(error); - } - ); - - } - retrieve(state?: ClrDatagridStateInterface): void { - if (state) { - this.pageState = PageState.fromState(state, {totalPage: this.pageState.page.totalPage, totalCount: this.pageState.page.totalCount}); - } - if (this.cluster) { - this.deploymentClient.listPage(this.pageState, this.cluster, this.namespace) - .subscribe( - response => { - const data = response.data; - this.pageState.page.totalPage = data.totalPage; - this.pageState.page.totalCount = data.totalCount; - this.changedDeployments = data.list; - }, - error => this.messageHandlerService.handleError(error) - ); - } + migration(obj: any) { + this.migrationComponent.openModal(this.cluster, obj); } } diff --git a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.module.ts b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.module.ts index aac6fbc06..7f582f7a6 100644 --- a/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.module.ts +++ b/src/frontend/src/app/admin/kubernetes/deployment/kube-deployment.module.ts @@ -1,28 +1,26 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../../shared/shared.module'; -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'; +import { KubeDeploymentComponent } from './kube-deployment.component'; +import { KubernetesClient } from '../../../shared/client/v1/kubernetes/kubernetes'; +import { DeletionDialogModule } from '../../../shared/deletion-dialog/deletion-dialog.module'; +import { MigrationComponent } from './migration/migration.component'; +import { ListDeploymentComponent } from './list-deployment/list-deployment.component'; @NgModule({ imports: [ SharedModule, ReactiveFormsModule, + DeletionDialogModule ], providers: [ - DeploymentClient - ], - exports: [ - KubeDeploymentComponent, - KubeListDeploymentComponent, - KubeMigrationDeploymentComponent + KubernetesClient ], + exports: [], declarations: [ KubeDeploymentComponent, - KubeListDeploymentComponent, - KubeMigrationDeploymentComponent + ListDeploymentComponent, + MigrationComponent ] }) diff --git a/src/frontend/src/app/admin/kubernetes/deployment/list-deployment/list-deployment.component.html b/src/frontend/src/app/admin/kubernetes/deployment/list-deployment/list-deployment.component.html new file mode 100644 index 000000000..e495faa72 --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/deployment/list-deployment/list-deployment.component.html @@ -0,0 +1,63 @@ + + + + {{'ADMIN.KUBERNETES.DEPLOYMENT.LIST.NAME' | translate}} + + + + + {{'ADMIN.KUBERNETES.DEPLOYMENT.LIST.LABEL' | translate}} + + + + + {{'ADMIN.KUBERNETES.DEPLOYMENT.LIST.IMAGES' | translate}} + + + + + {{'ADMIN.KUBERNETES.DEPLOYMENT.LIST.STATUS' | translate}} + + + + + {{'ADMIN.KUBERNETES.DEPLOYMENT.LIST.AGE' | translate}} + + + + + + + + + + + {{ obj.metadata.name }} + + + + + + + + {{obj.status.readyReplicas ? obj.status.readyReplicas : 0 }}/{{obj.spec.replicas}} + + + + {{ obj.metadata.creationTimestamp | relativeTime}} + + + + + + diff --git a/src/frontend/src/app/admin/kubernetes/deployment/list-deployment/list-deployment.component.ts b/src/frontend/src/app/admin/kubernetes/deployment/list-deployment/list-deployment.component.ts new file mode 100644 index 000000000..2edbfa68d --- /dev/null +++ b/src/frontend/src/app/admin/kubernetes/deployment/list-deployment/list-deployment.component.ts @@ -0,0 +1,23 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { KubernetesListResource } from '../../../../shared/base/kubernetes-namespaced/kubernetes-list-resource'; +import { TplDetailService } from '../../../../shared/tpl-detail/tpl-detail.service'; + +@Component({ + selector: 'wayne-list-deployment', + templateUrl: './list-deployment.component.html' +}) + +export class ListDeploymentComponent extends KubernetesListResource { + @Input() resources: any[]; + @Input() showState: object; + + @Output() migration = new EventEmitter(); + + constructor(public tplDetailService: TplDetailService) { + super(tplDetailService); + } + + migrationResource(obj: any) { + this.migration.emit(obj); + } +} diff --git a/src/frontend/src/app/admin/kubernetes/deployment/list/kube-list-deployment.component.html b/src/frontend/src/app/admin/kubernetes/deployment/list/kube-list-deployment.component.html deleted file mode 100644 index 148c18a8d..000000000 --- a/src/frontend/src/app/admin/kubernetes/deployment/list/kube-list-deployment.component.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - 名称 - - - - - 标签 - - - - - 镜像 - - - - - 容器状态 - - - - - 已创建 - - - - - - - - - - {{deployment.objectMeta.name}} - - - - - - - - {{deployment.pods.current}}/{{deployment.pods.desired}} - - - - {{deployment.objectMeta.creationTimestamp | relativeTime}} - - - - - - diff --git a/src/frontend/src/app/admin/kubernetes/deployment/list/kube-list-deployment.component.ts b/src/frontend/src/app/admin/kubernetes/deployment/list/kube-list-deployment.component.ts deleted file mode 100644 index 5cf27d1d1..000000000 --- a/src/frontend/src/app/admin/kubernetes/deployment/list/kube-list-deployment.component.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Router } from '@angular/router'; -import { ClrDatagridStateInterface } from '@clr/angular'; -import { Page } from '../../../../shared/page/page-state'; -import { BreadcrumbService } from '../../../../shared/client/v1/breadcrumb.service'; -import { DeploymentList } from '../../../../shared/model/v1/deployment-list'; -import { TplDetailService } from '../../../../shared/tpl-detail/tpl-detail.service'; - -@Component({ - selector: 'kube-list-deployment', - templateUrl: 'kube-list-deployment.component.html' -}) -export class KubeListDeploymentComponent implements OnInit { - - @Input() deployments: DeploymentList[]; - @Input() page: Page; - @Input() showState: object; - currentPage = 1; - state: ClrDatagridStateInterface; - - @Output() paginate = new EventEmitter(); - @Output() detail = new EventEmitter(); - @Output() migration = new EventEmitter(); - - constructor( - private breadcrumbService: BreadcrumbService, - private router: Router, - private tplDetailService: TplDetailService) { - } - - ngOnInit(): void { - } - - pageSizeChange(pageSize: number) { - this.state.page.to = pageSize - 1; - this.state.page.size = pageSize; - this.currentPage = 1; - this.paginate.emit(this.state); - } - - refresh(state: ClrDatagridStateInterface) { - this.state = state; - this.paginate.emit(state); - } - - versionDetail(version: string) { - this.tplDetailService.openModal(version, '版本'); - } - - detailDeployment(obj: DeploymentList) { - this.detail.emit(obj); - } - - migrationDeployment(obj: DeploymentList) { - this.migration.emit(obj); - } -} diff --git a/src/frontend/src/app/admin/kubernetes/deployment/migration/kube-migration-deployment.component.ts b/src/frontend/src/app/admin/kubernetes/deployment/migration/kube-migration-deployment.component.ts deleted file mode 100644 index df17ad63b..000000000 --- a/src/frontend/src/app/admin/kubernetes/deployment/migration/kube-migration-deployment.component.ts +++ /dev/null @@ -1,124 +0,0 @@ -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(); - modalOpened: boolean; - - @ViewChild('ngForm') - currentForm: NgForm; - - @ViewChild(AceEditorBoxComponent) - aceBox: any; - - deployment: KubeDeployment; - isSubmitOnGoing = false; - 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.cluster = cluster; - - 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.initJsonEditor(); - } - - initJsonEditor(): void { - this.aceEditorService.announceMessage(AceEditorMsg.Instance(this.deployment)); - } - - onCancel() { - this.modalOpened = false; - this.currentForm.reset(); - } - - onSubmit() { - 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); - } - -} diff --git a/src/frontend/src/app/admin/kubernetes/deployment/migration/kube-migration-deployment.component.html b/src/frontend/src/app/admin/kubernetes/deployment/migration/migration.component.html similarity index 70% rename from src/frontend/src/app/admin/kubernetes/deployment/migration/kube-migration-deployment.component.html rename to src/frontend/src/app/admin/kubernetes/deployment/migration/migration.component.html index ce3c96305..488f54eea 100644 --- a/src/frontend/src/app/admin/kubernetes/deployment/migration/kube-migration-deployment.component.html +++ b/src/frontend/src/app/admin/kubernetes/deployment/migration/migration.component.html @@ -1,14 +1,14 @@ -