Skip to content

Commit be7254a

Browse files
authored
Merge pull request #5376 from bcgov/feat/5235
refactor(5235): encapsulate logic for cluster config generation
2 parents 960f776 + ece279e commit be7254a

File tree

11 files changed

+126
-92
lines changed

11 files changed

+126
-92
lines changed

app/app/api/private-cloud/products/[licencePlate]/namespace-subnet/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { GlobalRole } from '@/constants';
44
import createApiHandler from '@/core/api-handler';
55
import { OkResponse, UnauthorizedResponse } from '@/core/responses';
66
import { models } from '@/services/db';
7-
import { getSubnet } from '@/services/k8s';
7+
import { getSubnet } from '@/services/k8s/metrics';
88
import { getPathParamSchema } from '../schema';
99

1010
const queryParamSchema = z.object({

app/app/api/private-cloud/products/[licencePlate]/usage-metrics/route.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { environmentLongNames, GlobalRole } from '@/constants';
55
import createApiHandler from '@/core/api-handler';
66
import { OkResponse, UnauthorizedResponse } from '@/core/responses';
77
import { models } from '@/services/db';
8-
import { getPodMetrics } from '@/services/k8s';
8+
import { getPodMetrics } from '@/services/k8s/metrics';
99
import { getPathParamSchema } from '../schema';
1010

1111
const queryParamSchema = z.object({

app/helpers/auto-approval-check.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
ResourceRequests,
77
} from '@prisma/client';
88
import _each from 'lodash-es/each';
9-
import { getResourceDetails } from '@/services/k8s';
9+
import { getResourceDetails } from '@/services/k8s/metrics';
1010
import { iterateObject } from '@/utils/js';
1111

1212
const allowedAutoApprovalPercentage = 50;

app/jest.setup.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jest.mock('@/helpers/pdfs/emou/index', () => ({
5959
generateEmouPdf: jest.fn(async () => Buffer.alloc(0)),
6060
}));
6161

62-
jest.mock('@/services/k8s', () => ({
62+
jest.mock('@/services/k8s/metrics', () => ({
6363
getResourceDetails: jest.fn(async () => ({
6464
env: 'dev',
6565
allocation: {

app/services/k8s/core.ts

Lines changed: 0 additions & 87 deletions
This file was deleted.

app/services/k8s/helpers.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { KubeConfig, CoreV1Api, Metrics } from '@kubernetes/client-node';
2+
import { Cluster } from '@prisma/client';
3+
4+
function configureKubeConfig(cluster: string, token: string) {
5+
const kc = new KubeConfig();
6+
kc.loadFromOptions({
7+
clusters: [
8+
{
9+
name: cluster,
10+
server: `https://api.${cluster}.devops.gov.bc.ca:6443`,
11+
skipTLSVerify: false,
12+
},
13+
],
14+
users: [
15+
{
16+
name: 'my-user',
17+
token: token,
18+
},
19+
],
20+
contexts: [
21+
{
22+
name: `${cluster}-context`,
23+
user: 'my-user',
24+
cluster: cluster,
25+
},
26+
],
27+
currentContext: `${cluster}-context`,
28+
});
29+
30+
return kc;
31+
}
32+
33+
export function createK8sClusterConfigs(tokens: {
34+
[Cluster.KLAB]: string;
35+
[Cluster.CLAB]: string;
36+
[Cluster.KLAB2]: string;
37+
[Cluster.GOLDDR]: string;
38+
[Cluster.GOLD]: string;
39+
[Cluster.SILVER]: string;
40+
[Cluster.EMERALD]: string;
41+
}) {
42+
const k8sConfigs = {
43+
[Cluster.KLAB]: configureKubeConfig(Cluster.KLAB, tokens[Cluster.KLAB]),
44+
[Cluster.CLAB]: configureKubeConfig(Cluster.CLAB, tokens[Cluster.CLAB]),
45+
[Cluster.KLAB2]: configureKubeConfig(Cluster.KLAB2, tokens[Cluster.KLAB2]),
46+
[Cluster.GOLDDR]: configureKubeConfig(Cluster.GOLDDR, tokens[Cluster.GOLDDR]),
47+
[Cluster.GOLD]: configureKubeConfig(Cluster.GOLD, tokens[Cluster.GOLD]),
48+
[Cluster.SILVER]: configureKubeConfig(Cluster.SILVER, tokens[Cluster.SILVER]),
49+
[Cluster.EMERALD]: configureKubeConfig(Cluster.EMERALD, tokens[Cluster.EMERALD]),
50+
};
51+
52+
function getK8sClusterToken(cluster: Cluster) {
53+
return k8sConfigs[cluster];
54+
}
55+
56+
function getK8sClusterClients(cluster: Cluster) {
57+
const kc = k8sConfigs[cluster];
58+
const apiClient = kc.makeApiClient(CoreV1Api);
59+
const metricsClient = new Metrics(kc);
60+
61+
return {
62+
apiClient,
63+
metricsClient,
64+
};
65+
}
66+
67+
return {
68+
getK8sClusterToken,
69+
getK8sClusterClients,
70+
};
71+
}

app/services/k8s/metrics/core.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { Cluster } from '@prisma/client';
2+
import axios from 'axios';
3+
import {
4+
CLAB_METRICS_READER_TOKEN,
5+
KLAB_METRICS_READER_TOKEN,
6+
KLAB2_METRICS_READER_TOKEN,
7+
GOLDDR_METRICS_READER_TOKEN,
8+
GOLD_METRICS_READER_TOKEN,
9+
SILVER_METRICS_READER_TOKEN,
10+
EMERALD_METRICS_READER_TOKEN,
11+
} from '@/config';
12+
import { createK8sClusterConfigs } from '../helpers';
13+
14+
type PrometheusMetricResult = {
15+
metric: Record<string, string>;
16+
value: [number, string];
17+
};
18+
19+
type PrometheusQueryData = {
20+
resultType: string;
21+
result: PrometheusMetricResult[];
22+
};
23+
24+
type PrometheusQueryResponse = {
25+
status: string;
26+
data: PrometheusQueryData;
27+
};
28+
29+
const { getK8sClusterToken, getK8sClusterClients } = createK8sClusterConfigs({
30+
[Cluster.KLAB]: KLAB_METRICS_READER_TOKEN,
31+
[Cluster.CLAB]: CLAB_METRICS_READER_TOKEN,
32+
[Cluster.KLAB2]: KLAB2_METRICS_READER_TOKEN,
33+
[Cluster.GOLDDR]: GOLDDR_METRICS_READER_TOKEN,
34+
[Cluster.GOLD]: GOLD_METRICS_READER_TOKEN,
35+
[Cluster.SILVER]: SILVER_METRICS_READER_TOKEN,
36+
[Cluster.EMERALD]: EMERALD_METRICS_READER_TOKEN,
37+
});
38+
39+
export const getK8sClients = getK8sClusterClients;
40+
41+
export async function queryPrometheus(query: string, cluster: Cluster) {
42+
const METRICS_URL = `https://prometheus-k8s-openshift-monitoring.apps.${cluster}.devops.gov.bc.ca`;
43+
const METRICS_TOKEN = getK8sClusterToken(cluster);
44+
const response = await axios.get<PrometheusQueryResponse>(`${METRICS_URL}/api/v1/query`, {
45+
headers: { Authorization: `Bearer ${METRICS_TOKEN}` },
46+
params: { query },
47+
});
48+
49+
return response.data.data.result;
50+
}
File renamed without changes.
File renamed without changes.

app/services/k8s/resource-details.ts renamed to app/services/k8s/metrics/resource-details.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '@prisma/client';
88
import _each from 'lodash-es/each';
99
import { getTotalMetrics, memoryUnitMultipliers, cpuCoreToMillicoreMultiplier } from '@/helpers/resource-metrics';
10-
import { getPodMetrics } from '@/services/k8s';
10+
import { getPodMetrics } from '@/services/k8s/metrics';
1111

1212
export async function getResourceDetails({
1313
licencePlate,

0 commit comments

Comments
 (0)