UNPKG

tencentcloud-sdk-nodejs-common

Version:
210 lines (209 loc) 7.54 kB
import fs from "fs"; import path from "path"; import { homedir } from "os"; import { parse } from "ini"; import { CommonClient } from "./common_client"; import CvmRoleCredential from "./cvm_role_credential"; const EXPIRE_BUFFER = 30 * 1000; export class BasicCredential { constructor(secretId, secretKey, token) { this.secretId = secretId; this.secretKey = secretKey; this.token = token; } } export class EnvironmentVariableCredential { async getCredential() { const secretId = process.env.TENCENTCLOUD_SECRET_ID; const secretKey = process.env.TENCENTCLOUD_SECRET_KEY; const token = process.env.TENCENTCLOUD_SESSION_TOKEN; return new BasicCredential(secretId, secretKey, token); } } export class ProfileCredential { async getCredential() { let filePath = ""; const userHome = homedir(); const userCredentialsPath = path.join(userHome, ".tencentcloud", "credentials"); if (fs.existsSync(userCredentialsPath)) { filePath = userCredentialsPath; } else { filePath = "/etc/tencentcloud/credentials"; } if (filePath) { try { const content = fs.readFileSync(filePath, "utf8"); const { default: { secret_id, secret_key, token }, } = parse(content); if (secret_id && secret_key) { return new BasicCredential(secret_id, secret_key, token); } } catch (error) { } } return new BasicCredential("", ""); } } export class STSCredential { constructor(clientConfig, assumeRoleParams) { this.clientConfig = clientConfig; this.assumeRoleParams = assumeRoleParams; this.endpoint = "sts.tencentcloudapi.com"; this.version = "2018-08-13"; this.action = "AssumeRole"; this.region = "ap-guangzhou"; } async getCredentialWithStsAssumeRole() { const { endpoint, version, action, region, clientConfig, assumeRoleParams } = this; try { const client = new CommonClient(endpoint, version, { region, ...clientConfig, }); const result = await client.request(action, assumeRoleParams); return { TmpSecretId: result.Credentials.TmpSecretId, TmpSecretKey: result.Credentials.TmpSecretKey, Token: result.Credentials.Token, ExpiredTime: result.ExpiredTime, Expiration: result.Expiration, }; } catch (error) { throw new Error(`Get STS AssumeRole failed: ${error.message}`); } } async getCredential() { if (!this.credentialTask) { this.credentialTask = this.getCredentialWithStsAssumeRole(); } const credential = await this.credentialTask; if (credential.ExpiredTime * 1000 - EXPIRE_BUFFER <= Date.now()) { this.credentialTask = null; return this.getCredential(); } return { secretId: credential.TmpSecretId, secretKey: credential.TmpSecretKey, token: credential.Token, }; } } export { default as CvmRoleCredential } from "./cvm_role_credential"; export class OIDCRoleArnCredential { constructor(clientConfig, assumeRoleWithWebIdentityParams) { this.endpoint = "sts.tencentcloudapi.com"; this.version = "2018-08-13"; this.action = "AssumeRoleWithWebIdentity"; this.defaultSessionName = "tencentcloud-node-sdk-"; this.isTke = false; this.expirationReservationTime = 600; if (clientConfig && assumeRoleWithWebIdentityParams) { this.clientConfig = clientConfig; this.assumeRoleWithWebIdentityParams = assumeRoleWithWebIdentityParams; } else { this.isTke = true; this.clientConfig = { credential: new BasicCredential("", ""), ...clientConfig, }; } } initFromTke() { const region = process.env.TKE_REGION; if (!region) { throw new Error("env TKE_REGION not exist"); } const providerId = process.env.TKE_PROVIDER_ID; if (!providerId) { throw new Error("env TKE_PROVIDER_ID not exist"); } const tokenFile = process.env.TKE_WEB_IDENTITY_TOKEN_FILE; if (!tokenFile) { throw new Error("env TKE_WEB_IDENTITY_TOKEN_FILE not exist"); } let wbIdentityToken; try { wbIdentityToken = fs.readFileSync(tokenFile).toString(); } catch (error) { throw new Error(`failed to read token file: ${error.message}`); } const roleArn = process.env.TKE_ROLE_ARN; if (!roleArn) { throw new Error("env TKE_ROLE_ARN not exist"); } this.clientConfig.region = region; this.assumeRoleWithWebIdentityParams = { RoleArn: roleArn, RoleSessionName: `${this.defaultSessionName}${Date.now() * 1000}`, WebIdentityToken: wbIdentityToken, ProviderId: providerId, }; } async getCredentialWithStsAssumeRoleWithWebIdentity() { try { if (this.isTke) { this.initFromTke(); } const { endpoint, version, action, region, clientConfig, assumeRoleWithWebIdentityParams } = this; const client = new CommonClient(endpoint, version, { region: region, ...clientConfig, }); const result = await client.request(action, assumeRoleWithWebIdentityParams); return { TmpSecretId: result.Credentials.TmpSecretId, TmpSecretKey: result.Credentials.TmpSecretKey, Token: result.Credentials.Token, ExpiredTime: result.ExpiredTime, Expiration: result.Expiration, }; } catch (error) { throw new Error(`Get STS AssumeRoleWithWebIdentity failed: ${error.message}`); } } async getCredential() { if (!this.credentialTask) { this.credentialTask = this.getCredentialWithStsAssumeRoleWithWebIdentity(); } const credential = await this.credentialTask; if (credential.ExpiredTime * 1000 - this.expirationReservationTime <= Date.now()) { this.credentialTask = null; return this.getCredential(); } return { secretId: credential.TmpSecretId, secretKey: credential.TmpSecretKey, token: credential.Token, }; } } export class DefaultCredentialProvider { constructor() { this.providers = [ new EnvironmentVariableCredential(), new ProfileCredential(), new CvmRoleCredential(), new OIDCRoleArnCredential(), ]; } async getCredential() { for (const provider of this.providers) { try { const credential = await provider.getCredential(); if (credential.secretId && credential.secretKey) { return credential; } } catch (error) { console.error(error); continue; } } return new BasicCredential("", ""); } }