class ComposeTransformerTests(TestCase): def setUp(self): self.file_name = './container_transform/tests/docker-compose.yml' self.transformer = ComposeTransformer(self.file_name) @patch.object(uuid, 'uuid4', return_value='2e9c3538-b9d3-4f47-8a23-2a19315b370b') def test_emit_containers_no_name(self, mock_uuid): """ Test .emit_containers() for a container without a name """ containers = [{ 'image': 'postgres:9.3', 'cpu': 200 }] output = self.transformer.emit_containers(containers) self.assertEqual( ( 'services:\n' ' {mock_uuid}:\n' ' cpu: 200\n' ' image: postgres:9.3\n' 'version: \'2\'\n' ).format(mock_uuid=mock_uuid.return_value), output ) def test_emit_mapping(self): """ Test ._emit_mapping() """ mapping = { 'host_ip': '192.168.59.103', 'host_port': 8000, 'container_ip': '127.0.0.1', 'container_port': 80, } self.assertEqual( self.transformer._emit_mapping(mapping), '192.168.59.103:8000:127.0.0.1:80' ) def test_emit_mapping_udp(self): """ Test ._emit_mapping() with udp port """ mapping = { 'host_port': 53, 'container_port': 53, 'protocol': 'udp' } self.assertEqual( self.transformer._emit_mapping(mapping), '53:53/udp' ) def test_emit_mapping_missing_ports(self): """ Test ._emit_mapping() missing ports """ mapping = { 'host_ip': '192.168.59.103', 'container_ip': '127.0.0.1', } self.assertEqual( self.transformer._emit_mapping(mapping), '192.168.59.103:127.0.0.1' ) def test_parse_port_mapping_fails(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '192.168.59.103:8000:127.0.0.1:80:' self.assertEqual( self.transformer._parse_port_mapping(mapping), None ) def test_parse_port_mapping_udp(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '53:53/udp' self.assertEqual( self.transformer._parse_port_mapping(mapping), { 'host_port': 53, 'container_port': 53, 'protocol': 'udp' } ) def test_ingest_cpu(self): cpu = 100 self.assertEqual( self.transformer.ingest_cpu(cpu), cpu ) def test_emit_cpu(self): cpu = 100 self.assertEqual( self.transformer.emit_cpu(cpu), cpu )
def setUp(self): self.file_name = './container_transform/tests/docker-compose.yml' self.transformer = ComposeTransformer(self.file_name)
class ComposeTransformerTests(TestCase): def setUp(self): self.file_name = './container_transform/tests/docker-compose.yml' self.transformer = ComposeTransformer(self.file_name) @patch.object(uuid, 'uuid4', return_value='2e9c3538-b9d3-4f47-8a23-2a19315b370b') def test_emit_containers_no_name(self, mock_uuid): """ Test .emit_containers() for a container without a name """ containers = [{'image': 'postgres:9.3', 'cpu': 200}] output = self.transformer.emit_containers(containers) self.assertEqual( ('services:\n' ' {mock_uuid}:\n' ' cpu: 200\n' ' image: postgres:9.3\n' 'version: \'2\'\n').format(mock_uuid=mock_uuid.return_value), output) def test_emit_mapping(self): """ Test ._emit_mapping() """ mapping = { 'host_ip': '192.168.59.103', 'host_port': 8000, 'container_ip': '127.0.0.1', 'container_port': 80, } self.assertEqual(self.transformer._emit_mapping(mapping), '192.168.59.103:8000:127.0.0.1:80') def test_emit_mapping_udp(self): """ Test ._emit_mapping() with udp port """ mapping = {'host_port': 53, 'container_port': 53, 'protocol': 'udp'} self.assertEqual(self.transformer._emit_mapping(mapping), '53:53/udp') def test_emit_mapping_missing_ports(self): """ Test ._emit_mapping() missing ports """ mapping = { 'host_ip': '192.168.59.103', 'container_ip': '127.0.0.1', } self.assertEqual(self.transformer._emit_mapping(mapping), '192.168.59.103:127.0.0.1') def test_parse_port_mapping_fails(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '192.168.59.103:8000:127.0.0.1:80:' self.assertEqual(self.transformer._parse_port_mapping(mapping), None) def test_parse_port_mapping_udp(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '53:53/udp' self.assertEqual(self.transformer._parse_port_mapping(mapping), { 'host_port': 53, 'container_port': 53, 'protocol': 'udp' }) def test_ingest_cpu(self): cpu = 100 self.assertEqual(self.transformer.ingest_cpu(cpu), cpu) def test_emit_cpu(self): cpu = 100 self.assertEqual(self.transformer.emit_cpu(cpu), cpu) def test_ingest_environment(self): environment = {'DB_PAS': '******', 'DB_USER': '******'} environment_exp = {'DB_PAS': '******', 'DB_USER': '******'} self.assertEqual(self.transformer.ingest_environment(environment), environment_exp) def test_emit_environment(self): environment = {'DB_PAS': '******', 'DB_USER': '******'} environment_exp = {'DB_PAS': '******', 'DB_USER': '******'} self.assertEqual(self.transformer.emit_environment(environment), environment_exp) def test_ingest_command_list(self): """ Test .ingest_command() should respect that list items are single command args """ command = ["/bin/echo", "Hello world"] self.assertEqual(self.transformer.ingest_command(command), "/bin/echo 'Hello world'") def test_ingest_essential_dict(self): """ If the 'essential' param is a dict, check the Name field. If the Name field is 'false' or 'no' or isn't present, return False. Otherwise return True. """ dictionary = {'Name': 'test dictionary'} self.assertEqual(self.transformer.ingest_essential(dictionary), True) dictionary = {'Name': 'false'} self.assertEqual(self.transformer.ingest_essential(dictionary), False) dictionary = {'NoName': 'false'} self.assertEqual(self.transformer.ingest_essential(dictionary), False) def test_ingest_essential(self): """ If the 'essential' field is 'no' or 'false' or any other string """ self.assertEqual(self.transformer.ingest_essential('no'), False) self.assertEqual(self.transformer.ingest_essential('false'), False) self.assertEqual(self.transformer.emit_essential('Container_Name'), { 'MaximumRetryCount': 0, 'Name': 'container_name' }) def test_emit_essential_false(self): self.assertEqual(self.transformer.emit_essential(False), None)
class ComposeTransformerTests(TestCase): def setUp(self): self.file_name = './container_transform/tests/docker-compose.yml' self.transformer = ComposeTransformer(self.file_name) @patch.object(uuid, 'uuid4', return_value='2e9c3538-b9d3-4f47-8a23-2a19315b370b') def test_emit_containers_no_name(self, mock_uuid): """ Test .emit_containers() for a container without a name """ containers = [{'image': 'postgres:9.3', 'cpu': 200}] output = self.transformer.emit_containers(containers) self.assertEqual( ('services:\n' ' {mock_uuid}:\n' ' cpu: 200\n' ' image: postgres:9.3\n' 'version: \'2\'\n').format(mock_uuid=mock_uuid.return_value), output) def test_emit_mapping(self): """ Test ._emit_mapping() """ mapping = { 'host_ip': '192.168.59.103', 'host_port': 8000, 'container_ip': '127.0.0.1', 'container_port': 80, } self.assertEqual(self.transformer._emit_mapping(mapping), '192.168.59.103:8000:127.0.0.1:80') def test_emit_mapping_udp(self): """ Test ._emit_mapping() with udp port """ mapping = {'host_port': 53, 'container_port': 53, 'protocol': 'udp'} self.assertEqual(self.transformer._emit_mapping(mapping), '53:53/udp') def test_emit_mapping_missing_ports(self): """ Test ._emit_mapping() missing ports """ mapping = { 'host_ip': '192.168.59.103', 'container_ip': '127.0.0.1', } self.assertEqual(self.transformer._emit_mapping(mapping), '192.168.59.103:127.0.0.1') def test_parse_port_mapping_fails(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '192.168.59.103:8000:127.0.0.1:80:' self.assertEqual(self.transformer._parse_port_mapping(mapping), None) def test_parse_port_mapping_udp(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '53:53/udp' self.assertEqual(self.transformer._parse_port_mapping(mapping), { 'host_port': 53, 'container_port': 53, 'protocol': 'udp' }) def test_ingest_cpu(self): cpu = 100 self.assertEqual(self.transformer.ingest_cpu(cpu), cpu) def test_emit_cpu(self): cpu = 100 self.assertEqual(self.transformer.emit_cpu(cpu), cpu)
def generateConfigComposeDev(envName='dev', path='.', logger=None, secretEnv=None, keyEnv=None): configInputPath = '{}/{}/docker-compose.yml'.format(path, envName) if logger: logger.info( 'Reading configuration from {} file'.format(configInputPath)) transformer = ComposeTransformer(configInputPath) normalized_keys = transformer.ingest_containers() secrets = loadSecrets(secretEnv, keyEnv) awsKey = secrets["awsKey"] awsSecret = secrets["awsSecret"] services = {} for service in normalized_keys: services[service["name"]] = service service.pop("name", None) normalized_keys = services omigostService = normalized_keys["omigost"] omigostService["volumes"] = ["..:/opt/app/omigost"] omigostService["image"] = "openjdk:11" springArgs = " ".join([ "--spring.datasource.url=jdbc:postgresql://postgres:5432/docker_dev", "--spring.datasource.username=admin", "--spring.datasource.password=admin1", "--localstack.postgres.useExternal=true", "--localstack.services.useExternal=true", "--localstack.services.ip=localstack", "--localstack.services.sns.port=4575", "--localstack.services.dumb.port=4567", "--localstack.localAWSBudgets.useExternal=true", "--localstack.localAWSBudgets.ip=budgets", "--localstack.localAWSBudgets.port=5000", "--localstack.motocker.iam.useExternal=true", "--localstack.motocker.iam.ip=iam", "--localstack.motocker.iam.port=5000", "--localstack.motocker.ec2.useExternal=true", "--localstack.motocker.ec2.ip=ec2", "--localstack.motocker.ec2.port=5000", "--localstack.motocker.organizations.useExternal=true", "--localstack.motocker.organizations.ip=organizations", "--localstack.motocker.organizations.port=5000" ]) commandStr = ("./gradlew bootRun -PspringArgs='{}' && ".format(springArgs) * 50) + "echo FINISHED" omigostService["command"] = "sh -c \"cd /opt/app/omigost && {}\"".format( commandStr) omigostService["environment"] = [ "AWS_ACCESS_KEY={}".format(awsKey), "AWS_SECRET_KEY={}".format(awsSecret) ] omigostService["ports"].append("8100:8100") compose_config = {"version": "3", "services": normalized_keys} if logger: logger.info( 'Generated configuration from {} file'.format(configInputPath)) return yaml.dump(compose_config, default_flow_style=False)
def generateConfigAWS(envName='dev', path='.', logger=None, secretEnv=None, keyEnv=None): configInputPath = '{}/{}/docker-compose.yml'.format(path, envName) if logger: logger.info( 'Reading configuration from {} file'.format(configInputPath)) transformer = ComposeTransformer(configInputPath) normalized_keys = transformer.ingest_containers() secrets = loadSecrets(secretEnv, keyEnv) awsKey = secrets["awsKey"] awsSecret = secrets["awsSecret"] global_envs = [{ 'name': 'AWS_ACCESS_KEY', 'value': awsKey }, { 'name': 'AWS_SECRET_KEY', 'value': awsSecret }] ecs_config = json.loads(ECSTransformer().emit_containers(normalized_keys)) ecs_config['AWSEBDockerrunVersion'] = 2 for container in ecs_config['containerDefinitions']: container['cpu'] = 1 container['essential'] = True container['memory'] = 525 container['name'] = container['hostname'] = container['container_name'] if 'links' in container: newLinks = [] for linkSpec in container['links']: newLinks.append("{}:{}".format(linkSpec, linkSpec)) container['links'] = newLinks if 'ports' in container: newPorts = [] for portSpec in container['ports']: portTokens = portSpec.split(':') newPorts.append({ "hostPort": portTokens[0], "containerPort": portTokens[1] }) container['portMappings'] = newPorts container.pop('ports') newEnv = global_envs + [{ 'name': 'HOSTNAME', 'value': container['container_name'] }] if 'environment' in container: if type(container['environment']) is list: for var in container['environment']: varTokens = var.split('=') newEnv.append({ 'name': varTokens[0], 'value': varTokens[1] }) else: for k, v in container['environment'].items(): newEnv.append({'name': k, 'value': v}) container['environment'] = newEnv if logger: logger.info( 'Generated configuration from {} file'.format(configInputPath)) return json.dumps(ecs_config, indent=4, sort_keys=True)
class ComposeTransformerTests(TestCase): def setUp(self): self.file_name = './container_transform/tests/docker-compose.yml' self.transformer = ComposeTransformer(self.file_name) @patch.object(uuid, 'uuid4', return_value='2e9c3538-b9d3-4f47-8a23-2a19315b370b') def test_emit_containers_no_name(self, mock_uuid): """ Test .emit_containers() for a container without a name """ containers = [{'image': 'postgres:9.3', 'cpu': 200}] output = self.transformer.emit_containers(containers) self.assertEqual( ('services:\n' ' {mock_uuid}:\n' ' cpu: 200\n' ' image: postgres:9.3\n' 'version: \'2\'\n').format(mock_uuid=mock_uuid.return_value), output) def test_emit_mapping(self): """ Test ._emit_mapping() """ mapping = { 'host_ip': '192.168.59.103', 'host_port': 8000, 'container_ip': '127.0.0.1', 'container_port': 80, } self.assertEqual(self.transformer._emit_mapping(mapping), '192.168.59.103:8000:127.0.0.1:80') def test_emit_mapping_udp(self): """ Test ._emit_mapping() with udp port """ mapping = {'host_port': 53, 'container_port': 53, 'protocol': 'udp'} self.assertEqual(self.transformer._emit_mapping(mapping), '53:53/udp') def test_emit_mapping_missing_ports(self): """ Test ._emit_mapping() missing ports """ mapping = { 'host_ip': '192.168.59.103', 'container_ip': '127.0.0.1', } self.assertEqual(self.transformer._emit_mapping(mapping), '192.168.59.103:127.0.0.1') def test_parse_port_mapping_fails(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '192.168.59.103:8000:127.0.0.1:80:' self.assertEqual(self.transformer._parse_port_mapping(mapping), None) def test_parse_port_mapping_udp(self): """ Test ._parse_port_mapping() fails on > 4 parts """ mapping = '53:53/udp' self.assertEqual(self.transformer._parse_port_mapping(mapping), { 'host_port': 53, 'container_port': 53, 'protocol': 'udp' }) def test_ingest_cpu(self): cpu = 100 self.assertEqual(self.transformer.ingest_cpu(cpu), cpu) def test_emit_cpu(self): cpu = 100 self.assertEqual(self.transformer.emit_cpu(cpu), cpu) def test_ingest_environment(self): environment = {'DB_PAS': '******', 'DB_USER': '******'} environment_exp = {'DB_PAS': '******', 'DB_USER': '******'} self.assertEqual(self.transformer.ingest_environment(environment), environment_exp) def test_ingest_secrets(self): secrets = ['DB_PAS', 'DB_USER', 'EXTERNAL_SECRET'] secrets_exp = {'DB_PAS': '******', 'DB_USER': '******'} self.assertEqual(self.transformer.ingest_secrets(secrets), secrets_exp) def test_ingest_secrets_error_file_not_found(self): secrets = {'DOESNOTEXIST': 'abc'} self.assertEqual(self.transformer.ingest_secrets(secrets), {}) def test_ingest_secrets_error_key_not_exist(self): secrets = {'UNKNOWN': 'abc'} self.assertEqual(self.transformer.ingest_secrets(secrets), {}) def test_emit_environment(self): environment = {'DB_PAS': '******', 'DB_USER': '******'} environment_exp = {'DB_PAS': '******', 'DB_USER': '******'} self.assertEqual(self.transformer.emit_environment(environment), environment_exp) def test_emit_secrets(self): secrets = {'DB_PAS': '******', 'DB_USER': '******'} secrets_exp = {'DB_PAS': '******', 'DB_USER': '******'} self.assertEqual(self.transformer.emit_secrets(secrets), secrets_exp) def test_ingest_command_list(self): """ Test .ingest_command() should respect that list items are single command args """ command = ["/bin/echo", "Hello world"] self.assertEqual(self.transformer.ingest_command(command), "/bin/echo 'Hello world'")