tencentcloud-sdk-nodejs-common
Version:
210 lines (209 loc) • 7.54 kB
JavaScript
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("", "");
}
}