in codebuild/create_project.py [0:0]
def main(args, config):
""" Create the CFN template and do stuff with said template. """
codebuild = Template()
config
codebuild.set_version('2010-09-09')
# Create a single CloudWatch Event role to allow codebuild:startBuild
cw_event_role = build_cw_cb_role(codebuild, config)
temp_yaml_filename = args.output_dir + "/s2n_codebuild_projects.yml"
# Role used by GitHub Actions.
if config.has_option('Global', 'create_github_role') and config.getboolean('Global', 'create_github_role'):
build_github_role(codebuild, config)
# Walk the config file, adding each stanza to the Troposphere template.
for job in config.sections():
if ':' in job:
job_title = job.split(':')[1]
if 'CodeBuild:' in job:
service_role = build_codebuild_role(config, template=codebuild, project_name=job_title).to_dict()
# Pull the env out of the section, and use the snippet for the other values.
# Note: only env is over-ridden with snippets.
if 'snippet' in config[job]:
build_project(template=codebuild, project_name=job_title, section=config.get(job, 'snippet'),
service_role=service_role['Ref'], raw_env=config.get(job, 'env'))
else:
build_project(template=codebuild, project_name=job_title, section=job, service_role=service_role['Ref'])
# Scheduled runs triggered by CloudWatch.
build_cw_event(template=codebuild, project_name=job_title, role=cw_event_role)
if 'CloudWatchEvent' in job:
# CloudWatch input allows us to over-ride environment variables passed to codebuild.
cw_input = json.loads(config.get(job, 'input'))
# Note that for Cloudwatch need to reference an existing CodeBuild Job.
build_cw_event(template=codebuild, project_name=job_title, target_job=config.get(job, 'build_job_name'),
role=cw_event_role,
hour=config.get(job, 'start_time'), input_json=cw_input)
if 'ScheduledTemplate' in job:
# Use a template within our config to create a list of scheduled CloudWatch events.
# Example
# [ScheduledTemplate:tests/fuzz/]
# start_time: 05:00
# jobnamesuffix: afl
# build_job_name: s2nFuzzAFLScheduled
# input: {"environmentVariablesOverride": [{"name": "FUZZ_TESTS","value": TESTNAME}]}
# tests/fuzz is the path to *test.c files, relative to the root of gitrepo
# start_time: scheduled UTC runtime of job
# jobnamesuffix: appended to the TESTNAME to make it uniq
# build_job_name: The existing CodeBuild job to use as the target for the scheduled run
# input: Over-ride environment variable JSON string
schedule_templates, test_name_list = [], []
# use the fileglob from the job name
try:
test_file_list = os.listdir(job_title)
except:
raise OSError(f'failed to read from {job_title}')
for i in list(filter(lambda x: ('test.c' in x), test_file_list)):
test_name_list.append(i.split('.')[:1][0])
cw_input = config.get(job, 'input')
for test_name in test_name_list:
# Make the case consistent, Camel with s2n lowered.
casefix = test_name.split('s2n')[1:][0].title()
casefix = 's2n' + casefix
# Randomize the minute, between 0-9, that schedule jobs start to avoid being throttled.
build_cw_event(template=codebuild,
project_name=str(casefix + config.get(job, 'job_name_suffix').title()),
target_job=config.get(job, 'build_job_name'),
role=cw_event_role,
hour=config.get(job, 'start_time'),
minute=random.randrange(0,9),
input_json=cw_input.replace('TESTNAME', test_name))
# Write out a CloudFormation template. This is ephemeral and is not used again.
with(open(temp_yaml_filename, 'w')) as fh:
fh.write(codebuild.to_yaml())
logging.info(f"Wrote cfn yaml file to {temp_yaml_filename}")
if args.noop:
logging.info("Respecting noop, Done.")
return
else:
# Fire up the boto, exit gracefully if the user doesn't have creds setup.
client = boto3.client('cloudformation', region_name=config.get('Global', 'aws_region'))
try:
validate_cfn(client, codebuild.to_yaml())
except exceptions.NoCredentialsError:
raise SystemExit(f"Something went wrong with your AWS credentials; Exiting.")
# Default to not making changes
if not args.production:
logging.info('Production flag not set, skipping mutating behavior.')
return
if args.modify_existing is True:
modify_existing_stack(client, config, codebuild)
else:
create_new_stack(client, config, codebuild)