Repository: amplify-education/serverless-domain-manager
Pull request #480 (2022-01-27 19:02:27)

Disable ip v6
<!--- Information about referencing Github Issues: https://help.github.com/articles/basic-writing-and-formatting-syntax/#referencing-issues-and-pull-requests --->
Fixes #365 

**Description of Issue Fixed**


**Changes proposed in this pull request**:

* Added an option to disable IPv6
* Refactoring

<!--- Please remember to allow edits from maintainers: https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork --->



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33f84fe..c4ef544 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,15 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## [5.8.0] - 2021-01-27
+
+### Added
+- Added an option to disable IPv6. Thank you @davehensley ([365](https://github.com/amplify-education/serverless-domain-manager/pull/365))
+
 ## [5.7.0] - 2021-01-27
 
 ### Added
-- Added tagging of apiGateway custom domain. Thank you @mooniker ([254](https://github.com/amplify-education/serverless-domain-manager/pull/254))
+- Added tagging of apiGateway custom domain. Thank you @fdobrovolny ([328](https://github.com/amplify-education/serverless-domain-manager/pull/328))
 
 ### Changed
 - Refactoring of the code
diff --git a/README.md b/README.md
index 40bf03d..32c357b 100644
--- a/README.md
+++ b/README.md
@@ -68,6 +68,7 @@ custom:
     basePath: api
     certificateName: '*.foo.com'
     createRoute53Record: true
+    createRoute53IPv6Record: true
     endpointType: 'regional'
     securityPolicy: tls_1_2
     apiType: rest
@@ -85,6 +86,7 @@ custom:
       basePath: api
       certificateName: '*.foo.com'
       createRoute53Record: true
+      createRoute53IPv6Record: true
       endpointType: 'regional'
       securityPolicy: tls_1_2
     http:
@@ -93,6 +95,7 @@ custom:
       basePath: api
       certificateName: '*.foo.com'
       createRoute53Record: true
+      createRoute53IPv6Record: true
       endpointType: 'regional'
       securityPolicy: tls_1_2
     websocket:
@@ -101,6 +104,7 @@ custom:
       basePath: api
       certificateName: '*.foo.com'
       createRoute53Record: true
+      createRoute53IPv6Record: true
       endpointType: 'regional'
       securityPolicy: tls_1_2
 ```
@@ -143,7 +147,8 @@ custom:
 | stage | Value of `--stage`, or `provider.stage` (serverless will default to `dev` if unset) | The stage to create the domain name for. This parameter allows you to specify a different stage for the domain name than the stage specified for the serverless deployment. |
 | certificateName | Closest match | The name of a specific certificate from Certificate Manager to use with this API. If not specified, the closest match will be used (i.e. for a given domain name `api.example.com`, a certificate for `api.example.com` will take precedence over a `*.example.com` certificate). <br><br> Note: Edge-optimized endpoints require that the certificate be located in `us-east-1` to be used with the CloudFront distribution. |
 | certificateArn | `(none)` | The arn of a specific certificate from Certificate Manager to use with this API. |
-| createRoute53Record | `true` | Toggles whether or not the plugin will create an A Alias and AAAA Alias records in Route53 mapping the `domainName` to the generated distribution domain name. If false, does not create a record. |
+| createRoute53Record | `true` | Toggles whether or not the plugin will create A Alias and AAAA Alias records in Route53 mapping the `domainName` to the generated distribution domain name. If false, does not create a record. |
+| createRoute53IPv6Record | `true` | Toggles whether or not the plugin will create an AAAA Alias record in Route53 mapping the `domainName` to the generated distribution domain name. If false, does not create a record. |
 | route53Profile | `(none)` | Profile to use for accessing Route53 resources when Route53 records are in a different account |
 | route53Region | `(none)` | Region to send Route53 services requests to (only applicable if also using route53Profile option) |
 | endpointType | edge | Defines the endpoint type, accepts `regional` or `edge`. |
diff --git a/package.json b/package.json
index 06d3cb6..035afec 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "serverless-domain-manager",
-  "version": "5.7.0",
+  "version": "5.8.0",
   "engines": {
     "node": ">=12"
   },
diff --git a/src/aws/route53-wrapper.ts b/src/aws/route53-wrapper.ts
index a2df9f3..8e2d853 100644
--- a/src/aws/route53-wrapper.ts
+++ b/src/aws/route53-wrapper.ts
@@ -60,7 +60,8 @@ class Route53Wrapper {
             }
         }
 
-        const changes = ["A", "AAAA"].map((Type) => ({
+        const recordsToCreate = domain.createRoute53IPv6Record ? ["A", "AAAA"] : ["A"];
+        const changes = recordsToCreate.map((Type) => ({
             Action: action,
             ResourceRecordSet: {
                 AliasTarget: {
@@ -73,11 +74,10 @@ class Route53Wrapper {
                 ...routingOptions,
             },
         }));
-
         const params = {
             ChangeBatch: {
                 Changes: changes,
-                Comment: "Record created by serverless-domain-manager",
+                Comment: `Record created by "${Globals.pluginName}"`,
             },
             HostedZoneId: route53HostedZoneId,
         };
diff --git a/src/domain-config.ts b/src/domain-config.ts
index a025353..80552a3 100644
--- a/src/domain-config.ts
+++ b/src/domain-config.ts
@@ -15,6 +15,7 @@ class DomainConfig {
     public certificateName: string | undefined;
     public certificateArn: string | undefined;
     public createRoute53Record: boolean | undefined;
+    public createRoute53IPv6Record: boolean | undefined;
     public route53Profile: string | undefined;
     public route53Region: string | undefined;
     public endpointType: string | undefined;
@@ -40,6 +41,7 @@ class DomainConfig {
         this.certificateArn = config.certificateArn;
         this.certificateName = config.certificateName;
         this.createRoute53Record = this.evaluateBoolean(config.createRoute53Record, true);
+        this.createRoute53IPv6Record = this.evaluateBoolean(config.createRoute53IPv6Record, true);
         this.route53Profile = config.route53Profile;
         this.route53Region = config.route53Region;
         this.hostedZoneId = config.hostedZoneId;
diff --git a/src/types.ts b/src/types.ts
index ed45639..3e15c6a 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -7,6 +7,7 @@ export interface CustomDomain { // tslint:disable-line
     certificateName: string | undefined;
     certificateArn: string | undefined;
     createRoute53Record: boolean | undefined;
+    createRoute53IPv6Record: boolean | undefined;
     route53Profile: string | undefined;
     route53Region: string | undefined;
     endpointType: string | undefined;


Test patch:
diff --git a/test/unit-tests/index.test.ts b/test/unit-tests/index.test.ts
index 518ffcf..5701310 100644
--- a/test/unit-tests/index.test.ts
+++ b/test/unit-tests/index.test.ts
@@ -50,6 +50,7 @@ const constructPlugin = (customDomainOptions, multiple: boolean = false) => {
         certificateArn: customDomainOptions.certificateArn,
         certificateName: customDomainOptions.certificateName,
         createRoute53Record: customDomainOptions.createRoute53Record,
+        createRoute53IPv6Record: customDomainOptions.createRoute53IPv6Record,
         domainName: customDomainOptions.domainName,
         enabled: customDomainOptions.enabled,
         endpointType: customDomainOptions.endpointType,
@@ -680,7 +681,7 @@ describe("Custom Domain Plugin", () => {
             expect(spy).to.have.been.called.with(expectedParams);
         });
 
-        it("Create a new A Alias Record", async () => {
+        it("Create new A and AAAA Alias Records", async () => {
             AWS.mock("Route53", "listHostedZones", (params, callback) => {
                 // @ts-ignore
                 callback(null, {
@@ -741,7 +742,64 @@ describe("Custom Domain Plugin", () => {
                             },
                         },
                     ],
-                    Comment: "Record created by serverless-domain-manager",
+                    Comment: `Record created by "${Globals.pluginName}"`
+                },
+                HostedZoneId: "test_host_id",
+            };
+            expect(spy).to.have.been.called.with(expectedParams);
+        });
+
+        it("Create new A Alias Record Only", async () => {
+            AWS.mock("Route53", "listHostedZones", (params, callback) => {
+                // @ts-ignore
+                callback(null, {
+                    HostedZones: [{
+                        Name: "test_domain",
+                        Id: "test_host_id",
+                        Config: {PrivateZone: false}
+                    }]
+                });
+            });
+
+            AWS.mock("Route53", "changeResourceRecordSets", (params, callback) => {
+                // @ts-ignore
+                callback(null, params);
+            });
+
+            const plugin = constructPlugin({
+                basePath: "test_basepath",
+                createRoute53IPv6Record: false,
+                domainName: "test_domain",
+            });
+            const route53Wrapper = new Route53Wrapper();
+            const dc: DomainConfig = new DomainConfig(plugin.serverless.service.custom.customDomain);
+
+            dc.domainInfo = new DomainInfo({
+                distributionDomainName: "test_distribution_name",
+                distributionHostedZoneId: "test_id",
+            });
+
+            const spy = chai.spy.on(route53Wrapper.route53, "changeResourceRecordSets");
+
+            await route53Wrapper.changeResourceRecordSet("UPSERT", dc);
+
+            const expectedParams = {
+                ChangeBatch: {
+                    Changes: [
+                        {
+                            Action: "UPSERT",
+                            ResourceRecordSet: {
+                                AliasTarget: {
+                                    DNSName: "test_distribution_name",
+                                    EvaluateTargetHealth: false,
+                                    HostedZoneId: "test_id",
+                                },
+                                Name: "test_domain",
+                                Type: "A",
+                            },
+                        },
+                    ],
+                    Comment: `Record created by "${Globals.pluginName}"`
                 },
                 HostedZoneId: "test_host_id",
             };
@@ -1076,7 +1134,7 @@ describe("Custom Domain Plugin", () => {
                             },
                         },
                     ],
-                    Comment: "Record created by serverless-domain-manager",
+                    Comment: `Record created by "${Globals.pluginName}"`
                 },
                 HostedZoneId: "test_host_id"
             };
@@ -2131,7 +2189,7 @@ describe("Custom Domain Plugin", () => {
                             },
                         },
                     ],
-                    Comment: "Record created by serverless-domain-manager",
+                    Comment: `Record created by "${Globals.pluginName}"`
                 },
                 HostedZoneId: "test_host_id"
             };
@@ -2213,7 +2271,7 @@ describe("Custom Domain Plugin", () => {
                             },
                         },
                     ],
-                    Comment: "Record created by serverless-domain-manager",
+                    Comment: `Record created by "${Globals.pluginName}"`
                 },
                 HostedZoneId: "test_host_id"
             };
@@ -2292,7 +2350,7 @@ describe("Custom Domain Plugin", () => {
                             },
                         },
                     ],
-                    Comment: "Record created by serverless-domain-manager",
+                    Comment: `Record created by "${Globals.pluginName}"`
                 },
                 HostedZoneId: "test_host_id"
             };
@@ -2367,7 +2425,7 @@ describe("Custom Domain Plugin", () => {
                             },
                         },
                     ],
-                    Comment: "Record created by serverless-domain-manager",
+                    Comment: `Record created by "${Globals.pluginName}"`
                 },
                 HostedZoneId: "test_host_id"
             };