UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

2 lines (1 loc) 5.52 kB
"use strict";var{ACM:C,waitUntilCertificateValidated:N}=require("@aws-sdk/client-acm"),{Route53:R,waitUntilResourceRecordSetsChanged:U}=require("@aws-sdk/client-route-53"),A=function(e){return new Promise(r=>setTimeout(r,e))},T,P,m=A,h=Math.random,d=10,w=function(e,r,o,t,s,i){return new Promise((a,c)=>{let u=require("https"),{URL:l}=require("url");var f=JSON.stringify({Status:o,Reason:i,PhysicalResourceId:t||r.logStreamName,StackId:e.StackId,RequestId:e.RequestId,LogicalResourceId:e.LogicalResourceId,Data:s});let n=new l(e.ResponseURL||T),g={hostname:n.hostname,port:443,path:n.pathname+n.search,method:"PUT",headers:{"Content-Type":"","Content-Length":f.length}};u.request(g).on("error",c).on("response",p=>{p.resume(),p.statusCode>=400?c(new Error(`Server returned error ${p.statusCode}: ${p.statusMessage}`)):a()}).end(f,"utf8")})},S=async function(e,r,o){let t=Array.from(Object.entries(o)).map(([i,a])=>({Key:i,Value:a}));await new C({region:r}).addTagsToCertificate({CertificateArn:e,Tags:t})},q=async function(e,r,o,t,s,i,a){let c=require("crypto"),u=new C({region:i}),l=a?new R({endpoint:a}):new R;console.log(`Requesting certificate for ${r}`);let f=await u.requestCertificate({DomainName:r,SubjectAlternativeNames:o,Options:{CertificateTransparencyLoggingPreference:t},IdempotencyToken:c.createHash("sha256").update(e).digest("hex").slice(0,32),ValidationMethod:"DNS"});console.log(`Certificate ARN: ${f.CertificateArn}`),console.log("Waiting for ACM to provide DNS records for validation...");let n=[];for(let g=0;g<d&&!n.length;g++){let{Certificate:p}=await u.describeCertificate({CertificateArn:f.CertificateArn});if(n=D(p),!n.length){let y=Math.pow(2,g);await m(h()*y*50+y*150)}}if(!n.length)throw new Error(`Response from describeCertificate did not contain DomainValidationOptions after ${d} attempts.`);return console.log(`Upserting ${n.length} DNS records into zone ${s}:`),await I(l,n,s),console.log("Waiting for validation..."),await N({client:u,maxAttempts:19,delay:30},{CertificateArn:f.CertificateArn}),f.CertificateArn},b=async function(e,r,o,t,s){let i=new C({region:r}),a=t?new R({endpoint:t}):new R;try{console.log(`Waiting for certificate ${e} to become unused`);let c,u=[];for(let l=0;l<d;l++){let{Certificate:f}=await i.describeCertificate({CertificateArn:e});if(s&&(u=D(f)),c=f.InUseBy||[],c.length||!u.length){let n=Math.pow(2,l);await m(h()*n*50+n*150)}else break}if(c.length)throw new Error(`Response from describeCertificate did not contain an empty InUseBy list after ${d} attempts.`);if(s&&!u.length)throw new Error(`Response from describeCertificate did not contain DomainValidationOptions after ${d} attempts.`);console.log(`Deleting certificate ${e}`),await i.deleteCertificate({CertificateArn:e}),s&&(console.log(`Deleting ${u.length} DNS records from zone ${o}:`),await I(a,u,o,"DELETE"))}catch(c){if(c.name!=="ResourceNotFoundException")throw c}};function D(e){let r=e.DomainValidationOptions||[];if(r.length>0&&r.every(o=>o&&!!o.ResourceRecord)){let o=r.map(t=>t.ResourceRecord).reduce((t,s)=>(t[s.Name]=s,t),{});return Object.keys(o).sort().map(t=>o[t])}return[]}async function I(e,r,o,t="UPSERT"){let s=await e.changeResourceRecordSets({ChangeBatch:{Changes:r.map(i=>(console.log(`${i.Name} ${i.Type} ${i.Value}`),{Action:t,ResourceRecordSet:{Name:i.Name,Type:i.Type,TTL:60,ResourceRecords:[{Value:i.Value}]}}))},HostedZoneId:o});console.log("Waiting for DNS records to commit..."),await U({client:e,delay:30,maxAttempts:10},{Id:s.ChangeInfo.Id})}function $(e,r,o){return!e||e.DomainName!==r.DomainName||e.SubjectAlternativeNames!==r.SubjectAlternativeNames||e.CertificateTransparencyLoggingPreference!==r.CertificateTransparencyLoggingPreference||e.HostedZoneId!==r.HostedZoneId||e.Region!==r.Region||!o||!o.startsWith("arn:")}exports.certificateRequestHandler=async function(e,r){var o={},t,s;async function i(){s=await q(e.RequestId,e.ResourceProperties.DomainName,e.ResourceProperties.SubjectAlternativeNames,e.ResourceProperties.CertificateTransparencyLoggingPreference,e.ResourceProperties.HostedZoneId,e.ResourceProperties.Region,e.ResourceProperties.Route53Endpoint),o.Arn=t=s}try{switch(e.RequestType){case"Create":await i(),e.ResourceProperties.Tags&&t.startsWith("arn:")&&await S(t,e.ResourceProperties.Region,e.ResourceProperties.Tags);break;case"Update":$(e.OldResourceProperties,e.ResourceProperties,e.PhysicalResourceId)?await i():o.Arn=t=e.PhysicalResourceId,e.ResourceProperties.Tags&&t.startsWith("arn:")&&await S(t,e.ResourceProperties.Region,e.ResourceProperties.Tags);break;case"Delete":t=e.PhysicalResourceId;let a=e.ResourceProperties.RemovalPolicy??"destroy";t.startsWith("arn:")&&a==="destroy"&&await b(t,e.ResourceProperties.Region,e.ResourceProperties.HostedZoneId,e.ResourceProperties.Route53Endpoint,e.ResourceProperties.CleanupRecords==="true");break;default:throw new Error(`Unsupported request type ${e.RequestType}`)}console.log("Uploading SUCCESS response to S3..."),await w(e,r,"SUCCESS",t,o),console.log("Done.")}catch(a){console.log(`Caught error ${a}. Uploading FAILED message to S3.`),await w(e,r,"FAILED",t,null,a.message)}},exports.withReporter=function(e){w=e},exports.withDefaultResponseURL=function(e){T=e},exports.withWaiter=function(e){P=e},exports.resetWaiter=function(){P=void 0},exports.withSleep=function(e){m=e},exports.resetSleep=function(){m=A},exports.withRandom=function(e){h=e},exports.resetRandom=function(){h=Math.random},exports.withMaxAttempts=function(e){d=e},exports.resetMaxAttempts=function(){d=10};