mirror of https://github.com/certd/certd
perf: 更新k8s底层api库
parent
7b451bbf6e
commit
746bb9d385
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
alter table cd_access alter column setting type text using setting::text;
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -9,6 +9,8 @@ export class K8sAccess {
|
|||
@AccessInput({
|
||||
title: 'kubeconfig',
|
||||
component: {
|
||||
name: 'a-textarea',
|
||||
vModel: 'value',
|
||||
placeholder: 'kubeconfig',
|
||||
},
|
||||
required: true,
|
||||
|
|
|
@ -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`;
|
||||
|
|
Loading…
Reference in New Issue