@@ -371,6 +371,187 @@ const createNameSpaceForTeam = async (team) => {
371
371
}
372
372
} ;
373
373
374
+ // Fill in the createK8sChallenge53DeploymentForTeam function
375
+ const createK8sChallenge53DeploymentForTeam = async ( { team, passcodeHash } ) => {
376
+ logger . info ( `Creating Challenge 53 deployment for team ${ team } ` ) ;
377
+
378
+ const deploymentChallenge53Config = {
379
+ apiVersion : 'apps/v1' ,
380
+ kind : 'Deployment' ,
381
+ metadata : {
382
+ name : 'secret-challenge-53' ,
383
+ namespace : `t-${ team } ` ,
384
+ labels : {
385
+ app : 'secret-challenge-53' ,
386
+ team : `${ team } ` ,
387
+ 'deployment-context' : get ( 'deploymentContext' ) ,
388
+ } ,
389
+ annotations : {
390
+ 'wrongsecrets-ctf-party/lastRequest' : `${ new Date ( ) . getTime ( ) } ` ,
391
+ 'wrongsecrets-ctf-party/lastRequestReadable' : new Date ( ) . toString ( ) ,
392
+ 'wrongsecrets-ctf-party/passcode' : passcodeHash ,
393
+ 'wrongsecrets-ctf-party/challengesSolved' : '0' ,
394
+ 'wrongsecrets-ctf-party/challenges' : '[]' ,
395
+ } ,
396
+ } ,
397
+ spec : {
398
+ progressDeadlineSeconds : 20 ,
399
+ replicas : 1 ,
400
+ revisionHistoryLimit : 10 ,
401
+ selector : {
402
+ matchLabels : {
403
+ app : 'secret-challenge-53' ,
404
+ team : `${ team } ` ,
405
+ 'deployment-context' : get ( 'deploymentContext' ) ,
406
+ } ,
407
+ } ,
408
+ template : {
409
+ metadata : {
410
+ labels : {
411
+ app : 'secret-challenge-53' ,
412
+ team : `${ team } ` ,
413
+ 'deployment-context' : get ( 'deploymentContext' ) ,
414
+ } ,
415
+ name : 'secret-challenge-53' ,
416
+ } ,
417
+ spec : {
418
+ securityContext : {
419
+ runAsUser : 2000 ,
420
+ runAsGroup : 2000 ,
421
+ fsGroup : 2000 ,
422
+ } ,
423
+ containers : [
424
+ {
425
+ image : 'jeroenwillemsen/wrongsecrets-challenge53:1.12.0' ,
426
+ name : 'secret-challenge-53' ,
427
+ imagePullPolicy : 'IfNotPresent' ,
428
+ resources : {
429
+ requests : {
430
+ memory : '32Mi' ,
431
+ cpu : '50m' ,
432
+ 'ephemeral-storage' : '100Mi' ,
433
+ } ,
434
+ limits : {
435
+ memory : '64Mi' ,
436
+ cpu : '100m' ,
437
+ 'ephemeral-storage' : '200Mi' ,
438
+ } ,
439
+ } ,
440
+ securityContext : {
441
+ capabilities : {
442
+ drop : [ 'ALL' ] ,
443
+ } ,
444
+ allowPrivilegeEscalation : false ,
445
+ readOnlyRootFilesystem : true ,
446
+ runAsNonRoot : true ,
447
+ privileged : false ,
448
+ seccompProfile : {
449
+ type : 'RuntimeDefault' ,
450
+ } ,
451
+ } ,
452
+ env : [
453
+ {
454
+ name : 'TEAM_NAME' ,
455
+ value : team ,
456
+ } ,
457
+ {
458
+ name : 'DEPLOYMENT_CONTEXT' ,
459
+ value : get ( 'deploymentContext' ) ,
460
+ } ,
461
+ ] ,
462
+ volumeMounts : [
463
+ {
464
+ mountPath : '/tmp' ,
465
+ name : 'ephemeral' ,
466
+ } ,
467
+ ] ,
468
+ } ,
469
+ ] ,
470
+ volumes : [
471
+ {
472
+ name : 'ephemeral' ,
473
+ emptyDir : { } ,
474
+ } ,
475
+ ] ,
476
+ tolerations : get ( 'wrongsecrets.tolerations' ) ,
477
+ affinity : get ( 'wrongsecrets.affinity' ) ,
478
+ runtimeClassName : get ( 'wrongsecrets.runtimeClassName' )
479
+ ? get ( 'wrongsecrets.runtimeClassName' )
480
+ : undefined ,
481
+ } ,
482
+ } ,
483
+ } ,
484
+ } ;
485
+
486
+ try {
487
+ logger . info ( `Deploying Challenge 53 to namespace t-${ team } ` ) ;
488
+ const response = await k8sAppsApi . createNamespacedDeployment (
489
+ `t-${ team } ` ,
490
+ deploymentChallenge53Config
491
+ ) ;
492
+ logger . info ( `Successfully created Challenge 53 deployment for team ${ team } ` ) ;
493
+ return response ;
494
+ } catch ( error ) {
495
+ logger . error ( `Failed to create Challenge 53 deployment for team ${ team } :` , error . message ) ;
496
+ throw new Error ( `Failed to create Challenge 53 deployment: ${ error . message } ` ) ;
497
+ }
498
+ } ;
499
+
500
+ // Add helper function to check Challenge 53 deployment status
501
+ const getChallenge53InstanceForTeam = async ( team ) => {
502
+ logger . info ( `Checking Challenge 53 deployment status for team ${ team } ` ) ;
503
+
504
+ try {
505
+ const validatedTeamName = validateTeamName ( team ) ;
506
+ const deploymentName = 'secret-challenge-53' ;
507
+ const namespace = `t-${ validatedTeamName } ` ;
508
+
509
+ logger . info ( `Checking Challenge 53 deployment ${ deploymentName } in namespace ${ namespace } ` ) ;
510
+
511
+ const res = await safeApiCall (
512
+ ( ) => k8sAppsApi . readNamespacedDeployment ( deploymentName , namespace ) ,
513
+ `Check Challenge 53 deployment for team ${ team } `
514
+ ) ;
515
+
516
+ if ( ! res || ! res . body ) {
517
+ logger . info ( `No Challenge 53 deployment found for team ${ team } ` ) ;
518
+ return undefined ;
519
+ }
520
+
521
+ const deployment = res . body ;
522
+
523
+ return {
524
+ readyReplicas : deployment . status ?. readyReplicas || 0 ,
525
+ availableReplicas : deployment . status ?. availableReplicas || 0 ,
526
+ replicas : deployment . status ?. replicas || 0 ,
527
+ conditions : deployment . status ?. conditions || [ ] ,
528
+ } ;
529
+ } catch ( error ) {
530
+ logger . error ( `Error checking Challenge 53 deployment for team ${ team } :` , error . message ) ;
531
+ if ( error . message && error . message . includes ( 'not found' ) ) {
532
+ return undefined ;
533
+ }
534
+ throw error ;
535
+ }
536
+ } ;
537
+
538
+ // Add function to delete Challenge 53 deployment
539
+ const deleteChallenge53DeploymentForTeam = async ( team ) => {
540
+ logger . info ( `Deleting Challenge 53 deployment for team ${ team } ` ) ;
541
+
542
+ try {
543
+ await k8sAppsApi . deleteNamespacedDeployment ( 'secret-challenge-53' , `t-${ team } ` ) ;
544
+ logger . info ( `Successfully deleted Challenge 53 deployment for team ${ team } ` ) ;
545
+ } catch ( error ) {
546
+ if ( error . statusCode === 404 ) {
547
+ logger . warn ( `Challenge 53 deployment not found for team ${ team } , nothing to delete` ) ;
548
+ return ;
549
+ }
550
+ logger . error ( `Failed to delete Challenge 53 deployment for team ${ team } :` , error . message ) ;
551
+ throw new Error ( `Failed to delete Challenge 53 deployment: ${ error . message } ` ) ;
552
+ }
553
+ } ;
554
+
374
555
/**
375
556
* Enhanced deployment creation with SealedSecret integration
376
557
*/
@@ -2320,6 +2501,9 @@ module.exports = {
2320
2501
getSealedSecretsPublicKey,
2321
2502
createNameSpaceForTeam,
2322
2503
createK8sDeploymentForTeam,
2504
+ createK8sChallenge53DeploymentForTeam,
2505
+ getChallenge53InstanceForTeam,
2506
+ deleteChallenge53DeploymentForTeam,
2323
2507
2324
2508
// AWS functions
2325
2509
createAWSSecretsProviderForTeam,
0 commit comments