Example #1
0
    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'])
Example #2
0
 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')
Example #3
0
 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)
Example #4
0
 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"]
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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 _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']
Example #10
0
 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
Example #11
0
    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)
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
 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
Example #15
0
    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)
Example #16
0
    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'])
Example #17
0
    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'])
Example #18
0
    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
Example #19
0
    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'])
Example #20
0
    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
Example #21
0
 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']
Example #22
0
 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']
Example #23
0
 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"]