perf: 更新k8s底层api库

pull/148/head
xiaojunnuo 2024-08-14 15:10:55 +08:00
parent 7b451bbf6e
commit 746bb9d385
8 changed files with 85 additions and 64 deletions

View File

@ -13,8 +13,7 @@
"preview": "vite preview"
},
"dependencies": {
"kubernetes-client": "^9.0.0",
"shelljs": "^0.8.5"
"@kubernetes/client-node": "0.21.0"
},
"devDependencies": {
"@certd/pipeline": "^1.23.1",

View File

@ -1,32 +1,40 @@
import kubernetesClient from 'kubernetes-client';
//@ts-ignore
import { KubeConfig, CoreV1Api, V1Secret, NetworkingV1Api, V1Ingress } from '@kubernetes/client-node';
import dns from 'dns';
import { ILogger } from '@certd/pipeline';
//@ts-ignore
const { KubeConfig, Client, Request } = kubernetesClient;
export class K8sClient {
export type K8sClientOpts = {
kubeConfigStr: string;
lookup!: any;
client!: any;
logger: ILogger;
constructor(kubeConfigStr: string, logger: ILogger) {
this.kubeConfigStr = kubeConfigStr;
this.logger = logger;
//{ [domain]:{ip:'xxx.xx.xxx'} }
//暂时没用
lookup?: any;
};
export class K8sClient {
kubeconfig!: KubeConfig;
kubeConfigStr: string;
lookup!: (hostnameReq: any, options: any, callback: any) => void;
client!: CoreV1Api;
logger: ILogger;
constructor(opts: K8sClientOpts) {
this.kubeConfigStr = opts.kubeConfigStr;
this.logger = opts.logger;
this.setLookup(opts.lookup);
this.init();
}
init() {
const kubeconfig = new KubeConfig();
kubeconfig.loadFromString(this.kubeConfigStr);
const reqOpts = { kubeconfig, request: {} } as any;
if (this.lookup) {
reqOpts.request.lookup = this.lookup;
}
this.kubeconfig = kubeconfig;
this.client = kubeconfig.makeApiClient(CoreV1Api);
const backend = new Request(reqOpts);
this.client = new Client({ backend, version: '1.13' });
// const reqOpts = { kubeconfig, request: {} } as any;
// if (this.lookup) {
// reqOpts.request.lookup = this.lookup;
// }
//
// const backend = new Request(reqOpts);
// this.client = new Client({ backend, version: '1.13' });
}
/**
@ -34,6 +42,9 @@ export class K8sClient {
* @param localRecords { [domain]:{ip:'xxx.xx.xxx'} }
*/
setLookup(localRecords: { [key: string]: { ip: string } }) {
if (localRecords == null) {
return;
}
this.lookup = (hostnameReq: any, options: any, callback: any) => {
this.logger.info('custom lookup', hostnameReq, localRecords);
if (localRecords[hostnameReq]) {
@ -43,7 +54,6 @@ export class K8sClient {
dns.lookup(hostnameReq, options, callback);
}
};
this.init();
}
/**
@ -51,9 +61,9 @@ export class K8sClient {
* @param opts = {namespace:default}
* @returns secretsList
*/
async getSecret(opts: { namespace: string }) {
async getSecrets(opts: { namespace: string }) {
const namespace = opts.namespace || 'default';
return await this.client.api.v1.namespaces(namespace).secrets.get();
return await this.client.listNamespacedSecret(namespace);
}
/**
@ -61,59 +71,61 @@ export class K8sClient {
* @param opts {namespace:default, body:yamlStr}
* @returns {Promise<*>}
*/
async createSecret(opts: any) {
async createSecret(opts: { namespace: string; body: V1Secret }) {
const namespace = opts.namespace || 'default';
const created = await this.client.api.v1.namespaces(namespace).secrets.post({
body: opts.body,
});
this.logger.info('new secrets:', created);
return created;
const created = await this.client.createNamespacedSecret(namespace, opts.body);
this.logger.info('new secrets:', created.body);
return created.body;
}
async updateSecret(opts: any) {
// async updateSecret(opts: any) {
// const namespace = opts.namespace || 'default';
// const secretName = opts.secretName;
// if (secretName == null) {
// throw new Error('secretName 不能为空');
// }
// return await this.client.replaceNamespacedSecret(secretName, namespace, opts.body);
// }
async patchSecret(opts: { namespace: string; secretName: string; body: V1Secret }) {
const namespace = opts.namespace || 'default';
const secretName = opts.secretName;
if (secretName == null) {
throw new Error('secretName 不能为空');
}
return await this.client.api.v1.namespaces(namespace).secrets(secretName).put({
body: opts.body,
});
const res = await this.client.patchNamespacedSecret(secretName, namespace, opts.body);
this.logger.info('secret patched:', res.body);
return res.body;
}
async patchSecret(opts: any) {
async getIngressList(opts: { namespace: string }) {
const namespace = opts.namespace || 'default';
const secretName = opts.secretName;
if (secretName == null) {
throw new Error('secretName 不能为空');
}
return await this.client.api.v1.namespaces(namespace).secrets(secretName).patch({
body: opts.body,
});
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
const res = await client.listNamespacedIngress(namespace);
this.logger.info('ingress list get:', res.body);
return res.body;
}
async getIngressList(opts: any) {
const namespace = opts.namespace || 'default';
return await this.client.apis.extensions.v1beta1.namespaces(namespace).ingresses.get();
}
// async getIngress(opts: { namespace: string; ingressName: string }) {
// const namespace = opts.namespace || 'default';
// const ingressName = opts.ingressName;
// if (!ingressName) {
// throw new Error('ingressName 不能为空');
// }
// const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
// const res = await client.listNamespacedIngress();
// return await this.client.apis.extensions.v1beta1.namespaces(namespace).ingresses(ingressName).get();
// }
async getIngress(opts: any) {
async patchIngress(opts: { namespace: string; ingressName: string; body: V1Ingress }) {
const namespace = opts.namespace || 'default';
const ingressName = opts.ingressName;
if (!ingressName) {
throw new Error('ingressName 不能为空');
}
return await this.client.apis.extensions.v1beta1.namespaces(namespace).ingresses(ingressName).get();
}
async patchIngress(opts: any) {
const namespace = opts.namespace || 'default';
const ingressName = opts.ingressName;
if (!ingressName) {
throw new Error('ingressName 不能为空');
}
return await this.client.apis.extensions.v1beta1.namespaces(namespace).ingresses(ingressName).patch({
body: opts.body,
});
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
const res = await client.patchNamespacedIngress(ingressName, namespace, opts.body);
this.logger.info('ingress patched:', res.body);
return res;
}
}

View File

@ -97,7 +97,7 @@ export class CertApplyLegoPlugin extends CertApplyBasePlugin {
this.http = this.ctx.http;
this.lastStatus = this.ctx.lastStatus as Step;
if (this.legoEabAccessId) {
this.eab = await this.ctx.accessService.getById(this.legoEabAccessId);
this.eab = await this.accessService.getById(this.legoEabAccessId);
}
}
async onInit(): Promise<void> {}

View File

@ -0,0 +1 @@
alter table cd_access alter column setting type text using setting::text;

View File

@ -4,3 +4,4 @@ export * from './plugin-tencent/index.js';
export * from './plugin-host/index.js';
export * from './plugin-huawei/index.js';
export * from './plugin-demo/index.js';
export * from './plugin-other/index.js';

View File

@ -115,7 +115,10 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
const kubeConfigStr = await this.getKubeConfig(client, clusterId, isPrivateIpAddress);
this.logger.info('kubeconfig已成功获取');
const k8sClient = new K8sClient(kubeConfigStr, this.logger);
const k8sClient = new K8sClient({
kubeConfigStr,
logger: this.logger,
});
const ingressType = ingressClass || 'qcloud';
if (ingressType === 'qcloud') {
throw new Error('暂未实现');
@ -128,7 +131,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
// await this.restartIngress({ k8sClient, props })
}
async restartIngress(options: { k8sClient: any }) {
async restartIngress(options: { k8sClient: K8sClient }) {
const { k8sClient } = options;
const { namespace } = this;
@ -141,10 +144,10 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
};
const ingressList = await k8sClient.getIngressList({ namespace });
console.log('ingressList:', ingressList);
if (!ingressList || !ingressList.body || !ingressList.body.items) {
if (!ingressList || !ingressList.items) {
return;
}
const ingressNames = ingressList.body.items
const ingressNames = ingressList.items
.filter((item: any) => {
if (!item.spec.tls) {
return false;
@ -165,7 +168,7 @@ export class DeployCertToAliyunAckIngressPlugin extends AbstractTaskPlugin {
}
}
async patchNginxCertSecret(options: { cert: any; k8sClient: any }) {
async patchNginxCertSecret(options: { cert: CertInfo; k8sClient: K8sClient }) {
const { cert, k8sClient } = options;
const crt = cert.crt;
const key = cert.key;

View File

@ -9,6 +9,8 @@ export class K8sAccess {
@AccessInput({
title: 'kubeconfig',
component: {
name: 'a-textarea',
vModel: 'value',
placeholder: 'kubeconfig',
},
required: true,

View File

@ -97,7 +97,10 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
const kubeConfigStr = await this.getTkeKubeConfig(tkeClient, this.clusterId);
this.logger.info('kubeconfig已成功获取');
const k8sClient = new K8sClient(kubeConfigStr, this.logger);
const k8sClient = new K8sClient({
kubeConfigStr,
logger: this.logger,
});
if (this.clusterIp != null) {
if (!this.clusterDomain) {
this.clusterDomain = `${this.clusterId}.ccs.tencent-cloud.com`;