Skip to content

Commit 51e7212

Browse files
committed
Add support for usage metrics
1 parent 201999d commit 51e7212

7 files changed

Lines changed: 409 additions & 7 deletions

File tree

OpenFlow/src/KubeUtil.ts

Lines changed: 371 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { CoreV1Api, AppsV1Api, ExtensionsV1beta1Api, ExtensionsApi } from "@kubernetes/client-node";
1+
import { CoreV1Api, AppsV1Api, ExtensionsV1beta1Api, ExtensionsApi, VoidAuth, ApiKeyAuth } from "@kubernetes/client-node";
22
import { Config } from "./Config";
3+
import http = require('http');
4+
const localVarRequest = require("request");
5+
let defaultBasePath = 'https://localhost';
36

47
export class KubeUtil {
58
public CoreV1Api: CoreV1Api = null; // kc.makeApiClient(k8s.CoreV1Api);
69
public AppsV1Api: AppsV1Api = null; // kc.makeApiClient(k8s.AppsV1Api);
710
public ExtensionsV1beta1Api: ExtensionsV1beta1Api = null; // kc.makeApiClient(k8s.ExtensionsV1beta1Api);
11+
public Metricsv1beta1Api: Metricsv1beta1Api = null;
812

913
private static _instance: KubeUtil = null;
1014
public static instance(): KubeUtil {
@@ -35,6 +39,7 @@ export class KubeUtil {
3539
this.CoreV1Api = kc.makeApiClient(k8s.CoreV1Api);
3640
this.AppsV1Api = kc.makeApiClient(k8s.AppsV1Api);
3741
this.ExtensionsV1beta1Api = kc.makeApiClient(k8s.ExtensionsV1beta1Api);
42+
this.Metricsv1beta1Api = kc.makeApiClient(Metricsv1beta1Api);
3843
}
3944

4045
async GetStatefulSet(namespace, name) {
@@ -89,4 +94,368 @@ export class KubeUtil {
8994
return null;
9095
}
9196

92-
}
97+
async GetPodMetrics(namespace, name) {
98+
var list = await this.Metricsv1beta1Api.GetPod(namespace, name);
99+
if (list.body.containers.length > 0) {
100+
list.body.containers[0].usage.window = list.body.window;
101+
return list.body.containers[0].usage;
102+
}
103+
return null;
104+
}
105+
106+
}
107+
108+
109+
export class Metricsv1beta1Api {
110+
private _basePath: string = null;
111+
private authentications: any = null;
112+
private _useQuerystring: any = null;
113+
private defaultHeaders: any = null;
114+
115+
constructor(basePathOrUsername, password, basePath) {
116+
this._basePath = defaultBasePath;
117+
this.authentications = {
118+
'default': new VoidAuth(),
119+
'BearerToken': new ApiKeyAuth('header', 'authorization'),
120+
};
121+
if (password) {
122+
if (basePath) {
123+
this.basePath = basePath;
124+
}
125+
}
126+
else {
127+
if (basePathOrUsername) {
128+
this.basePath = basePathOrUsername;
129+
}
130+
}
131+
}
132+
set useQuerystring(value) {
133+
this._useQuerystring = value;
134+
}
135+
set basePath(basePath) {
136+
this._basePath = basePath;
137+
}
138+
get basePath() {
139+
return this._basePath;
140+
}
141+
setDefaultAuthentication(auth) {
142+
this.authentications.default = auth;
143+
}
144+
async GetPods(namespace) {
145+
let localVarPath = this.basePath + '/apis/metrics.k8s.io/v1beta1/pods';
146+
if (namespace != null) localVarPath = this.basePath + '/apis/metrics.k8s.io/v1beta1/namespaces/' + namespace + "/pods";
147+
let localVarHeaderParams = Object.assign({}, this.defaultHeaders);
148+
let localVarUseFormData = false;
149+
let localVarQueryParameters = {};
150+
let localVarRequestOptions = {
151+
method: 'GET',
152+
qs: localVarQueryParameters,
153+
headers: localVarHeaderParams,
154+
uri: localVarPath,
155+
useQuerystring: this._useQuerystring,
156+
json: true,
157+
};
158+
this.authentications.BearerToken.applyToRequest(localVarRequestOptions);
159+
this.authentications.default.applyToRequest(localVarRequestOptions);
160+
return new Promise((resolve, reject) => {
161+
localVarRequest(localVarRequestOptions, (error, response, body) => {
162+
if (error) {
163+
reject(error);
164+
}
165+
else {
166+
body = ObjectSerializer.deserialize(body, "PodMetricsList");
167+
if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
168+
resolve({ response: response, body: body });
169+
}
170+
else {
171+
reject({ response: response, body: body });
172+
}
173+
}
174+
});
175+
});
176+
177+
}
178+
async GetPod(namespace: string, pod: string): Promise<{
179+
response: http.IncomingMessage;
180+
body: PodMetrics;
181+
}> {
182+
const localVarPath = this.basePath + '/apis/metrics.k8s.io/v1beta1/namespaces/' + namespace + "/pods/" + pod;
183+
let localVarHeaderParams = Object.assign({}, this.defaultHeaders);
184+
let localVarUseFormData = false;
185+
let localVarQueryParameters = {};
186+
let localVarRequestOptions = {
187+
method: 'GET',
188+
qs: localVarQueryParameters,
189+
headers: localVarHeaderParams,
190+
uri: localVarPath,
191+
useQuerystring: this._useQuerystring,
192+
json: true,
193+
};
194+
this.authentications.BearerToken.applyToRequest(localVarRequestOptions);
195+
this.authentications.default.applyToRequest(localVarRequestOptions);
196+
return new Promise((resolve, reject) => {
197+
localVarRequest(localVarRequestOptions, (error, response, body) => {
198+
if (error) {
199+
reject(error);
200+
}
201+
else {
202+
body = ObjectSerializer.deserialize(body, "PodMetrics");
203+
if (response.statusCode && response.statusCode >= 200 && response.statusCode <= 299) {
204+
resolve({ response: response, body: body });
205+
}
206+
else {
207+
reject({ response: response, body: body });
208+
}
209+
}
210+
});
211+
});
212+
213+
}
214+
}
215+
216+
217+
218+
219+
220+
let primitives = [
221+
"string",
222+
"boolean",
223+
"double",
224+
"integer",
225+
"long",
226+
"float",
227+
"number",
228+
"any"
229+
];
230+
class ObjectSerializer {
231+
static findCorrectType(data, expectedType) {
232+
if (data == undefined) {
233+
return expectedType;
234+
}
235+
else if (primitives.indexOf(expectedType.toLowerCase()) !== -1) {
236+
return expectedType;
237+
}
238+
else if (expectedType === "Date") {
239+
return expectedType;
240+
}
241+
else {
242+
if (enumsMap[expectedType]) {
243+
return expectedType;
244+
}
245+
if (!typeMap[expectedType]) {
246+
return expectedType; // w/e we don't know the type
247+
}
248+
// Check the discriminator
249+
let discriminatorProperty = typeMap[expectedType].discriminator;
250+
if (discriminatorProperty == null) {
251+
return expectedType; // the type does not have a discriminator. use it.
252+
}
253+
else {
254+
if (data[discriminatorProperty]) {
255+
return data[discriminatorProperty]; // use the type given in the discriminator
256+
}
257+
else {
258+
return expectedType; // discriminator was not present (or an empty string)
259+
}
260+
}
261+
}
262+
}
263+
static serialize(data, type) {
264+
if (data == undefined) {
265+
return data;
266+
}
267+
else if (primitives.indexOf(type.toLowerCase()) !== -1) {
268+
return data;
269+
}
270+
else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
271+
let subType = type.replace("Array<", ""); // Array<Type> => Type>
272+
subType = subType.substring(0, subType.length - 1); // Type> => Type
273+
let transformedData = [];
274+
for (let index in data) {
275+
let date = data[index];
276+
transformedData.push(ObjectSerializer.serialize(date, subType));
277+
}
278+
return transformedData;
279+
}
280+
else if (type === "Date") {
281+
return data.toString();
282+
}
283+
else {
284+
if (enumsMap[type]) {
285+
return data;
286+
}
287+
if (!typeMap[type]) { // in case we dont know the type
288+
return data;
289+
}
290+
// get the map for the correct type.
291+
let attributeTypes = typeMap[type].getAttributeTypeMap();
292+
let instance = {};
293+
for (let index in attributeTypes) {
294+
let attributeType = attributeTypes[index];
295+
instance[attributeType.baseName] = ObjectSerializer.serialize(data[attributeType.name], attributeType.type);
296+
}
297+
return instance;
298+
}
299+
}
300+
static deserialize(data, type) {
301+
// polymorphism may change the actual type.
302+
type = ObjectSerializer.findCorrectType(data, type);
303+
if (data == undefined) {
304+
return data;
305+
}
306+
else if (primitives.indexOf(type.toLowerCase()) !== -1) {
307+
return data;
308+
}
309+
else if (type.lastIndexOf("Array<", 0) === 0) { // string.startsWith pre es6
310+
let subType = type.replace("Array<", ""); // Array<Type> => Type>
311+
subType = subType.substring(0, subType.length - 1); // Type> => Type
312+
let transformedData = [];
313+
for (let index in data) {
314+
let date = data[index];
315+
transformedData.push(ObjectSerializer.deserialize(date, subType));
316+
}
317+
return transformedData;
318+
}
319+
else if (type === "Date") {
320+
return new Date(data);
321+
}
322+
else {
323+
if (enumsMap[type]) { // is Enum
324+
return data;
325+
}
326+
if (!typeMap[type]) { // dont know the type
327+
return data;
328+
}
329+
let instance = new typeMap[type]();
330+
let attributeTypes = typeMap[type].getAttributeTypeMap();
331+
for (let index in attributeTypes) {
332+
let attributeType = attributeTypes[index];
333+
instance[attributeType.name] = ObjectSerializer.deserialize(data[attributeType.baseName], attributeType.type);
334+
}
335+
return instance;
336+
}
337+
}
338+
}
339+
340+
341+
342+
343+
344+
export class PodMetrics {
345+
public name: string;
346+
public containers: PodMetric[];
347+
public timestamp: Date;
348+
public window: string;
349+
public metadata: any;
350+
}
351+
export class PodMetric {
352+
public name: string;
353+
public usage: PodMetricUsage;
354+
}
355+
export class PodMetricUsage {
356+
public cpu: string;
357+
public memory: string;
358+
public window: string;
359+
}
360+
export class PodMetricsListReference {
361+
static discriminator = undefined;
362+
static attributeTypeMap = [
363+
{
364+
"name": "apiVersion",
365+
"baseName": "apiVersion",
366+
"type": "string"
367+
},
368+
{
369+
"name": "items",
370+
"baseName": "items",
371+
"type": "Array<PodMetricReference>"
372+
},
373+
{
374+
"name": "kind",
375+
"baseName": "kind",
376+
"type": "string"
377+
},
378+
{
379+
"name": "metadata",
380+
"baseName": "metadata",
381+
"type": "V1ListMeta"
382+
}
383+
];
384+
static getAttributeTypeMap() {
385+
return PodMetricsListReference.attributeTypeMap;
386+
}
387+
}
388+
389+
export class PodMetricReference {
390+
static discriminator = undefined;
391+
static attributeTypeMap = [
392+
{
393+
"name": "containers",
394+
"baseName": "containers",
395+
"type": "Array<PodMetricContainerReference>"
396+
},
397+
{
398+
"name": "timestamp",
399+
"baseName": "timestamp",
400+
"type": "Date"
401+
},
402+
{
403+
"name": "window",
404+
"baseName": "window",
405+
"type": "string"
406+
},
407+
{
408+
"name": "metadata",
409+
"baseName": "metadata",
410+
"type": "V1ListMeta"
411+
}
412+
];
413+
static getAttributeTypeMap() {
414+
return PodMetricReference.attributeTypeMap;
415+
}
416+
}
417+
418+
export class PodMetricContainerReference {
419+
static discriminator = undefined;
420+
static attributeTypeMap = [
421+
{
422+
"name": "name",
423+
"baseName": "name",
424+
"type": "string"
425+
},
426+
{
427+
"name": "usage",
428+
"baseName": "usage",
429+
"type": "PodMetricContainerUsageReference"
430+
}
431+
]
432+
static getAttributeTypeMap() {
433+
return PodMetricContainerReference.attributeTypeMap;
434+
}
435+
}
436+
export class PodMetricContainerUsageReference {
437+
static discriminator = undefined;
438+
static attributeTypeMap = [
439+
{
440+
"name": "cpu",
441+
"baseName": "cpu",
442+
"type": "string"
443+
},
444+
{
445+
"name": "memory",
446+
"baseName": "memory",
447+
"type": "string"
448+
}
449+
];
450+
static getAttributeTypeMap() {
451+
return PodMetricContainerUsageReference.attributeTypeMap;
452+
}
453+
}
454+
455+
let enumsMap = {};
456+
let typeMap = {
457+
"PodMetricsList": PodMetricsListReference,
458+
"PodMetricReference": PodMetricReference,
459+
"PodMetricContainerReference": PodMetricContainerReference,
460+
"PodMetricContainerUsageReference": PodMetricContainerUsageReference
461+
}

0 commit comments

Comments
 (0)