From 6d71ea190fbf7b22e8b35f3700c69dcb1e8fc6c7 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 10 Jun 2020 11:28:23 +0200 Subject: [PATCH 01/11] Add service account backend --- src/app/backend/api/types.go | 2 + .../backend/resource/serviceaccount/common.go | 52 ++++++++++++ .../backend/resource/serviceaccount/detail.go | 51 ++++++++++++ .../backend/resource/serviceaccount/list.go | 81 +++++++++++++++++++ 4 files changed, 186 insertions(+) create mode 100644 src/app/backend/resource/serviceaccount/common.go create mode 100644 src/app/backend/resource/serviceaccount/detail.go create mode 100644 src/app/backend/resource/serviceaccount/list.go diff --git a/src/app/backend/api/types.go b/src/app/backend/api/types.go index 566142439f89..a9e0b4e16a9b 100644 --- a/src/app/backend/api/types.go +++ b/src/app/backend/api/types.go @@ -120,6 +120,7 @@ const ( ResourceKindEvent = "event" ResourceKindHorizontalPodAutoscaler = "horizontalpodautoscaler" ResourceKindIngress = "ingress" + ResourceKindServiceAccount = "serviceaccount" ResourceKindJob = "job" ResourceKindCronJob = "cronjob" ResourceKindLimitRange = "limitrange" @@ -216,6 +217,7 @@ var KindToAPIMapping = map[string]APIMapping{ ResourceKindResourceQuota: {"resourcequotas", ClientTypeDefault, true}, ResourceKindSecret: {"secrets", ClientTypeDefault, true}, ResourceKindService: {"services", ClientTypeDefault, true}, + ResourceKindServiceAccount: {"serviceaccounts", ClientTypeDefault, true}, ResourceKindStatefulSet: {"statefulsets", ClientTypeAppsClient, true}, ResourceKindStorageClass: {"storageclasses", ClientTypeStorageClient, false}, ResourceKindEndpoint: {"endpoints", ClientTypeDefault, true}, diff --git a/src/app/backend/resource/serviceaccount/common.go b/src/app/backend/resource/serviceaccount/common.go new file mode 100644 index 000000000000..21d77de3586d --- /dev/null +++ b/src/app/backend/resource/serviceaccount/common.go @@ -0,0 +1,52 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serviceaccount + +import ( + "github.com/kubernetes/dashboard/src/app/backend/resource/dataselect" + v1 "k8s.io/api/core/v1" +) + +type ServiceAccountCell v1.ServiceAccount + +func (self ServiceAccountCell) GetProperty(name dataselect.PropertyName) dataselect.ComparableValue { + switch name { + case dataselect.NameProperty: + return dataselect.StdComparableString(self.ObjectMeta.Name) + case dataselect.CreationTimestampProperty: + return dataselect.StdComparableTime(self.ObjectMeta.CreationTimestamp.Time) + case dataselect.NamespaceProperty: + return dataselect.StdComparableString(self.ObjectMeta.Namespace) + default: + // If name is not supported then just return a constant dummy value, sort will have no effect. + return nil + } +} + +func toCells(std []v1.ServiceAccount) []dataselect.DataCell { + cells := make([]dataselect.DataCell, len(std)) + for i := range std { + cells[i] = ServiceAccountCell(std[i]) + } + return cells +} + +func fromCells(cells []dataselect.DataCell) []v1.ServiceAccount { + std := make([]v1.ServiceAccount, len(cells)) + for i := range std { + std[i] = v1.ServiceAccount(cells[i].(ServiceAccountCell)) + } + return std +} diff --git a/src/app/backend/resource/serviceaccount/detail.go b/src/app/backend/resource/serviceaccount/detail.go new file mode 100644 index 000000000000..65f0f2e03086 --- /dev/null +++ b/src/app/backend/resource/serviceaccount/detail.go @@ -0,0 +1,51 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serviceaccount + +import ( + "context" + v1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + client "k8s.io/client-go/kubernetes" + "log" +) + +// ServiceAccountDetail contains detailed information about a service account. +type ServiceAccountDetail struct { + // Extends list item structure. + ServiceAccount `json:",inline"` + + // List of non-critical errors, that occurred during resource retrieval. + Errors []error `json:"errors"` +} + +// GetServiceAccountDetail returns detailed information about a service account. +func GetServiceAccountDetail(client client.Interface, namespace, name string) (*ServiceAccountDetail, error) { + log.Printf("Getting details of %s service account in %s namespace", name, namespace) + + raw, err := client.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metaV1.GetOptions{}) + + if err != nil { + return nil, err + } + + return getServiceAccountDetail(raw), nil +} + +func getServiceAccountDetail(sa *v1.ServiceAccount) *ServiceAccountDetail { + return &ServiceAccountDetail{ + ServiceAccount: toServiceAccount(sa), + } +} diff --git a/src/app/backend/resource/serviceaccount/list.go b/src/app/backend/resource/serviceaccount/list.go new file mode 100644 index 000000000000..1c040cb0f929 --- /dev/null +++ b/src/app/backend/resource/serviceaccount/list.go @@ -0,0 +1,81 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serviceaccount + +import ( + "context" + v1 "k8s.io/api/core/v1" + + "github.com/kubernetes/dashboard/src/app/backend/api" + "github.com/kubernetes/dashboard/src/app/backend/errors" + "github.com/kubernetes/dashboard/src/app/backend/resource/common" + "github.com/kubernetes/dashboard/src/app/backend/resource/dataselect" + client "k8s.io/client-go/kubernetes" +) + +// ServiceAccount contains an information about single service account in the list. +type ServiceAccount struct { + api.ObjectMeta `json:"objectMeta"` + api.TypeMeta `json:"typeMeta"` +} + +// ServiceAccountList contains a list of service accounts. +type ServiceAccountList struct { + api.ListMeta `json:"listMeta"` + + // Unordered list of service accounts. + Items []ServiceAccount `json:"items"` + + // List of non-critical errors, that occurred during resource retrieval. + Errors []error `json:"errors"` +} + +// GetServiceAccountList lists service accounts from given namespace using given data select query. +func GetServiceAccountList(client client.Interface, namespace *common.NamespaceQuery, + dsQuery *dataselect.DataSelectQuery) (*ServiceAccountList, error) { + saList, err := client.CoreV1().ServiceAccounts(namespace.ToRequestParam()).List(context.TODO(), api.ListEverything) + + nonCriticalErrors, criticalError := errors.HandleError(err) + if criticalError != nil { + return nil, criticalError + } + + return toServiceAccountList(saList.Items, nonCriticalErrors, dsQuery), nil +} + +func toServiceAccount(sa *v1.ServiceAccount) ServiceAccount { + return ServiceAccount{ + ObjectMeta: api.NewObjectMeta(sa.ObjectMeta), + TypeMeta: api.NewTypeMeta(api.ResourceKindServiceAccount), + } +} + +func toServiceAccountList(serviceAccounts []v1.ServiceAccount, nonCriticalErrors []error, dsQuery *dataselect.DataSelectQuery) *ServiceAccountList { + newServiceAccountList := &ServiceAccountList{ + ListMeta: api.ListMeta{TotalItems: len(serviceAccounts)}, + Items: make([]ServiceAccount, 0), + Errors: nonCriticalErrors, + } + + saCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(serviceAccounts), dsQuery) + serviceAccounts = fromCells(saCells) + newServiceAccountList.ListMeta = api.ListMeta{TotalItems: filteredTotal} + + for _, sa := range serviceAccounts { + newServiceAccountList.Items = append(newServiceAccountList.Items, toServiceAccount(&sa)) + } + + return newServiceAccountList +} From 249e50d9267f4f10b68859b3f75c5bef4161b1d8 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 10 Jun 2020 11:55:01 +0200 Subject: [PATCH 02/11] Format files --- .../backend/resource/serviceaccount/detail.go | 6 +----- src/app/backend/resource/serviceaccount/list.go | 16 +++++++--------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/app/backend/resource/serviceaccount/detail.go b/src/app/backend/resource/serviceaccount/detail.go index 65f0f2e03086..31b5b80a3418 100644 --- a/src/app/backend/resource/serviceaccount/detail.go +++ b/src/app/backend/resource/serviceaccount/detail.go @@ -24,11 +24,8 @@ import ( // ServiceAccountDetail contains detailed information about a service account. type ServiceAccountDetail struct { - // Extends list item structure. ServiceAccount `json:",inline"` - - // List of non-critical errors, that occurred during resource retrieval. - Errors []error `json:"errors"` + Errors []error `json:"errors"` } // GetServiceAccountDetail returns detailed information about a service account. @@ -36,7 +33,6 @@ func GetServiceAccountDetail(client client.Interface, namespace, name string) (* log.Printf("Getting details of %s service account in %s namespace", name, namespace) raw, err := client.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metaV1.GetOptions{}) - if err != nil { return nil, err } diff --git a/src/app/backend/resource/serviceaccount/list.go b/src/app/backend/resource/serviceaccount/list.go index 1c040cb0f929..dca084855d6b 100644 --- a/src/app/backend/resource/serviceaccount/list.go +++ b/src/app/backend/resource/serviceaccount/list.go @@ -34,18 +34,15 @@ type ServiceAccount struct { // ServiceAccountList contains a list of service accounts. type ServiceAccountList struct { api.ListMeta `json:"listMeta"` - - // Unordered list of service accounts. - Items []ServiceAccount `json:"items"` - - // List of non-critical errors, that occurred during resource retrieval. - Errors []error `json:"errors"` + Items []ServiceAccount `json:"items"` + Errors []error `json:"errors"` } // GetServiceAccountList lists service accounts from given namespace using given data select query. func GetServiceAccountList(client client.Interface, namespace *common.NamespaceQuery, dsQuery *dataselect.DataSelectQuery) (*ServiceAccountList, error) { - saList, err := client.CoreV1().ServiceAccounts(namespace.ToRequestParam()).List(context.TODO(), api.ListEverything) + saList, err := client.CoreV1().ServiceAccounts(namespace.ToRequestParam()).List(context.TODO(), + api.ListEverything) nonCriticalErrors, criticalError := errors.HandleError(err) if criticalError != nil { @@ -62,7 +59,8 @@ func toServiceAccount(sa *v1.ServiceAccount) ServiceAccount { } } -func toServiceAccountList(serviceAccounts []v1.ServiceAccount, nonCriticalErrors []error, dsQuery *dataselect.DataSelectQuery) *ServiceAccountList { +func toServiceAccountList(serviceAccounts []v1.ServiceAccount, nonCriticalErrors []error, + dsQuery *dataselect.DataSelectQuery) *ServiceAccountList { newServiceAccountList := &ServiceAccountList{ ListMeta: api.ListMeta{TotalItems: len(serviceAccounts)}, Items: make([]ServiceAccount, 0), @@ -71,8 +69,8 @@ func toServiceAccountList(serviceAccounts []v1.ServiceAccount, nonCriticalErrors saCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(serviceAccounts), dsQuery) serviceAccounts = fromCells(saCells) - newServiceAccountList.ListMeta = api.ListMeta{TotalItems: filteredTotal} + newServiceAccountList.ListMeta = api.ListMeta{TotalItems: filteredTotal} for _, sa := range serviceAccounts { newServiceAccountList.Items = append(newServiceAccountList.Items, toServiceAccount(&sa)) } From 64927d6b205858c87a6dfa9875eda0a6dfbfc3ea Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 10 Jun 2020 12:09:03 +0200 Subject: [PATCH 03/11] Register endpoints --- src/app/backend/handler/apihandler.go | 48 +++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/app/backend/handler/apihandler.go b/src/app/backend/handler/apihandler.go index 0c5a0b8cbb71..bbe9c7331cb2 100644 --- a/src/app/backend/handler/apihandler.go +++ b/src/app/backend/handler/apihandler.go @@ -63,6 +63,7 @@ import ( "github.com/kubernetes/dashboard/src/app/backend/resource/rolebinding" "github.com/kubernetes/dashboard/src/app/backend/resource/secret" resourceService "github.com/kubernetes/dashboard/src/app/backend/resource/service" + "github.com/kubernetes/dashboard/src/app/backend/resource/serviceaccount" "github.com/kubernetes/dashboard/src/app/backend/resource/statefulset" "github.com/kubernetes/dashboard/src/app/backend/resource/storageclass" "github.com/kubernetes/dashboard/src/app/backend/scaling" @@ -445,6 +446,19 @@ func CreateHTTPAPIHandler(iManager integration.IntegrationManager, cManager clie To(apiHandler.handleGetServicePods). Writes(pod.PodList{})) + apiV1Ws.Route( + apiV1Ws.GET("/serviceaccount"). + To(apiHandler.handleGetServiceAccountList). + Writes(serviceaccount.ServiceAccountList{})) + apiV1Ws.Route( + apiV1Ws.GET("/serviceaccount/{namespace}"). + To(apiHandler.handleGetServiceAccountList). + Writes(serviceaccount.ServiceAccountList{})) + apiV1Ws.Route( + apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}"). + To(apiHandler.handleGetServiceAccountDetail). + Writes(serviceaccount.ServiceAccountDetail{})) + apiV1Ws.Route( apiV1Ws.GET("/ingress"). To(apiHandler.handleGetIngressList). @@ -903,6 +917,40 @@ func (apiHandler *APIHandler) handleGetServiceEvent(request *restful.Request, re response.WriteHeaderAndEntity(http.StatusOK, result) } +func (apiHandler *APIHandler) handleGetServiceAccountList(request *restful.Request, response *restful.Response) { + k8sClient, err := apiHandler.cManager.Client(request) + if err != nil { + errors.HandleInternalError(response, err) + return + } + + namespace := parseNamespacePathParameter(request) + dataSelect := parser.ParseDataSelectPathParameter(request) + result, err := serviceaccount.GetServiceAccountList(k8sClient, namespace, dataSelect) + if err != nil { + errors.HandleInternalError(response, err) + return + } + response.WriteHeaderAndEntity(http.StatusOK, result) +} + +func (apiHandler *APIHandler) handleGetServiceAccountDetail(request *restful.Request, response *restful.Response) { + k8sClient, err := apiHandler.cManager.Client(request) + if err != nil { + errors.HandleInternalError(response, err) + return + } + + namespace := request.PathParameter("namespace") + name := request.PathParameter("serviceaccount") + result, err := serviceaccount.GetServiceAccountDetail(k8sClient, namespace, name) + if err != nil { + errors.HandleInternalError(response, err) + return + } + response.WriteHeaderAndEntity(http.StatusOK, result) +} + func (apiHandler *APIHandler) handleGetIngressDetail(request *restful.Request, response *restful.Response) { k8sClient, err := apiHandler.cManager.Client(request) if err != nil { From 7664c4e36a25ac28610e6e2a34d5911b454ae83d Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 10 Jun 2020 12:46:46 +0200 Subject: [PATCH 04/11] Add details view --- .../common/services/resource/endpoint.ts | 1 + .../config/serviceaccount/detail/component.ts | 62 +++++++++++++++++++ .../serviceaccount/detail/template.html | 18 ++++++ .../config/serviceaccount/list/component.ts | 21 +++++++ .../resource/config/serviceaccount/module.ts | 28 +++++++++ .../resource/config/serviceaccount/routing.ts | 46 ++++++++++++++ src/app/frontend/typings/backendapi.ts | 2 + 7 files changed, 178 insertions(+) create mode 100644 src/app/frontend/resource/config/serviceaccount/detail/component.ts create mode 100644 src/app/frontend/resource/config/serviceaccount/detail/template.html create mode 100644 src/app/frontend/resource/config/serviceaccount/list/component.ts create mode 100644 src/app/frontend/resource/config/serviceaccount/module.ts create mode 100644 src/app/frontend/resource/config/serviceaccount/routing.ts diff --git a/src/app/frontend/common/services/resource/endpoint.ts b/src/app/frontend/common/services/resource/endpoint.ts index 8750fb287e0c..d2d40433eeca 100644 --- a/src/app/frontend/common/services/resource/endpoint.ts +++ b/src/app/frontend/common/services/resource/endpoint.ts @@ -39,6 +39,7 @@ export enum Resource { secret = 'secret', ingress = 'ingress', service = 'service', + serviceAccount = 'serviceaccount', event = 'event', container = 'container', plugin = 'plugin', diff --git a/src/app/frontend/resource/config/serviceaccount/detail/component.ts b/src/app/frontend/resource/config/serviceaccount/detail/component.ts new file mode 100644 index 000000000000..d0f4a4dc5318 --- /dev/null +++ b/src/app/frontend/resource/config/serviceaccount/detail/component.ts @@ -0,0 +1,62 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import 'rxjs/add/operator/startWith'; + +import {Component, OnDestroy, OnInit} from '@angular/core'; +import {ActivatedRoute} from '@angular/router'; +import {ServiceAccountDetail} from '@api/backendapi'; +import {Subscription} from 'rxjs/Subscription'; + +import {ActionbarService, ResourceMeta} from '../../../../common/services/global/actionbar'; +import {NotificationsService} from '../../../../common/services/global/notifications'; +import {EndpointManager, Resource} from '../../../../common/services/resource/endpoint'; +import {NamespacedResourceService} from '../../../../common/services/resource/resource'; + +@Component({ + selector: 'kd-service-account-detail', + templateUrl: './template.html', +}) +export class ServiceAccountDetailComponent implements OnInit, OnDestroy { + private serviceAccountSubscription_: Subscription; + private readonly endpoint_ = EndpointManager.resource(Resource.serviceAccount, true); + serviceAccount: ServiceAccountDetail; + isInitialized = false; + + constructor( + private readonly serviceAccount_: NamespacedResourceService, + private readonly actionbar_: ActionbarService, + private readonly activatedRoute_: ActivatedRoute, + private readonly notifications_: NotificationsService, + ) {} + + ngOnInit(): void { + const resourceName = this.activatedRoute_.snapshot.params.resourceName; + const resourceNamespace = this.activatedRoute_.snapshot.params.resourceNamespace; + + this.serviceAccountSubscription_ = this.serviceAccount_ + .get(this.endpoint_.detail(), resourceName, resourceNamespace) + .subscribe((d: ServiceAccountDetail) => { + this.serviceAccount = d; + this.notifications_.pushErrors(d.errors); + this.actionbar_.onInit.emit(new ResourceMeta('Service Account', d.objectMeta, d.typeMeta)); + this.isInitialized = true; + }); + } + + ngOnDestroy(): void { + this.serviceAccountSubscription_.unsubscribe(); + this.actionbar_.onDetailsLeave.emit(); + } +} diff --git a/src/app/frontend/resource/config/serviceaccount/detail/template.html b/src/app/frontend/resource/config/serviceaccount/detail/template.html new file mode 100644 index 000000000000..11b40deb810e --- /dev/null +++ b/src/app/frontend/resource/config/serviceaccount/detail/template.html @@ -0,0 +1,18 @@ + + + diff --git a/src/app/frontend/resource/config/serviceaccount/list/component.ts b/src/app/frontend/resource/config/serviceaccount/list/component.ts new file mode 100644 index 000000000000..e30c7c200f05 --- /dev/null +++ b/src/app/frontend/resource/config/serviceaccount/list/component.ts @@ -0,0 +1,21 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {Component} from '@angular/core'; + +@Component({ + selector: 'kd-service-account-list-state', + template: '', +}) +export class ServiceAccountListComponent {} diff --git a/src/app/frontend/resource/config/serviceaccount/module.ts b/src/app/frontend/resource/config/serviceaccount/module.ts new file mode 100644 index 000000000000..2d4f212ef24c --- /dev/null +++ b/src/app/frontend/resource/config/serviceaccount/module.ts @@ -0,0 +1,28 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {NgModule} from '@angular/core'; + +import {ComponentsModule} from '../../../common/components/module'; +import {SharedModule} from '../../../shared.module'; + +import {ServiceAccountDetailComponent} from './detail/component'; +import {ServiceAccountListComponent} from './list/component'; +import {ServiceAccountRoutingModule} from './routing'; + +@NgModule({ + imports: [SharedModule, ComponentsModule, ServiceAccountRoutingModule], + declarations: [ServiceAccountListComponent, ServiceAccountDetailComponent], +}) +export class ServiceAccountModule {} diff --git a/src/app/frontend/resource/config/serviceaccount/routing.ts b/src/app/frontend/resource/config/serviceaccount/routing.ts new file mode 100644 index 000000000000..9da7c6a94028 --- /dev/null +++ b/src/app/frontend/resource/config/serviceaccount/routing.ts @@ -0,0 +1,46 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {NgModule} from '@angular/core'; +import {Route, RouterModule} from '@angular/router'; +import {DEFAULT_ACTIONBAR} from '../../../common/components/actionbars/routing'; + +import {CONFIG_ROUTE} from '../routing'; + +import {ServiceAccountDetailComponent} from './detail/component'; +import {ServiceAccountListComponent} from './list/component'; + +const SERVICEACCOUNT_LIST_ROUTE: Route = { + path: '', + component: ServiceAccountListComponent, + data: { + breadcrumb: 'Service Accounts', + parent: CONFIG_ROUTE, + }, +}; + +const SERVICEACCOUNT_DETAIL_ROUTE: Route = { + path: ':resourceNamespace/:resourceName', + component: ServiceAccountDetailComponent, + data: { + breadcrumb: '{{ resourceName }}', + parent: SERVICEACCOUNT_LIST_ROUTE, + }, +}; + +@NgModule({ + imports: [RouterModule.forChild([SERVICEACCOUNT_LIST_ROUTE, SERVICEACCOUNT_DETAIL_ROUTE, DEFAULT_ACTIONBAR])], + exports: [RouterModule], +}) +export class ServiceAccountRoutingModule {} diff --git a/src/app/frontend/typings/backendapi.ts b/src/app/frontend/typings/backendapi.ts index 6f847799c1e6..d590d07dfe11 100644 --- a/src/app/frontend/typings/backendapi.ts +++ b/src/app/frontend/typings/backendapi.ts @@ -446,6 +446,8 @@ export interface SecretDetail extends ResourceDetail { data: StringMap; } +export type ServiceAccountDetail = ResourceDetail; + export type IngressDetail = ResourceDetail; export interface PersistentVolumeClaimDetail extends ResourceDetail { From 82281ce9eb9d950a4e9107f0635ad280b18cb51e Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 10 Jun 2020 12:59:13 +0200 Subject: [PATCH 05/11] Add list view --- i18n/de/messages.de.xlf | 58 ++++++++-- i18n/fr/messages.fr.xlf | 58 ++++++++-- i18n/ja/messages.ja.xlf | 58 ++++++++-- i18n/ko/messages.ko.xlf | 58 ++++++++-- i18n/messages.xlf | 43 +++++++- i18n/zh-Hans/messages.zh-Hans.xlf | 58 ++++++++-- i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf | 58 ++++++++-- i18n/zh-Hant/messages.zh-Hant.xlf | 58 ++++++++-- src/app/frontend/chrome/nav/template.html | 5 + src/app/frontend/chrome/routing.ts | 4 + src/app/frontend/common/components/module.ts | 20 +--- .../components/resourcelist/groupids.ts | 1 + .../resourcelist/serviceaccount/component.ts | 66 ++++++++++++ .../resourcelist/serviceaccount/template.html | 100 ++++++++++++++++++ src/app/frontend/overview/template.html | 2 + .../frontend/resource/config/template.html | 2 + src/app/frontend/typings/backendapi.ts | 6 ++ 17 files changed, 563 insertions(+), 92 deletions(-) create mode 100644 src/app/frontend/common/components/resourcelist/serviceaccount/component.ts create mode 100644 src/app/frontend/common/components/resourcelist/serviceaccount/template.html diff --git a/i18n/de/messages.de.xlf b/i18n/de/messages.de.xlf index 93b8d1ee89f4..31f613cb7c5e 100644 --- a/i18n/de/messages.de.xlf +++ b/i18n/de/messages.de.xlf @@ -702,13 +702,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -786,13 +790,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Age @@ -882,13 +890,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Annotations @@ -1290,6 +1302,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + Items:  Elemente:  @@ -1409,6 +1429,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Host @@ -1909,6 +1933,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Replications Controllers @@ -2890,6 +2918,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2897,7 +2935,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2907,7 +2945,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2916,7 +2954,7 @@ Einstellungen ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2925,7 +2963,7 @@ Über ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/fr/messages.fr.xlf b/i18n/fr/messages.fr.xlf index 26cc752de568..c2ed93671907 100644 --- a/i18n/fr/messages.fr.xlf +++ b/i18n/fr/messages.fr.xlf @@ -706,13 +706,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -790,13 +794,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Age @@ -886,13 +894,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Annotations @@ -1294,6 +1306,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + Items:  Éléments :  @@ -1413,6 +1433,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Host @@ -1913,6 +1937,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Replications Controllers @@ -2894,6 +2922,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2901,7 +2939,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2911,7 +2949,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2920,7 +2958,7 @@ Paramètres ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2929,7 +2967,7 @@ À propos ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/ja/messages.ja.xlf b/i18n/ja/messages.ja.xlf index 8b4996aa6c9e..9ef3db75a32e 100644 --- a/i18n/ja/messages.ja.xlf +++ b/i18n/ja/messages.ja.xlf @@ -665,6 +665,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Name @@ -774,13 +778,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -858,13 +866,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Labels @@ -938,13 +950,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Schedule @@ -1085,6 +1101,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Age @@ -2389,6 +2409,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + You can deploy a containerized app, select other namespace or @@ -2612,6 +2640,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2619,7 +2657,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2629,7 +2667,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2638,7 +2676,7 @@ 設定 ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2647,7 +2685,7 @@ Kubernetes Dashboard について ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/ko/messages.ko.xlf b/i18n/ko/messages.ko.xlf index 33c3d004238b..25206d7516f6 100644 --- a/i18n/ko/messages.ko.xlf +++ b/i18n/ko/messages.ko.xlf @@ -861,6 +861,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Name @@ -970,13 +974,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -1054,13 +1062,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Labels @@ -1134,13 +1146,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Schedule @@ -1281,6 +1297,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Age @@ -2420,6 +2440,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + You can deploy a containerized app, select other namespace or @@ -2666,6 +2694,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2673,7 +2711,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2683,7 +2721,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2693,7 +2731,7 @@ ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2703,7 +2741,7 @@ ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/messages.xlf b/i18n/messages.xlf index 8f0f68faf648..647bbdda39d4 100644 --- a/i18n/messages.xlf +++ b/i18n/messages.xlf @@ -902,6 +902,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Name @@ -1009,6 +1013,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 51 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 + ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 @@ -1092,6 +1100,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 63 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 + ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 @@ -1171,6 +1183,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 69 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 + ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 @@ -1314,6 +1330,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Cluster Roles @@ -2284,6 +2304,13 @@ 91 + + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + You can deploy a containerized app, select other namespace or @@ -2479,12 +2506,20 @@ 145 + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2492,7 +2527,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2500,7 +2535,7 @@ ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2508,7 +2543,7 @@ ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/zh-Hans/messages.zh-Hans.xlf b/i18n/zh-Hans/messages.zh-Hans.xlf index 353b26967d27..6ba4736f8090 100644 --- a/i18n/zh-Hans/messages.zh-Hans.xlf +++ b/i18n/zh-Hans/messages.zh-Hans.xlf @@ -861,6 +861,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Name @@ -970,13 +974,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -1054,13 +1062,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Labels @@ -1134,13 +1146,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Schedule @@ -1281,6 +1297,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Age @@ -2420,6 +2440,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + You can deploy a containerized app, select other namespace or @@ -2666,6 +2694,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2673,7 +2711,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2683,7 +2721,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2693,7 +2731,7 @@ ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2703,7 +2741,7 @@ ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf b/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf index c37c414fc813..a6fc68236bfb 100644 --- a/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf +++ b/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf @@ -861,6 +861,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Name @@ -970,13 +974,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -1054,13 +1062,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Labels @@ -1134,13 +1146,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Schedule @@ -1281,6 +1297,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Age @@ -2424,6 +2444,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + You can deploy a containerized app, select other namespace or @@ -2670,6 +2698,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2677,7 +2715,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2687,7 +2725,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2697,7 +2735,7 @@ ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2707,7 +2745,7 @@ ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/i18n/zh-Hant/messages.zh-Hant.xlf b/i18n/zh-Hant/messages.zh-Hant.xlf index 343eea316170..f8ae90661a1b 100644 --- a/i18n/zh-Hant/messages.zh-Hant.xlf +++ b/i18n/zh-Hant/messages.zh-Hant.xlf @@ -861,6 +861,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 23 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 23 + Name @@ -970,13 +974,17 @@ 51 - ../src/app/frontend/create/from/form/environmentvariables/template.html - 29 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 42 ../src/app/frontend/resource/workloads/deployment/detail/template.html 223 + + ../src/app/frontend/create/from/form/environmentvariables/template.html + 29 + Namespace @@ -1054,13 +1062,17 @@ 63 - ../src/app/frontend/create/from/form/template.html - 184 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 54 ../src/app/frontend/resource/workloads/deployment/detail/template.html 231 + + ../src/app/frontend/create/from/form/template.html + 184 + Labels @@ -1134,13 +1146,17 @@ 69 - ../src/app/frontend/create/from/form/template.html - 164 + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 60 ../src/app/frontend/resource/workloads/deployment/detail/template.html 254 + + ../src/app/frontend/create/from/form/template.html + 164 + Schedule @@ -1281,6 +1297,10 @@ ../src/app/frontend/common/components/resourcelist/service/template.html 101 + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 70 + Age @@ -2424,6 +2444,14 @@ 91 + + Service Accounts + Service Accounts + + ../src/app/frontend/common/components/resourcelist/serviceaccount/template.html + 21 + + You can deploy a containerized app, select other namespace or @@ -2670,6 +2698,16 @@ 145 + + Service Accounts + + Service Accounts + + + ../src/app/frontend/chrome/nav/template.html + 150 + + Plugins @@ -2677,7 +2715,7 @@ ../src/app/frontend/chrome/nav/template.html - 151 + 156 @@ -2687,7 +2725,7 @@ ../src/app/frontend/chrome/nav/template.html - 163 + 168 @@ -2697,7 +2735,7 @@ ../src/app/frontend/chrome/nav/template.html - 175 + 180 @@ -2707,7 +2745,7 @@ ../src/app/frontend/chrome/nav/template.html - 181 + 186 diff --git a/src/app/frontend/chrome/nav/template.html b/src/app/frontend/chrome/nav/template.html index 854ac7125db4..62fb111bcb10 100644 --- a/src/app/frontend/chrome/nav/template.html +++ b/src/app/frontend/chrome/nav/template.html @@ -144,6 +144,11 @@ id="nav-secret" i18n>Secrets + Service Accounts + import('resource/config/secret/module').then(m => m.SecretModule), }, + { + path: 'serviceaccount', + loadChildren: () => import('resource/config/serviceaccount/module').then(m => m.ServiceAccountModule), + }, // Custom resource definitions { diff --git a/src/app/frontend/common/components/module.ts b/src/app/frontend/common/components/module.ts index 761d014e1ccf..5ff2cfa64964 100644 --- a/src/app/frontend/common/components/module.ts +++ b/src/app/frontend/common/components/module.ts @@ -94,6 +94,7 @@ import {TextInputComponent} from './textinput/component'; import {UploadFileComponent} from './uploadfile/component'; import {WorkloadStatusComponent} from './workloadstatus/component'; import {ZeroStateComponent} from './zerostate/component'; +import {ServiceAccountListComponent} from './resourcelist/serviceaccount/component'; const components = [ ActionbarDetailActionsComponent, @@ -105,9 +106,7 @@ const components = [ ActionbarDetailPinComponent, ActionbarComponent, ActionbarDetailTriggerComponent, - BreadcrumbsComponent, - CardComponent, CardListFilterComponent, ChipsComponent, @@ -123,43 +122,32 @@ const components = [ CRDListComponent, CRDObjectListComponent, CRDVersionListComponent, - DaemonSetListComponent, DateComponent, DeploymentListComponent, DefaultActionbar, - EndpointListComponent, ExternalEndpointComponent, EventListComponent, - GraphComponent, GraphCardComponent, GraphMetricsComponent, - HiddenPropertyComponent, HorizontalPodAutoscalerListComponent, - IngressListComponent, InternalEndpointComponent, - JobListComponent, - LoadingSpinner, ListZeroStateComponent, LogsScaleDefaultActionbar, LogsExecDefaultActionbar, LogsDefaultActionbar, - MenuComponent, - NamespaceListComponent, NodeListComponent, NamespaceSelectorComponent, NamespaceChangeDialog, - ObjectMetaComponent, - PodStatusCardComponent, PropertyComponent, ProxyComponent, @@ -168,26 +156,22 @@ const components = [ PersistentVolumeClaimListComponent, PolicyRuleListComponent, PinDefaultActionbar, - ResourceQuotaListComponent, ResourceLimitListComponent, ReplicaSetListComponent, ReplicationControllerListComponent, RowDetailComponent, - StorageClassListComponent, StatefulSetListComponent, SecretListComponent, ServiceListComponent, + ServiceAccountListComponent, CpuSparklineComponent, MemorySparklineComponent, ScaleDefaultActionbar, - TextInputComponent, TriggerDefaultActionbar, - UploadFileComponent, - ZeroStateComponent, WorkloadStatusComponent, ]; diff --git a/src/app/frontend/common/components/resourcelist/groupids.ts b/src/app/frontend/common/components/resourcelist/groupids.ts index fb92959125da..6af9b1e47d45 100644 --- a/src/app/frontend/common/components/resourcelist/groupids.ts +++ b/src/app/frontend/common/components/resourcelist/groupids.ts @@ -29,6 +29,7 @@ export enum ListIdentifier { replicaSet = 'replicaSetList', ingress = 'ingressList', service = 'serviceList', + serviceAccount = 'serviceAccountList', configMap = 'configMapList', persistentVolumeClaim = 'persistentVolumeClaimList', secret = 'secretList', diff --git a/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts b/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts new file mode 100644 index 000000000000..98094f652648 --- /dev/null +++ b/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts @@ -0,0 +1,66 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import {HttpParams} from '@angular/common/http'; +import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input} from '@angular/core'; +import {Observable} from 'rxjs/Observable'; +import {ServiceAccount, ServiceAccountList} from 'typings/backendapi'; + +import {ResourceListBase} from '../../../resources/list'; +import {NotificationsService} from '../../../services/global/notifications'; +import {EndpointManager, Resource} from '../../../services/resource/endpoint'; +import {NamespacedResourceService} from '../../../services/resource/resource'; +import {MenuComponent} from '../../list/column/menu/component'; +import {ListGroupIdentifier, ListIdentifier} from '../groupids'; + +@Component({ + selector: 'kd-service-account-list', + templateUrl: './template.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ServiceAccountListComponent extends ResourceListBase { + @Input() endpoint = EndpointManager.resource(Resource.serviceAccount, true).list(); + + constructor( + private readonly serviceAccount_: NamespacedResourceService, + notifications: NotificationsService, + cdr: ChangeDetectorRef, + ) { + super('serviceAccount', notifications, cdr); + this.id = ListIdentifier.serviceAccount; + this.groupId = ListGroupIdentifier.config; + + // Register action columns. + this.registerActionColumn('menu', MenuComponent); + + // Register dynamic columns. + this.registerDynamicColumn('namespace', 'name', this.shouldShowNamespaceColumn_.bind(this)); + } + + getResourceObservable(params?: HttpParams): Observable { + return this.serviceAccount_.get(this.endpoint, undefined, undefined, params); + } + + map(serviceAccountList: ServiceAccountList): ServiceAccount[] { + return serviceAccountList.items; + } + + getDisplayColumns(): string[] { + return ['name', 'labels', 'created']; + } + + private shouldShowNamespaceColumn_(): boolean { + return this.namespaceService_.areMultipleNamespacesSelected(); + } +} diff --git a/src/app/frontend/common/components/resourcelist/serviceaccount/template.html b/src/app/frontend/common/components/resourcelist/serviceaccount/template.html new file mode 100644 index 000000000000..f5640ca8e820 --- /dev/null +++ b/src/app/frontend/common/components/resourcelist/serviceaccount/template.html @@ -0,0 +1,100 @@ + + + +
Service Accounts
+
Items: {{totalItems}}
+
+ +
+ +
+
+ + + + Name + + + {{serviceAccount.objectMeta.name}} + + + + + + Namespace + {{serviceAccount.objectMeta.namespace}} + + + + Labels + + + + + + + Created + + + + + + + + + + + + + + + + + +
+ +
+ +
+
diff --git a/src/app/frontend/overview/template.html b/src/app/frontend/overview/template.html index 94b0af4f37dc..cb3e3698aa38 100644 --- a/src/app/frontend/overview/template.html +++ b/src/app/frontend/overview/template.html @@ -62,6 +62,8 @@ [hideable]="true"> + diff --git a/src/app/frontend/resource/config/template.html b/src/app/frontend/resource/config/template.html index 30e7ff05ce3f..30cf431a4c7c 100644 --- a/src/app/frontend/resource/config/template.html +++ b/src/app/frontend/resource/config/template.html @@ -21,6 +21,8 @@ [hideable]="true"> + diff --git a/src/app/frontend/typings/backendapi.ts b/src/app/frontend/typings/backendapi.ts index d590d07dfe11..2505d6858418 100644 --- a/src/app/frontend/typings/backendapi.ts +++ b/src/app/frontend/typings/backendapi.ts @@ -123,6 +123,10 @@ export interface IngressList extends ResourceList { items: Ingress[]; } +export interface ServiceAccountList extends ResourceList { + items: ServiceAccount[]; +} + export interface JobList extends ResourceList { cumulativeMetrics: Metric[] | null; jobs: Job[]; @@ -195,6 +199,8 @@ export type ClusterRole = Resource; export type ConfigMap = Resource; +export type ServiceAccount = Resource; + export interface Controller extends Resource { pods: PodInfo; containerImages: string[]; From 1fa850495f8451b76afd324c5af3667eccdf41d0 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Wed, 10 Jun 2020 13:01:07 +0200 Subject: [PATCH 06/11] Fix link --- .../common/components/resourcelist/serviceaccount/component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts b/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts index 98094f652648..20d00a13a484 100644 --- a/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts +++ b/src/app/frontend/common/components/resourcelist/serviceaccount/component.ts @@ -37,7 +37,7 @@ export class ServiceAccountListComponent extends ResourceListBase Date: Thu, 18 Jun 2020 13:32:52 +0200 Subject: [PATCH 07/11] Add image pull secret list to the service account detail view --- i18n/de/messages.de.xlf | 16 ++--- i18n/fr/messages.fr.xlf | 16 ++--- i18n/ja/messages.ja.xlf | 16 ++--- i18n/ko/messages.ko.xlf | 6 +- i18n/messages.xlf | 4 +- i18n/zh-Hans/messages.zh-Hans.xlf | 6 +- i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf | 6 +- i18n/zh-Hant/messages.zh-Hant.xlf | 6 +- src/app/backend/handler/apihandler.go | 24 +++++++ src/app/backend/resource/secret/list.go | 4 +- src/app/backend/resource/secret/list_test.go | 2 +- .../resource/serviceaccount/secrets.go | 65 +++++++++++++++++++ .../resourcelist/secret/component.ts | 1 + .../resourcelist/secret/template.html | 2 +- .../common/services/resource/endpoint.ts | 1 + .../config/serviceaccount/detail/component.ts | 3 + .../serviceaccount/detail/template.html | 3 + 17 files changed, 139 insertions(+), 42 deletions(-) create mode 100644 src/app/backend/resource/serviceaccount/secrets.go diff --git a/i18n/de/messages.de.xlf b/i18n/de/messages.de.xlf index 31f613cb7c5e..4709c1a12fe6 100644 --- a/i18n/de/messages.de.xlf +++ b/i18n/de/messages.de.xlf @@ -1794,6 +1794,14 @@ 58
+ + + + + ../src/app/frontend/common/components/resourcelist/secret/template.html + 21 + + Schedule Planung @@ -1970,14 +1978,6 @@ 54 - - Secrets - Secrets - - ../src/app/frontend/common/components/resourcelist/secret/template.html - 21 - - Message Nachricht diff --git a/i18n/fr/messages.fr.xlf b/i18n/fr/messages.fr.xlf index c2ed93671907..739e1425e62d 100644 --- a/i18n/fr/messages.fr.xlf +++ b/i18n/fr/messages.fr.xlf @@ -1798,6 +1798,14 @@ 58 + + + + + ../src/app/frontend/common/components/resourcelist/secret/template.html + 21 + + Schedule Planning @@ -1974,14 +1982,6 @@ 54 - - Secrets - Secrets - - ../src/app/frontend/common/components/resourcelist/secret/template.html - 21 - - Message Message diff --git a/i18n/ja/messages.ja.xlf b/i18n/ja/messages.ja.xlf index 9ef3db75a32e..3e77a7e0efd6 100644 --- a/i18n/ja/messages.ja.xlf +++ b/i18n/ja/messages.ja.xlf @@ -2293,6 +2293,14 @@ 58 + + + + + ../src/app/frontend/common/components/resourcelist/secret/template.html + 21 + + Stateful Sets ステートフルセット @@ -2365,14 +2373,6 @@ 22 - - Secrets - シークレット - - ../src/app/frontend/common/components/resourcelist/secret/template.html - 21 - - Services サービス diff --git a/i18n/ko/messages.ko.xlf b/i18n/ko/messages.ko.xlf index 25206d7516f6..0f2310a77032 100644 --- a/i18n/ko/messages.ko.xlf +++ b/i18n/ko/messages.ko.xlf @@ -2396,9 +2396,9 @@ 58 - - Secrets - 시크릿 + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/messages.xlf b/i18n/messages.xlf index 647bbdda39d4..a95c32a26f1a 100644 --- a/i18n/messages.xlf +++ b/i18n/messages.xlf @@ -2265,8 +2265,8 @@ 58 - - Secrets + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/zh-Hans/messages.zh-Hans.xlf b/i18n/zh-Hans/messages.zh-Hans.xlf index 6ba4736f8090..00d5d07d2cb8 100644 --- a/i18n/zh-Hans/messages.zh-Hans.xlf +++ b/i18n/zh-Hans/messages.zh-Hans.xlf @@ -2396,9 +2396,9 @@ 58 - - Secrets - Secrets + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf b/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf index a6fc68236bfb..4dba5f743a10 100644 --- a/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf +++ b/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf @@ -2400,9 +2400,9 @@ 58 - - Secrets - Secrets + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/zh-Hant/messages.zh-Hant.xlf b/i18n/zh-Hant/messages.zh-Hant.xlf index f8ae90661a1b..4dc600947045 100644 --- a/i18n/zh-Hant/messages.zh-Hant.xlf +++ b/i18n/zh-Hant/messages.zh-Hant.xlf @@ -2400,9 +2400,9 @@ 58 - - Secrets - Secrets + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/src/app/backend/handler/apihandler.go b/src/app/backend/handler/apihandler.go index bbe9c7331cb2..b10f4cbb3c8b 100644 --- a/src/app/backend/handler/apihandler.go +++ b/src/app/backend/handler/apihandler.go @@ -458,6 +458,10 @@ func CreateHTTPAPIHandler(iManager integration.IntegrationManager, cManager clie apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}"). To(apiHandler.handleGetServiceAccountDetail). Writes(serviceaccount.ServiceAccountDetail{})) + apiV1Ws.Route( + apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}/imagepullsecret"). + To(apiHandler.handleGetServiceAccountImagePullSecrets). + Writes(secret.SecretList{})) apiV1Ws.Route( apiV1Ws.GET("/ingress"). @@ -951,6 +955,26 @@ func (apiHandler *APIHandler) handleGetServiceAccountDetail(request *restful.Req response.WriteHeaderAndEntity(http.StatusOK, result) } +func (apiHandler *APIHandler) handleGetServiceAccountImagePullSecrets(request *restful.Request, response *restful.Response) { + k8sClient, err := apiHandler.cManager.Client(request) + if err != nil { + errors.HandleInternalError(response, err) + return + } + + namespace := request.PathParameter("namespace") + name := request.PathParameter("serviceaccount") + dataSelect := parser.ParseDataSelectPathParameter(request) + result, err := serviceaccount.GetServiceAccountImagePullSecrets(k8sClient, namespace, name, dataSelect) + if err != nil { + errors.HandleInternalError(response, err) + return + } + response.WriteHeaderAndEntity(http.StatusOK, result) +} + + + func (apiHandler *APIHandler) handleGetIngressDetail(request *restful.Request, response *restful.Response) { k8sClient, err := apiHandler.cManager.Client(request) if err != nil { diff --git a/src/app/backend/resource/secret/list.go b/src/app/backend/resource/secret/list.go index 70e0c2cd21bb..f31ba22935bc 100644 --- a/src/app/backend/resource/secret/list.go +++ b/src/app/backend/resource/secret/list.go @@ -93,7 +93,7 @@ func GetSecretList(client kubernetes.Interface, namespace *common.NamespaceQuery return nil, criticalError } - return toSecretList(secretList.Items, nonCriticalErrors, dsQuery), nil + return ToSecretList(secretList.Items, nonCriticalErrors, dsQuery), nil } // CreateSecret creates a single secret using the cluster API client @@ -120,7 +120,7 @@ func toSecret(secret *v1.Secret) Secret { } } -func toSecretList(secrets []v1.Secret, nonCriticalErrors []error, dsQuery *dataselect.DataSelectQuery) *SecretList { +func ToSecretList(secrets []v1.Secret, nonCriticalErrors []error, dsQuery *dataselect.DataSelectQuery) *SecretList { newSecretList := &SecretList{ ListMeta: api.ListMeta{TotalItems: len(secrets)}, Secrets: make([]Secret, 0), diff --git a/src/app/backend/resource/secret/list_test.go b/src/app/backend/resource/secret/list_test.go index 8a8cb9335aff..4b6155bda30d 100644 --- a/src/app/backend/resource/secret/list_test.go +++ b/src/app/backend/resource/secret/list_test.go @@ -76,7 +76,7 @@ func TestToSecretList(t *testing.T) { } for _, c := range cases { - actual := toSecretList(c.secrets, nil, dataselect.NoDataSelect) + actual := ToSecretList(c.secrets, nil, dataselect.NoDataSelect) if !reflect.DeepEqual(actual, c.expected) { t.Errorf("toSecretList() ==\n%#v\nExpected: %#v", actual, c.expected) } diff --git a/src/app/backend/resource/serviceaccount/secrets.go b/src/app/backend/resource/serviceaccount/secrets.go new file mode 100644 index 000000000000..3037485ad64f --- /dev/null +++ b/src/app/backend/resource/serviceaccount/secrets.go @@ -0,0 +1,65 @@ +// Copyright 2017 The Kubernetes Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package serviceaccount + +import ( + "context" + "github.com/kubernetes/dashboard/src/app/backend/resource/common" + "github.com/kubernetes/dashboard/src/app/backend/resource/dataselect" + "github.com/kubernetes/dashboard/src/app/backend/resource/secret" + v1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sClient "k8s.io/client-go/kubernetes" +) + +// GetServiceAccountImagePullSecrets lits of image pull secrets of given service account. +func GetServiceAccountImagePullSecrets(client k8sClient.Interface, namespace, + name string, dsQuery *dataselect.DataSelectQuery) (*secret.SecretList, error) { + secretList := secret.SecretList{ + Secrets: []secret.Secret{}, + } + + serviceAccount, err := client.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metaV1.GetOptions{}) + if err != nil { + return &secretList, err + } + + if serviceAccount.ImagePullSecrets == nil { + return &secretList, nil + } + + channels := &common.ResourceChannels{ + SecretList: common.GetSecretListChannel(client, common.NewSameNamespaceQuery(namespace), 1), + } + + apiSecretList := <-channels.SecretList.List + if err := <-channels.SecretList.Error; err != nil { + return &secretList, err + } + + imagePullSecretsMap := map[string]struct{}{} + for _, ips := range serviceAccount.ImagePullSecrets { + imagePullSecretsMap[ips.Name] = struct{}{} + } + + var imagePullSecretList []v1.Secret + for _, apiSecret := range apiSecretList.Items { + if _, ok := imagePullSecretsMap[apiSecret.Name]; ok { + imagePullSecretList = append(imagePullSecretList, apiSecret) + } + } + + return secret.ToSecretList(imagePullSecretList, []error{}, dsQuery), nil +} diff --git a/src/app/frontend/common/components/resourcelist/secret/component.ts b/src/app/frontend/common/components/resourcelist/secret/component.ts index 56a9ecc39a28..853dbed9985b 100644 --- a/src/app/frontend/common/components/resourcelist/secret/component.ts +++ b/src/app/frontend/common/components/resourcelist/secret/component.ts @@ -29,6 +29,7 @@ import {ListGroupIdentifier, ListIdentifier} from '../groupids'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class SecretListComponent extends ResourceListBase { + @Input() cardTitle = 'Secrets'; @Input() endpoint = EndpointManager.resource(Resource.secret, true).list(); constructor( diff --git a/src/app/frontend/common/components/resourcelist/secret/template.html b/src/app/frontend/common/components/resourcelist/secret/template.html index b761bc152e2d..22420ebdb9d9 100644 --- a/src/app/frontend/common/components/resourcelist/secret/template.html +++ b/src/app/frontend/common/components/resourcelist/secret/template.html @@ -18,7 +18,7 @@ [hidden]="isHidden()">
Secrets
+ i18n>{{cardTitle}}
Items: {{totalItems}}
diff --git a/src/app/frontend/common/services/resource/endpoint.ts b/src/app/frontend/common/services/resource/endpoint.ts index d2d40433eeca..29ac37ab8be5 100644 --- a/src/app/frontend/common/services/resource/endpoint.ts +++ b/src/app/frontend/common/services/resource/endpoint.ts @@ -37,6 +37,7 @@ export enum Resource { configMap = 'configmap', persistentVolumeClaim = 'persistentvolumeclaim', secret = 'secret', + imagePullSecret = 'imagepullsecret', ingress = 'ingress', service = 'service', serviceAccount = 'serviceaccount', diff --git a/src/app/frontend/resource/config/serviceaccount/detail/component.ts b/src/app/frontend/resource/config/serviceaccount/detail/component.ts index d0f4a4dc5318..e3a3f6efaec9 100644 --- a/src/app/frontend/resource/config/serviceaccount/detail/component.ts +++ b/src/app/frontend/resource/config/serviceaccount/detail/component.ts @@ -31,6 +31,7 @@ import {NamespacedResourceService} from '../../../../common/services/resource/re export class ServiceAccountDetailComponent implements OnInit, OnDestroy { private serviceAccountSubscription_: Subscription; private readonly endpoint_ = EndpointManager.resource(Resource.serviceAccount, true); + secretListEndpoint: string; serviceAccount: ServiceAccountDetail; isInitialized = false; @@ -45,6 +46,8 @@ export class ServiceAccountDetailComponent implements OnInit, OnDestroy { const resourceName = this.activatedRoute_.snapshot.params.resourceName; const resourceNamespace = this.activatedRoute_.snapshot.params.resourceNamespace; + this.secretListEndpoint = this.endpoint_.child(resourceName, Resource.imagePullSecret, resourceNamespace); + this.serviceAccountSubscription_ = this.serviceAccount_ .get(this.endpoint_.detail(), resourceName, resourceNamespace) .subscribe((d: ServiceAccountDetail) => { diff --git a/src/app/frontend/resource/config/serviceaccount/detail/template.html b/src/app/frontend/resource/config/serviceaccount/detail/template.html index 11b40deb810e..72248e9b11e0 100644 --- a/src/app/frontend/resource/config/serviceaccount/detail/template.html +++ b/src/app/frontend/resource/config/serviceaccount/detail/template.html @@ -16,3 +16,6 @@ + + From f2e415f2074953f9a814e3e06f4a4355f683043a Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 18 Jun 2020 13:34:23 +0200 Subject: [PATCH 08/11] Update variable name --- .../resource/config/serviceaccount/detail/component.ts | 4 ++-- .../resource/config/serviceaccount/detail/template.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/frontend/resource/config/serviceaccount/detail/component.ts b/src/app/frontend/resource/config/serviceaccount/detail/component.ts index e3a3f6efaec9..dab14b3c65c4 100644 --- a/src/app/frontend/resource/config/serviceaccount/detail/component.ts +++ b/src/app/frontend/resource/config/serviceaccount/detail/component.ts @@ -31,7 +31,7 @@ import {NamespacedResourceService} from '../../../../common/services/resource/re export class ServiceAccountDetailComponent implements OnInit, OnDestroy { private serviceAccountSubscription_: Subscription; private readonly endpoint_ = EndpointManager.resource(Resource.serviceAccount, true); - secretListEndpoint: string; + imagePullSecretListEndpoint: string; serviceAccount: ServiceAccountDetail; isInitialized = false; @@ -46,7 +46,7 @@ export class ServiceAccountDetailComponent implements OnInit, OnDestroy { const resourceName = this.activatedRoute_.snapshot.params.resourceName; const resourceNamespace = this.activatedRoute_.snapshot.params.resourceNamespace; - this.secretListEndpoint = this.endpoint_.child(resourceName, Resource.imagePullSecret, resourceNamespace); + this.imagePullSecretListEndpoint = this.endpoint_.child(resourceName, Resource.imagePullSecret, resourceNamespace); this.serviceAccountSubscription_ = this.serviceAccount_ .get(this.endpoint_.detail(), resourceName, resourceNamespace) diff --git a/src/app/frontend/resource/config/serviceaccount/detail/template.html b/src/app/frontend/resource/config/serviceaccount/detail/template.html index 72248e9b11e0..dd84bca46bdc 100644 --- a/src/app/frontend/resource/config/serviceaccount/detail/template.html +++ b/src/app/frontend/resource/config/serviceaccount/detail/template.html @@ -17,5 +17,5 @@ - From 3d97184571bd7c7c69d49dffa8df63ac5691a7b3 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 18 Jun 2020 14:24:09 +0200 Subject: [PATCH 09/11] Add secrets --- src/app/backend/handler/apihandler.go | 56 ++++++++---- .../resource/serviceaccount/secrets.go | 88 ++++++++++++++----- .../config/serviceaccount/detail/component.ts | 2 + .../serviceaccount/detail/template.html | 2 + 4 files changed, 108 insertions(+), 40 deletions(-) diff --git a/src/app/backend/handler/apihandler.go b/src/app/backend/handler/apihandler.go index b10f4cbb3c8b..343d4dc9c8e3 100644 --- a/src/app/backend/handler/apihandler.go +++ b/src/app/backend/handler/apihandler.go @@ -458,10 +458,14 @@ func CreateHTTPAPIHandler(iManager integration.IntegrationManager, cManager clie apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}"). To(apiHandler.handleGetServiceAccountDetail). Writes(serviceaccount.ServiceAccountDetail{})) - apiV1Ws.Route( - apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}/imagepullsecret"). - To(apiHandler.handleGetServiceAccountImagePullSecrets). - Writes(secret.SecretList{})) + apiV1Ws.Route( + apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}/secret"). + To(apiHandler.handleGetServiceAccountSecrets). + Writes(secret.SecretList{})) + apiV1Ws.Route( + apiV1Ws.GET("/serviceaccount/{namespace}/{serviceaccount}/imagepullsecret"). + To(apiHandler.handleGetServiceAccountImagePullSecrets). + Writes(secret.SecretList{})) apiV1Ws.Route( apiV1Ws.GET("/ingress"). @@ -956,24 +960,40 @@ func (apiHandler *APIHandler) handleGetServiceAccountDetail(request *restful.Req } func (apiHandler *APIHandler) handleGetServiceAccountImagePullSecrets(request *restful.Request, response *restful.Response) { - k8sClient, err := apiHandler.cManager.Client(request) - if err != nil { - errors.HandleInternalError(response, err) - return - } + k8sClient, err := apiHandler.cManager.Client(request) + if err != nil { + errors.HandleInternalError(response, err) + return + } - namespace := request.PathParameter("namespace") - name := request.PathParameter("serviceaccount") - dataSelect := parser.ParseDataSelectPathParameter(request) - result, err := serviceaccount.GetServiceAccountImagePullSecrets(k8sClient, namespace, name, dataSelect) - if err != nil { - errors.HandleInternalError(response, err) - return - } - response.WriteHeaderAndEntity(http.StatusOK, result) + namespace := request.PathParameter("namespace") + name := request.PathParameter("serviceaccount") + dataSelect := parser.ParseDataSelectPathParameter(request) + result, err := serviceaccount.GetServiceAccountImagePullSecrets(k8sClient, namespace, name, dataSelect) + if err != nil { + errors.HandleInternalError(response, err) + return + } + response.WriteHeaderAndEntity(http.StatusOK, result) } +func (apiHandler *APIHandler) handleGetServiceAccountSecrets(request *restful.Request, response *restful.Response) { + k8sClient, err := apiHandler.cManager.Client(request) + if err != nil { + errors.HandleInternalError(response, err) + return + } + namespace := request.PathParameter("namespace") + name := request.PathParameter("serviceaccount") + dataSelect := parser.ParseDataSelectPathParameter(request) + result, err := serviceaccount.GetServiceAccountSecrets(k8sClient, namespace, name, dataSelect) + if err != nil { + errors.HandleInternalError(response, err) + return + } + response.WriteHeaderAndEntity(http.StatusOK, result) +} func (apiHandler *APIHandler) handleGetIngressDetail(request *restful.Request, response *restful.Response) { k8sClient, err := apiHandler.cManager.Client(request) diff --git a/src/app/backend/resource/serviceaccount/secrets.go b/src/app/backend/resource/serviceaccount/secrets.go index 3037485ad64f..5512926e6d6a 100644 --- a/src/app/backend/resource/serviceaccount/secrets.go +++ b/src/app/backend/resource/serviceaccount/secrets.go @@ -15,28 +15,72 @@ package serviceaccount import ( - "context" - "github.com/kubernetes/dashboard/src/app/backend/resource/common" - "github.com/kubernetes/dashboard/src/app/backend/resource/dataselect" - "github.com/kubernetes/dashboard/src/app/backend/resource/secret" - v1 "k8s.io/api/core/v1" - metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" - k8sClient "k8s.io/client-go/kubernetes" + "context" + "github.com/kubernetes/dashboard/src/app/backend/resource/common" + "github.com/kubernetes/dashboard/src/app/backend/resource/dataselect" + "github.com/kubernetes/dashboard/src/app/backend/resource/secret" + v1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sClient "k8s.io/client-go/kubernetes" ) -// GetServiceAccountImagePullSecrets lits of image pull secrets of given service account. +// GetServiceAccountImagePullSecrets list image pull secrets of given service account. func GetServiceAccountImagePullSecrets(client k8sClient.Interface, namespace, name string, dsQuery *dataselect.DataSelectQuery) (*secret.SecretList, error) { - secretList := secret.SecretList{ - Secrets: []secret.Secret{}, - } + imagePullSecretList := secret.SecretList{ + Secrets: []secret.Secret{}, + } serviceAccount, err := client.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metaV1.GetOptions{}) if err != nil { - return &secretList, err + return &imagePullSecretList, err } if serviceAccount.ImagePullSecrets == nil { + return &imagePullSecretList, nil + } + + channels := &common.ResourceChannels{ + SecretList: common.GetSecretListChannel(client, common.NewSameNamespaceQuery(namespace), 1), + } + + apiSecretList := <-channels.SecretList.List + if err := <-channels.SecretList.Error; err != nil { + return &imagePullSecretList, err + } + + imagePullSecretsMap := map[string]struct{}{} + for _, ips := range serviceAccount.ImagePullSecrets { + imagePullSecretsMap[ips.Name] = struct{}{} + } + + var rawImagePullSecretList []v1.Secret + for _, apiSecret := range apiSecretList.Items { + if _, ok := imagePullSecretsMap[apiSecret.Name]; ok { + rawImagePullSecretList = append(rawImagePullSecretList, apiSecret) + } + } + + return secret.ToSecretList(rawImagePullSecretList, []error{}, dsQuery), nil +} + +// GetServiceAccountSecrets list secrets of given service account. +// Note: Secrets are referenced by ObjectReference compared to image pull secrets LocalObjectReference but still only +// the name field is used and most of the time other fields are empty. Because of that we are using only the name field +// to find referenced objects assuming that the namespace is the same. ObjectReference is being slowly replaced with +// more specific types. +func GetServiceAccountSecrets(client k8sClient.Interface, namespace, + name string, dsQuery *dataselect.DataSelectQuery) (*secret.SecretList, error) { + secretList := secret.SecretList{ + Secrets: []secret.Secret{}, + } + + serviceAccount, err := client.CoreV1().ServiceAccounts(namespace).Get(context.TODO(), name, metaV1.GetOptions{}) + if err != nil { + return &secretList, err + } + + if serviceAccount.Secrets == nil { return &secretList, nil } @@ -49,17 +93,17 @@ func GetServiceAccountImagePullSecrets(client k8sClient.Interface, namespace, return &secretList, err } - imagePullSecretsMap := map[string]struct{}{} - for _, ips := range serviceAccount.ImagePullSecrets { - imagePullSecretsMap[ips.Name] = struct{}{} - } + secretsMap := map[string]v1.ObjectReference{} + for _, s := range serviceAccount.Secrets { + secretsMap[s.Name] = s + } - var imagePullSecretList []v1.Secret + var rawSecretList []v1.Secret for _, apiSecret := range apiSecretList.Items { - if _, ok := imagePullSecretsMap[apiSecret.Name]; ok { - imagePullSecretList = append(imagePullSecretList, apiSecret) - } - } + if _, ok := secretsMap[apiSecret.Name]; ok { + rawSecretList = append(rawSecretList, apiSecret) + } + } - return secret.ToSecretList(imagePullSecretList, []error{}, dsQuery), nil + return secret.ToSecretList(rawSecretList, []error{}, dsQuery), nil } diff --git a/src/app/frontend/resource/config/serviceaccount/detail/component.ts b/src/app/frontend/resource/config/serviceaccount/detail/component.ts index dab14b3c65c4..5903a8178cd0 100644 --- a/src/app/frontend/resource/config/serviceaccount/detail/component.ts +++ b/src/app/frontend/resource/config/serviceaccount/detail/component.ts @@ -31,6 +31,7 @@ import {NamespacedResourceService} from '../../../../common/services/resource/re export class ServiceAccountDetailComponent implements OnInit, OnDestroy { private serviceAccountSubscription_: Subscription; private readonly endpoint_ = EndpointManager.resource(Resource.serviceAccount, true); + secretListEndpoint: string; imagePullSecretListEndpoint: string; serviceAccount: ServiceAccountDetail; isInitialized = false; @@ -46,6 +47,7 @@ export class ServiceAccountDetailComponent implements OnInit, OnDestroy { const resourceName = this.activatedRoute_.snapshot.params.resourceName; const resourceNamespace = this.activatedRoute_.snapshot.params.resourceNamespace; + this.secretListEndpoint = this.endpoint_.child(resourceName, Resource.secret, resourceNamespace); this.imagePullSecretListEndpoint = this.endpoint_.child(resourceName, Resource.imagePullSecret, resourceNamespace); this.serviceAccountSubscription_ = this.serviceAccount_ diff --git a/src/app/frontend/resource/config/serviceaccount/detail/template.html b/src/app/frontend/resource/config/serviceaccount/detail/template.html index dd84bca46bdc..b447633a8961 100644 --- a/src/app/frontend/resource/config/serviceaccount/detail/template.html +++ b/src/app/frontend/resource/config/serviceaccount/detail/template.html @@ -17,5 +17,7 @@ + + From 4ca98f49ed343b5c9e2e2e33b90a639825d94536 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 18 Jun 2020 14:34:04 +0200 Subject: [PATCH 10/11] Change property name --- i18n/de/messages.de.xlf | 6 +++--- i18n/fr/messages.fr.xlf | 6 +++--- i18n/ja/messages.ja.xlf | 6 +++--- i18n/ko/messages.ko.xlf | 6 +++--- i18n/messages.xlf | 4 ++-- i18n/zh-Hans/messages.zh-Hans.xlf | 6 +++--- i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf | 6 +++--- i18n/zh-Hant/messages.zh-Hant.xlf | 6 +++--- .../common/components/resourcelist/secret/component.ts | 2 +- .../common/components/resourcelist/secret/template.html | 2 +- 10 files changed, 25 insertions(+), 25 deletions(-) diff --git a/i18n/de/messages.de.xlf b/i18n/de/messages.de.xlf index 4709c1a12fe6..ad364aae4f06 100644 --- a/i18n/de/messages.de.xlf +++ b/i18n/de/messages.de.xlf @@ -1794,9 +1794,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/fr/messages.fr.xlf b/i18n/fr/messages.fr.xlf index 739e1425e62d..7b5a44879ca5 100644 --- a/i18n/fr/messages.fr.xlf +++ b/i18n/fr/messages.fr.xlf @@ -1798,9 +1798,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/ja/messages.ja.xlf b/i18n/ja/messages.ja.xlf index 3e77a7e0efd6..f670d3d42f36 100644 --- a/i18n/ja/messages.ja.xlf +++ b/i18n/ja/messages.ja.xlf @@ -2293,9 +2293,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/ko/messages.ko.xlf b/i18n/ko/messages.ko.xlf index 0f2310a77032..d5b7b7c1d990 100644 --- a/i18n/ko/messages.ko.xlf +++ b/i18n/ko/messages.ko.xlf @@ -2396,9 +2396,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/messages.xlf b/i18n/messages.xlf index a95c32a26f1a..86176e7b89a1 100644 --- a/i18n/messages.xlf +++ b/i18n/messages.xlf @@ -2265,8 +2265,8 @@ 58 - - + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/zh-Hans/messages.zh-Hans.xlf b/i18n/zh-Hans/messages.zh-Hans.xlf index 00d5d07d2cb8..cce752c47724 100644 --- a/i18n/zh-Hans/messages.zh-Hans.xlf +++ b/i18n/zh-Hans/messages.zh-Hans.xlf @@ -2396,9 +2396,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf b/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf index 4dba5f743a10..45493c8fb753 100644 --- a/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf +++ b/i18n/zh-Hant-HK/messages.zh-Hant-HK.xlf @@ -2400,9 +2400,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/i18n/zh-Hant/messages.zh-Hant.xlf b/i18n/zh-Hant/messages.zh-Hant.xlf index 4dc600947045..0ce901fba80d 100644 --- a/i18n/zh-Hant/messages.zh-Hant.xlf +++ b/i18n/zh-Hant/messages.zh-Hant.xlf @@ -2400,9 +2400,9 @@ 58 - - - + + + ../src/app/frontend/common/components/resourcelist/secret/template.html 21 diff --git a/src/app/frontend/common/components/resourcelist/secret/component.ts b/src/app/frontend/common/components/resourcelist/secret/component.ts index 853dbed9985b..1daca09d6535 100644 --- a/src/app/frontend/common/components/resourcelist/secret/component.ts +++ b/src/app/frontend/common/components/resourcelist/secret/component.ts @@ -29,7 +29,7 @@ import {ListGroupIdentifier, ListIdentifier} from '../groupids'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class SecretListComponent extends ResourceListBase { - @Input() cardTitle = 'Secrets'; + @Input() title = 'Secrets'; @Input() endpoint = EndpointManager.resource(Resource.secret, true).list(); constructor( diff --git a/src/app/frontend/common/components/resourcelist/secret/template.html b/src/app/frontend/common/components/resourcelist/secret/template.html index 22420ebdb9d9..34fc3909bd7a 100644 --- a/src/app/frontend/common/components/resourcelist/secret/template.html +++ b/src/app/frontend/common/components/resourcelist/secret/template.html @@ -18,7 +18,7 @@ [hidden]="isHidden()">
{{cardTitle}}
+ i18n>{{title}}
Items: {{totalItems}}
From 19373dd71cb060bfcb7042ae890d518cd32979e4 Mon Sep 17 00:00:00 2001 From: Marcin Maciaszczyk Date: Thu, 18 Jun 2020 16:05:39 +0200 Subject: [PATCH 11/11] Goimport files --- src/app/backend/resource/serviceaccount/detail.go | 3 ++- src/app/backend/resource/serviceaccount/list.go | 1 + src/app/backend/resource/serviceaccount/secrets.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/backend/resource/serviceaccount/detail.go b/src/app/backend/resource/serviceaccount/detail.go index 31b5b80a3418..db53b94ca736 100644 --- a/src/app/backend/resource/serviceaccount/detail.go +++ b/src/app/backend/resource/serviceaccount/detail.go @@ -16,10 +16,11 @@ package serviceaccount import ( "context" + "log" + v1 "k8s.io/api/core/v1" metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" client "k8s.io/client-go/kubernetes" - "log" ) // ServiceAccountDetail contains detailed information about a service account. diff --git a/src/app/backend/resource/serviceaccount/list.go b/src/app/backend/resource/serviceaccount/list.go index dca084855d6b..ed370594e38f 100644 --- a/src/app/backend/resource/serviceaccount/list.go +++ b/src/app/backend/resource/serviceaccount/list.go @@ -16,6 +16,7 @@ package serviceaccount import ( "context" + v1 "k8s.io/api/core/v1" "github.com/kubernetes/dashboard/src/app/backend/api" diff --git a/src/app/backend/resource/serviceaccount/secrets.go b/src/app/backend/resource/serviceaccount/secrets.go index 5512926e6d6a..17357619efd6 100644 --- a/src/app/backend/resource/serviceaccount/secrets.go +++ b/src/app/backend/resource/serviceaccount/secrets.go @@ -16,6 +16,7 @@ package serviceaccount import ( "context" + "github.com/kubernetes/dashboard/src/app/backend/resource/common" "github.com/kubernetes/dashboard/src/app/backend/resource/dataselect" "github.com/kubernetes/dashboard/src/app/backend/resource/secret"