1-
21import { LambdaClient , InvokeCommand } from "@aws-sdk/client-lambda"
3- import { getCFConfigValue , getCloudFormationExports , calculateVersionedStackName } from "../config"
2+ import { getCFConfigValue , getCloudFormationExports } from "../config"
3+ import { fixSpec } from "./fixSpec"
44
55export type ApiConfig = {
6- specification : string
6+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7+ spec : any
78 apiName : string
89 version : string
910 apigeeEnvironment : string
@@ -18,9 +19,31 @@ export type ApiConfig = {
1819 hiddenPaths : Array < string >
1920}
2021
22+ const lambda = new LambdaClient ( { } )
23+
24+ async function invokeLambda (
25+ dryRun : boolean ,
26+ functionName : string ,
27+ payload : unknown
28+ ) : Promise < void > {
29+ if ( dryRun ) {
30+ console . log ( `Would invoke lambda ${ functionName } ` )
31+ return
32+ }
33+ const invokeResult = await lambda . send ( new InvokeCommand ( {
34+ FunctionName : functionName ,
35+ Payload : Buffer . from ( JSON . stringify ( payload ) )
36+ } ) )
37+ const responsePayload = Buffer . from ( invokeResult . Payload ! ) . toString ( )
38+ if ( invokeResult . FunctionError ) {
39+ throw new Error ( `Error calling lambda ${ functionName } : ${ responsePayload } ` )
40+ }
41+ console . log ( `Lambda ${ functionName } invoked successfully. Response:` , responsePayload )
42+ }
43+
2144export async function deployApi (
2245 {
23- specification ,
46+ spec ,
2447 apiName,
2548 version,
2649 apigeeEnvironment,
@@ -36,59 +59,16 @@ export async function deployApi(
3659 } : ApiConfig ,
3760 dryRun : boolean
3861) : Promise < void > {
39- const lambda = new LambdaClient ( { } )
40- async function invokeLambda ( functionName : string , payload : unknown ) : Promise < void > {
41- if ( dryRun ) {
42- console . log ( `Would invoke lambda ${ functionName } ` )
43- return
44- }
45-
46- const invokeResult = await lambda . send ( new InvokeCommand ( {
47- FunctionName : functionName ,
48- Payload : Buffer . from ( JSON . stringify ( payload ) )
49- } ) )
50- const responsePayload = Buffer . from ( invokeResult . Payload ! ) . toString ( )
51- if ( invokeResult . FunctionError ) {
52- throw new Error ( `Error calling lambda ${ functionName } : ${ responsePayload } ` )
53- }
54- console . log ( `Lambda ${ functionName } invoked successfully. Response:` , responsePayload )
55- }
56-
57- let instance = apiName
58- const spec = JSON . parse ( specification )
59- if ( isPullRequest ) {
60- const pr_id = stackName . split ( "-" ) . pop ( )
61- instance = `${ apiName } -pr-${ pr_id } `
62- spec . info . title = `[PR-${ pr_id } ] ${ spec . info . title } `
63- spec [ "x-nhsd-apim" ] . monitoring = false
64- delete spec [ "x-nhsd-apim" ] . target . security . secret
65- } else {
66- stackName = calculateVersionedStackName ( stackName , version )
67- spec [ "x-nhsd-apim" ] . target . security . secret = mtlsSecretName
68- }
69- spec . info . version = version
70- spec [ "x-nhsd-apim" ] . target . url = `https://${ stackName } .${ awsEnvironment } .eps.national.nhs.uk`
71-
72- function replaceSchemeRefs ( domain : string ) {
73- const schemes = [ "nhs-cis2-aal3" , "nhs-login-p9" , "app-level3" , "app-level0" ]
74- for ( const scheme of schemes ) {
75- if ( spec . components . securitySchemes [ scheme ] ) {
76- spec . components . securitySchemes [ scheme ] = {
77- "$ref" : `https://${ domain } /components/securitySchemes/${ scheme } `
78- }
79- }
80- }
81- }
82- if ( apigeeEnvironment === "prod" ) {
83- spec . servers = [ { url : `https://api.service.nhs.uk/${ instance } ` } ]
84- replaceSchemeRefs ( "proxygen.prod.api.platform.nhs.uk" )
85- } else {
86- spec . servers = [ { url : `https://${ apigeeEnvironment } .api.service.nhs.uk/${ instance } ` } ]
87- replaceSchemeRefs ( "proxygen.ptl.api.platform.nhs.uk" )
88- }
89- if ( apigeeEnvironment . includes ( "sandbox" ) ) {
90- delete spec [ "x-nhsd-apim" ] [ "target-attributes" ] // Resolve issue with sandbox trying to look up app name
91- }
62+ const instance = fixSpec (
63+ spec ,
64+ apiName ,
65+ version ,
66+ apigeeEnvironment ,
67+ isPullRequest ,
68+ awsEnvironment ,
69+ stackName ,
70+ mtlsSecretName
71+ )
9272
9373 const exports = await getCloudFormationExports ( )
9474 const clientCertArn = getCFConfigValue ( exports , `account-resources:${ clientCertExportName } ` )
@@ -104,32 +84,37 @@ export async function deployApi(
10484 spec_publish_lambda = "lambda-resources-ProxygenProdSpecPublish"
10585 }
10686
107- // --- Store the secret used for mutual TLS ---
10887 if ( ! isPullRequest ) {
10988 console . log ( "Store the secret used for mutual TLS to AWS using Proxygen proxy lambda" )
110- await invokeLambda ( put_secret_lambda , {
89+ await invokeLambda (
90+ dryRun ,
91+ put_secret_lambda ,
92+ {
93+ apiName,
94+ environment : apigeeEnvironment ,
95+ secretName : mtlsSecretName ,
96+ secretKeyName : clientPrivateKeyArn ,
97+ secretCertName : clientCertArn ,
98+ kid : proxygenKid ,
99+ proxygenSecretName : proxygenPrivateKeyArn
100+ }
101+ )
102+ }
103+
104+ console . log ( "Deploy the API instance using Proxygen proxy lambda" )
105+ await invokeLambda (
106+ dryRun ,
107+ instance_put_lambda ,
108+ {
111109 apiName,
112110 environment : apigeeEnvironment ,
113- secretName : mtlsSecretName ,
114- secretKeyName : clientPrivateKeyArn ,
115- secretCertName : clientCertArn ,
111+ specDefinition : spec ,
112+ instance,
116113 kid : proxygenKid ,
117114 proxygenSecretName : proxygenPrivateKeyArn
118- } )
119- }
120-
121- // --- Deploy the API instance ---
122- console . log ( "Deploy the API instance using Proxygen proxy lambda" )
123- await invokeLambda ( instance_put_lambda , {
124- apiName,
125- environment : apigeeEnvironment ,
126- specDefinition : spec ,
127- instance,
128- kid : proxygenKid ,
129- proxygenSecretName : proxygenPrivateKeyArn
130- } )
115+ }
116+ )
131117
132- // --- Publish the API spec to the catalogue ---
133118 let spec_publish_env
134119 if ( apigeeEnvironment === "int" ) {
135120 console . log ( "Deploy the API spec to prod catalogue as it is int environment" )
@@ -142,17 +127,19 @@ export async function deployApi(
142127 }
143128 if ( spec_publish_env ) {
144129 for ( const path of hiddenPaths ) {
145- if ( spec . paths [ path ] ) {
146- delete spec . paths [ path ]
147- }
130+ delete spec . paths [ path ]
148131 }
149- await invokeLambda ( spec_publish_lambda , {
150- apiName,
151- environment : spec_publish_env ,
152- specDefinition : spec ,
153- instance,
154- kid : proxygenKid ,
155- proxygenSecretName : proxygenPrivateKeyArn
156- } )
132+ await invokeLambda (
133+ dryRun ,
134+ spec_publish_lambda ,
135+ {
136+ apiName,
137+ environment : spec_publish_env ,
138+ specDefinition : spec ,
139+ instance,
140+ kid : proxygenKid ,
141+ proxygenSecretName : proxygenPrivateKeyArn
142+ }
143+ )
157144 }
158145}
0 commit comments