fanqiang 2.4.1 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. package/README.md +4 -1
  2. package/bin/fanqiang.js +10 -1
  3. package/bin/fanqiang.js.map +1 -1
  4. package/bin/fanqiang.ts +16 -4
  5. package/lib/core/AwsS3CloudStorage.d.ts +1 -1
  6. package/lib/core/AwsS3CloudStorage.d.ts.map +1 -1
  7. package/lib/core/AwsS3CloudStorage.ts +1 -1
  8. package/lib/{domain → core}/Clash.d.ts +2 -2
  9. package/lib/core/Clash.d.ts.map +1 -0
  10. package/lib/{domain → core}/Clash.js +16 -2
  11. package/lib/core/Clash.js.map +1 -0
  12. package/lib/{domain → core}/Clash.ts +17 -3
  13. package/lib/{domain → core}/CloudStorage.d.ts +0 -0
  14. package/lib/{domain → core}/CloudStorage.d.ts.map +0 -0
  15. package/lib/{domain → core}/CloudStorage.js +0 -0
  16. package/lib/{domain → core}/CloudStorage.js.map +0 -0
  17. package/lib/{domain → core}/CloudStorage.ts +0 -0
  18. package/lib/core/Terraform.d.ts +1 -1
  19. package/lib/core/Terraform.d.ts.map +1 -1
  20. package/lib/core/Terraform.js +0 -1
  21. package/lib/core/Terraform.js.map +1 -1
  22. package/lib/core/Terraform.ts +1 -2
  23. package/lib/core/TerraformTunnelProxyOperations.d.ts +2 -2
  24. package/lib/core/TerraformTunnelProxyOperations.d.ts.map +1 -1
  25. package/lib/core/TerraformTunnelProxyOperations.js +16 -3
  26. package/lib/core/TerraformTunnelProxyOperations.js.map +1 -1
  27. package/lib/core/TerraformTunnelProxyOperations.ts +23 -10
  28. package/lib/core/analysis.d.ts +2 -0
  29. package/lib/core/analysis.d.ts.map +1 -0
  30. package/lib/core/analysis.js +16 -0
  31. package/lib/core/analysis.js.map +1 -0
  32. package/lib/core/analysis.ts +12 -0
  33. package/lib/domain/TunnelProxyOperations.d.ts +5 -7
  34. package/lib/domain/TunnelProxyOperations.d.ts.map +1 -1
  35. package/lib/domain/TunnelProxyOperations.ts +5 -6
  36. package/lib/handlers.d.ts +2 -1
  37. package/lib/handlers.d.ts.map +1 -1
  38. package/lib/handlers.js +3 -6
  39. package/lib/handlers.js.map +1 -1
  40. package/lib/handlers.ts +5 -13
  41. package/package.json +6 -2
  42. package/terraform/main.tf +30 -0
  43. package/terraform/modules/analysis/main.tf +29 -0
  44. package/terraform/modules/analysis/output.tf +9 -0
  45. package/terraform/modules/analysis/variables.tf +3 -0
  46. package/terraform/modules/proxy/cloud-init.tpl +24 -17
  47. package/terraform/modules/proxy/main.tf +6 -2
  48. package/terraform/modules/proxy/variables.tf +14 -0
  49. package/terraform/modules/tunnel/cloud-init.tpl +23 -1
  50. package/terraform/modules/tunnel/main.tf +10 -3
  51. package/terraform/modules/tunnel/variables.tf +20 -0
  52. package/terraform/outputs.tf +4 -1
  53. package/terraform/variables.tf +11 -0
  54. package/lib/domain/Clash.d.ts.map +0 -1
  55. package/lib/domain/Clash.js.map +0 -1
package/README.md CHANGED
@@ -7,11 +7,12 @@ This project creates a command line tool that helps to automatically deploy a sh
7
7
  - Has **Nodejs** installed on local machine. See [download link][1] for more details.
8
8
  - Has **Terraform** installed on local machine. See [Install Terraform][5] for more details.
9
9
  - Has an AWS access token. See [manage AWS access token][2] for more details.
10
- - Has an Aliyun access token if you want to use tunnel feature.
10
+ - Has an Aliyun access token. See [Aliyun Account][6] for more details
11
11
 
12
12
  [1]: https://nodejs.org/en/
13
13
  [2]: https://console.aws.amazon.com/iam/home#security_credential
14
14
  [5]: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
15
+ [6]: https://account.aliyun.com
15
16
 
16
17
  ## Installation
17
18
 
@@ -39,6 +40,8 @@ Options:
39
40
  [string]
40
41
  --aliyun-credentials Must be in format: <ACCESS_KEY_ID>:<ACCESS_KEY_SECRET>
41
42
  [string]
43
+ --public-key SSH public key for login proxy or tunnel server
44
+ [string]
42
45
  --help Show help [boolean]
43
46
  --version Show version number [boolean]
