@@ -238,9 +238,7 @@ class Apigw {
238
238
return secretIdsOutput
239
239
}
240
240
241
- async setupApiUsagePlan ( { endpoint } ) {
242
- const { usagePlan = { } } = endpoint
243
-
241
+ async setupApiUsagePlan ( { usagePlan } ) {
244
242
const usageInputs = {
245
243
usagePlanName : usagePlan . usagePlanName || '' ,
246
244
usagePlanDesc : usagePlan . usagePlanDesc || '' ,
@@ -249,15 +247,16 @@ class Apigw {
249
247
}
250
248
251
249
const usagePlanOutput = {
252
- created : false ,
253
- id : usagePlan . usagePlanId
250
+ created : usagePlan . created || false ,
251
+ id : usagePlan . id
254
252
}
255
253
256
- if ( ! usagePlan . usagePlanId ) {
257
- usagePlanOutput . id = await this . request ( {
254
+ if ( ! usagePlan . id ) {
255
+ const createUsagePlan = await this . request ( {
258
256
Action : 'CreateUsagePlan' ,
259
257
...usageInputs
260
258
} )
259
+ usagePlanOutput . id = createUsagePlan . usagePlanId
261
260
usagePlanOutput . created = true
262
261
console . debug ( `Usage plan with ID ${ usagePlanOutput . id } created.` )
263
262
} else {
@@ -272,6 +271,35 @@ class Apigw {
272
271
return usagePlanOutput
273
272
}
274
273
274
+ /**
275
+ * get all unbound secretids
276
+ */
277
+ async getUnboundSecretIds ( { usagePlanId, secretIds } ) {
278
+ const getAllBoundSecrets = async ( res = [ ] , { limit, offset = 0 } ) => {
279
+ const { secretIdList } = await this . request ( {
280
+ Action : 'DescribeUsagePlanSecretIds' ,
281
+ usagePlanId,
282
+ limit,
283
+ offset
284
+ } )
285
+ if ( secretIdList . length < limit ) {
286
+ return res
287
+ }
288
+ return getAllBoundSecrets ( res , { limit, offset : offset + secretIdList . length } )
289
+ }
290
+ const allBoundSecretObjs = await getAllBoundSecrets ( [ ] , { limit : 100 } )
291
+ const allBoundSecretIds = allBoundSecretObjs . map ( ( item ) => item . secretId )
292
+ const unboundSecretIds = secretIds . filter ( ( item ) => {
293
+ if ( allBoundSecretIds . indexOf ( item ) === - 1 ) {
294
+ return true
295
+ }
296
+ console . log ( `Usage plan ${ usagePlanId } secret id ${ item } already bound` )
297
+ return false
298
+ } )
299
+ return unboundSecretIds
300
+ }
301
+
302
+ // bind custom domains
275
303
async bindCustomDomain ( { serviceId, subDomain, inputs } ) {
276
304
const { customDomains, oldState = { } } = inputs
277
305
// 1. unbind all custom domain
@@ -338,8 +366,44 @@ class Apigw {
338
366
return customDomainOutput
339
367
}
340
368
369
+ // bind environment fo usage plan
370
+ async bindUsagePlanEnvironment ( {
371
+ environment,
372
+ bindType = 'API' ,
373
+ serviceId,
374
+ apiId,
375
+ endpoint,
376
+ usagePlan
377
+ } ) {
378
+ const { usagePlanList } = await this . request ( {
379
+ Action : 'DescribeApiUsagePlan' ,
380
+ serviceId,
381
+ apiIds : [ apiId ]
382
+ } )
383
+
384
+ const oldUsagePlan = usagePlanList . find ( ( item ) => item . usagePlanId === usagePlan . id )
385
+ if ( oldUsagePlan ) {
386
+ console . debug (
387
+ `Usage plan with id ${ usagePlan . id } already bind to api id ${ apiId } path ${ endpoint . method } ${ endpoint . path } .`
388
+ )
389
+ } else {
390
+ console . debug (
391
+ `Binding usage plan with id ${ usagePlan . id } to api id ${ apiId } path ${ endpoint . method } ${ endpoint . path } .`
392
+ )
393
+ await this . request ( {
394
+ Action : 'BindEnvironment' ,
395
+ serviceId,
396
+ environment,
397
+ bindType : bindType ,
398
+ usagePlanIds : [ usagePlan . id ] ,
399
+ apiIds : [ apiId ]
400
+ } )
401
+ console . debug ( 'Binding successed.' )
402
+ }
403
+ }
404
+
341
405
async deploy ( inputs ) {
342
- const { oldState = { } } = inputs
406
+ const { environment , oldState = { } } = inputs
343
407
inputs . protocols = this . getProtocolString ( inputs . protocols )
344
408
345
409
const { serviceId, serviceName, subDomain, serviceCreated } = await this . createOrUpdateService (
@@ -369,10 +433,51 @@ class Apigw {
369
433
curApi . created = true
370
434
}
371
435
372
- // TODO: set api auth and use plan
373
- // if (endpoint.auth) {
374
- // await this.setupUsagePlan
375
- // }
436
+ // set api auth and use plan
437
+ if ( endpoint . auth ) {
438
+ curApi . bindType = endpoint . bindType || 'API'
439
+ const usagePlan = await this . setupApiUsagePlan ( {
440
+ usagePlan : {
441
+ ...( ( exist && exist . usagePlan ) || { } ) ,
442
+ ...endpoint . usagePlan
443
+ }
444
+ } )
445
+ // store in api list
446
+ curApi . usagePlan = usagePlan
447
+
448
+ const { secretIds = [ ] } = endpoint . auth
449
+ const secrets = await this . setupUsagePlanSecret ( {
450
+ secretName : endpoint . auth . secretName ,
451
+ secretIds
452
+ } )
453
+ const unboundSecretIds = await this . getUnboundSecretIds ( {
454
+ usagePlanId : usagePlan . id ,
455
+ secretIds : secrets . secretIds
456
+ } )
457
+ if ( unboundSecretIds . length > 0 ) {
458
+ console . debug (
459
+ `Binding secret key ${ unboundSecretIds } to usage plan with id ${ usagePlan . id } .`
460
+ )
461
+ await this . request ( {
462
+ Action : 'BindSecretIds' ,
463
+ usagePlanId : usagePlan . id ,
464
+ secretIds : unboundSecretIds
465
+ } )
466
+ console . debug ( 'Binding secret key successed.' )
467
+ }
468
+ // store in api list
469
+ curApi . usagePlan . secrets = secrets
470
+
471
+ // bind environment
472
+ await this . bindUsagePlanEnvironment ( {
473
+ environment,
474
+ serviceId,
475
+ apiId : curApi . apiId ,
476
+ bindType : curApi . bindType ,
477
+ usagePlan,
478
+ endpoint
479
+ } )
480
+ }
376
481
377
482
apiList . push ( curApi )
378
483
console . debug (
@@ -413,11 +518,63 @@ class Apigw {
413
518
414
519
async remove ( inputs ) {
415
520
const { created, environment, serviceId, apiList, customDomains } = inputs
416
- // remove all apis
521
+ // 1. remove all apis
417
522
for ( let i = 0 ; i < apiList . length ; i ++ ) {
418
523
const curApi = apiList [ i ]
419
- // TODO: remove usagePlan and api auth(secretIds)
420
- // delete only apis created by serverless framework
524
+
525
+ // 1. remove usage plan
526
+ if ( curApi . usagePlan ) {
527
+ // 1.1 unbind secrete ids
528
+ const { secrets } = curApi . usagePlan
529
+ if ( secrets && secrets . secretIds ) {
530
+ await this . request ( {
531
+ Action : 'UnBindSecretIds' ,
532
+ secretIds : secrets . secretIds ,
533
+ usagePlanId : curApi . usagePlan . id
534
+ } )
535
+ console . debug ( `Unbinding secret key to usage plan with ID ${ curApi . usagePlan . id } .` )
536
+
537
+ // delelet all created api key
538
+ if ( curApi . usagePlan . secrets . created === true ) {
539
+ for ( let sIdx = 0 ; sIdx < secrets . secretIds . length ; sIdx ++ ) {
540
+ const secretId = secrets . secretIds [ sIdx ]
541
+ await this . request ( {
542
+ Action : 'DisableApiKey' ,
543
+ secretId
544
+ } )
545
+ await this . request ( {
546
+ Action : 'DeleteApiKey' ,
547
+ secretId
548
+ } )
549
+ console . debug ( `Removing any previously deployed secret key. ${ secretId } ` )
550
+ }
551
+ }
552
+ }
553
+
554
+ // 1.2 unbind environment
555
+ await this . request ( {
556
+ Action : 'UnBindEnvironment' ,
557
+ serviceId,
558
+ usagePlanIds : [ curApi . usagePlan . id ] ,
559
+ environment,
560
+ bindType : curApi . bindType ,
561
+ apiIds : [ curApi . apiId ]
562
+ } )
563
+ console . debug (
564
+ `Unbinding usage plan with ID ${ curApi . usagePlan . id } to service with ID ${ serviceId } .`
565
+ )
566
+
567
+ // 1.3 delete created usage plan
568
+ if ( curApi . usagePlan . created === true ) {
569
+ console . debug ( `Removing any previously deployed usage plan ids ${ curApi . usagePlan . id } ` )
570
+ await this . request ( {
571
+ Action : 'DeleteUsagePlan' ,
572
+ usagePlanId : curApi . usagePlan . id
573
+ } )
574
+ }
575
+ }
576
+
577
+ // 2. delete only apis created by serverless framework
421
578
if ( curApi . apiId && curApi . created === true ) {
422
579
console . debug ( `Removing api: ${ curApi . apiId } ` )
423
580
await this . request ( {
@@ -427,7 +584,8 @@ class Apigw {
427
584
} )
428
585
}
429
586
}
430
- // unbind all custom domains
587
+
588
+ // 2. unbind all custom domains
431
589
if ( customDomains ) {
432
590
for ( let i = 0 ; i < customDomains . length ; i ++ ) {
433
591
const curDomain = customDomains [ i ]
@@ -442,7 +600,7 @@ class Apigw {
442
600
}
443
601
}
444
602
445
- // unrelease service
603
+ // 3. unrelease service
446
604
console . debug ( `Unreleasing service: ${ serviceId } , environment: ${ environment } ` )
447
605
await this . request ( {
448
606
Action : 'UnReleaseService' ,
0 commit comments