Skip to content

Commit a3e823c

Browse files
committed
Adding methods for challenge53 items
1 parent c11b867 commit a3e823c

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed

wrongsecrets-balancer/src/kubernetes.js

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,187 @@ const createNameSpaceForTeam = async (team) => {
371371
}
372372
};
373373

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+
374555
/**
375556
* Enhanced deployment creation with SealedSecret integration
376557
*/
@@ -2320,6 +2501,9 @@ module.exports = {
23202501
getSealedSecretsPublicKey,
23212502
createNameSpaceForTeam,
23222503
createK8sDeploymentForTeam,
2504+
createK8sChallenge53DeploymentForTeam,
2505+
getChallenge53InstanceForTeam,
2506+
deleteChallenge53DeploymentForTeam,
23232507

23242508
// AWS functions
23252509
createAWSSecretsProviderForTeam,

wrongsecrets-balancer/src/teams/teams.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const {
3939
createRoleForWebTop,
4040
createRoleBindingForWebtop,
4141
createNSPsforTeam,
42+
createK8sChallenge53DeploymentForTeam,
4243
} = require('../kubernetes');
4344

4445
const loginCounter = new promClient.Counter({
@@ -362,6 +363,15 @@ async function createTeam(req, res) {
362363
res.status(500).send({ message: 'Failed to Create Instance' });
363364
}
364365

366+
try {
367+
logger.info(`Creating challenge53 Deployment for team '${team}'`);
368+
await createK8sChallenge53DeploymentForTeam({ team, passcodeHash: hash });
369+
logger.info(`Created challenge53 Deployment for team '${team}'`);
370+
} catch (error) {
371+
logger.error(`Error while creating challenge53 deployment for team ${team}: ${error.message}`);
372+
res.status(500).send({ message: 'Failed to Create Instance' });
373+
}
374+
365375
try {
366376
loginCounter.inc({ type: 'registration', userType: 'user' }, 1);
367377

@@ -494,6 +504,15 @@ async function createAWSTeam(req, res) {
494504
res.status(500).send({ message: 'Failed to Create Instance' });
495505
}
496506

507+
try {
508+
logger.info(`Creating challenge53 Deployment for team '${team}'`);
509+
await createK8sChallenge53DeploymentForTeam({ team, passcodeHash: hash });
510+
logger.info(`Created challenge53 Deployment for team '${team}'`);
511+
} catch (error) {
512+
logger.error(`Error while creating challenge53 deployment for team ${team}: ${error.message}`);
513+
res.status(500).send({ message: 'Failed to Create Instance' });
514+
}
515+
497516
try {
498517
loginCounter.inc({ type: 'registration', userType: 'user' }, 1);
499518

@@ -615,6 +634,14 @@ async function createAzureTeam(req, res) {
615634
logger.error(`Error while network security policies for team ${team}: ${error}`);
616635
res.status(500).send({ message: 'Failed to Create Instance' });
617636
}
637+
try {
638+
logger.info(`Creating challenge53 Deployment for team '${team}'`);
639+
await createK8sChallenge53DeploymentForTeam({ team, passcodeHash: hash });
640+
logger.info(`Created challenge53 Deployment for team '${team}'`);
641+
} catch (error) {
642+
logger.error(`Error while creating challenge53 deployment for team ${team}: ${error.message}`);
643+
res.status(500).send({ message: 'Failed to Create Instance' });
644+
}
618645

619646
try {
620647
loginCounter.inc({ type: 'registration', userType: 'user' }, 1);
@@ -763,6 +790,14 @@ async function createGCPTeam(req, res) {
763790
logger.error(`Error while network security policies for team ${team}: ${error}`);
764791
res.status(500).send({ message: 'Failed to Create Instance' });
765792
}
793+
try {
794+
logger.info(`Creating challenge53 Deployment for team '${team}'`);
795+
await createK8sChallenge53DeploymentForTeam({ team, passcodeHash: hash });
796+
logger.info(`Created challenge53 Deployment for team '${team}'`);
797+
} catch (error) {
798+
logger.error(`Error while creating challenge53 deployment for team ${team}: ${error.message}`);
799+
res.status(500).send({ message: 'Failed to Create Instance' });
800+
}
766801

767802
try {
768803
loginCounter.inc({ type: 'registration', userType: 'user' }, 1);

0 commit comments

Comments
 (0)