1
- import { CoreV1Api , V1Node , V1Pod , V1PodList , V1Container } from './gen/api' ;
2
- import { Metrics , PodMetric } from './metrics' ;
3
- import { add , podsForNode , quantityToScalar , totalCPU , totalMemory } from './util' ;
1
+ import { CoreV1Api , V1Node , V1Pod , V1PodList } from './gen/api' ;
2
+ import { ContainerMetric , Metrics , PodMetric } from './metrics' ;
3
+ import {
4
+ add ,
5
+ podsForNode ,
6
+ quantityToScalar ,
7
+ ResourceStatus ,
8
+ totalCPU ,
9
+ totalCPUForContainer ,
10
+ totalMemory ,
11
+ totalMemoryForContainer ,
12
+ } from './util' ;
4
13
5
14
export class ResourceUsage {
6
15
constructor (
@@ -29,8 +38,8 @@ export class NodeStatus {
29
38
export class ContainerStatus {
30
39
constructor (
31
40
public readonly Container : string ,
32
- public readonly CPUUsage : number | BigInt ,
33
- public readonly Memory : number | BigInt ,
41
+ public readonly CPUUsage : CurrentResourceUsage ,
42
+ public readonly MemoryUsage : CurrentResourceUsage ,
34
43
) { }
35
44
}
36
45
@@ -43,8 +52,6 @@ export class PodStatus {
43
52
) { }
44
53
}
45
54
46
-
47
-
48
55
export async function topNodes ( api : CoreV1Api ) : Promise < NodeStatus [ ] > {
49
56
// TODO: Support metrics APIs in the client and this library
50
57
const nodes = await api . listNode ( ) ;
@@ -75,50 +82,81 @@ export async function topNodes(api: CoreV1Api): Promise<NodeStatus[]> {
75
82
return result ;
76
83
}
77
84
85
+ // TODO describe what this method does
78
86
export async function topPods ( api : CoreV1Api , metrics : Metrics , namespace ?: string ) : Promise < PodStatus [ ] > {
79
-
80
- const getPodList = async ( ) :Promise < V1PodList > => {
87
+ const getPodList = async ( ) : Promise < V1PodList > => {
81
88
if ( namespace ) {
82
- return ( await api . listNamespacedPod ( namespace ) ) . body
89
+ return ( await api . listNamespacedPod ( namespace ) ) . body ;
83
90
} else {
84
- return ( await api . listPodForAllNamespaces ( ) ) . body
91
+ return ( await api . listPodForAllNamespaces ( ) ) . body ;
85
92
}
86
- }
93
+ } ;
87
94
88
- const [ podMetrics , podList ] = await Promise . all ( [ metrics . getPodMetrics ( namespace ) , getPodList ( ) ] )
95
+ const [ podMetrics , podList ] = await Promise . all ( [ metrics . getPodMetrics ( namespace ) , getPodList ( ) ] ) ;
89
96
97
+ // Create a map of pod names to their metric usage
98
+ // to make it easier to look up when we need it later
90
99
const podMetricsMap = podMetrics . items . reduce ( ( accum , next ) => {
91
- accum . set ( next . metadata . name , next )
92
- return accum
93
- } , ( new Map < string , PodMetric > ( ) ) )
100
+ accum . set ( next . metadata . name , next ) ;
101
+ return accum ;
102
+ } , new Map < string , PodMetric > ( ) ) ;
94
103
95
104
const result : PodStatus [ ] = [ ] ;
96
105
for ( const pod of podList . items ) {
106
+ const podMetric = podMetricsMap . get ( pod . metadata ! . name ! ) ;
97
107
98
- const podMetric = podMetricsMap . get ( pod . metadata ! . name ! )
99
-
108
+ // TODO we are calculating the contianer usages twice
109
+ // Once per pod, then below per container
110
+ // calculate the pod usage in this method instead to avoid
111
+ // duplicating work
100
112
const cpuTotal = totalCPU ( pod ) ;
101
113
const memTotal = totalMemory ( pod ) ;
102
114
const containerStatuses : ContainerStatus [ ] = [ ] ;
103
115
let currentPodCPU : number | bigint = 0 ;
104
116
let currentPodMem : number | bigint = 0 ;
105
117
106
- if ( podMetric !== undefined ) {
107
- podMetric . containers . forEach ( container => {
108
- const containerCPUUsage = quantityToScalar ( container . usage . cpu ) ;
109
- const containerMemUsage = quantityToScalar ( container . usage . memory ) ;
110
- currentPodCPU = add ( currentPodCPU , containerCPUUsage )
111
- currentPodMem = add ( currentPodMem , containerMemUsage )
112
- containerStatuses . push ( new ContainerStatus ( container . name , containerCPUUsage , containerMemUsage ) )
113
- } )
118
+ if ( podMetric !== undefined ) {
119
+ // Create a map of container names to their resource spec
120
+ // to make it easier to look up when we need it later
121
+ const containerResourceStatuses = pod . spec ! . containers . reduce ( ( accum , next ) => {
122
+ const containerCpuTotal = totalCPUForContainer ( next ) ;
123
+ const containerMemTotal = totalMemoryForContainer ( next ) ;
124
+ accum . set ( next . name , [ containerCpuTotal , containerMemTotal ] ) ;
125
+ return accum ;
126
+ } , new Map < string , [ ResourceStatus , ResourceStatus ] > ( ) ) ;
127
+
128
+ podMetric . containers . forEach ( ( containerMetrics : ContainerMetric ) => {
129
+ const currentContainerCPUUsage = quantityToScalar ( containerMetrics . usage . cpu ) ;
130
+ const currentContainerMemUsage = quantityToScalar ( containerMetrics . usage . memory ) ;
131
+ currentPodCPU = add ( currentPodCPU , currentContainerCPUUsage ) ;
132
+ currentPodMem = add ( currentPodMem , currentContainerMemUsage ) ;
133
+
134
+ const containerResourceStatus = containerResourceStatuses . get ( containerMetrics . name ) ;
135
+
136
+ if ( containerResourceStatus !== undefined ) {
137
+ const [ containerCpuTotal , containerMemTotal ] = containerResourceStatus ;
138
+
139
+ const containerCpuUsage = new CurrentResourceUsage (
140
+ currentContainerCPUUsage ,
141
+ containerCpuTotal . request ,
142
+ containerCpuTotal . limit ,
143
+ ) ;
144
+ const containerMemUsage = new CurrentResourceUsage (
145
+ currentContainerMemUsage ,
146
+ containerMemTotal . request ,
147
+ containerMemTotal . limit ,
148
+ ) ;
149
+
150
+ containerStatuses . push (
151
+ new ContainerStatus ( containerMetrics . name , containerCpuUsage , containerMemUsage ) ,
152
+ ) ;
153
+ }
154
+ } ) ;
114
155
}
115
156
116
- const cpuUsage = new CurrentResourceUsage ( currentPodCPU , cpuTotal . request , cpuTotal . limit ) ;
117
- const memUsage = new CurrentResourceUsage ( currentPodMem , memTotal . request , memTotal . limit ) ;
118
- result . push ( new PodStatus ( pod , cpuUsage , memUsage , containerStatuses ) ) ;
119
-
157
+ const podCpuUsage = new CurrentResourceUsage ( currentPodCPU , cpuTotal . request , cpuTotal . limit ) ;
158
+ const podMemUsage = new CurrentResourceUsage ( currentPodMem , memTotal . request , memTotal . limit ) ;
159
+ result . push ( new PodStatus ( pod , podCpuUsage , podMemUsage , containerStatuses ) ) ;
120
160
}
121
161
return result ;
122
-
123
-
124
162
}
0 commit comments