Skip to content

Commit 83233b8

Browse files
committed
Merge remote-tracking branch 'origin/master' into upsteream-rebase
2 parents dd933f1 + 371d1a5 commit 83233b8

File tree

46 files changed

+763
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+763
-88
lines changed

custom-src/frontend/app/custom/helm/list-types/monocular-repository-list-config.service.ts

+14-16
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
1+
import { HttpClient } from '@angular/common/http';
12
import { Injectable, NgZone } from '@angular/core';
3+
import { MatSnackBar } from '@angular/material';
24
import { ActivatedRoute } from '@angular/router';
35
import { Store } from '@ngrx/store';
6+
import { UnregisterEndpoint } from 'frontend/packages/store/src/actions/endpoint.actions';
7+
import { entityCatalog } from 'frontend/packages/store/src/entity-catalog/entity-catalog.service';
8+
import { endpointSchemaKey } from 'frontend/packages/store/src/helpers/entity-factory';
9+
import { selectDeletionInfo } from 'frontend/packages/store/src/selectors/api.selectors';
410
import { of as observableOf } from 'rxjs';
11+
import { pairwise } from 'rxjs/operators';
512

613
import { AppState } from '../../../../../store/src/app-state';
714
import { EntityMonitorFactory } from '../../../../../store/src/monitors/entity-monitor.factory.service';
815
import { InternalEventMonitorFactory } from '../../../../../store/src/monitors/internal-event-monitor.factory';
916
import { PaginationMonitorFactory } from '../../../../../store/src/monitors/pagination-monitor.factory';
1017
import { EndpointModel } from '../../../../../store/src/types/endpoint.types';
18+
import { STRATOS_ENDPOINT_TYPE } from '../../../base-entity-schemas';
19+
import { CurrentUserPermissions } from '../../../core/current-user-permissions.config';
20+
import { CurrentUserPermissionsService } from '../../../core/current-user-permissions.service';
21+
import { environment } from '../../../environments/environment';
1122
import { getFullEndpointApiUrl } from '../../../features/endpoints/endpoint-helpers';
23+
import { ConfirmationDialogConfig } from '../../../shared/components/confirmation-dialog.config';
24+
import { ConfirmationDialogService } from '../../../shared/components/confirmation-dialog.service';
1225
import { ITableColumn } from '../../../shared/components/list/list-table/table.types';
1326
import {
1427
EndpointCardComponent,
1528
} from '../../../shared/components/list/list-types/endpoint/endpoint-card/endpoint-card.component';
1629
import {
1730
TableCellEndpointStatusComponent,
1831
} from '../../../shared/components/list/list-types/endpoint/table-cell-endpoint-status/table-cell-endpoint-status.component';
19-
import { IListConfig, ListViewTypes, IListAction } from '../../../shared/components/list/list.component.types';
32+
import { IListAction, IListConfig, ListViewTypes } from '../../../shared/components/list/list.component.types';
2033
import { defaultHelmKubeListPageSize } from '../../kubernetes/list-types/kube-helm-list-types';
2134
import { MonocularRepositoryDataSource } from './monocular-repository-list-source';
22-
import { HttpClient } from '@angular/common/http';
23-
import { environment } from '../../../environments/environment';
24-
import { map, pairwise } from 'rxjs/operators';
25-
import { MatSnackBar } from '@angular/material';
26-
import { SendClearEventAction } from 'frontend/packages/store/src/actions/internal-events.actions';
27-
import { DisconnectEndpoint, UnregisterEndpoint } from 'frontend/packages/store/src/actions/endpoint.actions';
28-
import { entityCatalog } from 'frontend/packages/store/src/entity-catalog/entity-catalog.service';
29-
import { selectDeletionInfo } from 'frontend/packages/store/src/selectors/api.selectors';
30-
import { STRATOS_ENDPOINT_TYPE } from '../../../base-entity-schemas';
31-
import { endpointSchemaKey } from 'frontend/packages/store/src/helpers/entity-factory';
32-
import { ConfirmationDialogService } from '../../../shared/components/confirmation-dialog.service';
33-
import { ConfirmationDialogConfig } from '../../../shared/components/confirmation-dialog.config';
34-
import { CurrentUserPermissionsService } from '../../../core/current-user-permissions.service';
35-
import { CurrentUserPermissions } from '../../../core/current-user-permissions.config';
3635

