def test_generate_service_with_new_alb(self, mock_region_service, mock_get_account_id, mock_build_config): environment = 'staging' application_name = 'dummy' mock_service_configuration = MagicMock(spec=ServiceConfiguration, service_name=application_name, environment=environment) mock_service_configuration.get_config.return_value = { "cloudlift_version": 'test-version', "notifications_arn": "some", "ecr_repo": {"name": "test-service-repo"}, "services": { "Dummy": { "memory_reservation": Decimal(1000), "secrets_name": "something", "command": None, "http_interface": { "internal": False, "alb": { "create_new": True, "target_5xx_error_threshold": 10 }, "container_port": Decimal(7003), "restrict_access_to": ["0.0.0.0/0"], "health_check_path": "/elb-check" }, "autoscaling": { "max_capacity": 10, "min_capacity": 5, "request_count_per_target": { "target_value": 10, "scale_in_cool_down_seconds": 120, "scale_out_cool_down_seconds": 60 } } }, } } mock_build_config.side_effect = mock_build_config_impl mock_get_account_id.return_value = "12537612" mock_region_service.get_region_for_environment.return_value = "us-west-2" mock_region_service.get_ssl_certification_for_environment.return_value = "certificateARN1234" template_generator = ServiceTemplateGenerator(mock_service_configuration, self._get_env_stack(), './test/templates/test_env.sample', "12537612.dkr.ecr.us-west-2.amazonaws.com/test-service-repo:1.1.1", desired_counts={"Dummy": 100, "DummyRunSidekiqsh": 199}) generated_template = template_generator.generate_service() template_file_path = os.path.join(os.path.dirname(__file__), '../templates/expected_service_with_new_alb_template.yml') with(open(template_file_path)) as expected_template_file: expected = load(''.join(expected_template_file.readlines())) generated = load(generated_template) diff = list(dictdiffer.diff(generated, expected)) assert diff == []
def create_expected_diff(self, first, second, already_formatted=False): if not already_formatted: deployed_dict, deployed_format = cfn_flip.load(first) generated_dict, generated_format = cfn_flip.load(second) dumpers = {'json': cfn_flip.dump_json, 'yaml': cfn_flip.dump_yaml} first = dumpers[generated_format](deployed_dict) second = dumpers[generated_format](generated_dict) first_list, second_list = first.splitlines(), second.splitlines() return list( difflib.unified_diff(first_list, second_list, fromfile='deployed', tofile='generated', lineterm=''))
def _stub_get_template(self, stubber, stack_id, template_type="json"): with open(self.template_file(), "r") as template_file: template_body_raw, _ = load(template_file.read()) template_file.close() if template_type == "yaml": template_body = dump_yaml(template_body_raw) else: template_body = dump_json(template_body_raw) expected_params = {"StackName": self.stack_id()} mock_response = { "TemplateBody": template_body, "StagesAvailable": ["Original", "Processed"], "ResponseMetadata": { "RequestId": "a31f5380-73ad-4f7f-a440-aaaaaaaaab", "HTTPStatusCode": 200, "HTTPHeaders": { "x-amzn-requestid": "a31f5380-73ad-4f7f-a440-aaaaaaaaab", "content-type": "text/xml", "content-length": "1798", "date": "Thu, 18 Mar 2021 09:36:17 GMT", }, "RetryAttempts": 0, }, } stubber.add_response("get_template", mock_response, expected_params)
def _adapt_template(self, stack_id): """ Adapter: query AWS for the template body for the given stack. @returns The parsed template body as a dict ({key:value}) """ # https://github.com/boto/botocore/issues/1889 # Ensure that the TemplateBody is parsed. # Difference in behaviour between YAML and JSON :( template_response = self.client.get_template(StackName=stack_id) try: parsed_template, _ = load(template_response["TemplateBody"]) template_response["TemplateBody"] = parsed_template except TypeError as _: logging.debug( "Ignoring TypeError parsing TemplateBody - assuming it is already parsed JSON" ) return template_response
def test_generate_service_for_ecs_with_custom_roles(self, mock_region_service, mock_get_account_id, mock_build_config): environment = 'staging' application_name = 'dummy' mock_service_configuration = MagicMock(spec=ServiceConfiguration, service_name=application_name, environment=environment) mock_service_configuration.get_config.return_value = { "cloudlift_version": 'test-version', "notifications_arn": "some", "ecr_repo": {"name": "main-repo", "assume_role_arn": "arn1234", "account_id": "1234"}, "services": { "Dummy": { "memory_reservation": Decimal(1000), "secrets_name": "something", "command": None, "task_role_arn": "TASK_ARN", "task_execution_role_arn": "TASK_EXECUTION_ARN" }, } } mock_build_config.side_effect = mock_build_config_impl mock_get_account_id.return_value = "12537612" mock_region_service.get_region_for_environment.return_value = "us-west-2" mock_region_service.get_ssl_certification_for_environment.return_value = "certificateARN1234" template_generator = ServiceTemplateGenerator(mock_service_configuration, self._get_env_stack(), './test/templates/test_env.sample', "12537612.dkr.ecr.us-west-2.amazonaws.com/test-service-repo:1.1.1", desired_counts={"Dummy": 1}) generated_template = template_generator.generate_service() loaded_template = load(to_json(generated_template)) self.assertGreaterEqual(len(loaded_template), 1, "no template generated") generated = loaded_template[0] assert "DummyRole" in generated['Resources'] assert "DummyTaskExecutionRole" in generated['Resources'] assert "ECSServiceRole" in generated['Resources'] td = generated['Resources']['DummyTaskDefinition'] assert td['Properties']['TaskRoleArn'] == 'TASK_ARN' assert td['Properties']['ExecutionRoleArn'] == 'TASK_EXECUTION_ARN'
def test_generate_service_for_ecr(self, mock_region_service, mock_get_account_id, mock_build_config): environment = 'staging' application_name = 'dummy' mock_service_configuration = MagicMock(spec=ServiceConfiguration, service_name=application_name, environment=environment) mock_service_configuration.get_config.return_value = { "cloudlift_version": 'test-version', "notifications_arn": "some", "ecr_repo": {"name": "main-repo", "assume_role_arn": "arn1234", "account_id": "1234"}, "services": { "Dummy": { "memory_reservation": Decimal(1000), "secrets_name": "something", "command": None, }, } } mock_build_config.side_effect = mock_build_config_impl mock_get_account_id.return_value = "12537612" mock_region_service.get_region_for_environment.return_value = "us-west-2" mock_region_service.get_ssl_certification_for_environment.return_value = "certificateARN1234" template_generator = ServiceTemplateGenerator(mock_service_configuration, self._get_env_stack(), './test/templates/test_env.sample', "12537612.dkr.ecr.us-west-2.amazonaws.com/test-service-repo:1.1.1", desired_counts={"Dummy": 1}) generated_template = template_generator.generate_service() loaded_template = load(to_json(generated_template)) self.assertGreaterEqual(len(loaded_template), 1, "no template generated") generated = loaded_template[0] self.check_in_outputs(generated, 'ECRRepoName', 'main-repo') self.check_in_outputs(generated, 'ECRAccountID', '1234') self.check_in_outputs(generated, 'ECRAssumeRoleARN', 'arn1234')
def load_template(template_name): project_root = Path(__file__).parent.parent.absolute() with open(project_root.joinpath("templates", template_name)) as f: return load(f.read())[0]
def main(filenameArg, outDir="", showRoles=True): filenames = [] if os.path.isfile(filenameArg): filenames.append(filenameArg) elif os.path.isdir(filenameArg): dirname = filenameArg for filename in os.listdir(dirname): fullpath = dirname + "/" + filename if os.path.isdir(fullpath): print("*** ignoring sub-directory ", filename) elif os.path.isfile(fullpath): filenames.append(fullpath) else: print("*** ignoring non-file ", filename) else: print("***", filenameArg, "is not a file or directory", file=sys.stderr) return bulkRun = len(filenames) > 1 if outDir == "": outDir = "./output" if not os.path.isdir(outDir): print("*** ", outDir, " is not a directory") outDir = "" return contents = {} for filename in filenames: baseTemplateName = os.path.basename(filename) with open(filename) as f: str = f.read() # Redirect output to file if not doing a bulk run print("Processing file ", filename, ", length", len(str), "characters ...") oldstdout = sys.stdout if bulkRun and 1 == 2: sys.stdout = None elif outDir != "": outputFileName = outDir + "/" + baseTemplateName + ".txt" print("Output redirected to file ", outputFileName) sys.stdout = open(outputFileName, 'w') (data, format) = cfn_flip.load(str) #(data) = cfn_flip.load_yaml(str) #format = "yaml" print("{0:s} ({1:s})".format(baseTemplateName, format)) print() print() results = analyseConfiguration(data) sys.stdout = oldstdout # End of redirect contents[baseTemplateName] = results # Generate a csv file of template v resource type (+ count) listings # xxx.template, resource, count if bulkRun: if outDir != "": CSVFilename = outDir + "/" + "resourceTypes.csv" generateResourceTypeCSV(contents, CSVFilename) CSVFilename = outDir + "/" + "sections.csv" generateSectionsCSV(contents, CSVFilename) else: print("No output CSV file specified for resource types")