44
47
  ```
package/bin/fanqiang.js CHANGED
@@ -32,10 +32,19 @@ async function main() {
32
32
  type: "string",
33
33
  description: "Must be in format: <ACCESS_KEY_ID>:<ACCESS_KEY_SECRET>",
34
34
  },
35
+ "public-key": {
36
+ type: "string",
37
+ description: "ssh public key for login proxy or tunnel server",
38
+ },
35
39
  })
36
40
  .demandCommand(1)
37
41
  .strict()
38
- .command("create", "Create new tunnel proxy infrastructures", () => void 0, (args) => index_1.handlers.create(args.region, args["tunnel-region"], args["bucket"], {
42
+ .command("create", "Create new tunnel proxy infrastructures", () => void 0, (args) => index_1.handlers.create({
43
+ proxyRegion: args.region,
44
+ tunnelRegion: args["tunnel-region"],
45
+ bucket: args["bucket"],
46
+ publicKey: args["public-key"],
47
+ }, {
39
48
  aws: args["aws-credentials"],
40
49
  aliyun: args["aliyun-credentials"],
41
50
  }))
@@ -1 +1 @@
1
- {"version":3,"file":"fanqiang.js","sourceRoot":"","sources":["fanqiang.ts"],"names":[],"mappings":";;;;AAEA,0DAA0B;AAC1B,+CAAyB;AACzB,oCAAoD;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,eAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC/B,KAAK,CAAC,+BAA+B,CAAC;SACtC,OAAO,CAAC;QACP,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,sBAAc,CAAC,KAAK;YAC7B,WAAW,EAAE,2CAA2C;SACzD;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,sBAAc,CAAC,MAAM;YAC9B,WAAW,EAAE,qCAAqC;SACnD;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,WAAW,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ;YAC7C,WAAW,EAAE,qDAAqD;SACnE;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wDAAwD;SACtE;QACD,oBAAoB,EAAE;YACpB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wDAAwD;SACtE;KACF,CAAC;SACD,aAAa,CAAC,CAAC,CAAC;SAChB,MAAM,EAAE;SACR,OAAO,CACN,QAAQ,EACR,yCAAyC,EACzC,GAAG,EAAE,CAAC,KAAK,CAAC,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,gBAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;QAClE,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC5B,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC;KACnC,CAAC,CACL;SACA,OAAO,CACN,SAAS,EACT,sCAAsC,EACtC,GAAG,EAAE,CAAC,KAAK,CAAC,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,gBAAQ,CAAC,OAAO,CAAC;QACf,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC5B,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC;KACnC,CAAC,CACL;SACA,IAAI,EAAE;SACN,OAAO,EAAE;SACT,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"fanqiang.js","sourceRoot":"","sources":["fanqiang.ts"],"names":[],"mappings":";;;;AAEA,0DAA0B;AAC1B,+CAAyB;AACzB,oCAAoD;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,eAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC/B,KAAK,CAAC,+BAA+B,CAAC;SACtC,OAAO,CAAC;QACP,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,sBAAc,CAAC,KAAK;YAC7B,WAAW,EAAE,2CAA2C;SACzD;QACD,eAAe,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,sBAAc,CAAC,MAAM;YAC9B,WAAW,EAAE,qCAAqC;SACnD;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,WAAW,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ;YAC7C,WAAW,EAAE,qDAAqD;SACnE;QACD,iBAAiB,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wDAAwD;SACtE;QACD,oBAAoB,EAAE;YACpB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,wDAAwD;SACtE;QACD,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,iDAAiD;SAC/D;KACF,CAAC;SACD,aAAa,CAAC,CAAC,CAAC;SAChB,MAAM,EAAE;SACR,OAAO,CACN,QAAQ,EACR,yCAAyC,EACzC,GAAG,EAAE,CAAC,KAAK,CAAC,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,gBAAQ,CAAC,MAAM,CACb;QACE,WAAW,EAAE,IAAI,CAAC,MAAM;QACxB,YAAY,EAAE,IAAI,CAAC,eAAe,CAAC;QACnC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC;QACtB,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC;KAC9B,EACD;QACE,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC5B,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC;KACnC,CACF,CACJ;SACA,OAAO,CACN,SAAS,EACT,sCAAsC,EACtC,GAAG,EAAE,CAAC,KAAK,CAAC,EACZ,CAAC,IAAI,EAAE,EAAE,CACP,gBAAQ,CAAC,OAAO,CAAC;QACf,GAAG,EAAE,IAAI,CAAC,iBAAiB,CAAC;QAC5B,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC;KACnC,CAAC,CACL;SACA,IAAI,EAAE;SACN,OAAO,EAAE;SACT,cAAc,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC"}
package/bin/fanqiang.ts CHANGED
@@ -31,6 +31,10 @@ async function main(): Promise<void> {
31
31
  type: "string",
32
32
  description: "Must be in format: <ACCESS_KEY_ID>:<ACCESS_KEY_SECRET>",
33
33
  },
34
+ "public-key": {
35
+ type: "string",
36
+ description: "ssh public key for login proxy or tunnel server",
37
+ },
34
38
  })
35
39
  .demandCommand(1)
36
40
  .strict()
@@ -39,10 +43,18 @@ async function main(): Promise<void> {
39
43
  "Create new tunnel proxy infrastructures",
40
44
  () => void 0,
41
45
  (args) =>
42
- handlers.create(args.region, args["tunnel-region"], args["bucket"], {
43
- aws: args["aws-credentials"],
44
- aliyun: args["aliyun-credentials"],
45
- })
46
+ handlers.create(
47
+ {
48
+ proxyRegion: args.region,
49
+ tunnelRegion: args["tunnel-region"],
50
+ bucket: args["bucket"],
51
+ publicKey: args["public-key"],
52
+ },
53
+ {
54
+ aws: args["aws-credentials"],
55
+ aliyun: args["aliyun-credentials"],
56
+ }
57
+ )
46
58
  )
47
59
  .command(
48
60
  "destroy",
@@ -1,4 +1,4 @@
1
- import { CloudStorage } from "../domain/CloudStorage";
1
+ import { CloudStorage } from "./CloudStorage";
2
2
  export declare class AwsS3CloudStorage implements CloudStorage {
3
3
  private readonly region;
4
4
  private readonly bucket;
@@ -1 +1 @@
1
- {"version":3,"file":"AwsS3CloudStorage.d.ts","sourceRoot":"","sources":["AwsS3CloudStorage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,qBAAa,iBAAkB,YAAW,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxE,MAAM,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAahE"}
1
+ {"version":3,"file":"AwsS3CloudStorage.d.ts","sourceRoot":"","sources":["AwsS3CloudStorage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,qBAAa,iBAAkB,YAAW,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAU,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAxE,MAAM,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM,EAAmB,MAAM,EAAE,MAAM;IAEvG,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAahE"}
@@ -1,5 +1,5 @@
1
1
  import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
2
- import { CloudStorage } from "../domain/CloudStorage";
2
+ import { CloudStorage } from "./CloudStorage";
3
3
 
4
4
  export class AwsS3CloudStorage implements CloudStorage {
5
5
  constructor(private readonly region: string, private readonly bucket: string, private readonly domain: string) {}
@@ -1,6 +1,6 @@
1
- import { ProxyOptions } from "./TunnelProxyOperations";
1
+ import { ProxyOptions } from "../domain/TunnelProxyOperations";
2
2
  export declare type TunnelProxyConnectionInfo = ProxyOptions & {
3
3
  address: string;
4
4
  };
5
- export declare function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string;
5
+ export declare function generateConfigFrom(endpoints: TunnelProxyConnectionInfo, ruleUrl: string): string;
6
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,iCAAiC,CAAC;AAE/D,oBAAY,yBAAyB,GAAG,YAAY,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,yBAAyB,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAwChG"}
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateConfigFrom = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const yaml_1 = tslib_1.__importDefault(require("yaml"));
6
- function generateConfigFrom(endpoints) {
6
+ function generateConfigFrom(endpoints, ruleUrl) {
7
7
  return yaml_1.default.stringify({
8
8
  port: 7890,
9
9
  "socks-port": 7891,
@@ -27,7 +27,21 @@ function generateConfigFrom(endpoints) {
27
27
  password: endpoints.password,
28
28
  },
29
29
  ],
30
- rules: ["DOMAIN-SUFFIX,google.com,auto", "DOMAIN,ad.com,REJECT", "GEOIP,CN,DIRECT", "MATCH,auto"],
30
+ "rule-providers": {
31
+ domestic: {
32
+ type: "http",
33
+ behavior: "domain",
34
+ path: "./direct_domains.yaml",
35
+ url: ruleUrl,
36
+ },
37
+ },
38
+ rules: [
39
+ "RULE-SET,domestic,DIRECT",
40
+ "DOMAIN-SUFFIX,google.com,auto",
41
+ "DOMAIN,ad.com,REJECT",
42
+ "GEOIP,CN,DIRECT",
43
+ "MATCH,auto",
44
+ ],
31
45
  });
32
46
  }
33
47
  exports.generateConfigFrom = generateConfigFrom;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Clash.js","sourceRoot":"","sources":["Clash.ts"],"names":[],"mappings":";;;;AAAA,wDAAwB;AAOxB,SAAgB,kBAAkB,CAAC,SAAoC,EAAE,OAAe;IACtF,OAAO,cAAI,CAAC,SAAS,CAAC;QACpB,IAAI,EAAE,IAAI;QACV,YAAY,EAAE,IAAI;QAClB,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,IAAI;QACnB,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,YAAY;YACpB,eAAe,EAAE,YAAY;YAC7B,UAAU,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,2BAA2B,CAAC;SAC1F;QACD,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,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;QACD,gBAAgB,EAAE;YAChB,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM;gBACZ,QAAQ,EAAE,QAAQ;gBAClB,IAAI,EAAE,uBAAuB;gBAC7B,GAAG,EAAE,OAAO;aACb;SACF;QACD,KAAK,EAAE;YACL,0BAA0B;YAC1B,+BAA+B;YAC/B,sBAAsB;YACtB,iBAAiB;YACjB,YAAY;SACb;KACF,CAAC,CAAC;AACL,CAAC;AAxCD,gDAwCC"}
@@ -1,11 +1,11 @@
1
1
  import yaml from "yaml";
2
- import { ProxyOptions } from "./TunnelProxyOperations";
2
+ import { ProxyOptions } from "../domain/TunnelProxyOperations";
3
3
 
4
4
  export type TunnelProxyConnectionInfo = ProxyOptions & {
5
5
  address: string;
6
6
  };
7
7
 
8
- export function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string {
8
+ export function generateConfigFrom(endpoints: TunnelProxyConnectionInfo, ruleUrl: string): string {
9
9
  return yaml.stringify({
10
10
  port: 7890,
11
11
  "socks-port": 7891,
@@ -29,6 +29,20 @@ export function generateConfigFrom(endpoints: TunnelProxyConnectionInfo): string
29
29
  password: endpoints.password,
30
30
  },
31
31
  ],
32
- rules: ["DOMAIN-SUFFIX,google.com,auto", "DOMAIN,ad.com,REJECT", "GEOIP,CN,DIRECT", "MATCH,auto"],
32
+ "rule-providers": {
33
+ domestic: {
34
+ type: "http",
35
+ behavior: "domain",
36
+ path: "./direct_domains.yaml",
37
+ url: ruleUrl,
38
+ },
39
+ },
40
+ rules: [
41
+ "RULE-SET,domestic,DIRECT",
42
+ "DOMAIN-SUFFIX,google.com,auto",
43
+ "DOMAIN,ad.com,REJECT",
44
+ "GEOIP,CN,DIRECT",
45
+ "MATCH,auto",
46
+ ],
33
47
  });
34
48
  }
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" />
2
- export declare type TerraformVariableType = string | number | boolean;
2
+ export declare type TerraformVariableType = string | number | boolean | Record<string, string | number | boolean>;
3
3
  declare type ApplyResult = Record<string, TerraformVariableType>;
4
4
  export default class Terraform {
5
5
  private readonly workdir;
@@ -1 +1 @@
1
- {"version":3,"file":"Terraform.d.ts","sourceRoot":"","sources":["Terraform.ts"],"names":[],"mappings":";AAIA,oBAAY,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC9D,aAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAIzD,MAAM,CAAC,OAAO,OAAO,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAhF,OAAO;IAED,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAMhG,OAAO,CAAC,OAAO;IAMT,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;WAIlB,cAAc,CACzB,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,MAAM,CAAC,UAAe,EACjC,OAAO,GAAE,MAAqB,GAC7B,OAAO,CAAC,SAAS,CAAC;CAQtB"}
1
+ {"version":3,"file":"Terraform.d.ts","sourceRoot":"","sources":["Terraform.ts"],"names":[],"mappings":";AAIA,oBAAY,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAC1G,aAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAIzD,MAAM,CAAC,OAAO,OAAO,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,SAAS;IAAhF,OAAO;IAED,KAAK,CAAC,CAAC,SAAS,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAMhG,OAAO,CAAC,OAAO;IAMT,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;WAIlB,cAAc,CACzB,YAAY,EAAE,MAAM,EACpB,SAAS,GAAE,MAAM,CAAC,UAAe,EACjC,OAAO,GAAE,MAAqB,GAC7B,OAAO,CAAC,SAAS,CAAC;CAOtB"}
@@ -32,7 +32,6 @@ class Terraform {
32
32
  return fs.pathExists(path_1.default.join(this.workdir, StateFile));
33
33
  }
34
34
  static async createInstance(configSource, customEnv = {}, workdir = configSource) {
35
- await fs.ensureDir(workdir);
36
35
  if (workdir != configSource) {
37
36
  await fs.copy(configSource, workdir, { recursive: true, overwrite: true });
38
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Terraform.js","sourceRoot":"","sources":["Terraform.ts"],"names":[],"mappings":";;;AAAA,qDAA+B;AAC/B,wDAAwB;AACxB,uCAAoD;AAIpD,MAAM,SAAS,GAAG,mBAAmB,CAAC;AACtC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,MAAqB,SAAS;IAC5B,YAAqC,OAAe,EAAmB,YAA+B,EAAE;QAAnE,YAAO,GAAP,OAAO,CAAQ;QAAmB,cAAS,GAAT,SAAS,CAAwB;IAAG,CAAC;IAE5G,KAAK,CAAC,KAAK,CAAwB,SAAgD;QACjF,MAAM,EAAE,CAAC,SAAS,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;QACrE,MAAM,wBAAc,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5F,OAAU,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,iBAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpG,CAAC;IAEO,OAAO,CAAC,gBAAqB;QACnC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACtF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE;YAC/B,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAChD,OAAO;SACR;QACD,MAAM,wBAAc,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAChG,CAAC;IAED,WAAW;QACT,OAAO,EAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,YAAoB,EACpB,YAA+B,EAAE,EACjC,UAAkB,YAAY;QAE9B,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,OAAO,IAAI,YAAY,EAAE;YAC3B,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;SAC5E;QACD,MAAM,wBAAc,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;CACF;AAvCD,4BAuCC"}
1
+ {"version":3,"file":"Terraform.js","sourceRoot":"","sources":["Terraform.ts"],"names":[],"mappings":";;;AAAA,qDAA+B;AAC/B,wDAAwB;AACxB,uCAAoD;AAIpD,MAAM,SAAS,GAAG,mBAAmB,CAAC;AACtC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,MAAqB,SAAS;IAC5B,YAAqC,OAAe,EAAmB,YAA+B,EAAE;QAAnE,YAAO,GAAP,OAAO,CAAQ;QAAmB,cAAS,GAAT,SAAS,CAAwB;IAAG,CAAC;IAE5G,KAAK,CAAC,KAAK,CAAwB,SAAgD;QACjF,MAAM,EAAE,CAAC,SAAS,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;QACrE,MAAM,wBAAc,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5F,OAAU,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,iBAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpG,CAAC;IAEO,OAAO,CAAC,gBAAqB;QACnC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACtF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE;YAC/B,OAAO,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YAChD,OAAO;SACR;QACD,MAAM,wBAAc,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAChG,CAAC;IAED,WAAW;QACT,OAAO,EAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,cAAc,CACzB,YAAoB,EACpB,YAA+B,EAAE,EACjC,UAAkB,YAAY;QAE9B,IAAI,OAAO,IAAI,YAAY,EAAE;YAC3B,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;SAC5E;QACD,MAAM,wBAAc,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3C,CAAC;CACF;AAtCD,4BAsCC"}
@@ -2,7 +2,7 @@ import * as fs from "fs-extra";
2
2
  import path from "path";
3
3
  import { execute, executeInherit } from "./process";
4
4
 
5
- export type TerraformVariableType = string | number | boolean;
5
+ export type TerraformVariableType = string | number | boolean | Record<string, string | number | boolean>;
6
6
  type ApplyResult = Record<string, TerraformVariableType>;
7
7
  const StateFile = "terraform.tfstate";
8
8
  const VariableFile = "terraform.tfvars.json";
@@ -39,7 +39,6 @@ export default class Terraform {
39
39
  customEnv: NodeJS.ProcessEnv = {},
40
40
  workdir: string = configSource
41
41
  ): Promise<Terraform> {
42
- await fs.ensureDir(workdir);
43
42
  if (workdir != configSource) {
44
43
  await fs.copy(configSource, workdir, { recursive: true, overwrite: true });
45
44
  }
@@ -1,9 +1,9 @@
1
- import { TunnelProxyCreatingRequest, TunnelProxyCreatingResult, TunnelProxyOperations } from "../domain/TunnelProxyOperations";
1
+ import { ClashConfigUrl, TunnelProxyCreatingRequest, TunnelProxyOperations } from "../domain/TunnelProxyOperations";
2
2
  import { Configuration } from "./Configuration";
3
3
  export declare class TerraformTunnelProxyOperations implements TunnelProxyOperations {
4
4
  private readonly configuration;
5
5
  constructor(configuration: Configuration);
6
- create(request: TunnelProxyCreatingRequest): Promise<TunnelProxyCreatingResult>;
6
+ create(request: TunnelProxyCreatingRequest): Promise<ClashConfigUrl>;
7
7
  destroy(): Promise<void>;
8
8
  }
9
9
  //# sourceMappingURL=TerraformTunnelProxyOperations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TerraformTunnelProxyOperations.d.ts","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAUhD,qBAAa,8BAA+B,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEnD,MAAM,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAsB/E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAU/B"}
1
+ {"version":3,"file":"TerraformTunnelProxyOperations.d.ts","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACpH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAYhD,qBAAa,8BAA+B,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEnD,MAAM,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,cAAc,CAAC;IAqCpE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAU/B"}
@@ -8,12 +8,17 @@ const netUtils_1 = require("./netUtils");
8
8
  const path_1 = tslib_1.__importDefault(require("path"));
9
9
  const Terraform_1 = tslib_1.__importDefault(require("./Terraform"));
10
10
  const terraformUtils_1 = require("./terraformUtils");
11
+ const analysis_1 = require("./analysis");
12
+ const Clash_1 = require("./Clash");
11
13
  const TerraformConfigSource = path_1.default.resolve(__dirname, "..", "..", "terraform");
12
14
  class TerraformTunnelProxyOperations {
13
15
  constructor(configuration) {
14
16
  this.configuration = configuration;
15
17
  }
16
18
  async create(request) {
19
+ await fs.ensureDir(this.configuration.terraformWorkspace);
20
+ const analysisBundlePath = path_1.default.join(this.configuration.terraformWorkspace, "analysis.tar.gz");
21
+ await analysis_1.createBundle(analysisBundlePath);
17
22
  const terraform = await Terraform_1.default.createInstance(TerraformConfigSource, terraformUtils_1.asEnvironmentVariables(this.configuration.credentialsProviders), this.configuration.terraformWorkspace);
18
23
  const applyResult = await terraform.apply({
19
24
  proxy_region: request.proxyRegion,
@@ -22,12 +27,20 @@ class TerraformTunnelProxyOperations {
22
27
  password: request.password,
23
28
  encryption_algorithm: request.encryptionAlgorithm,
24
29
  bucket: request.bucket,
30
+ public_key: request.publicKey,
31
+ analysis: {
32
+ queue_name: "fanqiang",
33
+ bundle_path: analysisBundlePath,
34
+ s3_rules_key: "clash/domain_rules.yaml",
35
+ },
25
36
  });
26
- await netUtils_1.waitServiceAvailable(request.port, applyResult.address);
27
- return {
28
- address: applyResult.address,
37
+ await netUtils_1.waitServiceAvailable(request.port, applyResult.tunnel_public_ip);
38
+ const result = {
39
+ address: applyResult.tunnel_public_ip,
29
40
  cloudStorage: new AwsS3CloudStorage_1.AwsS3CloudStorage(request.proxyRegion, request.bucket, applyResult.bucket_domain_name),
30
41
  };
42
+ const ruleUrl = await result.cloudStorage.save("clash/domain_rules.yaml", "payload: []");
43
+ return result.cloudStorage.save("clash/config.yaml", Clash_1.generateConfigFrom(Object.assign(Object.assign({}, request), { address: result.address }), ruleUrl));
31
44
  }
32
45
  async destroy() {
33
46
  const terraform = await Terraform_1.default.createInstance(TerraformConfigSource, terraformUtils_1.asEnvironmentVariables(this.configuration.credentialsProviders), this.configuration.terraformWorkspace);
@@ -1 +1 @@
1
- {"version":3,"file":"TerraformTunnelProxyOperations.js","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":";;;;AAMA,2DAAwD;AACxD,qDAA+B;AAC/B,yCAAkD;AAClD,wDAAwB;AACxB,oEAAoC;AACpC,qDAA0D;AAE1D,MAAM,qBAAqB,GAAG,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAE/E,MAAa,8BAA8B;IACzC,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE7D,KAAK,CAAC,MAAM,CAAC,OAAmC;QAC9C,MAAM,SAAS,GAAG,MAAM,mBAAS,CAAC,cAAc,CAC9C,qBAAqB,EACrB,uCAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAC/D,IAAI,CAAC,aAAa,CAAC,kBAAkB,CACtC,CAAC;QAEF,MAAM,WAAW,GAAoD,MAAM,SAAS,CAAC,KAAK,CAAC;YACzF,YAAY,EAAE,OAAO,CAAC,WAAW;YACjC,aAAa,EAAE,OAAO,CAAC,YAAY;YACnC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,oBAAoB,EAAE,OAAO,CAAC,mBAAmB;YACjD,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,MAAM,+BAAoB,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,YAAY,EAAE,IAAI,qCAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,kBAAkB,CAAC;SACzG,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,GAAG,MAAM,mBAAS,CAAC,cAAc,CAC9C,qBAAqB,EACrB,uCAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAC/D,IAAI,CAAC,aAAa,CAAC,kBAAkB,CACtC,CAAC;QACF,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;CACF;AAnCD,wEAmCC"}
1
+ {"version":3,"file":"TerraformTunnelProxyOperations.js","sourceRoot":"","sources":["TerraformTunnelProxyOperations.ts"],"names":[],"mappings":";;;;AAEA,2DAAwD;AACxD,qDAA+B;AAC/B,yCAAkD;AAClD,wDAAwB;AACxB,oEAAoC;AACpC,qDAA0D;AAC1D,yCAA0C;AAC1C,mCAA6C;AAE7C,MAAM,qBAAqB,GAAG,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAE/E,MAAa,8BAA8B;IACzC,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE7D,KAAK,CAAC,MAAM,CAAC,OAAmC;QAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC;QAC1D,MAAM,kBAAkB,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;QAC/F,MAAM,uBAAY,CAAC,kBAAkB,CAAC,CAAC;QAEvC,MAAM,SAAS,GAAG,MAAM,mBAAS,CAAC,cAAc,CAC9C,qBAAqB,EACrB,uCAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAC/D,IAAI,CAAC,aAAa,CAAC,kBAAkB,CACtC,CAAC;QAEF,MAAM,WAAW,GAA6D,MAAM,SAAS,CAAC,KAAK,CAAC;YAClG,YAAY,EAAE,OAAO,CAAC,WAAW;YACjC,aAAa,EAAE,OAAO,CAAC,YAAY;YACnC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,oBAAoB,EAAE,OAAO,CAAC,mBAAmB;YACjD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,OAAO,CAAC,SAAS;YAC7B,QAAQ,EAAE;gBACR,UAAU,EAAE,UAAU;gBACtB,WAAW,EAAE,kBAAkB;gBAC/B,YAAY,EAAE,yBAAyB;aACxC;SACF,CAAC,CAAC;QACH,MAAM,+BAAoB,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,gBAAgB,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG;YACb,OAAO,EAAE,WAAW,CAAC,gBAAgB;YACrC,YAAY,EAAE,IAAI,qCAAiB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,kBAAkB,CAAC;SACzG,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,yBAAyB,EAAE,aAAa,CAAC,CAAC;QACzF,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,CAC7B,mBAAmB,EACnB,0BAAkB,iCAAM,OAAO,KAAE,OAAO,EAAE,MAAM,CAAC,OAAO,KAAI,OAAO,CAAC,CACrE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,SAAS,GAAG,MAAM,mBAAS,CAAC,cAAc,CAC9C,qBAAqB,EACrB,uCAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,EAC/D,IAAI,CAAC,aAAa,CAAC,kBAAkB,CACtC,CAAC;QACF,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;CACF;AAlDD,wEAkDC"}
@@ -1,8 +1,4 @@
1
- import {
2
- TunnelProxyCreatingRequest,
3
- TunnelProxyCreatingResult,
4
- TunnelProxyOperations,
5
- } from "../domain/TunnelProxyOperations";
1
+ import { ClashConfigUrl, TunnelProxyCreatingRequest, TunnelProxyOperations } from "../domain/TunnelProxyOperations";
6
2
  import { Configuration } from "./Configuration";
7
3
  import { AwsS3CloudStorage } from "./AwsS3CloudStorage";
8
4
  import * as fs from "fs-extra";
@@ -10,32 +6,49 @@ import { waitServiceAvailable } from "./netUtils";
10
6
  import path from "path";
11
7
  import Terraform from "./Terraform";
12
8
  import { asEnvironmentVariables } from "./terraformUtils";
9
+ import { createBundle } from "./analysis";
10
+ import { generateConfigFrom } from "./Clash";
13
11
 
14
12
  const TerraformConfigSource = path.resolve(__dirname, "..", "..", "terraform");
15
13
 
16
14
  export class TerraformTunnelProxyOperations implements TunnelProxyOperations {
17
15
  constructor(private readonly configuration: Configuration) {}
18
16
 
19
- async create(request: TunnelProxyCreatingRequest): Promise<TunnelProxyCreatingResult> {
17
+ async create(request: TunnelProxyCreatingRequest): Promise<ClashConfigUrl> {
18
+ await fs.ensureDir(this.configuration.terraformWorkspace);
19
+ const analysisBundlePath = path.join(this.configuration.terraformWorkspace, "analysis.tar.gz");
20
+ await createBundle(analysisBundlePath);
21
+
20
22
  const terraform = await Terraform.createInstance(
21
23
  TerraformConfigSource,
22
24
  asEnvironmentVariables(this.configuration.credentialsProviders),
23
25
  this.configuration.terraformWorkspace
24
26
  );
25
27
 
26
- const applyResult: { address: string; bucket_domain_name: string } = await terraform.apply({
28
+ const applyResult: { tunnel_public_ip: string; bucket_domain_name: string } = await terraform.apply({
27
29
  proxy_region: request.proxyRegion,
28
30
  tunnel_region: request.tunnelRegion,
29
31
  port: request.port,
30
32
  password: request.password,
31
33
  encryption_algorithm: request.encryptionAlgorithm,
32
34
  bucket: request.bucket,
35
+ public_key: request.publicKey,
36
+ analysis: {
37
+ queue_name: "fanqiang",
38
+ bundle_path: analysisBundlePath,
39
+ s3_rules_key: "clash/domain_rules.yaml",
40
+ },
33
41
  });
34
- await waitServiceAvailable(request.port, applyResult.address);
35
- return {
36
- address: applyResult.address,
42
+ await waitServiceAvailable(request.port, applyResult.tunnel_public_ip);
43
+ const result = {
44
+ address: applyResult.tunnel_public_ip,
37
45
  cloudStorage: new AwsS3CloudStorage(request.proxyRegion, request.bucket, applyResult.bucket_domain_name),
38
46
  };
47
+ const ruleUrl = await result.cloudStorage.save("clash/domain_rules.yaml", "payload: []");
48
+ return result.cloudStorage.save(
49
+ "clash/config.yaml",
50
+ generateConfigFrom({ ...request, address: result.address }, ruleUrl)
51
+ );
39
52
  }
40
53
 
41
54
  async destroy(): Promise<void> {
@@ -0,0 +1,2 @@
1
+ export declare function createBundle(bundlePath: string): Promise<void>;
2
+ //# sourceMappingURL=analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["analysis.ts"],"names":[],"mappings":"AAGA,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpE"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createBundle = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const tar = tslib_1.__importStar(require("tar"));
6
+ const path_1 = tslib_1.__importDefault(require("path"));
7
+ async function createBundle(bundlePath) {
8
+ await tar.create({
9
+ file: path_1.default.join(bundlePath),
10
+ gzip: true,
11
+ cwd: path_1.default.join(__dirname, "..", "..", "analysis"),
12
+ filter: p => !p.endsWith("tests.py")
13
+ }, ["."]);
14
+ }
15
+ exports.createBundle = createBundle;
16
+ //# sourceMappingURL=analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["analysis.ts"],"names":[],"mappings":";;;;AAAA,iDAA2B;AAC3B,wDAAwB;AAEjB,KAAK,UAAU,YAAY,CAAC,UAAkB;IACnD,MAAM,GAAG,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,cAAI,CAAC,IAAI,CAAC,UAAU,CAAC;QAC3B,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC;QACjD,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;KACrC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AAEZ,CAAC;AARD,oCAQC"}
@@ -0,0 +1,12 @@
1
+ import * as tar from "tar";
2
+ import path from "path";
3
+
4
+ export async function createBundle(bundlePath: string): Promise<void> {
5
+ await tar.create({
6
+ file: path.join(bundlePath),
7
+ gzip: true,
8
+ cwd: path.join(__dirname, "..", "..", "analysis"),
9
+ filter: p => !p.endsWith("tests.py")
10
+ }, ["."]);
11
+
12
+ }
@@ -1,20 +1,18 @@
1
- import { CloudStorage } from "./CloudStorage";
1
+ export declare type ClashConfigUrl = string;
2
2
  export interface TunnelProxyOperations {
3
- create(request: TunnelProxyCreatingRequest): Promise<TunnelProxyCreatingResult>;
3
+ create(request: TunnelProxyCreatingRequest): Promise<ClashConfigUrl>;
4
4
  destroy(): Promise<void>;
5
5
  }
6
- export declare type TunnelProxyCreatingRequest = ProxyOptions & {
6
+ export declare type TunnelProxyCreatingRequest = ProxyOptions & InfrastructureOptions;
7
+ export declare type InfrastructureOptions = {
7
8
  proxyRegion: string;
8
9
  tunnelRegion: string;
9
10
  bucket: string;
11
+ publicKey?: string;
10
12
  };
11
13
  export declare type ProxyOptions = {
12
14
  port: number;
13
15
  encryptionAlgorithm: string;
14
16
  password: string;
15
17
  };
16
- export declare type TunnelProxyCreatingResult = {
17
- address: string;
18
- cloudStorage: CloudStorage;
19
- };
20
18
  //# sourceMappingURL=TunnelProxyOperations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TunnelProxyOperations.d.ts","sourceRoot":"","sources":["TunnelProxyOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEhF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,oBAAY,0BAA0B,GAAG,YAAY,GAAG;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,oBAAY,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,oBAAY,yBAAyB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"TunnelProxyOperations.d.ts","sourceRoot":"","sources":["TunnelProxyOperations.ts"],"names":[],"mappings":"AAAA,oBAAY,cAAc,GAAG,MAAM,CAAC;AACpC,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAErE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,oBAAY,0BAA0B,GAAG,YAAY,GAAG,qBAAqB,CAAC;AAC9E,oBAAY,qBAAqB,GAAG;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AACF,oBAAY,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC"}
@@ -1,20 +1,19 @@
1
- import { CloudStorage } from "./CloudStorage";
2
-
1
+ export type ClashConfigUrl = string;
3
2
  export interface TunnelProxyOperations {
4
- create(request: TunnelProxyCreatingRequest): Promise<TunnelProxyCreatingResult>;
3
+ create(request: TunnelProxyCreatingRequest): Promise<ClashConfigUrl>;
5
4
 
6
5
  destroy(): Promise<void>;
7
6
  }
8
7
 
9
- export type TunnelProxyCreatingRequest = ProxyOptions & {
8
+ export type TunnelProxyCreatingRequest = ProxyOptions & InfrastructureOptions;
9
+ export type InfrastructureOptions = {
10
10
  proxyRegion: string;
11
11
  tunnelRegion: string;
12
12
  bucket: string;
13
+ publicKey?: string;
13
14
  };
14
15
  export type ProxyOptions = {
15
16
  port: number;
16
17
  encryptionAlgorithm: string;
17
18
  password: string;
18
19
  };
19
-
20
- export type TunnelProxyCreatingResult = { address: string; cloudStorage: CloudStorage };
package/lib/handlers.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { CredentialsProviders } from "./core/Credentials";
2
+ import { InfrastructureOptions } from "./domain/TunnelProxyOperations";
2
3
  declare type StringCredentialsProviders = Record<keyof CredentialsProviders, string>;
3
- export declare function create(proxyRegion: string, tunnelRegion: string, bucket: string, credentials?: StringCredentialsProviders): Promise<void>;
4
+ export declare function create(infrastructureOptions: InfrastructureOptions, credentials?: StringCredentialsProviders): Promise<void>;
4
5
  export declare function destroy(credentials?: StringCredentialsProviders): Promise<void>;
5
6
  export {};
6
7
  //# sourceMappingURL=handlers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["handlers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,oBAAoB,CAAC;AAEjF,aAAK,0BAA0B,GAAG,MAAM,CAAC,MAAM,oBAAoB,EAAE,MAAM,CAAC,CAAC;AAE7E,wBAAsB,MAAM,CAC1B,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,0BAA0B,GACvC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,OAAO,CAAC,WAAW,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrF"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["handlers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,aAAK,0BAA0B,GAAG,MAAM,CAAC,MAAM,oBAAoB,EAAE,MAAM,CAAC,CAAC;AAE7E,wBAAsB,MAAM,CAC1B,qBAAqB,EAAE,qBAAqB,EAC5C,WAAW,CAAC,EAAE,0BAA0B,GACvC,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,wBAAsB,OAAO,CAAC,WAAW,CAAC,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrF"}
package/lib/handlers.js CHANGED
@@ -3,14 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.destroy = exports.create = void 0;
4
4
  const Configuration_1 = require("./core/Configuration");
5
5
  const crypto_1 = require("crypto");
6
- const Clash_1 = require("./domain/Clash");
7
6
  const Credentials_1 = require("./core/Credentials");
8
- async function create(proxyRegion, tunnelRegion, bucket, credentials) {
7
+ async function create(infrastructureOptions, credentials) {
9
8
  await runCommand(async (configuration) => {
10
- const request = Object.assign(Object.assign({ proxyRegion,
11
- tunnelRegion }, Configuration_1.ProxyDefaults), { password: crypto_1.randomBytes(20).toString("base64"), bucket });
12
- const result = await configuration.tunnelProxyOperations.create(request);
13
- const clashConfigUrl = await result.cloudStorage.save("clash/config.yaml", Clash_1.generateConfigFrom(Object.assign(Object.assign({}, request), { address: result.address })));
9
+ const request = Object.assign(Object.assign(Object.assign({}, infrastructureOptions), Configuration_1.ProxyDefaults), { password: crypto_1.randomBytes(20).toString("base64") });
10
+ const clashConfigUrl = await configuration.tunnelProxyOperations.create(request);
14
11
  console.log("Saved Clash config to: " + clashConfigUrl);
15
12
  }, credentials);
16
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.js","sourceRoot":"","sources":["handlers.ts"],"names":[],"mappings":";;;AAAA,wDAAuF;AACvF,mCAAqC;AACrC,0CAAoD;AACpD,oDAAiF;AAI1E,KAAK,UAAU,MAAM,CAC1B,WAAmB,EACnB,YAAoB,EACpB,MAAc,EACd,WAAwC;IAExC,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;QACvC,MAAM,OAAO,iCACX,WAAW;YACX,YAAY,IACT,6BAAa,KAChB,QAAQ,EAAE,oBAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAC5C,MAAM,GACP,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzE,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,IAAI,CACnD,mBAAmB,EACnB,0BAAkB,iCAAM,OAAO,KAAE,OAAO,EAAE,MAAM,CAAC,OAAO,IAAG,CAC5D,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,cAAc,CAAC,CAAC;IAC1D,CAAC,EAAE,WAAW,CAAC,CAAC;AAClB,CAAC;AAtBD,wBAsBC;AAEM,KAAK,UAAU,OAAO,CAAC,WAAwC;IACpE,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;QACvC,MAAM,aAAa,CAAC,qBAAqB,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC,EAAE,WAAW,CAAC,CAAC;AAClB,CAAC;AALD,0BAKC;AAED,KAAK,UAAU,UAAU,CACvB,QAAyD,EACzD,WAAwC;IAExC,MAAM,aAAa,GAAG,MAAM,iCAAiB,EAAE,CAAC;IAChD,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,GAAG,EAAE;QACpB,aAAa,CAAC,oBAAoB,CAAC,GAAG,GAAG,mCAAqB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;KACjF;IACD,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,EAAE;QACvB,aAAa,CAAC,oBAAoB,CAAC,MAAM,GAAG,mCAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;KACvF;IACD,MAAM,QAAQ,CAAC,aAAa,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["handlers.ts"],"names":[],"mappings":";;;AAAA,wDAAuF;AACvF,mCAAqC;AAErC,oDAAiF;AAK1E,KAAK,UAAU,MAAM,CAC1B,qBAA4C,EAC5C,WAAwC;IAExC,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;QACvC,MAAM,OAAO,iDACR,qBAAqB,GACrB,6BAAa,KAChB,QAAQ,EAAE,oBAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAC7C,CAAC;QACF,MAAM,cAAc,GAAG,MAAM,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,cAAc,CAAC,CAAC;IAC1D,CAAC,EAAE,WAAW,CAAC,CAAC;AAClB,CAAC;AAbD,wBAaC;AAEM,KAAK,UAAU,OAAO,CAAC,WAAwC;IACpE,MAAM,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE;QACvC,MAAM,aAAa,CAAC,qBAAqB,CAAC,OAAO,EAAE,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACtE,CAAC,EAAE,WAAW,CAAC,CAAC;AAClB,CAAC;AALD,0BAKC;AAED,KAAK,UAAU,UAAU,CACvB,QAAyD,EACzD,WAAwC;IAExC,MAAM,aAAa,GAAG,MAAM,iCAAiB,EAAE,CAAC;IAChD,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,GAAG,EAAE;QACpB,aAAa,CAAC,oBAAoB,CAAC,GAAG,GAAG,mCAAqB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;KACjF;IACD,IAAI,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,MAAM,EAAE;QACvB,aAAa,CAAC,oBAAoB,CAAC,MAAM,GAAG,mCAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;KACvF;IACD,MAAM,QAAQ,CAAC,aAAa,CAAC,CAAC;AAChC,CAAC"}
package/lib/handlers.ts CHANGED
@@ -1,30 +1,22 @@
1
1
  import { Configuration, loadConfiguration, ProxyDefaults } from "./core/Configuration";
2
2
  import { randomBytes } from "crypto";
3
- import { generateConfigFrom } from "./domain/Clash";
3
+
4
4
  import { CredentialsProviders, parseCredentialsToken } from "./core/Credentials";
5
+ import { InfrastructureOptions } from "./domain/TunnelProxyOperations";
5
6
 
6
7
  type StringCredentialsProviders = Record<keyof CredentialsProviders, string>;
7
8
 
8
9
  export async function create(
9
- proxyRegion: string,
10
- tunnelRegion: string,
11
- bucket: string,
10
+ infrastructureOptions: InfrastructureOptions,
12
11
  credentials?: StringCredentialsProviders
13
12
  ): Promise<void> {
14
13
  await runCommand(async (configuration) => {
15
14
  const request = {
16
- proxyRegion,
17
- tunnelRegion,
15
+ ...infrastructureOptions,
18
16
  ...ProxyDefaults,
19
17
  password: randomBytes(20).toString("base64"),
20
- bucket,
21
18
  };
22
- const result = await configuration.tunnelProxyOperations.create(request);
23
-
24
- const clashConfigUrl = await result.cloudStorage.save(
25
- "clash/config.yaml",
26
- generateConfigFrom({ ...request, address: result.address })
27
- );
19
+ const clashConfigUrl = await configuration.tunnelProxyOperations.create(request);
28
20
  console.log("Saved Clash config to: " + clashConfigUrl);
29
21
  }, credentials);
30
22
  }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "fanqiang",
3
- "version": "2.4.1",
3
+ "version": "2.6.0",
4
4
  "description": "Tunnel Proxy Auto Deployment",
5
5
  "bin": "./bin/fanqiang.js",
6
6
  "scripts": {
7
7
  "clean": "rimraf \"index.{d.ts,js}{,.map}\" \"{lib,bin}/**/*.{d.ts,js}{,.map}\" \"{terraform,test}/**/{terraform.tfvars.json,terraform.tfstate,terraform.tfstate.backup,.terraform}\"",
8
8
  "lint": "eslint --ext .ts . && prettier -c .",
9
- "lint:fix": "eslint --ext .ts --fix . && prettier --write .",
9
+ "lint:fix": "eslint --ext .ts --fix . && prettier --write . && yapf -i -r analysis",
10
10
  "lint:terraform": "terraform fmt -recursive",
11
11
  "test": "mocha --timeout 0 --require espower-typescript/guess \"test/**/*.ts\"",
12
12
  "prepare": "husky install",
@@ -38,6 +38,8 @@
38
38
  "@types/mocha": "^8.2.3",
39
39
  "@types/node": "^14.14.31",
40
40
  "@types/promise-retry": "^1.1.3",
41
+ "@types/tar": "^6.1.0",
42
+ "@types/tmp": "^0.2.1",
41
43
  "@types/yargs": "^17.0.2",
42
44
  "@typescript-eslint/eslint-plugin": "^4.28.2",
43
45
  "@typescript-eslint/parser": "^4.28.2",
@@ -55,6 +57,7 @@
55
57
  "prettier": "2.3.2",
56
58
  "rimraf": "^3.0.2",
57
59
  "semantic-release": "^17.4.4",
60
+ "tmp": "^0.2.1",
58
61
  "ts-node": "^8.10.2",
59
62
  "typescript": "^4.3.5"
60
63
  },
@@ -68,6 +71,7 @@
68
71
  "fs-extra": "^10.0.0",
69
72
  "lodash": "^4.17.21",
70
73
  "promise-retry": "^2.0.1",
74
+ "tar": "^6.1.0",
71
75
  "tslib": "^2.3.0",
72
76
  "yaml": "^1.10.2",
73
77
  "yargs": "^17.0.1"
package/terraform/main.tf CHANGED
@@ -24,12 +24,34 @@ module "proxy" {
24
24
  instance_name = "fanqiang"
25
25
  password = var.password
26
26
  port = var.port
27
+ public_key = var.public_key
28
+ analysis = {
29
+ queue_name = var.analysis.queue_name
30
+ bundle_url = "http://${aws_s3_bucket.default.bucket_domain_name}/${aws_s3_bucket_object.analysis_bundle.id}"
31
+ aws_access_key_id = module.analysis.aws_access_key_id
32
+ aws_secret_access_key = module.analysis.aws_secret_access_key
33
+ }
27
34
  }
28
35
 
29
36
  module "tunnel" {
30
37
  source = "./modules/tunnel"
31
38
  proxy_port = var.port
32
39
  proxy_public_ip = module.proxy.public_ip
40
+ public_key = var.public_key
41
+ analysis = {
42
+ queue_name = var.analysis.queue_name
43
+ queue_region = var.proxy_region
44
+ bundle_url = "http://${aws_s3_bucket.default.bucket_domain_name}/${aws_s3_bucket_object.analysis_bundle.id}"
45
+ aws_access_key_id = module.analysis.aws_access_key_id
46
+ aws_secret_access_key = module.analysis.aws_secret_access_key
47
+ s3_bucket = aws_s3_bucket.default.id
48
+ s3_rules_key = var.analysis.s3_rules_key
49
+ }
50
+ }
51
+
52
+ module "analysis" {
53
+ source = "./modules/analysis"
54
+ queue_name = var.analysis.queue_name
33
55
  }
34
56
 
35
57
  resource "aws_s3_bucket" "default" {
@@ -37,3 +59,11 @@ resource "aws_s3_bucket" "default" {
37
59
  acl = "public-read"
38
60
  force_destroy = true
39
61
  }
62
+
63
+ resource "aws_s3_bucket_object" "analysis_bundle" {
64
+ bucket = aws_s3_bucket.default.id
65
+ key = "bundles/${basename(var.analysis.bundle_path)}"
66
+ acl = "public-read"
67
+ force_destroy = true
68
+ source = var.analysis.bundle_path
69
+ }
@@ -0,0 +1,29 @@
1
+ terraform {
2
+ required_providers {
3
+ aws = {
4
+ source = "hashicorp/aws"
5
+ version = "3.60.0"
6
+ }
7
+ }
8
+ }
9
+
10
+ resource "aws_sqs_queue" "default" {
11
+ name = var.queue_name
12
+ visibility_timeout_seconds = 60
13
+ receive_wait_time_seconds = 20
14
+ }
15
+
16
+ resource "aws_iam_user" "default" {
17
+ name = "fanqiang-analysis"
18
+ force_destroy = true
19
+ }
20
+
21
+ resource "aws_iam_user_policy_attachment" "default" {
22
+ for_each = toset(["AmazonSQSFullAccess", "AmazonS3FullAccess"])
23
+ user = aws_iam_user.default.name
24
+ policy_arn = "arn:aws:iam::aws:policy/${each.key}"
25
+ }
26
+
27
+ resource "aws_iam_access_key" "default" {
28
+ user = aws_iam_user.default.name
29
+ }
@@ -0,0 +1,9 @@
1
+ output "user" {
2
+ value = aws_iam_user.default.name
3
+ }
4
+ output "aws_access_key_id" {
5
+ value = aws_iam_access_key.default.id
6
+ }
7
+ output "aws_secret_access_key" {
8
+ value = aws_iam_access_key.default.secret
9
+ }
@@ -0,0 +1,3 @@
1
+ variable "queue_name" {
2
+ type = string
3
+ }
@@ -1,34 +1,41 @@
1
1
  PORT=${port}
2
2
  ENCRYPTION_ALGORITHM=${encryption_algorithm}
3
3
  PASSWORD=${password}
4
+ ANALYSIS_QUEUE_NAME=${analysis_queue_name}
5
+ ANALYSIS_BUNDLE_URL=${analysis_bundle_url}
6
+ export AWS_ACCESS_KEY_ID=${analysis_aws_access_key_id}
7
+ export AWS_SECRET_ACCESS_KEY=${analysis_aws_secret_access_key}
4
8
 
5
- mkdir -p /etc/shadowsocks /var/lib/shadowsocks /var/log/shadowsocks
9
+
10
+ mkdir -p /etc/shadowsocks /var/lib/shadowsocks /var/log/shadowsocks /var/lib/fanqiang-analysis /var/log/fanqiang-analysis
11
+ export PATH=$PATH:/var/lib/shadowsocks:/var/lib/fanqiang-analysis
6
12
  until ping -c1 github.com &>/dev/null ; do sleep 1 ; done
7
13
 
8
14
  curl --location https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.11.1/shadowsocks-v1.11.1.x86_64-unknown-linux-gnu.tar.xz \
9
15
  | tar --extract --xz --file=- --directory=/var/lib/shadowsocks
10
16
 
11
17
  cat > /etc/shadowsocks/log4rs.yml <<EOF
12
- refresh_rate: 30 seconds
13
18
  appenders:
14
- file:
15
- kind: rolling_file
16
- path: /var/log/shadowsocks/ssserver.log
19
+ stdout:
20
+ kind: console
17
21
  encoder:
18
- kind: pattern
19
- pattern: "{d} {h({l}):<5} {m}{n}"
20
- policy:
21
- trigger:
22
- kind: size
23
- limit: 10 mb
24
- roller:
25
- kind: fixed_window
26
- pattern: ssserver.{}.log
27
- count: 5
22
+ pattern: "{l} {M} {m}{n}"
23
+
28
24
  root:
29
25
  level: debug
30
26
  appenders:
31
- - file
27
+ - stdout
32
28
  EOF
33
29
 
34
- /var/lib/shadowsocks/ssserver -s "[::]:$PORT" -m "$ENCRYPTION_ALGORITHM" -k "$PASSWORD" -d --log-config /etc/shadowsocks/log4rs.yml
30
+ if [ -n "$ANALYSIS_QUEUE_NAME" ]
31
+ then
32
+ yum install python3 jq -y
33
+ curl $ANALYSIS_BUNDLE_URL | tar --extract --gzip --file=- --directory=/var/lib/fanqiang-analysis
34
+ chmod a+x /var/lib/fanqiang-analysis/collector.py
35
+ pip3 install -r /var/lib/fanqiang-analysis/requirements.txt
36
+ ssserver -s "[::]:$PORT" -m "$ENCRYPTION_ALGORITHM" -k "$PASSWORD" --log-config /etc/shadowsocks/log4rs.yml \
37
+ | collector.py --region=$(jq --raw-output .v1.region /run/cloud-init/instance-data.json) \
38
+ --queue=$ANALYSIS_QUEUE_NAME &> /var/log/fanqiang-analysis/collector.log &
39
+ else
40
+ ssserver -s "[::]:$PORT" -m "$ENCRYPTION_ALGORITHM" -k "$PASSWORD" -d
41
+ fi
@@ -14,9 +14,13 @@ resource "aws_lightsail_instance" "default" {
14
14
  name = var.instance_name
15
15
  key_pair_name = var.public_key != null ? aws_lightsail_key_pair.default[0].id : null
16
16
  user_data = templatefile("${path.module}/cloud-init.tpl", {
17
- port = var.port,
18
- encryption_algorithm = var.encryption_algorithm,
17
+ port = var.port
18
+ encryption_algorithm = var.encryption_algorithm
19
19
  password = var.password
20
+ analysis_queue_name = var.analysis.queue_name
21
+ analysis_bundle_url = var.analysis.bundle_url
22
+ analysis_aws_access_key_id = var.analysis.aws_access_key_id
23
+ analysis_aws_secret_access_key = var.analysis.aws_secret_access_key
20
24
  })
21
25
  }
22
26
 
@@ -14,3 +14,17 @@ variable "public_key" {
14
14
  type = string
15
15
  default = null
16
16
  }
17
+ variable "analysis" {
18
+ type = object({
19
+ queue_name = string
20
+ bundle_url = string
21
+ aws_access_key_id = string
22
+ aws_secret_access_key = string
23
+ })
24
+ default = {
25
+ queue_name = ""
26
+ bundle_url = ""
27
+ aws_access_key_id = ""
28
+ aws_secret_access_key = ""
29
+ }
30
+ }
@@ -3,6 +3,14 @@
3
3
  PROXY_PORT=${proxy_port}
4
4
  PROXY_ADDRESS=${proxy_address}
5
5
  ELASTIC_IP_ALLOCATION_ID=${elastic_ip_allocation_id}
6
+ ANALYSIS_QUEUE_NAME=${analysis_queue_name}
7
+ ANALYSIS_QUEUE_REGION=${analysis_queue_region}
8
+ ANALYSIS_BUNDLE_URL=${analysis_bundle_url}
9
+ S3_BUCKET=${s3_bucket}
10
+ S3_RULES_KEY=${s3_rules_key}
11
+ export AWS_ACCESS_KEY_ID=${analysis_aws_access_key_id}
12
+ export AWS_SECRET_ACCESS_KEY=${analysis_aws_secret_access_key}
13
+
6
14
 
7
15
  REGION="$(curl --silent http://100.100.100.200/latest/meta-data/region-id)"
8
16
  aliyun configure set --region $REGION --mode EcsRamRole \
@@ -13,7 +21,7 @@ aliyun --endpoint "vpc-vpc.$REGION.aliyuncs.com" vpc AssociateEipAddress \
13
21
 
14
22
  until ping -c1 aliyun.com &>/dev/null ; do sleep 1 ; done
15
23
 
16
- yum install -y nginx nginx-all-modules
24
+ yum install -y nginx nginx-all-modules python3
17
25
 
18
26
  cat > /etc/nginx/nginx.conf <<EOF
19
27
  user nginx;
@@ -36,3 +44,17 @@ stream {
36
44
  EOF
37
45
 
38
46
  systemctl start nginx
47
+
48
+ if [ -n "$ANALYSIS_QUEUE_NAME" ]
49
+ then
50
+ mkdir -p /var/lib/fanqiang-analysis /var/log/fanqiang-analysis /root/.config/clash
51
+ echo "rules: []" > /root/.config/clash/fanqiang.yaml
52
+ curl "$ANALYSIS_BUNDLE_URL" | tar --extract --gzip --file=- --directory=/var/lib/fanqiang-analysis
53
+ chmod a+x /var/lib/fanqiang-analysis/analyzer.py
54
+ pip3 install -r /var/lib/fanqiang-analysis/requirements.txt
55
+ /var/lib/fanqiang-analysis/analyzer.py \
56
+ --region="$ANALYSIS_QUEUE_REGION" \
57
+ --queue="$ANALYSIS_QUEUE_NAME" \
58
+ --log=DEBUG \
59
+ "$S3_BUCKET" "$S3_RULES_KEY" &> /var/log/fanqiang-analysis/analyzer.log
60
+ fi
@@ -63,9 +63,16 @@ resource "alicloud_ecs_launch_template" "default" {
63
63
  spot_strategy = "SpotAsPriceGo"
64
64
  ram_role_name = alicloud_ram_role.default.id
65
65
  user_data = base64encode(templatefile("${path.module}/cloud-init.tpl", {
66
- proxy_port = var.proxy_port,
67
- proxy_address = var.proxy_public_ip,
68
- elastic_ip_allocation_id = alicloud_eip_address.default.id,
66
+ proxy_port = var.proxy_port
67
+ proxy_address = var.proxy_public_ip
68
+ elastic_ip_allocation_id = alicloud_eip_address.default.id
69
+ analysis_queue_name = var.analysis.queue_name
70
+ analysis_queue_region = var.analysis.queue_region
71
+ analysis_bundle_url = var.analysis.bundle_url
72
+ analysis_aws_access_key_id = var.analysis.aws_access_key_id
73
+ analysis_aws_secret_access_key = var.analysis.aws_secret_access_key
74
+ s3_bucket = var.analysis.s3_bucket
75
+ s3_rules_key = var.analysis.s3_rules_key
69
76
  }))
70
77
  system_disk {
71
78
  category = "cloud_efficiency"
@@ -8,3 +8,23 @@ variable "public_key" {
8
8
  type = string
9
9
  default = null
10
10
  }
11
+ variable "analysis" {
12
+ type = object({
13
+ queue_name = string
14
+ queue_region = string
15
+ bundle_url = string
16
+ aws_access_key_id = string
17
+ aws_secret_access_key = string
18
+ s3_bucket = string
19
+ s3_rules_key = string
20
+ })
21
+ default = {
22
+ queue_name = ""
23
+ queue_region = ""
24
+ bundle_url = ""
25
+ aws_access_key_id = ""
26
+ aws_secret_access_key = ""
27
+ s3_bucket = ""
28
+ s3_rules_key = ""
29
+ }
30
+ }
@@ -1,6 +1,9 @@
1
- output "address" {
1
+ output "tunnel_public_ip" {
2
2
  value = module.tunnel.public_ip
3
3
  }
4
4
  output "bucket_domain_name" {
5
5
  value = aws_s3_bucket.default.bucket_domain_name
6
6
  }
7
+ output "proxy_public_ip" {
8
+ value = module.proxy.public_ip
9
+ }
@@ -16,3 +16,14 @@ variable "encryption_algorithm" {
16
16
  variable "bucket" {
17
17
  type = string
18
18
  }
19
+ variable "public_key" {
20
+ type = string
21
+ default = null
22
+ }
23
+ variable "analysis" {
24
+ type = object({
25
+ queue_name = string
26
+ bundle_path = string
27
+ s3_rules_key = string
28
+ })
29
+ }
@@ -1 +0,0 @@
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,CA0B/E"}
@@ -1 +0,0 @@
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,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,IAAI;QACnB,YAAY,EAAE,IAAI;QAClB,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE;YACH,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,YAAY;YACpB,eAAe,EAAE,YAAY;YAC7B,UAAU,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,2BAA2B,CAAC;SAC1F;QACD,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,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;QACD,KAAK,EAAE,CAAC,+BAA+B,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,YAAY,CAAC;KAClG,CAAC,CAAC;AACL,CAAC;AA1BD,gDA0BC"}