From 8925d4272ba4bb03392e87c1104d7ba17a91d859 Mon Sep 17 00:00:00 2001 From: Brandon Liu Date: Thu, 28 Sep 2023 14:31:22 +0800 Subject: [PATCH] add utility module for AWS regions. (#259) --- serverless/aws/src/aws_region.test.ts | 52 +++++++++++++++++++++++++++ serverless/aws/src/aws_region.ts | 48 +++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 serverless/aws/src/aws_region.test.ts create mode 100644 serverless/aws/src/aws_region.ts diff --git a/serverless/aws/src/aws_region.test.ts b/serverless/aws/src/aws_region.test.ts new file mode 100644 index 0000000..d7d0fb5 --- /dev/null +++ b/serverless/aws/src/aws_region.test.ts @@ -0,0 +1,52 @@ +import { test } from "node:test"; +import assert from "node:assert"; + +import { get_region } from "./aws_region"; + +test("one bucket", () => { + let result = get_region( + "us-west-1", + { bucket: "mybucket", region: "us-west-1" }, + [], + ); + assert.deepEqual(result, { bucket: "mybucket", region: "us-west-1" }); +}); + +test("unknown region", () => { + let result = get_region( + "us-nullisland-1", + { bucket: "mybucket", region: "us-west-1" }, + [], + ); + assert.deepEqual(result, { bucket: "mybucket", region: "us-west-1" }); +}); + +test("exact region match", () => { + let result = get_region( + "us-west-1", + { bucket: "mybucket", region: "us-west-1" }, + [{ bucket: "mybucket-ap-south-1", region: "ap-south-1" }], + ); + assert.deepEqual(result, { bucket: "mybucket", region: "us-west-1" }); + result = get_region( + "ap-south-1", + { bucket: "mybucket", region: "us-west-1" }, + [{ bucket: "mybucket-ap-south-1", region: "ap-south-1" }], + ); + assert.deepEqual(result, { + bucket: "mybucket-ap-south-1", + region: "ap-south-1", + }); +}); + +test("priority match", () => { + let result = get_region( + "us-west-1", + { bucket: "mybucket", region: "ap-south-1" }, + [{ bucket: "mybucket-us-west-2", region: "us-west-2" }], + ); + assert.deepEqual(result, { + bucket: "mybucket-us-west-2", + region: "us-west-2", + }); +}); diff --git a/serverless/aws/src/aws_region.ts b/serverless/aws/src/aws_region.ts new file mode 100644 index 0000000..29036d3 --- /dev/null +++ b/serverless/aws/src/aws_region.ts @@ -0,0 +1,48 @@ +interface Bucket { + bucket: string; + region: string; +} + +const REGION_MATRIX: Record = { + "us-east-2": ["us-east-1"], // ohio + "us-east-1": ["us-east-2"], // virginia + "us-west-2": ["us-west-1"], // oregon + "us-west-1": ["us-west-2"], // california + "ap-south-1": ["ap-southeast-1"], // mumbai + "ap-southeast-1": ["ap-southeast-2", "ap-northeast-1", "ap-northeast-2"], // singapore + "ap-southeast-2": ["ap-southeast-1"], // sydney + "ap-northeast-2": ["ap-northeast-1", "ap-southeast-1"], // seoul + "ap-northeast-1": ["ap-northeast-2", "ap-southeast-1"], // tokyo + "eu-central-1": ["eu-west-1", "eu-west-2"], // frankfurt + "eu-west-1": ["eu-west-2", "eu-central-1"], // dublin + "eu-west-2": ["eu-west-1", "eu-central-1"], // london + "sa-east-1": ["us-east-1", "us-east-2"], // sao paulo +}; + +export let get_region = ( + exec_region: string, + primary: Bucket, + replicas: Bucket[], +): Bucket => { + if (primary.region === exec_region) { + return primary; + } + + for (let replica of replicas) { + if (replica.region === exec_region) { + return replica; + } + } + + if (exec_region in REGION_MATRIX) { + for (let region of REGION_MATRIX[exec_region]) { + for (let replica of replicas) { + if (replica.region === region) { + return replica; + } + } + } + } + + return primary; +};