3736
@Injectable()
3837
export class MonocularRepositoryListConfig implements IListConfig<EndpointModel> {
@@ -47,7 +46,6 @@ export class MonocularRepositoryListConfig implements IListConfig<EndpointModel>
4746
};
4847
pageSizeOptions = defaultHelmKubeListPageSize;
4948
enableTextFilter = true;
50-
tableFixedRowHeight = true;
5149
columns: ITableColumn<EndpointModel>[] = [
5250
{
5351
columnId: 'name',

custom-src/frontend/app/custom/kubernetes/kubernetes.module.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { NgxChartsModule } from '@swimlane/ngx-charts';
55

66
import { CoreModule } from '../../core/core.module';
77
import { SharedModule } from '../../shared/shared.module';
8+
import {
9+
KubedashConfigurationComponent,
10+
} from './kubernetes-dashboard/kubedash-configuration/kubedash-configuration.component';
811
import { KubernetesDashboardTabComponent } from './kubernetes-dashboard/kubernetes-dashboard.component';
912
import {
1013
KubernetesNamespacePodsComponent,
@@ -70,6 +73,9 @@ import {
7073
KubernetesNodeTagsCardComponent,
7174
} from './list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-tags-card/kubernetes-node-tags-card.component';
7275
import { NodePodCountComponent } from './list-types/kubernetes-nodes/node-pod-count/node-pod-count.component';
76+
import {
77+
KubernetesPodContainersComponent,
78+
} from './list-types/kubernetes-pods/kubernetes-pod-containers/kubernetes-pod-containers.component';
7379
import {
7480
KubernetesPodStatusComponent,
7581
} from './list-types/kubernetes-pods/kubernetes-pod-status/kubernetes-pod-status.component';
@@ -86,7 +92,6 @@ import { KubernetesNamespacesTabComponent } from './tabs/kubernetes-namespaces-t
8692
import { KubernetesNodesTabComponent } from './tabs/kubernetes-nodes-tab/kubernetes-nodes-tab.component';
8793
import { KubernetesPodsTabComponent } from './tabs/kubernetes-pods-tab/kubernetes-pods-tab.component';
8894
import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kubernetes-summary.component';
89-
import { KubedashConfigurationComponent } from './kubernetes-dashboard/kubedash-configuration/kubedash-configuration.component';
9095

9196

9297
/* tslint:enable */
@@ -141,6 +146,7 @@ import { KubedashConfigurationComponent } from './kubernetes-dashboard/kubedash-
141146
KubernetesResourceViewerComponent,
142147
KubeServiceCardComponent,
143148
KubedashConfigurationComponent,
149+
KubernetesPodContainersComponent
144150
],
145151
providers: [
146152
KubernetesService,
@@ -163,7 +169,8 @@ import { KubedashConfigurationComponent } from './kubernetes-dashboard/kubedash-
163169
KubernetesServicePortsComponent,
164170
KubernetesPodStatusComponent,
165171
KubeServiceCardComponent,
166-
KubernetesResourceViewerComponent
172+
KubernetesResourceViewerComponent,
173+
KubernetesPodContainersComponent
167174
],
168175
exports: [
169176
KubernetesResourceViewerComponent

custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-endpoints/kubernetes-endpoints-list-config.service.ts

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ export class KubernetesEndpointsListConfigService implements IListConfig<Endpoin
3030
noEntries: 'There are no endpoints'
3131
};
3232
enableTextFilter = true;
33-
tableFixedRowHeight = true;
3433

3534

3635
constructor(

custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-nodes/kubernetes-node-summary/kubernetes-node-condition-card/kubernetes-node-condition-card.component.spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { KubernetesNodeService } from '../../../../services/kubernetes-node.serv
77
import { KubernetesNodeConditionCardComponent } from './kubernetes-node-condition-card.component';
88
import { KubernetesNodeConditionComponent } from './kubernetes-node-condition/kubernetes-node-condition.component';
99

10-
// TODO: RC xdescribed
1110
describe('KubernetesNodeConditionCardComponent', () => {
1211
let component: KubernetesNodeConditionCardComponent;
1312
let fixture: ComponentFixture<KubernetesNodeConditionCardComponent>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<div class="pod-containers">
2+
<app-table [dataSource]="containerDataSource" [columns]="columns" [inExpandedRow]="true">
3+
</app-table>
4+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.pod-containers {
2+
display: flex;
3+
app-table {
4+
flex: 1;
5+
padding-bottom: 10px;
6+
padding-left: 57px;
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { KubernetesBaseTestModules } from '../../../kubernetes.testing.module';
4+
import { KubernetesPod } from '../../../store/kube.types';
5+
import { KubernetesPodContainersComponent } from './kubernetes-pod-containers.component';
6+
7+
describe('KubernetesPodContainersComponent', () => {
8+
let component: KubernetesPodContainersComponent;
9+
let fixture: ComponentFixture<KubernetesPodContainersComponent>;
10+
11+
beforeEach(async(() => {
12+
TestBed.configureTestingModule({
13+
declarations: [KubernetesPodContainersComponent],
14+
imports: KubernetesBaseTestModules
15+
})
16+
.compileComponents();
17+
}));
18+
19+
beforeEach(() => {
20+
fixture = TestBed.createComponent(KubernetesPodContainersComponent);
21+
component = fixture.componentInstance;
22+
component.row = {
23+
metadata: {
24+
uid: ''
25+
},
26+
status: {
27+
28+
}
29+
} as KubernetesPod;
30+
fixture.detectChanges();
31+
});
32+
33+
it('should create', () => {
34+
expect(component).toBeTruthy();
35+
});
36+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import { TitleCasePipe } from '@angular/common';
2+
import { Component, Input } from '@angular/core';
3+
import { Store } from '@ngrx/store';
4+
import * as moment from 'moment';
5+
import { of } from 'rxjs';
6+
import { filter, map } from 'rxjs/operators';
7+
8+
import { AppState } from '../../../../../../../store/src/app-state';
9+
import { entityCatalog } from '../../../../../../../store/src/entity-catalog/entity-catalog.service';
10+
import { selectEntity } from '../../../../../../../store/src/selectors/api.selectors';
11+
import { BooleanIndicatorType } from '../../../../../shared/components/boolean-indicator/boolean-indicator.component';
12+
import { ITableListDataSource } from '../../../../../shared/components/list/data-sources-controllers/list-data-source-types';
13+
import {
14+
TableCellBooleanIndicatorComponent,
15+
TableCellBooleanIndicatorComponentConfig,
16+
} from '../../../../../shared/components/list/list-table/table-cell-boolean-indicator/table-cell-boolean-indicator.component';
17+
import {
18+
TableCellIconComponent,
19+
TableCellIconComponentConfig,
20+
} from '../../../../../shared/components/list/list-table/table-cell-icon/table-cell-icon.component';
21+
import { ITableColumn } from '../../../../../shared/components/list/list-table/table.types';
22+
import { CardCell } from '../../../../../shared/components/list/list.types';
23+
import { KUBERNETES_ENDPOINT_TYPE, kubernetesPodsEntityType } from '../../../kubernetes-entity-factory';
24+
import { Container, ContainerState, ContainerStatus, InitContainer, KubernetesPod } from '../../../store/kube.types';
25+
26+
export interface ContainerForTable {
27+
isInit: boolean;
28+
container: Container | InitContainer;
29+
containerStatus: ContainerStatus;
30+
}
31+
32+
@Component({
33+
selector: 'app-kubernetes-pod-containers',
34+
templateUrl: './kubernetes-pod-containers.component.html',
35+
styleUrls: ['./kubernetes-pod-containers.component.scss'],
36+
providers: [
37+
TitleCasePipe
38+
]
39+
})
40+
export class KubernetesPodContainersComponent extends CardCell<KubernetesPod> {
41+
42+
private entityConfig = entityCatalog.getEntity(KUBERNETES_ENDPOINT_TYPE, kubernetesPodsEntityType);
43+
44+
@Input()
45+
set row(row: KubernetesPod) {
46+
if (!row || !!this.containerDataSource) {
47+
return;
48+
}
49+
this.containerDataSource = {
50+
isTableLoading$: of(false),
51+
connect: () => this.store.select<KubernetesPod>(selectEntity(this.entityConfig.entityKey, row.metadata.uid)).pipe(
52+
filter(pod => !!pod),
53+
map(pod => this.map(pod)),
54+
),
55+
disconnect: () => { },
56+
trackBy: (index, container: ContainerForTable) => container.container.name,
57+
};
58+
}
59+
60+
constructor(
61+
private store: Store<AppState>,
62+
private titleCase: TitleCasePipe,
63+
) {
64+
super();
65+
}
66+
67+
private readyBoolConfig: TableCellBooleanIndicatorComponentConfig<ContainerForTable> = {
68+
isEnabled: (row: ContainerForTable) => row.containerStatus.ready,
69+
type: BooleanIndicatorType.yesNo,
70+
subtle: false,
71+
showText: false
72+
};
73+
74+
private iconConfig: TableCellIconComponentConfig<ContainerForTable> = {
75+
getIcon: (row: ContainerForTable) => row.isInit ?
76+
{
77+
icon: 'border_clear',
78+
font: '',
79+
tooltip: 'Init Container'
80+
} : {
81+
icon: 'border_outer',
82+
font: '',
83+
tooltip: 'Container'
84+
},
85+
};
86+
87+
public containerDataSource: ITableListDataSource<ContainerForTable>;
88+
public columns: ITableColumn<ContainerForTable>[] = [
89+
{
90+
columnId: 'icon',
91+
headerCell: () => '',
92+
cellComponent: TableCellIconComponent,
93+
cellConfig: this.iconConfig,
94+
cellFlex: '0 0 53px',
95+
},
96+
{
97+
columnId: 'name',
98+
headerCell: () => 'Container Name',
99+
cellDefinition: {
100+
valuePath: 'container.name'
101+
},
102+
cellFlex: '2',
103+
},
104+
{
105+
columnId: 'image',
106+
headerCell: () => 'Image',
107+
cellDefinition: {
108+
valuePath: 'container.image'
109+
},
110+
cellFlex: '3',
111+
},
112+
{
113+
columnId: 'ready',
114+
headerCell: () => 'Ready',
115+
cellComponent: TableCellBooleanIndicatorComponent,
116+
cellConfig: this.readyBoolConfig,
117+
cellFlex: '1',
118+
},
119+
{
120+
columnId: 'status',
121+
headerCell: () => 'State',
122+
cellDefinition: {
123+
getValue: cft => {
124+
if (!cft.containerStatus.state) {
125+
return 'Unknown';
126+
}
127+
const entries = Object.entries(cft.containerStatus.state);
128+
if (!entries.length) {
129+
return 'Unknown';
130+
}
131+
const sorted = entries.sort((a, b) => {
132+
const aStarted = moment(a[1].startedAt);
133+
const bStarted = moment(b[1].startedAt);
134+
135+
return aStarted.isBefore(bStarted) ? -1 :
136+
aStarted.isAfter(bStarted) ? 1 : 0;
137+
138+
});
139+
return this.containerStatusToString(sorted[0][0], sorted[0][1]);
140+
}
141+
},
142+
cellFlex: '2'
143+
},
144+
{
145+
columnId: 'restarts',
146+
headerCell: () => 'Restarts',
147+
cellDefinition: {
148+
getValue: cft => cft.containerStatus.restartCount.toString()
149+
},
150+
cellFlex: '1',
151+
},
152+
{
153+
columnId: 'probes',
154+
headerCell: () => 'Probes (L:R)',
155+
cellDefinition: {
156+
getValue: cft => {
157+
if (cft.isInit) {
158+
return '';
159+
}
160+
const container: Container = cft.container as Container;
161+
return cft.isInit ? '' : `${container.livenessProbe ? 'on' : 'off'}:${container.readinessProbe ? 'on' : 'off'}`;
162+
}
163+
},
164+
cellFlex: '1',
165+
},
166+
];
167+
168+
private map(row: KubernetesPod): ContainerForTable[] {
169+
const containerStatus = row.status.containerStatuses || [];
170+
const initContainerStatuses = row.status.initContainerStatuses || [];
171+
const containerStatusWithContainers: ContainerForTable[] = [
172+
...containerStatus.map(c => this.createContainerForTable(c, row.spec.containers)),
173+
...initContainerStatuses.map(c => this.createContainerForTable(c, row.spec.initContainers, true))
174+
];
175+
return containerStatusWithContainers.sort((a, b) => a.container.name.localeCompare(b.container.name));
176+
}
177+
178+
private createContainerForTable(containerStatus: ContainerStatus, containers: (Container | InitContainer)[], isInit = false):
179+
ContainerForTable {
180+
const containerForTable: ContainerForTable = {
181+
isInit,
182+
containerStatus,
183+
container: containers.find(c => c.name === containerStatus.name)
184+
};
185+
return containerForTable;
186+
}
187+
188+
private containerStatusToString(state: string, status: ContainerState): string {
189+
const exitCode = status.exitCode ? `:${status.exitCode}` : '';
190+
const signal = status.signal ? `:${status.signal}` : '';
191+
const reason = status.reason ? ` (${status.reason}${exitCode || signal})` : '';
192+
return `${this.titleCase.transform(state)}${reason}`;
193+
}
194+
}

custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-pods/kubernetes-pod-status/kubernetes-pod-status.component.spec.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ describe('KubernetesPodStatusComponent', () => {
99

1010
beforeEach(async(() => {
1111
TestBed.configureTestingModule({
12-
declarations: [KubernetesPodStatusComponent]
12+
declarations: [
13+
KubernetesPodStatusComponent
14+
]
1315
})
1416
.compileComponents();
1517
}));

custom-src/frontend/app/custom/kubernetes/list-types/kubernetes-pods/kubernetes-pods-list-config.service.ts

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
import { KubernetesPod } from '../../store/kube.types';
2121
import { defaultHelmKubeListPageSize } from '../kube-helm-list-types';
2222
import { createKubeAgeColumn } from '../kube-list.helper';
23+
import { KubernetesPodContainersComponent } from './kubernetes-pod-containers/kubernetes-pod-containers.component';
2324
import { KubernetesPodStatusComponent } from './kubernetes-pod-status/kubernetes-pod-status.component';
2425
import { KubernetesPodsDataSource } from './kubernetes-pods-data-source';
2526

@@ -139,6 +140,7 @@ export abstract class BaseKubernetesPodsListConfigService implements IListConfig
139140
noEntries: 'There are no pods'
140141
};
141142
abstract getDataSource: () => IListDataSource<KubernetesPod>;
143+
expandComponent = KubernetesPodContainersComponent;
142144

143145
getGlobalActions = () => null;
144146
getMultiActions = () => [];

0 commit comments

Comments
 (0)