1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/main/prometheus/provider-registry.ts
Janne Savolainen 589472c2b5
Shorten license header to reduce amount of clutter in top of the files (#4709)
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
2022-01-18 10:18:10 +02:00

91 lines
2.9 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { CoreV1Api } from "@kubernetes/client-node";
import { inspect } from "util";
import { Singleton } from "../../common/utils";
export type PrometheusService = {
id: string;
namespace: string;
service: string;
port: number;
};
export abstract class PrometheusProvider {
abstract readonly id: string;
abstract readonly name: string;
abstract readonly rateAccuracy: string;
abstract readonly isConfigurable: boolean;
abstract getQuery(opts: Record<string, string>, queryName: string): string;
abstract getPrometheusService(client: CoreV1Api): Promise<PrometheusService | undefined>;
protected bytesSent(ingress: string, namespace: string, statuses: string): string {
return `sum(rate(nginx_ingress_controller_bytes_sent_sum{ingress="${ingress}",namespace="${namespace}",status=~"${statuses}"}[${this.rateAccuracy}])) by (ingress, namespace)`;
}
protected async getFirstNamespacedService(client: CoreV1Api, ...selectors: string[]): Promise<PrometheusService> {
try {
for (const selector of selectors) {
const { body: { items: [service] }} = await client.listServiceForAllNamespaces(null, null, null, selector);
if (service) {
return {
id: this.id,
namespace: service.metadata.namespace,
service: service.metadata.name,
port: service.spec.ports[0].port,
};
}
}
} catch (error) {
throw new Error(`Failed to list services for Prometheus${this.name} in all namespaces: ${error.response.body.message}`);
}
throw new Error(`No service found for Prometheus${this.name} from any namespace`);
}
protected async getNamespacedService(client: CoreV1Api, name: string, namespace: string): Promise<PrometheusService> {
try {
const resp = await client.readNamespacedService(name, namespace);
const service = resp.body;
return {
id: this.id,
namespace: service.metadata.namespace,
service: service.metadata.name,
port: service.spec.ports[0].port,
};
} catch(error) {
throw new Error(`Failed to list services for Prometheus${this.name} in namespace=${inspect(namespace, false, undefined, false)}: ${error.response.body.message}`);
}
}
}
export class PrometheusProviderRegistry extends Singleton {
public providers = new Map<string, PrometheusProvider>();
getByKind(kind: string): PrometheusProvider {
const provider = this.providers.get(kind);
if (!provider) {
throw new Error("Unknown Prometheus provider");
}
return provider;
}
registerProvider(provider: PrometheusProvider): this {
if (this.providers.has(provider.id)) {
throw new Error("Provider already registered under that kind");
}
this.providers.set(provider.id, provider);
return this;
}
}