未验证 提交 b6508a34 编写于 作者: S Sebastian Florek 提交者: GitHub

Fix ingress view and long container env variables display (#5975)

* Fix ingress view and long container env variables display

* Improve container display and fix some styling issues
上级 3067ebf7
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -85,6 +85,9 @@ type Container struct {
// Security configuration that will be applied to a container.
SecurityContext *v1.SecurityContext `json:"securityContext"`
// Status of a pod container
Status *v1.ContainerStatus `json:"status"`
}
// EnvVar represents an environment variable of a container.
......@@ -258,6 +261,7 @@ func extractContainerInfo(containerList []v1.Container, pod *v1.Pod, configMaps
Args: container.Args,
VolumeMounts: volume_mounts,
SecurityContext: container.SecurityContext,
Status: extractContainerStatus(pod, &container),
})
}
return containers
......@@ -422,3 +426,13 @@ func extractContainerResourceValue(fs *v1.ResourceFieldSelector, container *v1.C
return "", fmt.Errorf("Unsupported container resource : %v", fs.Resource)
}
func extractContainerStatus(pod *v1.Pod, container *v1.Container) *v1.ContainerStatus {
for _, status := range pod.Status.ContainerStatuses {
if status.Name == container.Name {
return &status
}
}
return nil
}
......@@ -30,8 +30,7 @@ limitations under the License.
<div content>
<mat-table [dataSource]="getDataSource()"
[trackBy]="trackByConditionType"
class="kd-table-no-footer">
[trackBy]="trackByConditionType">
<ng-container [matColumnDef]="getConditionsColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Type</mat-header-cell>
......
......@@ -14,10 +14,10 @@
import {Component, Input, OnChanges} from '@angular/core';
import {ConfigMapKeyRef, Container, EnvVar, SecretKeyRef} from '@api/root.api';
import {Status, StatusClass} from '@common/components/resourcelist/statuses';
import {KdStateService} from '@common/services/global/state';
import * as _ from 'lodash';
import {KdStateService} from '../../services/global/state';
@Component({
selector: 'kd-container-card',
templateUrl: './template.html',
......@@ -30,6 +30,38 @@ export class ContainerCardComponent implements OnChanges {
constructor(private readonly state_: KdStateService) {}
get containerStatusClass(): string {
if (this.isTerminated_() && this.container.status.state.terminated.reason !== Status.Completed) {
return StatusClass.Error;
}
if (this.isWaiting_()) {
return StatusClass.Warning;
}
if (this.isRunning_() || this.isTerminated_()) {
return StatusClass.Success;
}
return StatusClass.Unknown;
}
get containerStatus(): string {
if (this.container.status && this.container.status.state.terminated) {
return Status.Terminated;
}
if (this.container.status && this.container.status.state.waiting) {
return Status.Waiting;
}
if (this.container.status && this.container.status.ready && this.container.status.started) {
return Status.Running;
}
return Status.Unknown;
}
ngOnChanges(): void {
this.container.env = this.container.env.sort((a, b) => a.name.localeCompare(b.name));
}
......@@ -61,4 +93,20 @@ export class ContainerCardComponent implements OnChanges {
hasSecurityContext(): boolean {
return this.container && !_.isEmpty(this.container.securityContext);
}
private hasState_(): boolean {
return !!this.container && !!this.container.status && !!this.container.status.state;
}
private isWaiting_(): boolean {
return this.hasState_() && !!this.container.status.state.waiting;
}
private isTerminated_(): boolean {
return this.hasState_() && !!this.container.status.state.terminated;
}
private isRunning_(): boolean {
return this.hasState_() && !!this.container.status.state.running;
}
}
......@@ -28,7 +28,11 @@
margin-top: $baseline-grid / 2;
}
.security-context-header {
.container-status-icon {
vertical-align: middle;
}
.section-header {
font-size: $subhead-font-size-base-lg;
margin: (2 * $baseline-grid) 0;
}
......@@ -15,9 +15,17 @@ limitations under the License.
-->
<kd-card [initialized]="initialized">
<div description><span class="kd-muted-light"
i18n>Image:&nbsp;</span>{{container.image}}</div>
<div title>{{container.name}}</div>
<div description>
<span class="kd-muted-light"
i18n>Image:&nbsp;</span>{{container.image}}
</div>
<div title>
<mat-icon *ngIf="container.status"
class="container-status-icon"
[ngClass]="containerStatusClass"
[matTooltip]="containerStatus">fiber_manual_record</mat-icon>
{{container.name}}
</div>
<div content
fxFlex
fxLayout="row wrap">
......@@ -28,8 +36,88 @@ limitations under the License.
<div value>{{container.image}}</div>
</kd-property>
<div *ngFor="let env of container?.env;trackBy:getEnvVarID"
fxFlex="20">
<div *ngIf="container.status?.state"
class="kd-muted section-header"
fxFlex="100"
i18n>Status</div>
<ng-container *ngIf="container.status">
<kd-property>
<div key
i18n>Ready
</div>
<div value>{{container.status.ready}}</div>
</kd-property>
<kd-property>
<div key
i18n>Started
</div>
<div value>{{container.status.started}}</div>
</kd-property>
</ng-container>
<ng-container *ngIf="container.status?.state?.waiting">
<kd-property *ngIf="container.status.state.waiting.reason">
<div key
i18n>Reason
</div>
<div value>{{container.status.state.waiting.reason}}</div>
</kd-property>
<kd-property *ngIf="container.status.state.waiting.message">
<div key
i18n>Message
</div>
<div value>{{container.status.state.waiting.message}}</div>
</kd-property>
</ng-container>
<ng-container *ngIf="container.status?.state?.terminated">
<kd-property *ngIf="container.status.state.terminated.reason">
<div key
i18n>Reason
</div>
<div value>{{container.status.state.terminated.reason}}</div>
</kd-property>
<kd-property *ngIf="container.status.state.terminated.message">
<div key
i18n>Message
</div>
<div value>{{container.status.state.terminated.message}}</div>
</kd-property>
<kd-property *ngIf="container.status.state.terminated.exitCode">
<div key
i18n>Exit Code
</div>
<div value>{{container.status.state.terminated.exitCode}}</div>
</kd-property>
<kd-property *ngIf="container.status.state.terminated.signal">
<div key
i18n>Signal
</div>
<div value>{{container.status.state.terminated.signal}}</div>
</kd-property>
</ng-container>
<ng-container *ngIf="container.status?.state?.running">
<kd-property *ngIf="container.status.state.running.startedAt">
<div key
i18n>Started At
</div>
<div value>{{container.status.state.running.startedAt}}</div>
</kd-property>
</ng-container>
<div *ngIf="container?.env?.length > 0"
class="kd-muted section-header"
fxFlex="100"
i18n>Environment Variables</div>
<div *ngFor="let env of container?.env;trackBy:getEnvVarID">
<ng-container *ngIf="!isSecret(env) && !isConfigMap(env)">
<kd-property>
<div key
......@@ -40,7 +128,7 @@ limitations under the License.
class="kd-env-variable-icon">public
</mat-icon>
</div>
<div value>{{env.value}}</div>
<div value>{{env.value || '-'}}</div>
</kd-property>
</ng-container>
......@@ -92,6 +180,8 @@ limitations under the License.
<kd-property *ngIf="container?.commands?.length"
fxFlex="100">
<div key
fxFlex
class="kd-muted section-header"
i18n>Commands
</div>
<div value>
......@@ -105,6 +195,8 @@ limitations under the License.
<kd-property *ngIf="container?.args?.length"
fxFlex="100">
<div key
fxFlex
class="kd-muted section-header"
i18n>Arguments
</div>
<div value>
......@@ -119,6 +211,8 @@ limitations under the License.
[stretched]="true"
fxFlex="100">
<div key
fxFlex
class="kd-muted section-header"
i18n>Mounts
</div>
<div value
......@@ -134,7 +228,7 @@ limitations under the License.
fxFlex="100"
fxLayout="column">
<div fxFlex
class="security-context-header kd-muted"
class="kd-muted section-header"
i18n>Security Context
</div>
......
......@@ -31,8 +31,7 @@ limitations under the License.
<div content
[hidden]="endpoints?.length === 0">
<mat-table [dataSource]="getDataSource()"
[trackBy]="trackByEndpoint"
class="kd-table-no-footer">
[trackBy]="trackByEndpoint">
<ng-container [matColumnDef]="getEndpointsColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Host</mat-header-cell>
......
......@@ -17,10 +17,3 @@
.kd-internal-endpoint {
padding: (.25 * $baseline-grid) 0;
}
.kd-middleellipsis2 {
display: inline-block;
max-width: 100%;
vertical-align: bottom;
}
......@@ -15,6 +15,7 @@
import {Component, Input, OnChanges, OnInit, SimpleChange} from '@angular/core';
import {MatTableDataSource} from '@angular/material/table';
import {IngressSpecRule, IngressSpecRuleHttpPath, IngressSpecTLS} from '@api/root.api';
import * as _ from 'lodash';
import {GlobalServicesModule} from '../../services/global/module';
import {KdStateService} from '../../services/global/state';
......@@ -43,6 +44,25 @@ export class IngressRuleFlatListComponent implements OnInit, OnChanges {
// Flat map of host -> secret name pairs.
private tlsHostMap_ = new Map<string, string>();
private get ingressRuleFlatList_(): IngressRuleFlat[] {
return [].concat(
...this.ingressSpecRules.map(rule => {
if (!rule.http) {
return [] as IngressRuleFlat[];
}
return rule.http.paths.map(
specPath =>
({
host: rule.host || '',
path: specPath,
tlsSecretName: this.tlsHostMap_.get(rule.host) || '',
} as IngressRuleFlat)
);
})
);
}
ngOnInit(): void {
this.tlsList = this.tlsList || [];
this.ingressSpecRules = this.ingressSpecRules || [];
......@@ -53,15 +73,19 @@ export class IngressRuleFlatListComponent implements OnInit, OnChanges {
this.tlsHostMap_.clear();
[]
.concat(
...(changes.tlsList.currentValue as IngressSpecTLS[]).map(spec =>
spec.hosts.map(
...(changes.tlsList.currentValue as IngressSpecTLS[]).map(spec => {
if (!_.isArray(spec.hosts)) {
return [] as IngressSpecTLSFlat[];
}
return spec.hosts.map(
host =>
({
host: host,
tlsSecretName: spec.secretName,
} as IngressSpecTLSFlat)
)
)
);
})
)
.forEach((specFlat: IngressSpecTLSFlat) => this.tlsHostMap_.set(specFlat.host, specFlat.tlsSecretName));
}
......@@ -78,19 +102,4 @@ export class IngressRuleFlatListComponent implements OnInit, OnChanges {
getDetailsHref(name: string, kind: string): string {
return this.kdState_.href(kind, name, this.namespace);
}
private get ingressRuleFlatList_(): IngressRuleFlat[] {
return [].concat(
...this.ingressSpecRules.map(rule =>
rule.http.paths.map(
specPath =>
({
host: rule.host || '',
path: specPath,
tlsSecretName: this.tlsHostMap_.get(rule.host) || '',
} as IngressRuleFlat)
)
)
);
}
}
......@@ -30,8 +30,7 @@ limitations under the License.
<div content
[hidden]="ingressSpecRules?.length === 0">
<mat-table [dataSource]="getDataSource()"
class="kd-table-no-footer">
<mat-table [dataSource]="getDataSource()">
<ng-container [matColumnDef]="getIngressRulesFlatColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Host</mat-header-cell>
......
......@@ -31,8 +31,7 @@ limitations under the License.
<div content
[hidden]="!limits?.length">
<mat-table [dataSource]="getDataSource()"
[trackBy]="trackByLimitRage"
class="kd-table-no-footer">
[trackBy]="trackByLimitRage">
<ng-container [matColumnDef]="getColumnIds()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Resource name</mat-header-cell>
......
......@@ -30,8 +30,7 @@ limitations under the License.
<div content
[hidden]="!rules">
<mat-table [dataSource]="getDataSource()"
class="kd-table-no-footer">
<mat-table [dataSource]="getDataSource()">
<ng-container [matColumnDef]="getRuleColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Resources</mat-header-cell>
......
......@@ -31,8 +31,7 @@ limitations under the License.
<div content
[hidden]="!quotas?.length">
<mat-table [dataSource]="getDataSource()"
[trackBy]="trackByResourceQuotaDetail"
class="kd-table-no-footer">
[trackBy]="trackByResourceQuotaDetail">
<ng-container [matColumnDef]="getQuotaColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Name</mat-header-cell>
......
......@@ -15,12 +15,11 @@
import {HttpParams} from '@angular/common/http';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Input} from '@angular/core';
import {CRD, CRDList} from '@api/root.api';
import {ResourceListWithStatuses} from '@common/resources/list';
import {NotificationsService} from '@common/services/global/notifications';
import {EndpointManager, Resource} from '@common/services/resource/endpoint';
import {ResourceService} from '@common/services/resource/resource';
import {Observable} from 'rxjs';
import {ResourceListWithStatuses} from '../../../resources/list';
import {NotificationsService} from '../../../services/global/notifications';
import {EndpointManager, Resource} from '../../../services/resource/endpoint';
import {ResourceService} from '../../../services/resource/resource';
import {MenuComponent} from '../../list/column/menu/component';
import {ListGroupIdentifier, ListIdentifier} from '../groupids';
......
......@@ -30,8 +30,7 @@ limitations under the License.
<div content>
<mat-table [dataSource]="getDataSource()"
[trackBy]="trackByCRDVersionName"
class="kd-table-no-footer">
[trackBy]="trackByCRDVersionName">
<ng-container [matColumnDef]="getDisplayColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Name</mat-header-cell>
......
......@@ -15,6 +15,7 @@ limitations under the License.
-->
<kd-card role="table"
[expanded]="totalItems > 0"
[hidden]="isHidden()">
<div title
fxLayout="row"
......
......@@ -16,6 +16,7 @@ limitations under the License.
<kd-card role="table"
[expanded]="totalItems > 0"
[hidden]="isHidden()">
<div title
fxLayout="row"
......
......@@ -23,7 +23,7 @@ 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';
import {Status} from '../statuses';
import {Status, StatusClass} from '../statuses';
@Component({
selector: 'kd-service-list',
......@@ -43,8 +43,8 @@ export class ServiceListComponent extends ResourceListWithStatuses<ServiceList,
this.groupId = ListGroupIdentifier.discovery;
// Register status icon handlers
this.registerBinding('kd-success', r => this.isInSuccessState(r), Status.Succees);
this.registerBinding('kd-warning', r => !this.isInSuccessState(r), Status.Pending);
this.registerBinding(StatusClass.Success, r => this.isInSuccessState(r), Status.Success);
this.registerBinding(StatusClass.Warning, r => !this.isInSuccessState(r), Status.Pending);
// Register action columns.
this.registerActionColumn<MenuComponent>('menu', MenuComponent);
......
......@@ -28,9 +28,18 @@ export enum Status {
Released = 'Released',
Running = 'Running',
Succeeded = 'Succeeded',
Succees = 'Succeeded',
Success = 'Succeeded',
Suspended = 'Suspended',
Terminating = 'Terminating',
Terminated = 'Terminated',
Unknown = 'Unknown',
Waiting = 'Waiting',
Warning = 'Warning',
}
export enum StatusClass {
Error = 'kd-error',
Success = 'kd-success',
Unknown = 'kd-muted',
Warning = 'kd-warning',
}
......@@ -30,8 +30,7 @@ limitations under the License.
<div content
[hidden]="!subjects">
<mat-table [dataSource]="getDataSource()"
class="kd-table-no-footer">
<mat-table [dataSource]="getDataSource()">
<ng-container [matColumnDef]="getColumns()[0]">
<mat-header-cell *matHeaderCellDef
......
......@@ -29,8 +29,7 @@ limitations under the License.
<div content
[hidden]="volumeMounts?.length === 0">
<mat-table [dataSource]="dataSource"
class="kd-table-no-footer">
<mat-table [dataSource]="dataSource">
<ng-container [matColumnDef]="columns[0]">
<mat-header-cell *matHeaderCellDef
i18n>Name</mat-header-cell>
......
......@@ -365,10 +365,8 @@ router-outlet::after {
display: none !important;
}
.kd-table-no-footer {
.mat-row:last-of-type {
border-bottom: 0;
}
.mat-row:last-of-type {
border-bottom: 0;
}
// Override Arial font type
......
......@@ -89,8 +89,7 @@ limitations under the License.
<div content>
<mat-table [dataSource]="getCapacityDataSource()"
[trackBy]="trackByCapacityItemName"
class="kd-table-no-footer">
[trackBy]="trackByCapacityItemName">
<ng-container [matColumnDef]="getCapacityColumns()[0]">
<mat-header-cell *matHeaderCellDef
i18n>Resource name</mat-header-cell>
......
......@@ -15,14 +15,13 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {JobDetail} from '@api/root.api';
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';
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
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-job-detail',
templateUrl: './template.html',
......
......@@ -15,15 +15,14 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Container, PodDetail} from '@api/root.api';
import {ActionbarService, ResourceMeta} from '@common/services/global/actionbar';
import {NotificationsService} from '@common/services/global/notifications';
import {KdStateService} from '@common/services/global/state';
import {EndpointManager, Resource} from '@common/services/resource/endpoint';
import {NamespacedResourceService} from '@common/services/resource/resource';
import * as _ from 'lodash';
import {Subject} from 'rxjs';
import {takeUntil} from 'rxjs/operators';
import * as _ from 'lodash';
import {ActionbarService, ResourceMeta} from '../../../../common/services/global/actionbar';
import {NotificationsService} from '../../../../common/services/global/notifications';
import {KdStateService} from '../../../../common/services/global/state';
import {EndpointManager, Resource} from '../../../../common/services/resource/endpoint';
import {NamespacedResourceService} from '../../../../common/services/resource/resource';
@Component({
selector: 'kd-pod-detail',
......
......@@ -14,7 +14,7 @@
@import '../../../../variables';
.security-context-header {
.section-header {
font-size: $subhead-font-size-base-lg;
margin: (2 * $baseline-grid) 0;
}
......@@ -106,7 +106,7 @@ limitations under the License.
fxFlex="100"
fxLayout="column">
<div fxFlex
class="security-context-header kd-muted"
class="kd-muted section-header"
i18n>Security Context
</div>
......
......@@ -806,17 +806,19 @@ export interface Condition {
}
export interface ContainerStateWaiting {
reason: string;
reason?: string;
message?: string;
}
export interface ContainerStateRunning {
startedAt: string;
startedAt?: string;
}
export interface ContainerStateTerminated {
reason: string;
signal: number;
exitCode: number;
reason?: string;
message?: string;
signal?: number;
}
export interface ContainerState {
......@@ -875,6 +877,16 @@ export interface Container {
args: string[];
volumeMounts: VolumeMounts[];
securityContext: ContainerSecurityContext;
status: ContainerStatus;
}
export interface ContainerStatus {
name: string;
state: ContainerState;
lastTerminationState: ContainerState;
ready: boolean;
restartCount: number;
started?: boolean;
}
export interface ISecurityContext {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册