def test_build_execution_context_next_run(self, mock_clients, mock_registry): fpipe = fakes.FakePipeline() fplan = fakes.FakePlan() mock_registry.Plan.get_by_id.return_value = fplan fplan.raw_content = { 'name': 'theplan', 'artifacts': [{'name': 'nodeus', 'artifact_type': 'heroku', 'content': { 'href': 'https://example.com/ex.git'}, 'language_pack': '1-2-3-4'}]} mock_exec = mock.MagicMock() mock_exec.context = json.dumps( {'stack_id': 'foo', 'build_service_url': 'url-for', 'base_image_id': '1-2-3-4', 'source_format': 'heroku', 'parameters': {'app_name': 'fruit', 'public_net': 'nsa-2-0'}}) mock_mistral = mock_clients.return_value.mistral.return_value mock_mistral.executions.get.return_value = mock_exec wbook = catalog.get('workbooks', 'build_deploy') mock_mistral.workbooks.get_definition.return_value = wbook handler = pipeline_handler.PipelineHandler(self.ctx) ex_ctx = handler._build_execution_context(fpipe) self.assertEqual('foo', ex_ctx['stack_id']) self.assertEqual('url-for', ex_ctx['build_service_url']) self.assertEqual('1-2-3-4', ex_ctx['base_image_id']) self.assertEqual('heroku', ex_ctx['source_format']) self.assertEqual('fruit', ex_ctx['parameters']['app_name']) self.assertEqual('nsa-2-0', ex_ctx['parameters']['public_net'])
def test_get_content_type(self): with mock.patch('solum.common.catalog.open', mock.mock_open(read_data='test content'), create=True) as m_open: val = catalog.get('test', 'test_data', content_type='fake') self.assertEqual('test content', val) m_open.assert_called_with( 'solum/common/../../etc/solum/test/test_data.fake')
def test_get_default(self): with mock.patch('solum.common.catalog.open', mock.mock_open(read_data='test content'), create=True) as m_open: val = catalog.get('test', 'test_data') self.assertEqual('test content', val) expect = os.path.join(self.proj_dir, 'etc/solum/test/test_data.yaml') m_open.assert_called_with(expect)
def test_get_content_type(self): with mock.patch('solum.common.catalog.open', mock.mock_open(read_data='test content'), create=True) as m_open: val = catalog.get('test', 'test_data', content_type='fake') self.assertEqual('test content', val) expect = os.path.join(self.proj_dir, 'etc/solum/test/test_data.fake') m_open.assert_called_with(expect)
def _deploy_infra(self, image_id): osc = clients.OpenStackClients(self.context) parameters = {"image": image_id} template = catalog.get("templates", "infra") created_stack = osc.heat().stacks.create(stack_name="infra", template=template, parameters=parameters) return created_stack["stack"]["id"]
def _get_template(self, ctxt, image_format, image_storage, image_loc, image_name, assem, ports, t_logger): template = None if image_format == 'docker': try: template = catalog.get('templates', 'basic') except exception.ObjectNotFound as onf_ex: LOG.exception(onf_ex) update_assembly(ctxt, assem.id, {'status': STATES.ERROR}) t_logger.log(logging.ERROR, "Error reading heat template.") t_logger.upload() return template elif image_format == 'vm': if image_storage == 'glance': msg = ("image_storage %s not supported with image_format %s" % (image_storage, image_format)) LOG.debug(msg) update_assembly(ctxt, assem.id, {'status': STATES.ERROR}) t_logger.log(logging.DEBUG, "Solum config error: %s " % msg) t_logger.upload() else: try: template = catalog.get('templates', 'coreos') except exception.ObjectNotFound as onf_ex: LOG.exception(onf_ex) update_assembly(ctxt, assem.id, {'status': STATES.ERROR}) t_logger.log(logging.ERROR, "Error reading heat template.") t_logger.upload() return template if image_storage == 'docker_registry': template = self._get_template_for_docker_reg( assem, template, image_loc, image_name, ports) else: LOG.debug("Image format %s is not supported." % image_format) update_assembly(ctxt, assem.id, {'status': STATES.ERROR}) t_logger.log(logging.DEBUG, "Solum config error: Image format.") t_logger.upload() return template
def _deploy_infra(self, image_id): osc = clients.OpenStackClients(self.context) parameters = {'image': image_id} template = catalog.get('templates', 'infra') created_stack = osc.heat().stacks.create(stack_name='infra', template=template, parameters=parameters) return created_stack['stack']['id']
def _ensure_workbook(self, pipeline): osc = clients.OpenStackClients(self.context) try: osc.mistral().workbooks.get(pipeline.workbook_name) except Exception as excp: if "Workbook not found" in str(excp): definition = catalog.get("workbooks", pipeline.workbook_name) # create the workbook for the user. osc.mistral().workbooks.create(pipeline.workbook_name, "solum generated workbook", ["solum", "builtin"]) osc.mistral().workbooks.upload_definition(pipeline.workbook_name, definition) else: raise
def test_ensure_workbook_not_exists(self, mock_clients, mock_registry): fpipe = fakes.FakePipeline() fpipe.workbook_name = 'build' mock_mistral = mock_clients.return_value.mistral.return_value mock_mistral.workbooks.get.side_effect = ValueError( 'Workbook not found') handler = pipeline_handler.PipelineHandler(self.ctx) handler._ensure_workbook(fpipe) mock_mistral.workbooks.create.assert_called_once_with( 'build', 'solum generated workbook', ['solum', 'builtin']) wbook = catalog.get('workbooks', 'build') mock_mistral.workbooks.upload_definition.assert_called_once_with( 'build', wbook)
def deploy(self, ctxt, assembly_id, image_id): osc = clients.OpenStackClients(ctxt) assem = objects.registry.Assembly.get_by_id(ctxt, assembly_id) parameters = {'app_name': assem.name, 'image': image_id} parameters.update(heat_utils.get_network_parameters(osc)) # TODO(asalkeld) support template flavors (maybe an autoscaling one) # this could also be stored in glance. template_flavor = 'basic' try: template = catalog.get('templates', template_flavor) except exception.ObjectNotFound as onf_ex: LOG.excepion(onf_ex) assem.status = STATES.ERROR assem.save(ctxt) return stack_name = self._get_stack_name(assem) stack_id = self._find_id_if_stack_exists(osc, assem) if stack_id is not None: osc.heat().stacks.update(stack_id, stack_name=stack_name, template=template, parameters=parameters) else: created_stack = osc.heat().stacks.create(stack_name=stack_name, template=template, parameters=parameters) stack_id = created_stack['stack']['id'] comp_name = 'Heat_Stack_for_%s' % assem.name comp_description = 'Heat Stack %s' % ( yaml.load(template).get('description')) objects.registry.Component.assign_and_create(ctxt, assem, comp_name, 'Heat Stack', comp_description, created_stack['stack'] ['links'][0]['href'], stack_id) assem.status = STATES.DEPLOYING assem.save(ctxt) self._update_assembly_status(ctxt, assem, osc, stack_id)
def _ensure_workbook(self, pipeline): osc = clients.OpenStackClients(self.context) try: osc.mistral().workbooks.get(pipeline.workbook_name) except Exception as excp: if 'Workbook not found' in str(excp): definition = catalog.get('workbooks', pipeline.workbook_name) # create the workbook for the user. osc.mistral().workbooks.create(pipeline.workbook_name, 'solum generated workbook', ['solum', 'builtin']) osc.mistral().workbooks.upload_definition( pipeline.workbook_name, definition) else: raise
def deploy(self, ctxt, assembly_id, image_id): osc = clients.OpenStackClients(ctxt) assem = objects.registry.Assembly.get_by_id(ctxt, assembly_id) parameters = {'app_name': assem.name, 'image': image_id} parameters.update(heat_utils.get_network_parameters(osc)) # TODO(asalkeld) support template flavors (maybe an autoscaling one) # this could also be stored in glance. template_flavor = 'basic' try: template = catalog.get('templates', template_flavor) except exception.ObjectNotFound as onf_ex: LOG.excepion(onf_ex) assem.status = STATES.ERROR assem.save(ctxt) return stack_name = self._get_stack_name(assem) stack_id = self._find_id_if_stack_exists(osc, assem) if stack_id is not None: osc.heat().stacks.update(stack_id, stack_name=stack_name, template=template, parameters=parameters) else: created_stack = osc.heat().stacks.create(stack_name=stack_name, template=template, parameters=parameters) stack_id = created_stack['stack']['id'] comp_name = 'Heat_Stack_for_%s' % assem.name comp_description = 'Heat Stack %s' % ( yaml.load(template).get('description')) objects.registry.Component.assign_and_create( ctxt, assem, comp_name, 'Heat Stack', comp_description, created_stack['stack']['links'][0]['href'], stack_id) assem.status = STATES.DEPLOYING assem.save(ctxt) self._update_assembly_status(ctxt, assem, osc, stack_id)
def test_build_execution_context_next_run(self, mock_clients, mock_registry): fpipe = fakes.FakePipeline() fplan = fakes.FakePlan() mock_registry.Plan.get_by_id.return_value = fplan fplan.raw_content = { 'name': 'theplan', 'artifacts': [{ 'name': 'nodeus', 'artifact_type': 'heroku', 'content': { 'href': 'https://example.com/ex.git' }, 'language_pack': '1-2-3-4' }] } mock_exec = mock.MagicMock() mock_exec.context = json.dumps({ 'stack_id': 'foo', 'build_service_url': 'url-for', 'base_image_id': '1-2-3-4', 'source_format': 'heroku', 'parameters': { 'app_name': 'fruit', 'public_net': 'nsa-2-0' } }) mock_mistral = mock_clients.return_value.mistral.return_value mock_mistral.executions.get.return_value = mock_exec wbook = catalog.get('workbooks', 'build_deploy') mock_mistral.workbooks.get_definition.return_value = wbook handler = pipeline_handler.PipelineHandler(self.ctx) ex_ctx = handler._build_execution_context(fpipe) self.assertEqual('foo', ex_ctx['stack_id']) self.assertEqual('url-for', ex_ctx['build_service_url']) self.assertEqual('1-2-3-4', ex_ctx['base_image_id']) self.assertEqual('heroku', ex_ctx['source_format']) self.assertEqual('fruit', ex_ctx['parameters']['app_name']) self.assertEqual('nsa-2-0', ex_ctx['parameters']['public_net'])
def test_get_context_from_last_execution(self, mock_clients, mock_registry): fpipe = fakes.FakePipeline() mock_exec = mock.MagicMock() mock_exec.context = json.dumps({'stack_id': 'foo', 'build_service_url': 'url-for', 'base_image_id': '1-2-3-4', 'source_format': 'heroku'}) mock_mistral = mock_clients.return_value.mistral.return_value mock_mistral.executions.get.return_value = mock_exec wbook = catalog.get('workbooks', 'build_deploy') mock_mistral.workbooks.get_definition.return_value = wbook handler = pipeline_handler.PipelineHandler(self.ctx) ex_ctx = handler._get_context_from_last_execution(fpipe) self.assertEqual('foo', ex_ctx['stack_id']) self.assertEqual('url-for', ex_ctx['build_service_url']) self.assertEqual('1-2-3-4', ex_ctx['base_image_id']) self.assertEqual('heroku', ex_ctx['source_format'])
def _build_execution_context(self, pipeline): # try and read the context from the previous execution ctx = self._get_context_from_last_execution(pipeline) if ctx is not None: return ctx ctx = {} # service urls. kc = self._clients.keystone() ctx['heat_service_url'] = kc.client.service_catalog.url_for( service_type='orchestration', interface='publicURL') ctx['build_service_url'] = kc.client.service_catalog.url_for( service_type='image_builder', interface='publicURL') # extract context from the plan # TODO(asalkeld) this should be versioned. plan_obj = objects.registry.Plan.get_by_id(self.context, pipeline.plan_id) ctx['name'] = plan_obj.name artifacts = plan_obj.raw_content.get('artifacts', []) for arti in artifacts: ctx['source_uri'] = arti['content']['href'] ctx['base_image_id'] = arti.get('language_pack', 'auto') ctx['source_format'] = arti.get('artifact_type', 'heroku') ctx['image_format'] = arti.get('image_format', CONF.api.image_format) ctx['template'] = catalog.get('templates', 'basic') # TODO(asalkeld) add support to the plan to pass heat parameters. ctx['parameters'] = {'app_name': pipeline.name} ctx['parameters'].update( heat_utils.get_network_parameters(self._clients)) ctx['stack_id'] = self._create_empty_stack(pipeline) ctx['stack_name'] = pipeline.name # TODO(asalkeld) integrate the Environment into the context. return ctx
def test_get_context_from_last_execution(self, mock_clients, mock_registry): fpipe = fakes.FakePipeline() mock_exec = mock.MagicMock() mock_exec.context = json.dumps({ 'stack_id': 'foo', 'build_service_url': 'url-for', 'base_image_id': '1-2-3-4', 'source_format': 'heroku' }) mock_mistral = mock_clients.return_value.mistral.return_value mock_mistral.executions.get.return_value = mock_exec wbook = catalog.get('workbooks', 'build_deploy') mock_mistral.workbooks.get_definition.return_value = wbook handler = pipeline_handler.PipelineHandler(self.ctx) ex_ctx = handler._get_context_from_last_execution(fpipe) self.assertEqual('foo', ex_ctx['stack_id']) self.assertEqual('url-for', ex_ctx['build_service_url']) self.assertEqual('1-2-3-4', ex_ctx['base_image_id']) self.assertEqual('heroku', ex_ctx['source_format'])
def _build_execution_context(self, pipeline): # try and read the context from the previous execution ctx = self._get_context_from_last_execution(pipeline) if ctx is not None: return ctx ctx = {} # service urls. kc = self._clients.keystone() ctx["heat_service_url"] = kc.client.service_catalog.url_for( service_type="orchestration", endpoint_type="publicURL" ) ctx["build_service_url"] = kc.client.service_catalog.url_for( service_type="image_builder", endpoint_type="publicURL" ) # extract context from the plan # TODO(asalkeld) this should be versioned. plan_obj = objects.registry.Plan.get_by_id(self.context, pipeline.plan_id) ctx["name"] = plan_obj.name artifacts = plan_obj.raw_content.get("artifacts", []) for arti in artifacts: ctx["source_uri"] = arti["content"]["href"] ctx["base_image_id"] = arti.get("language_pack", "auto") ctx["source_format"] = arti.get("artifact_type", "heroku") ctx["image_format"] = arti.get("image_format", CONF.api.image_format) ctx["template"] = catalog.get("templates", "basic") # TODO(asalkeld) add support to the plan to pass heat parameters. ctx["parameters"] = {"app_name": pipeline.name} ctx["parameters"].update(heat_utils.get_network_parameters(self._clients)) ctx["stack_id"] = self._create_empty_stack(pipeline) ctx["stack_name"] = pipeline.name # TODO(asalkeld) integrate the Environment into the context. return ctx
def _create_empty_stack(self, pipeline): osc = self._clients template = catalog.get('templates', 'empty') created_stack = osc.heat().stacks.create(stack_name=pipeline.name, template=template) return created_stack['stack']['id']
def _create_empty_stack(self, pipeline): osc = self._clients template = catalog.get("templates", "empty") created_stack = osc.heat().stacks.create(stack_name=pipeline.name, template=template) return created_stack["stack"]["id"]