1
+ import { isNumber } from 'underscore' ;
1
2
import { CoreV1Api , V1Container , V1Pod } from './gen/api' ;
2
3
3
4
export async function podsForNode ( api : CoreV1Api , nodeName : string ) : Promise < V1Pod [ ] > {
4
5
const allPods = await api . listPodForAllNamespaces ( ) ;
5
6
return allPods . body . items . filter ( ( pod : V1Pod ) => pod . spec ! . nodeName === nodeName ) ;
6
7
}
7
8
8
- export function quantityToScalar ( quantity : string ) : number {
9
+ export function findSuffix ( quantity : string ) : string {
10
+ let ix = quantity . length - 1 ;
11
+ while ( ix >= 0 && ! / [ \. 0 - 9 ] / . test ( quantity . charAt ( ix ) ) ) {
12
+ ix -- ;
13
+ }
14
+ return ix === - 1 ? '' : quantity . substring ( ix + 1 ) ;
15
+ }
16
+
17
+ export function quantityToScalar ( quantity : string ) : number | bigint {
9
18
if ( ! quantity ) {
10
19
return 0 ;
11
20
}
12
- if ( quantity . endsWith ( 'm' ) ) {
13
- return parseInt ( quantity . substr ( 0 , quantity . length - 1 ) , 10 ) / 1000.0 ;
14
- }
15
- if ( quantity . endsWith ( 'Ki' ) ) {
16
- return parseInt ( quantity . substr ( 0 , quantity . length - 2 ) , 10 ) * 1024 ;
21
+ const suffix = findSuffix ( quantity ) ;
22
+ if ( suffix === '' ) {
23
+ const num = Number ( quantity ) . valueOf ( ) ;
24
+ if ( isNaN ( num ) ) {
25
+ throw new Error ( 'Unknown quantity ' + quantity ) ;
26
+ }
27
+ return num ;
17
28
}
18
- const num = parseInt ( quantity , 10 ) ;
19
- if ( isNaN ( num ) ) {
20
- throw new Error ( 'Unknown quantity ' + quantity ) ;
29
+ switch ( suffix ) {
30
+ case 'm' :
31
+ return Number ( quantity . substr ( 0 , quantity . length - 1 ) ) . valueOf ( ) / 1000.0 ;
32
+ case 'Ki' :
33
+ return BigInt ( quantity . substr ( 0 , quantity . length - 2 ) ) * BigInt ( 1024 ) ;
34
+ case 'Mi' :
35
+ return BigInt ( quantity . substr ( 0 , quantity . length - 2 ) ) * BigInt ( 1024 * 1024 ) ;
36
+ case 'Gi' :
37
+ return BigInt ( quantity . substr ( 0 , quantity . length - 2 ) ) * BigInt ( 1024 * 1024 * 1024 ) ;
38
+ case 'Ti' :
39
+ return (
40
+ BigInt ( quantity . substr ( 0 , quantity . length - 2 ) ) * BigInt ( 1024 * 1024 * 1024 ) * BigInt ( 1024 )
41
+ ) ;
42
+ case 'Pi' :
43
+ return (
44
+ BigInt ( quantity . substr ( 0 , quantity . length - 2 ) ) *
45
+ BigInt ( 1024 * 1024 * 1024 ) *
46
+ BigInt ( 1024 * 1024 )
47
+ ) ;
48
+ case 'Ei' :
49
+ return (
50
+ BigInt ( quantity . substr ( 0 , quantity . length - 2 ) ) *
51
+ BigInt ( 1024 * 1024 * 1024 ) *
52
+ BigInt ( 1024 * 1024 * 1024 )
53
+ ) ;
54
+ default :
55
+ throw new Error ( `Unknown suffix: ${ suffix } ` ) ;
21
56
}
22
- return num ;
23
57
}
24
58
25
59
export class ResourceStatus {
26
60
constructor (
27
- public readonly request : number ,
28
- public readonly limit : number ,
61
+ public readonly request : bigint | number ,
62
+ public readonly limit : bigint | number ,
29
63
public readonly resourceType : string ,
30
64
) { }
31
65
}
@@ -38,16 +72,28 @@ export function totalMemory(pod: V1Pod): ResourceStatus {
38
72
return totalForResource ( pod , 'memory' ) ;
39
73
}
40
74
75
+ export function add ( n1 : number | bigint , n2 : number | bigint ) : number | bigint {
76
+ if ( isNumber ( n1 ) && isNumber ( n2 ) ) {
77
+ return n1 + n2 ;
78
+ }
79
+ if ( isNumber ( n1 ) ) {
80
+ return BigInt ( Math . round ( n1 ) ) + ( n2 as bigint ) ;
81
+ } else if ( isNumber ( n2 ) ) {
82
+ return ( n1 as bigint ) + BigInt ( Math . round ( n2 ) ) ;
83
+ }
84
+ return ( ( n1 as bigint ) + n2 ) as bigint ;
85
+ }
86
+
41
87
export function totalForResource ( pod : V1Pod , resource : string ) : ResourceStatus {
42
- let reqTotal = 0 ;
43
- let limitTotal = 0 ;
88
+ let reqTotal : number | bigint = 0 ;
89
+ let limitTotal : number | bigint = 0 ;
44
90
pod . spec ! . containers . forEach ( ( container : V1Container ) => {
45
91
if ( container . resources ) {
46
92
if ( container . resources . requests ) {
47
- reqTotal += quantityToScalar ( container . resources . requests [ resource ] ) ;
93
+ reqTotal = add ( reqTotal , quantityToScalar ( container . resources . requests [ resource ] ) ) ;
48
94
}
49
95
if ( container . resources . limits ) {
50
- limitTotal += quantityToScalar ( container . resources . limits [ resource ] ) ;
96
+ limitTotal = add ( limitTotal , quantityToScalar ( container . resources . limits [ resource ] ) ) ;
51
97
}
52
98
}
53
99
} ) ;
0 commit comments