fanqiang 2.4.1 → 2.6.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.
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"}