fanqiang 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +78 -0
- package/bin/fanqiang.d.ts +3 -0
- package/bin/fanqiang.d.ts.map +1 -0
- package/bin/fanqiang.js +31 -0
- package/bin/fanqiang.js.map +1 -0
- package/bin/fanqiang.ts +35 -0
- package/index.d.ts +3 -0
- package/index.d.ts.map +1 -0
- package/index.js +6 -0
- package/index.js.map +1 -0
- package/index.ts +3 -0
- package/lib/core/AwsS3CloudStorage.d.ts +6 -0
- package/lib/core/AwsS3CloudStorage.d.ts.map +1 -0
- package/lib/core/AwsS3CloudStorage.js +70 -0
- package/lib/core/AwsS3CloudStorage.js.map +1 -0
- package/lib/core/AwsS3CloudStorage.ts +90 -0
- package/lib/core/Configuration.d.ts +15 -0
- package/lib/core/Configuration.d.ts.map +1 -0
- package/lib/core/Configuration.js +24 -0
- package/lib/core/Configuration.js.map +1 -0
- package/lib/core/Configuration.ts +33 -0
- package/lib/core/StoredOptions.d.ts +18 -0
- package/lib/core/StoredOptions.d.ts.map +1 -0
- package/lib/core/StoredOptions.js +30 -0
- package/lib/core/StoredOptions.js.map +1 -0
- package/lib/core/StoredOptions.ts +37 -0
- package/lib/core/TerraformTunnelProxyOperations.d.ts +9 -0
- package/lib/core/TerraformTunnelProxyOperations.d.ts.map +1 -0
- package/lib/core/TerraformTunnelProxyOperations.js +38 -0
- package/lib/core/TerraformTunnelProxyOperations.js.map +1 -0
- package/lib/core/TerraformTunnelProxyOperations.ts +43 -0
- package/lib/core/aliyunCredentials.d.ts +7 -0
- package/lib/core/aliyunCredentials.d.ts.map +1 -0
- package/lib/core/aliyunCredentials.js +29 -0
- package/lib/core/aliyunCredentials.js.map +1 -0
- package/lib/core/aliyunCredentials.ts +30 -0
- package/lib/core/langUtils.d.ts +11 -0
- package/lib/core/langUtils.d.ts.map +1 -0
- package/lib/core/langUtils.js +69 -0
- package/lib/core/langUtils.js.map +1 -0
- package/lib/core/langUtils.ts +71 -0
- package/lib/core/terraform.d.ts +5 -0
- package/lib/core/terraform.d.ts.map +1 -0
- package/lib/core/terraform.js +90 -0
- package/lib/core/terraform.js.map +1 -0
- package/lib/core/terraform.ts +99 -0
- package/lib/domain/Clash.d.ts +6 -0
- package/lib/domain/Clash.d.ts.map +1 -0
- package/lib/domain/Clash.js +24 -0
- package/lib/domain/Clash.js.map +1 -0
- package/lib/domain/Clash.ts +24 -0
- package/lib/domain/CloudStorage.d.ts +9 -0
- package/lib/domain/CloudStorage.d.ts.map +1 -0
- package/lib/domain/CloudStorage.js +3 -0
- package/lib/domain/CloudStorage.js.map +1 -0
- package/lib/domain/CloudStorage.ts +11 -0
- package/lib/domain/TunnelProxyOperations.d.ts +19 -0
- package/lib/domain/TunnelProxyOperations.d.ts.map +1 -0
- package/lib/domain/TunnelProxyOperations.js +3 -0
- package/lib/domain/TunnelProxyOperations.js.map +1 -0
- package/lib/domain/TunnelProxyOperations.ts +19 -0
- package/lib/handlers.d.ts +3 -0
- package/lib/handlers.d.ts.map +1 -0
- package/lib/handlers.js +27 -0
- package/lib/handlers.js.map +1 -0
- package/lib/handlers.ts +28 -0
- package/package.json +81 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
export declare type Strict<T> = {
|
2
|
+
[K in keyof T]: NonNullable<T[K]>;
|
3
|
+
};
|
4
|
+
export declare function promiseAllSync<T, R>(values: T[], handler: (value: T) => Promise<R>): Promise<R[]>;
|
5
|
+
export declare function singletonResult<T>(result: T[]): T;
|
6
|
+
export declare function nonNullArray<T>(array: T[] | undefined): T[];
|
7
|
+
export declare function sleep(ms: number): Promise<void>;
|
8
|
+
export declare function waitCondition(checkCondition: () => Promise<boolean>, interval?: number, maxRetries?: number): Promise<void>;
|
9
|
+
export declare function executeWithEnvironment<R>(func: () => R, envKey: string, envValue: string): R;
|
10
|
+
export declare function invokeIgnoreError(func: () => Promise<void>, ignoredError: string, message?: string): Promise<void>;
|
11
|
+
//# sourceMappingURL=langUtils.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"langUtils.d.ts","sourceRoot":"","sources":["langUtils.ts"],"names":[],"mappings":"AAAA,oBAAY,MAAM,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAE9D,wBAAsB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAMvG;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,CAKjD;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,GAAG,CAAC,EAAE,CAE3D;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED,wBAAsB,aAAa,CACjC,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EACtC,QAAQ,CAAC,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,CAY5F;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACzB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.invokeIgnoreError = exports.executeWithEnvironment = exports.waitCondition = exports.sleep = exports.nonNullArray = exports.singletonResult = exports.promiseAllSync = void 0;
|
4
|
+
async function promiseAllSync(values, handler) {
|
5
|
+
const result = new Array(values.length);
|
6
|
+
for (const v of values) {
|
7
|
+
result.push(await handler(v));
|
8
|
+
}
|
9
|
+
return result;
|
10
|
+
}
|
11
|
+
exports.promiseAllSync = promiseAllSync;
|
12
|
+
function singletonResult(result) {
|
13
|
+
if (result.length !== 1) {
|
14
|
+
throw new Error("Not singleton, actual length: " + result.length);
|
15
|
+
}
|
16
|
+
return result[0];
|
17
|
+
}
|
18
|
+
exports.singletonResult = singletonResult;
|
19
|
+
function nonNullArray(array) {
|
20
|
+
return array && array.length ? array : [];
|
21
|
+
}
|
22
|
+
exports.nonNullArray = nonNullArray;
|
23
|
+
function sleep(ms) {
|
24
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
25
|
+
}
|
26
|
+
exports.sleep = sleep;
|
27
|
+
async function waitCondition(checkCondition, interval, maxRetries) {
|
28
|
+
let remain = maxRetries || 10;
|
29
|
+
const waitMillis = interval || 5000;
|
30
|
+
while (remain > 0) {
|
31
|
+
if (await checkCondition()) {
|
32
|
+
return;
|
33
|
+
}
|
34
|
+
await sleep(waitMillis);
|
35
|
+
remain -= 1;
|
36
|
+
}
|
37
|
+
throw new Error("Resource failed to reach status!");
|
38
|
+
}
|
39
|
+
exports.waitCondition = waitCondition;
|
40
|
+
function executeWithEnvironment(func, envKey, envValue) {
|
41
|
+
const oldValue = process.env[envKey];
|
42
|
+
process.env[envKey] = envValue;
|
43
|
+
try {
|
44
|
+
return func();
|
45
|
+
}
|
46
|
+
finally {
|
47
|
+
if (oldValue === undefined) {
|
48
|
+
delete process.env[envKey];
|
49
|
+
}
|
50
|
+
else {
|
51
|
+
process.env[envKey] = oldValue;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
exports.executeWithEnvironment = executeWithEnvironment;
|
56
|
+
async function invokeIgnoreError(func, ignoredError, message) {
|
57
|
+
try {
|
58
|
+
await func();
|
59
|
+
}
|
60
|
+
catch (e) {
|
61
|
+
if (e.name === ignoredError) {
|
62
|
+
console.log(message || e.message);
|
63
|
+
return;
|
64
|
+
}
|
65
|
+
throw e;
|
66
|
+
}
|
67
|
+
}
|
68
|
+
exports.invokeIgnoreError = invokeIgnoreError;
|
69
|
+
//# sourceMappingURL=langUtils.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"langUtils.js","sourceRoot":"","sources":["langUtils.ts"],"names":[],"mappings":";;;AAEO,KAAK,UAAU,cAAc,CAAO,MAAW,EAAE,OAAiC;IACvF,MAAM,MAAM,GAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE;QACtB,MAAM,CAAC,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;KAC/B;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAND,wCAMC;AAED,SAAgB,eAAe,CAAI,MAAW;IAC5C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;KACnE;IACD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AALD,0CAKC;AAED,SAAgB,YAAY,CAAI,KAAsB;IACpD,OAAO,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC;AAFD,oCAEC;AAED,SAAgB,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAFD,sBAEC;AAEM,KAAK,UAAU,aAAa,CACjC,cAAsC,EACtC,QAAiB,EACjB,UAAmB;IAEnB,IAAI,MAAM,GAAG,UAAU,IAAI,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,QAAQ,IAAI,IAAI,CAAC;IACpC,OAAO,MAAM,GAAG,CAAC,EAAE;QACjB,IAAI,MAAM,cAAc,EAAE,EAAE;YAC1B,OAAO;SACR;QACD,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QACxB,MAAM,IAAI,CAAC,CAAC;KACb;IACD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;AACtD,CAAC;AAfD,sCAeC;AAED,SAAgB,sBAAsB,CAAI,IAAa,EAAE,MAAc,EAAE,QAAgB;IACvF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;IAC/B,IAAI;QACF,OAAO,IAAI,EAAE,CAAC;KACf;YAAS;QACR,IAAI,QAAQ,KAAK,SAAS,EAAE;YAC1B,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;SAC5B;aAAM;YACL,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC;SAChC;KACF;AACH,CAAC;AAZD,wDAYC;AAEM,KAAK,UAAU,iBAAiB,CACrC,IAAyB,EACzB,YAAoB,EACpB,OAAgB;IAEhB,IAAI;QACF,MAAM,IAAI,EAAE,CAAC;KACd;IAAC,OAAO,CAAC,EAAE;QACV,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE;YAC3B,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;YAClC,OAAO;SACR;QACD,MAAM,CAAC,CAAC;KACT;AACH,CAAC;AAdD,8CAcC"}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
export type Strict<T> = { [K in keyof T]: NonNullable<T[K]> };
|
2
|
+
|
3
|
+
export async function promiseAllSync<T, R>(values: T[], handler: (value: T) => Promise<R>): Promise<R[]> {
|
4
|
+
const result: R[] = new Array(values.length);
|
5
|
+
for (const v of values) {
|
6
|
+
result.push(await handler(v));
|
7
|
+
}
|
8
|
+
return result;
|
9
|
+
}
|
10
|
+
|
11
|
+
export function singletonResult<T>(result: T[]): T {
|
12
|
+
if (result.length !== 1) {
|
13
|
+
throw new Error("Not singleton, actual length: " + result.length);
|
14
|
+
}
|
15
|
+
return result[0];
|
16
|
+
}
|
17
|
+
|
18
|
+
export function nonNullArray<T>(array: T[] | undefined): T[] {
|
19
|
+
return array && array.length ? array : [];
|
20
|
+
}
|
21
|
+
|
22
|
+
export function sleep(ms: number): Promise<void> {
|
23
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
24
|
+
}
|
25
|
+
|
26
|
+
export async function waitCondition(
|
27
|
+
checkCondition: () => Promise<boolean>,
|
28
|
+
interval?: number,
|
29
|
+
maxRetries?: number
|
30
|
+
): Promise<void> {
|
31
|
+
let remain = maxRetries || 10;
|
32
|
+
const waitMillis = interval || 5000;
|
33
|
+
while (remain > 0) {
|
34
|
+
if (await checkCondition()) {
|
35
|
+
return;
|
36
|
+
}
|
37
|
+
await sleep(waitMillis);
|
38
|
+
remain -= 1;
|
39
|
+
}
|
40
|
+
throw new Error("Resource failed to reach status!");
|
41
|
+
}
|
42
|
+
|
43
|
+
export function executeWithEnvironment<R>(func: () => R, envKey: string, envValue: string): R {
|
44
|
+
const oldValue = process.env[envKey];
|
45
|
+
process.env[envKey] = envValue;
|
46
|
+
try {
|
47
|
+
return func();
|
48
|
+
} finally {
|
49
|
+
if (oldValue === undefined) {
|
50
|
+
delete process.env[envKey];
|
51
|
+
} else {
|
52
|
+
process.env[envKey] = oldValue;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
export async function invokeIgnoreError(
|
58
|
+
func: () => Promise<void>,
|
59
|
+
ignoredError: string,
|
60
|
+
message?: string
|
61
|
+
): Promise<void> {
|
62
|
+
try {
|
63
|
+
await func();
|
64
|
+
} catch (e) {
|
65
|
+
if (e.name === ignoredError) {
|
66
|
+
console.log(message || e.message);
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
throw e;
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import { AliyunCredentials } from "./aliyunCredentials";
|
2
|
+
import { TunnelProxyCreatingRequest } from "../domain/TunnelProxyOperations";
|
3
|
+
export declare function apply(request: TunnelProxyCreatingRequest, backend: string, credentials: AliyunCredentials): Promise<string>;
|
4
|
+
export declare function destroy(request: TunnelProxyCreatingRequest, backend: string, credentials: AliyunCredentials): Promise<void>;
|
5
|
+
//# sourceMappingURL=terraform.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"terraform.d.ts","sourceRoot":"","sources":["terraform.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAA0B,MAAM,qBAAqB,CAAC;AAEhF,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAG7E,wBAAgB,KAAK,CACnB,OAAO,EAAE,0BAA0B,EACnC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,wBAAgB,OAAO,CACrB,OAAO,EAAE,0BAA0B,EACnC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,iBAAiB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.destroy = exports.apply = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const child_process = tslib_1.__importStar(require("child_process"));
|
6
|
+
const tmp = tslib_1.__importStar(require("tmp"));
|
7
|
+
const fs = tslib_1.__importStar(require("fs-extra"));
|
8
|
+
const path = tslib_1.__importStar(require("path"));
|
9
|
+
const aliyunCredentials_1 = require("./aliyunCredentials");
|
10
|
+
const util = tslib_1.__importStar(require("util"));
|
11
|
+
const process = tslib_1.__importStar(require("process"));
|
12
|
+
function apply(request, backend, credentials) {
|
13
|
+
return runInWorkdir(async (workdir) => {
|
14
|
+
await replaceTemplate(path.join(workdir, "backend.tf"), { "${bucket}": backend, "${region}": request.proxyRegion });
|
15
|
+
await init(workdir, credentials);
|
16
|
+
await provisioning(["apply", ...getBaseArgs(request, backend)], workdir, aliyunCredentials_1.asEnvironmentVariables(credentials));
|
17
|
+
return await inspecting(["output", "-raw", "address"], workdir);
|
18
|
+
});
|
19
|
+
}
|
20
|
+
exports.apply = apply;
|
21
|
+
function destroy(request, backend, credentials) {
|
22
|
+
return runInWorkdir(async (workdir) => {
|
23
|
+
await replaceTemplate(path.join(workdir, "backend.tf"), { "${bucket}": backend, "${region}": request.proxyRegion });
|
24
|
+
await init(workdir, credentials);
|
25
|
+
await provisioning(["destroy", ...getBaseArgs(request, backend)], workdir, aliyunCredentials_1.asEnvironmentVariables(credentials));
|
26
|
+
});
|
27
|
+
}
|
28
|
+
exports.destroy = destroy;
|
29
|
+
async function init(workdir, credentials) {
|
30
|
+
await provisioning(["init"], workdir, aliyunCredentials_1.asEnvironmentVariables(credentials));
|
31
|
+
}
|
32
|
+
async function provisioning(args, cwd, customEnv = {}) {
|
33
|
+
return new Promise((resolve, reject) => {
|
34
|
+
const p = child_process.spawn("terraform", args, { cwd, stdio: "inherit", env: Object.assign(Object.assign({}, process.env), customEnv) });
|
35
|
+
p.on("close", (code) => {
|
36
|
+
if (code === 0) {
|
37
|
+
resolve();
|
38
|
+
}
|
39
|
+
else {
|
40
|
+
reject("error code: " + code);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
p.on("error", reject);
|
44
|
+
});
|
45
|
+
}
|
46
|
+
async function inspecting(args, cwd) {
|
47
|
+
return (await util.promisify(child_process.execFile)("terraform", args, { cwd })).stdout;
|
48
|
+
}
|
49
|
+
async function runInWorkdir(executeFunc) {
|
50
|
+
const workdir = await prepareWorkdir();
|
51
|
+
console.log("Copy terraform configuration to: " + workdir);
|
52
|
+
try {
|
53
|
+
return await executeFunc(workdir);
|
54
|
+
}
|
55
|
+
finally {
|
56
|
+
await fs.rm(workdir, { force: true, recursive: true });
|
57
|
+
}
|
58
|
+
}
|
59
|
+
async function prepareWorkdir() {
|
60
|
+
const workdir = tmp.dirSync({ keep: false, unsafeCleanup: true }).name;
|
61
|
+
await fs.copy(path.join(__dirname, "..", "..", "terraform"), workdir, { overwrite: true, recursive: true });
|
62
|
+
return workdir;
|
63
|
+
}
|
64
|
+
async function replaceTemplate(file, params) {
|
65
|
+
const template = file + ".template";
|
66
|
+
let content = await fs.readFile(template, "utf8");
|
67
|
+
for (const k in params) {
|
68
|
+
content = content.replace(k, params[k]);
|
69
|
+
}
|
70
|
+
await fs.writeFile(file, content);
|
71
|
+
await fs.rm(template, { force: true });
|
72
|
+
}
|
73
|
+
function getBaseArgs(request, backend) {
|
74
|
+
return [
|
75
|
+
"-auto-approve",
|
76
|
+
"-var",
|
77
|
+
`proxy_region=${request.proxyRegion}`,
|
78
|
+
"-var",
|
79
|
+
`tunnel_region=${request.tunnelRegion}`,
|
80
|
+
"-var",
|
81
|
+
`port=${request.port}`,
|
82
|
+
"-var",
|
83
|
+
`password=${request.password}`,
|
84
|
+
"-var",
|
85
|
+
`encryption_algorithm=${request.encryptionAlgorithm}`,
|
86
|
+
"-var",
|
87
|
+
`bucket=${backend}`,
|
88
|
+
];
|
89
|
+
}
|
90
|
+
//# sourceMappingURL=terraform.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"terraform.js","sourceRoot":"","sources":["terraform.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import * as child_process from "child_process";
|
2
|
+
import * as tmp from "tmp";
|
3
|
+
import * as fs from "fs-extra";
|
4
|
+
import * as path from "path";
|
5
|
+
import { AliyunCredentials, asEnvironmentVariables } from "./aliyunCredentials";
|
6
|
+
import * as util from "util";
|
7
|
+
import { TunnelProxyCreatingRequest } from "../domain/TunnelProxyOperations";
|
8
|
+
import * as process from "process";
|
9
|
+
|
10
|
+
export function apply(
|
11
|
+
request: TunnelProxyCreatingRequest,
|
12
|
+
backend: string,
|
13
|
+
credentials: AliyunCredentials
|
14
|
+
): Promise<string> {
|
15
|
+
return runInWorkdir(async (workdir) => {
|
16
|
+
await replaceTemplate(path.join(workdir, "backend.tf"), { "${bucket}": backend, "${region}": request.proxyRegion });
|
17
|
+
await init(workdir, credentials);
|
18
|
+
await provisioning(["apply", ...getBaseArgs(request, backend)], workdir, asEnvironmentVariables(credentials));
|
19
|
+
return await inspecting(["output", "-raw", "address"], workdir);
|
20
|
+
});
|
21
|
+
}
|
22
|
+
|
23
|
+
export function destroy(
|
24
|
+
request: TunnelProxyCreatingRequest,
|
25
|
+
backend: string,
|
26
|
+
credentials: AliyunCredentials
|
27
|
+
): Promise<void> {
|
28
|
+
return runInWorkdir(async (workdir) => {
|
29
|
+
await replaceTemplate(path.join(workdir, "backend.tf"), { "${bucket}": backend, "${region}": request.proxyRegion });
|
30
|
+
await init(workdir, credentials);
|
31
|
+
await provisioning(["destroy", ...getBaseArgs(request, backend)], workdir, asEnvironmentVariables(credentials));
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
async function init(workdir: string, credentials: AliyunCredentials): Promise<void> {
|
36
|
+
await provisioning(["init"], workdir, asEnvironmentVariables(credentials));
|
37
|
+
}
|
38
|
+
|
39
|
+
async function provisioning(args: string[], cwd: string, customEnv: Record<string, string> = {}): Promise<void> {
|
40
|
+
return new Promise<void>((resolve, reject) => {
|
41
|
+
const p = child_process.spawn("terraform", args, { cwd, stdio: "inherit", env: { ...process.env, ...customEnv } });
|
42
|
+
p.on("close", (code) => {
|
43
|
+
if (code === 0) {
|
44
|
+
resolve();
|
45
|
+
} else {
|
46
|
+
reject("error code: " + code);
|
47
|
+
}
|
48
|
+
});
|
49
|
+
p.on("error", reject);
|
50
|
+
});
|
51
|
+
}
|
52
|
+
|
53
|
+
async function inspecting(args: string[], cwd: string): Promise<string> {
|
54
|
+
return (await util.promisify(child_process.execFile)("terraform", args, { cwd })).stdout;
|
55
|
+
}
|
56
|
+
|
57
|
+
async function runInWorkdir<R>(executeFunc: (workdir: string) => Promise<R>): Promise<R> {
|
58
|
+
const workdir = await prepareWorkdir();
|
59
|
+
console.log("Copy terraform configuration to: " + workdir);
|
60
|
+
try {
|
61
|
+
return await executeFunc(workdir);
|
62
|
+
} finally {
|
63
|
+
await fs.rm(workdir, { force: true, recursive: true });
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
async function prepareWorkdir(): Promise<string> {
|
68
|
+
const workdir = tmp.dirSync({ keep: false, unsafeCleanup: true }).name;
|
69
|
+
await fs.copy(path.join(__dirname, "..", "..", "terraform"), workdir, { overwrite: true, recursive: true });
|
70
|
+
return workdir;
|
71
|
+
}
|
72
|
+
|
73
|
+
async function replaceTemplate(file: string, params: Record<string, string>): Promise<void> {
|
74
|
+
const template = file + ".template";
|
75
|
+
let content = await fs.readFile(template, "utf8");
|
76
|
+
for (const k in params) {
|
77
|
+
content = content.replace(k, params[k]);
|
78
|
+
}
|
79
|
+
await fs.writeFile(file, content);
|
80
|
+
await fs.rm(template, { force: true });
|
81
|
+
}
|
82
|
+
|
83
|
+
function getBaseArgs(request: TunnelProxyCreatingRequest, backend: string): string[] {
|
84
|
+
return [
|
85
|
+
"-auto-approve",
|
86
|
+
"-var",
|
87
|
+
`proxy_region=${request.proxyRegion}`,
|
88
|
+
"-var",
|
89
|
+
`tunnel_region=${request.tunnelRegion}`,
|
90
|
+
"-var",
|
91
|
+
`port=${request.port}`,
|
92
|
+
"-var",
|
93
|
+
`password=${request.password}`,
|
94
|
+
"-var",
|
95
|
+
`encryption_algorithm=${request.encryptionAlgorithm}`,
|
96
|
+
"-var",
|
97
|
+
`bucket=${backend}`,
|
98
|
+
];
|
99
|
+
}
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { ProxyOptions } from "./TunnelProxyOperations";
|
2
|
+
export declare type TunnelProxyConnectionInfo = ProxyOptions & {
|
3
|
+
address: string;
|
4
|
+
};
|
5
|
+
export declare function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string;
|
6
|
+
//# sourceMappingURL=Clash.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"Clash.d.ts","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,oBAAY,yBAAyB,GAAG,YAAY,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,yBAAyB,GAAG,MAAM,CAgB/E"}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.generateConfigFrom = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const yaml_1 = tslib_1.__importDefault(require("yaml"));
|
6
|
+
function generateConfigFrom(endpoints) {
|
7
|
+
return yaml_1.default.stringify({
|
8
|
+
port: 7890,
|
9
|
+
"socks-port": 7891,
|
10
|
+
mode: "global",
|
11
|
+
proxies: [
|
12
|
+
{
|
13
|
+
name: "shadowsocks",
|
14
|
+
type: "ss",
|
15
|
+
server: endpoints.address,
|
16
|
+
port: endpoints.port,
|
17
|
+
cipher: endpoints.encryptionAlgorithm,
|
18
|
+
password: endpoints.password,
|
19
|
+
},
|
20
|
+
],
|
21
|
+
});
|
22
|
+
}
|
23
|
+
exports.generateConfigFrom = generateConfigFrom;
|
24
|
+
//# sourceMappingURL=Clash.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"Clash.js","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":";;;;AAAA,wDAAwB;AAOxB,SAAgB,kBAAkB,CAAC,SAAoC;IACrE,OAAO,cAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,IAAI;QACV,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,SAAS,CAAC,OAAO;gBACzB,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,MAAM,EAAE,SAAS,CAAC,mBAAmB;gBACrC,QAAQ,EAAE,SAAS,CAAC,QAAQ;aAC7B;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAhBD,gDAgBC"}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import yaml from "yaml";
|
2
|
+
import { ProxyOptions } from "./TunnelProxyOperations";
|
3
|
+
|
4
|
+
export type TunnelProxyConnectionInfo = ProxyOptions & {
|
5
|
+
address: string;
|
6
|
+
};
|
7
|
+
|
8
|
+
export function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string {
|
9
|
+
return yaml.stringify({
|
10
|
+
port: 7890,
|
11
|
+
"socks-port": 7891,
|
12
|
+
mode: "global",
|
13
|
+
proxies: [
|
14
|
+
{
|
15
|
+
name: "shadowsocks",
|
16
|
+
type: "ss",
|
17
|
+
server: endpoints.address,
|
18
|
+
port: endpoints.port,
|
19
|
+
cipher: endpoints.encryptionAlgorithm,
|
20
|
+
password: endpoints.password,
|
21
|
+
},
|
22
|
+
],
|
23
|
+
});
|
24
|
+
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
export interface Bucket {
|
2
|
+
readonly name: string;
|
3
|
+
save(objectKey: string, content: string): Promise<string>;
|
4
|
+
}
|
5
|
+
export interface CloudStorage {
|
6
|
+
getBucket(region: string): Promise<Bucket>;
|
7
|
+
destroy(region: string, bucket: string): Promise<void>;
|
8
|
+
}
|
9
|
+
//# sourceMappingURL=CloudStorage.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"CloudStorage.d.ts","sourceRoot":"","sources":["CloudStorage.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE3C,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD"}
|