-
Notifications
You must be signed in to change notification settings - Fork 9
Level Design
Nicholas Springer edited this page Aug 30, 2019
·
1 revision
This section of the guide will go through the three parts of implementing the create()
function: initialization, deployment, and setup.
When creating a level, we recommend starting from the template at levels/community/template
. The template python module's create()
has the 3 parts mapped out:
from core.framework import levels
from core.framework.cloudhelpers import deployments
LEVEL_PATH = 'community/template'
def create():
# Don't deploy the template. Delete this line when you implement your level.
exit('This is a template file. It is not meant to be deployed.')
# ---------Level Initialization---------
# Put code here that generates anything passed to the configuration template,
# sets up the project before deployment, or does anything else that happens
# before the deployment gets inserted.
# --------------------------------------
# ---------Deployment Insertion---------
# Insert the deployment, filling out labels, config template arguments,
# and the deployment manager template imports.
config_template_args = {}
labels = {}
template_files = []
deployments.insert(LEVEL_PATH,
config_template_args=config_template_args,
labels=labels,
template_files=template_files)
# --------------------------------------
# --------------Level Setup-------------
# Put code here that does anything that needs to happen after the deployment.
# This includes usings APIs to modify deployed resources or anything else.
# Print complete message and print/save start info
print(f'Level creation complete for: {LEVEL_PATH}\n'
f'Instruction for the level can be accessed at '
f'thunder-ctf.cloud/levels/{LEVEL_PATH}.html')
start_message = '--Put the start message here.--'
levels.write_start_info(LEVEL_PATH, start_message)
# --------------------------------------
The rest of this section will explain the 3 parts in more detail and will show and describe how they were implemented in thunder/a1openbucket
, a simple level that deploys a single public bucket with the secret inside the bucket in a file called secret.txt
.
The full implementation of thunder/a1openbucket
is shown below:
import random
from google.cloud import storage
from core.framework import levels
from core.framework.cloudhelpers import deployments
LEVEL_PATH = 'thunder/a1openbucket'
RESOURCE_PREFIX = 'a1'
def create():
# ---------Level Initialization---------
# Create randomized bucket name to avoid namespace conflict
nonce = str(random.randint(100000000000, 999999999999))
bucket_name = f'{RESOURCE_PREFIX}-bucket-{nonce}'
# --------------------------------------
# ---------Deployment Insertion---------
# Insert deployment
config_template_args = {'nonce': nonce}
template_files = ['core/framework/templates/bucket_acl.jinja']
deployments.insert(LEVEL_PATH,
template_files=template_files,
config_template_args=config_template_args)
# --------------------------------------
# --------------Level Setup-------------
print("Level setup started for: " + LEVEL_PATH)
# Insert secret into bucket
storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
secret_blob = storage.Blob('secret.txt', bucket)
secret = levels.make_secret(LEVEL_PATH)
secret_blob.upload_from_string(secret)
# Print complete message and print/save start info
print(f'Level creation complete for: {LEVEL_PATH}\n'
f'Instruction for the level can be accessed at thunder-ctf.cloud/levels/{LEVEL_PATH}.html')
start_message = f'The secret for this level can be found in the Google Cloud Storage (GCS) bucket {bucket_name}'
levels.write_start_info(LEVEL_PATH, start_message)
# --------------------------------------