/
resourcePrice.ts
96 lines (86 loc) · 2.37 KB
/
resourcePrice.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import type { NextApiRequest, NextApiResponse } from 'next';
import * as yaml from 'js-yaml';
import { getK8s } from '@/services/backend/kubernetes';
import { jsonRes } from '@/services/backend/response';
import { authSession } from '@/services/backend/auth';
export type Response = {
cpu: number;
memory: number;
storage: number;
nodeports: number;
};
type ResourceType =
| 'cpu'
| 'infra-cpu'
| 'storage'
| 'memory'
| 'disk'
| 'mongodb'
| 'minio'
| 'infra-memory'
| 'infra-disk'
| 'services.nodeports';
type PriceCrdType = {
apiVersion: 'account.sealos.io/v1';
kind: 'PriceQuery';
status: {
billingRecords: {
price: number;
resourceType: ResourceType;
}[];
};
};
const PRICE_SCALE = 1000000;
export const valuationMap: Record<string, number> = {
cpu: 1000,
memory: 1024,
storage: 1024
};
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
// source price
const { applyYamlList, k8sCustomObjects, namespace } = await getK8s({
kubeconfig: await authSession(req)
});
const crdJson = {
apiVersion: `account.sealos.io/v1`,
kind: 'PriceQuery',
metadata: {
name: 'prices',
namespace
},
spec: {}
};
const crdYaml = yaml.dump(crdJson);
try {
await applyYamlList([crdYaml], 'replace');
await new Promise<void>((resolve) => setTimeout(() => resolve(), 1000));
} catch (error) {}
const { body: priceResponse } = (await k8sCustomObjects.getNamespacedCustomObject(
'account.sealos.io',
'v1',
namespace,
'pricequeries',
crdJson.metadata.name
)) as { body: PriceCrdType };
const data = {
cpu: countSourcePrice(priceResponse, 'cpu'),
memory: countSourcePrice(priceResponse, 'memory'),
storage: countSourcePrice(priceResponse, 'storage'),
nodeports: countSourcePrice(priceResponse, 'services.nodeports')
};
jsonRes(res, {
data
});
} catch (error) {
console.log(error);
jsonRes(res, { code: 500, message: 'get price error' });
}
}
function countSourcePrice(rawData: PriceCrdType, type: ResourceType) {
const rawPrice =
rawData?.status?.billingRecords.find((item) => item.resourceType === type)?.price || 1;
const sourceScale = rawPrice * (valuationMap[type] || 1);
const unitScale = sourceScale / PRICE_SCALE;
return unitScale;
}