def test_stack_update_with_environment_files(self):
        # Setup
        stack_name = 'service_update_env_files_stack'
        params = {}
        template = '{ "Template": "data" }'
        old_stack = tools.get_stack(stack_name, self.ctx)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx)

        # prepare mocks
        self.patchobject(stack, 'Stack', return_value=stk)
        self.patchobject(stack.Stack, 'load', return_value=old_stack)
        self.patchobject(templatem, 'Template', return_value=stk.t)
        self.patchobject(environment, 'Environment', return_value=stk.env)
        self.patchobject(stk, 'validate', return_value=None)
        self.patchobject(eventlet.queue, 'LightQueue',
                         return_value=mock.Mock())

        mock_merge = self.patchobject(self.man, '_merge_environments')

        # Test
        environment_files = ['env_1']
        self.man.update_stack(self.ctx, old_stack.identifier(),
                              template, params, None, {},
                              environment_files=environment_files)

        # Verify
        mock_merge.assert_called_once_with(environment_files, None, params)
Exemple #2
0
    def test_stack_update_with_environment_files(self):
        # Setup
        stack_name = "service_update_env_files_stack"
        params = {}
        template = '{ "Template": "data" }'
        old_stack = tools.get_stack(stack_name, self.ctx)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id("1234")
        stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx)

        # prepare mocks
        self.patchobject(stack, "Stack", return_value=stk)
        self.patchobject(stack.Stack, "load", return_value=old_stack)
        self.patchobject(templatem, "Template", return_value=stk.t)
        self.patchobject(environment, "Environment", return_value=stk.env)
        self.patchobject(stk, "validate", return_value=None)
        self.patchobject(grevent, "Event", return_value=mock.Mock())

        mock_merge = self.patchobject(self.man, "_merge_environments")

        # Test
        environment_files = ["env_1"]
        self.man.update_stack(
            self.ctx, old_stack.identifier(), template, params, None, {}, environment_files=environment_files
        )

        # Verify
        mock_merge.assert_called_once_with(environment_files, None, params)
    def test_stack_create_nested(self, mock_validate, mock_tg):
        convergence_engine = cfg.CONF.convergence_engine
        stack_name = 'service_create_nested_test_stack'
        parent_stack = tools.get_stack(stack_name + '_parent', self.ctx)
        owner_id = parent_stack.store()
        mock_tg.return_value = tools.DummyThreadGroup()

        stk = tools.get_stack(stack_name, self.ctx, with_params=True,
                              owner_id=owner_id, nested_depth=1)
        tmpl_id = stk.t.store(self.ctx)

        mock_load = self.patchobject(templatem.Template, 'load',
                                     return_value=stk.t)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        result = self.man.create_stack(self.ctx, stack_name, None,
                                       None, None, {},
                                       owner_id=owner_id, nested_depth=1,
                                       template_id=tmpl_id)
        self.assertEqual(stk.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result['stack_id'])

        mock_load.assert_called_once_with(self.ctx, tmpl_id)
        mock_stack.assert_called_once_with(self.ctx, stack_name, stk.t,
                                           owner_id=owner_id, nested_depth=1,
                                           user_creds_id=None,
                                           stack_user_project_id=None,
                                           convergence=convergence_engine,
                                           parent_resource=None)

        mock_validate.assert_called_once_with()
Exemple #4
0
    def test_stack_update_verify_err(self):
        stack_name = "service_update_verify_err_test_stack"
        params = {"foo": "bar"}
        template = '{ "Template": "data" }'

        old_stack = tools.get_stack(stack_name, self.ctx)
        old_stack.store()
        sid = old_stack.store()
        old_stack.set_stack_user_project_id("1234")
        s = stack_object.Stack.get_by_id(self.ctx, sid)
        stk = tools.get_stack(stack_name, self.ctx)

        # prepare mocks
        mock_stack = self.patchobject(stack, "Stack", return_value=stk)
        mock_load = self.patchobject(stack.Stack, "load", return_value=old_stack)
        mock_tmpl = self.patchobject(templatem, "Template", return_value=stk.t)
        mock_env = self.patchobject(environment, "Environment", return_value=stk.env)
        ex_expected = exception.StackValidationFailed(message="fubar")
        mock_validate = self.patchobject(stk, "validate", side_effect=ex_expected)
        # do update
        api_args = {"timeout_mins": 60}
        ex = self.assertRaises(
            dispatcher.ExpectedException,
            self.man.update_stack,
            self.ctx,
            old_stack.identifier(),
            template,
            params,
            None,
            api_args,
        )

        # assertions
        self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(
            self.ctx,
            stk.name,
            stk.t,
            convergence=False,
            current_traversal=old_stack.current_traversal,
            prev_raw_template_id=None,
            current_deps=None,
            disable_rollback=True,
            nested_depth=0,
            owner_id=None,
            parent_resource=None,
            stack_user_project_id="1234",
            strict_validate=True,
            tenant_id="test_tenant_id",
            timeout_mins=60,
            user_creds_id=u"1",
            username="******",
        )
        mock_load.assert_called_once_with(self.ctx, stack=s)
        mock_validate.assert_called_once_with()
Exemple #5
0
    def test_stack_update_nested(self):
        stack_name = 'service_update_nested_test_stack'
        parent_stack = tools.get_stack(stack_name + '_parent', self.ctx)
        owner_id = parent_stack.store()
        old_stack = tools.get_stack(stack_name, self.ctx,
                                    owner_id=owner_id, nested_depth=1,
                                    user_creds_id=parent_stack.user_creds_id)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx)
        tmpl_id = stk.t.store(self.ctx)

        # prepare mocks
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        mock_load = self.patchobject(stack.Stack, 'load',
                                     return_value=old_stack)
        mock_tmpl = self.patchobject(templatem.Template, 'load',
                                     return_value=stk.t)

        mock_validate = self.patchobject(stk, 'validate', return_value=None)
        msgq_mock = mock.Mock()
        self.patchobject(eventlet.queue, 'LightQueue', return_value=msgq_mock)

        # do update
        api_args = {'timeout_mins': 60}
        result = self.man.update_stack(self.ctx, old_stack.identifier(),
                                       None, None, None, api_args,
                                       template_id=tmpl_id)

        # assertions
        self.assertEqual(old_stack.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result['stack_id'])
        self.assertEqual([msgq_mock], self.man.thread_group_mgr.msg_queues)
        mock_tmpl.assert_called_once_with(self.ctx, tmpl_id)
        mock_stack.assert_called_once_with(
            self.ctx, stk.name, stk.t,
            convergence=False,
            current_traversal=old_stack.current_traversal,
            prev_raw_template_id=None,
            current_deps=None,
            disable_rollback=True,
            nested_depth=1,
            owner_id=owner_id,
            parent_resource=None,
            stack_user_project_id='1234',
            strict_validate=True,
            tenant_id='test_tenant_id',
            timeout_mins=60,
            user_creds_id=u'1',
            username='******')
        mock_load.assert_called_once_with(self.ctx, stack=s)
        mock_validate.assert_called_once_with(validate_resources=False)
    def _test_stack_update_preview(self, orig_template, new_template,
                                   environment_files=None):
        stack_name = 'service_update_test_stack_preview'
        params = {'foo': 'bar'}
        old_stack = tools.get_stack(stack_name, self.ctx,
                                    template=orig_template)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx, template=new_template)

        # prepare mocks
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        mock_load = self.patchobject(stack.Stack, 'load',
                                     return_value=old_stack)
        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment, 'Environment',
                                    return_value=stk.env)
        mock_validate = self.patchobject(stk, 'validate', return_value=None)
        mock_merge = self.patchobject(self.man, '_merge_environments')

        # Patch _resolve_all_attributes or it tries to call novaclient
        self.patchobject(resource.Resource, '_resolve_all_attributes',
                         return_value=None)

        # do preview_update_stack
        api_args = {'timeout_mins': 60}
        result = self.man.preview_update_stack(
            self.ctx,
            old_stack.identifier(),
            new_template, params, None,
            api_args,
            environment_files=environment_files)

        # assertions
        mock_stack.assert_called_once_with(
            self.ctx, stk.name, stk.t, convergence=False,
            current_traversal=old_stack.current_traversal,
            prev_raw_template_id=None, current_deps=None,
            disable_rollback=True, nested_depth=0, owner_id=None,
            parent_resource=None, stack_user_project_id='1234',
            strict_validate=True, tenant_id='test_tenant_id', timeout_mins=60,
            user_creds_id=u'1', username='******')
        mock_load.assert_called_once_with(self.ctx, stack=s)
        mock_tmpl.assert_called_once_with(new_template, files=None,
                                          env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_validate.assert_called_once_with()

        if environment_files:
            mock_merge.assert_called_once_with(environment_files, None, params)

        return result
    def test_stack_update(self):
        stack_name = 'service_update_test_stack'
        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'
        old_stack = tools.get_stack(stack_name, self.ctx)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx)

        # prepare mocks
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        mock_load = self.patchobject(stack.Stack, 'load',
                                     return_value=old_stack)
        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment, 'Environment',
                                    return_value=stk.env)

        mock_validate = self.patchobject(stk, 'validate', return_value=None)
        event_mock = mock.Mock()
        self.patchobject(grevent, 'Event', return_value=event_mock)

        # do update
        api_args = {'timeout_mins': 60}
        result = self.man.update_stack(self.ctx, old_stack.identifier(),
                                       template, params, None, api_args)

        # assertions
        self.assertEqual(old_stack.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result['stack_id'])
        self.assertEqual([event_mock], self.man.thread_group_mgr.events)
        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(
            self.ctx, stk.name, stk.t,
            convergence=False,
            current_traversal=old_stack.current_traversal,
            prev_raw_template_id=None,
            current_deps=None,
            disable_rollback=True,
            nested_depth=0,
            owner_id=None,
            parent_resource=None,
            stack_user_project_id='1234',
            strict_validate=True,
            tenant_id='test_tenant_id',
            timeout_mins=60,
            user_creds_id=u'1',
            username='******')
        mock_load.assert_called_once_with(self.ctx, stack=s)
        mock_validate.assert_called_once_with()
Exemple #8
0
    def test_stack_update_nested(self):
        stack_name = "service_update_nested_test_stack"
        old_stack = tools.get_stack(stack_name, self.ctx)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id("1234")
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx)
        tmpl_id = stk.t.store()

        # prepare mocks
        mock_stack = self.patchobject(stack, "Stack", return_value=stk)
        mock_load = self.patchobject(stack.Stack, "load", return_value=old_stack)
        mock_tmpl = self.patchobject(templatem.Template, "load", return_value=stk.t)

        mock_validate = self.patchobject(stk, "validate", return_value=None)
        event_mock = mock.Mock()
        self.patchobject(grevent, "Event", return_value=event_mock)

        # do update
        api_args = {"timeout_mins": 60}
        result = self.man.update_stack(
            self.ctx, old_stack.identifier(), None, None, None, api_args, template_id=tmpl_id
        )

        # assertions
        self.assertEqual(old_stack.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result["stack_id"])
        self.assertEqual([event_mock], self.man.thread_group_mgr.events)
        mock_tmpl.assert_called_once_with(self.ctx, tmpl_id)
        mock_stack.assert_called_once_with(
            self.ctx,
            stk.name,
            stk.t,
            convergence=False,
            current_traversal=old_stack.current_traversal,
            prev_raw_template_id=None,
            current_deps=None,
            disable_rollback=True,
            nested_depth=0,
            owner_id=None,
            parent_resource=None,
            stack_user_project_id="1234",
            strict_validate=True,
            tenant_id="test_tenant_id",
            timeout_mins=60,
            user_creds_id=u"1",
            username="******",
        )
        mock_load.assert_called_once_with(self.ctx, stack=s)
        mock_validate.assert_called_once_with()
Exemple #9
0
    def test_stack_update_reuses_api_params(self):
        stack_name = "service_update_stack_reuses_api_params"
        params = {"foo": "bar"}
        template = '{ "Template": "data" }'

        old_stack = tools.get_stack(stack_name, self.ctx)
        old_stack.timeout_mins = 1
        old_stack.disable_rollback = False
        sid = old_stack.store()
        old_stack.set_stack_user_project_id("1234")
        s = stack_object.Stack.get_by_id(self.ctx, sid)
        stk = tools.get_stack(stack_name, self.ctx)

        # prepare mocks
        mock_stack = self.patchobject(stack, "Stack", return_value=stk)
        mock_load = self.patchobject(stack.Stack, "load", return_value=old_stack)
        mock_tmpl = self.patchobject(templatem, "Template", return_value=stk.t)
        mock_env = self.patchobject(environment, "Environment", return_value=stk.env)
        mock_validate = self.patchobject(stk, "validate", return_value=None)

        # do update
        result = self.man.update_stack(self.ctx, old_stack.identifier(), template, params, None, {})

        # assertions
        self.assertEqual(old_stack.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result["stack_id"])

        mock_validate.assert_called_once_with()
        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_load.assert_called_once_with(self.ctx, stack=s)
        mock_stack.assert_called_once_with(
            self.ctx,
            stk.name,
            stk.t,
            convergence=False,
            current_traversal=old_stack.current_traversal,
            prev_raw_template_id=None,
            current_deps=None,
            disable_rollback=False,
            nested_depth=0,
            owner_id=None,
            parent_resource=None,
            stack_user_project_id="1234",
            strict_validate=True,
            tenant_id="test_tenant_id",
            timeout_mins=1,
            user_creds_id=u"1",
            username="******",
        )
Exemple #10
0
    def test_signal_no_calls_metadata_update(self, mock_get, mock_signal,
                                             mock_update):
        # fake keystone client
        self.patchobject(keystone.KeystoneClientPlugin, '_create',
                         return_value=test_fakes.FakeKeystoneClient())

        stk = tools.get_stack('signal_reception', self.ctx, policy_template)
        self.stack = stk
        stk.store()
        stk.create()
        s = stack_object.Stack.get_by_id(self.ctx, self.stack.id)
        mock_get.return_value = s
        mock_signal.return_value = None
        res.Resource.signal_needs_metadata_updates = False

        self.eng.resource_signal(self.ctx,
                                 dict(self.stack.identifier()),
                                 'WebServerScaleDownPolicy', None,
                                 sync_call=True)

        mock_get.assert_called_once_with(self.ctx, self.stack.identifier())
        mock_signal.assert_called_once_with(mock.ANY, False)
        # this will never be called
        self.assertEqual(0, mock_update.call_count)

        res.Resource.signal_needs_metadata_updates = True
Exemple #11
0
    def test_stack_delete_current_engine_active_lock(self, mock_expired, mock_acquire, mock_try, mock_load):
        cfg.CONF.set_override("error_wait_time", 0)
        self.man.start()
        stack_name = "service_delete_test_stack_current_active_lock"
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(self.ctx, stack.id, self.man.engine_id)

        st = stack_object.Stack.get_by_id(self.ctx, sid)

        mock_load.return_value = stack
        mock_try.return_value = self.man.engine_id
        mock_stop = self.patchobject(self.man.thread_group_mgr, "stop")
        mock_send = self.patchobject(self.man.thread_group_mgr, "send")
        mock_expired.side_effect = [False, True]

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.man.thread_group_mgr.groups[sid].wait()

        mock_load.assert_called_with(self.ctx, stack=st)
        mock_send.assert_called_once_with(stack.id, "cancel")
        mock_stop.assert_called_once_with(stack.id)
        self.assertEqual(2, len(mock_load.mock_calls))
        mock_try.assert_called_with()
        mock_acquire.assert_called_once_with(True)
Exemple #12
0
    def test_stack_delete_other_dead_engine_active_lock(
        self, mock_expired, mock_acquire, mock_alive, mock_try, mock_load
    ):
        cfg.CONF.set_override("error_wait_time", 0)
        OTHER_ENGINE = "other-engine-fake-uuid"
        stack_name = "service_delete_test_stack_other_dead_engine"
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(self.ctx, stack.id, "other-engine-fake-uuid")

        st = stack_object.Stack.get_by_id(self.ctx, sid)
        mock_load.return_value = stack
        mock_try.return_value = OTHER_ENGINE
        mock_alive.return_value = False
        mock_expired.side_effect = [False, True]

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.man.thread_group_mgr.groups[sid].wait()

        mock_load.assert_called_with(self.ctx, stack=st)
        mock_try.assert_called_with()
        mock_acquire.assert_called_once_with(True)
        mock_alive.assert_called_with(self.ctx, OTHER_ENGINE)
Exemple #13
0
    def test_stack_delete_other_engine_active_lock_succeeded(
        self, mock_expired, mock_acquire, mock_alive, mock_try, mock_load
    ):
        cfg.CONF.set_override("error_wait_time", 0)

        OTHER_ENGINE = "other-engine-fake-uuid"
        self.man.start()
        stack_name = "service_delete_test_stack_other_engine_lock"
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(self.ctx, stack.id, OTHER_ENGINE)

        st = stack_object.Stack.get_by_id(self.ctx, sid)
        mock_load.return_value = stack
        mock_try.return_value = OTHER_ENGINE
        mock_alive.return_value = True
        mock_expired.side_effect = [False, True]
        mock_call = self.patchobject(self.man, "_remote_call", return_value=None)

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.man.thread_group_mgr.groups[sid].wait()

        self.assertEqual(2, len(mock_load.mock_calls))
        mock_load.assert_called_with(self.ctx, stack=st)
        mock_try.assert_called_with()
        mock_alive.assert_called_with(self.ctx, OTHER_ENGINE)
        mock_call.assert_has_calls(
            [
                mock.call(self.ctx, OTHER_ENGINE, mock.ANY, "send", message="cancel", stack_identity=mock.ANY),
                mock.call(self.ctx, OTHER_ENGINE, mock.ANY, "stop_stack", stack_identity=mock.ANY),
            ]
        )
        mock_acquire.assert_called_once_with(True)
Exemple #14
0
    def test_stack_update_existing_parameters(self):
        # Use a template with existing parameters, then update the stack
        # with a template containing additional parameters and ensure all
        # are preserved.

        stack_name = "service_update_test_stack_existing_parameters"
        update_params = {
            "encrypted_param_names": [],
            "parameter_defaults": {},
            "event_sinks": [],
            "parameters": {"newparam": 123},
            "resource_registry": {"resources": {}},
        }
        api_args = {rpc_api.PARAM_TIMEOUT: 60, rpc_api.PARAM_EXISTING: True}
        t = template_format.parse(tools.wp_template)

        stk = tools.get_stack(stack_name, self.ctx, with_params=True)
        stk.store()
        stk.set_stack_user_project_id("1234")
        self.assertEqual({"KeyName": "test"}, stk.t.env.params)

        t["parameters"]["newparam"] = {"type": "number"}
        with mock.patch("heat.engine.stack.Stack") as mock_stack:
            stk.update = mock.Mock()
            mock_stack.load.return_value = stk
            mock_stack.validate.return_value = None
            result = self.man.update_stack(self.ctx, stk.identifier(), t, update_params, None, api_args)
            tmpl = mock_stack.call_args[0][2]
            self.assertEqual({"KeyName": "test", "newparam": 123}, tmpl.env.params)
            self.assertEqual(stk.identifier(), result)
    def test_stack_create_verify_err(self, mock_validate):
        mock_validate.side_effect = exception.StackValidationFailed(message='')

        stack_name = 'service_create_verify_err_test_stack'
        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'

        stk = tools.get_stack(stack_name, self.ctx)

        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment, 'Environment',
                                    return_value=stk.env)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)

        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.create_stack,
                               self.ctx, stack_name, template, params,
                               None, {})
        self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])

        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(self.ctx, stack_name, stk.t,
                                           owner_id=None, nested_depth=0,
                                           user_creds_id=None,
                                           stack_user_project_id=None,
                                           convergence=False,
                                           parent_resource=None)
Exemple #16
0
    def test_update_immutable_parameter_disallowed(self):

        template = '''
heat_template_version: 2014-10-16
parameters:
  param1:
    type: string
    immutable: true
    default: foo
'''

        self.ctx = utils.dummy_context(password=None)
        stack_name = 'test_update_immutable_parameters'
        old_stack = tools.get_stack(stack_name, self.ctx,
                                    template=template)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        # prepare mocks
        self.patchobject(self.man, '_get_stack', return_value=s)
        self.patchobject(stack, 'Stack', return_value=old_stack)
        self.patchobject(stack.Stack, 'load', return_value=old_stack)

        params = {'param1': 'bar'}
        exc = self.assertRaises(dispatcher.ExpectedException,
                                self.man.update_stack,
                                self.ctx, old_stack.identifier(),
                                old_stack.t.t, params,
                                None, {})
        self.assertEqual(exception.ImmutableParameterModified, exc.exc_info[0])
        self.assertEqual('The following parameters are immutable and may not '
                         'be updated: param1', exc.exc_info[1].message)
    def test_stack_update_existing_parameters(self):
        # Use a template with existing parameters, then update the stack
        # with a template containing additional parameters and ensure all
        # are preserved.

        stack_name = 'service_update_test_stack_existing_parameters'
        update_params = {'encrypted_param_names': [],
                         'parameter_defaults': {},
                         'event_sinks': [],
                         'parameters': {'newparam': 123},
                         'resource_registry': {'resources': {}}}
        api_args = {rpc_api.PARAM_TIMEOUT: 60,
                    rpc_api.PARAM_EXISTING: True}
        t = template_format.parse(tools.wp_template)

        stk = tools.get_stack(stack_name, self.ctx, with_params=True)
        stk.store()
        stk.set_stack_user_project_id('1234')
        self.assertEqual({'KeyName': 'test'}, stk.t.env.params)

        with mock.patch('heat.engine.stack.Stack') as mock_stack:
            stk.update = mock.Mock()
            mock_stack.load.return_value = stk
            mock_stack.validate.return_value = None
            result = self.man.update_stack(self.ctx, stk.identifier(),
                                           t,
                                           update_params,
                                           None, api_args)
            tmpl = mock_stack.call_args[0][2]
            self.assertEqual({'KeyName': 'test', 'newparam': 123},
                             tmpl.env.params)
            self.assertEqual(stk.identifier(), result)
    def test_get_best_existing_db_resource(self, mock_cr):
        stack = tools.get_stack('test_stack', utils.dummy_context(),
                                template=tools.string_template_five,
                                convergence=True)
        stack.store()
        stack.prev_raw_template_id = 2
        stack.t.id = 1
        dummy_res = stack.resources['A']
        a_res_2 = res.Resource('A', dummy_res.t, stack)
        a_res_2.current_template_id = 2
        a_res_2.id = 2
        a_res_3 = res.Resource('A', dummy_res.t, stack)
        a_res_3.current_template_id = 3
        a_res_3.id = 3
        a_res_1 = res.Resource('A', dummy_res.t, stack)
        a_res_1.current_template_id = 1
        a_res_1.id = 1
        existing_res = {2: a_res_2,
                        3: a_res_3,
                        1: a_res_1}
        stack.ext_rsrcs_db = existing_res
        best_res = stack._get_best_existing_rsrc_db('A')
        # should return resource with template id 1 which is current template
        self.assertEqual(a_res_1.id, best_res.id)

        # no resource with current template id as 1
        existing_res = {2: a_res_2,
                        3: a_res_3}
        stack.ext_rsrcs_db = existing_res
        best_res = stack._get_best_existing_rsrc_db('A')
        # should return resource with template id 2 which is prev template
        self.assertEqual(a_res_2.id, best_res.id)
Exemple #19
0
    def test_update_immutable_parameter_same_value(self):

        template = '''
heat_template_version: 2014-10-16
parameters:
  param1:
    type: string
    immutable: true
    default: foo
'''

        self.ctx = utils.dummy_context(password=None)
        stack_name = 'test_update_immutable_parameters'
        params = {}
        old_stack = tools.get_stack(stack_name, self.ctx,
                                    template=template)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        # prepare mocks
        self.patchobject(self.man, '_get_stack', return_value=s)
        self.patchobject(stack, 'Stack', return_value=old_stack)
        self.patchobject(stack.Stack, 'load', return_value=old_stack)
        self.patchobject(templatem, 'Template', return_value=old_stack.t)
        self.patchobject(environment, 'Environment',
                         return_value=old_stack.env)

        params = {'param1': 'foo'}
        result = self.man.update_stack(self.ctx, old_stack.identifier(),
                                       templatem.Template(template), params,
                                       None, {})
        self.assertEqual(s.id, result['stack_id'])
Exemple #20
0
 def test_purge_db_does_not_delete_previous_template_when_stack_fails(self, mock_tmpl_delete, mock_cr):
     stack = tools.get_stack(
         "test_stack", utils.dummy_context(), template=tools.string_template_five, convergence=True
     )
     stack.status = stack.FAILED
     stack.purge_db()
     self.assertFalse(mock_tmpl_delete.called)
Exemple #21
0
 def test_purge_db_deletes_previous_template(self, mock_tmpl_delete, mock_cr):
     stack = tools.get_stack(
         "test_stack", utils.dummy_context(), template=tools.string_template_five, convergence=True
     )
     stack.prev_raw_template_id = 10
     stack.purge_db()
     self.assertTrue(mock_tmpl_delete.called)
    def test_stack_validate(self):
        stack_name = 'stack_create_test_validate'
        stk = tools.get_stack(stack_name, self.ctx)

        fc = fakes_nova.FakeClient()
        self.patchobject(nova.NovaClientPlugin, '_create', return_value=fc)
        self.patchobject(glance.GlanceClientPlugin, 'get_image_id',
                         return_value=744)

        resource = stk['WebServer']
        resource.properties = properties.Properties(
            resource.properties_schema,
            {
                'ImageId': 'CentOS 5.2',
                'KeyName': 'test',
                'InstanceType': 'm1.large'
            },
            context=self.ctx)
        stk.validate()

        resource.properties = properties.Properties(
            resource.properties_schema,
            {
                'KeyName': 'test',
                'InstanceType': 'm1.large'
            },
            context=self.ctx)
        self.assertRaises(exception.StackValidationFailed, stk.validate)
    def _test_stack_create(self, stack_name, mock_validate, mock_tg):
        mock_tg.return_value = tools.DummyThreadGroup()

        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'

        stk = tools.get_stack(stack_name, self.ctx)

        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment, 'Environment',
                                    return_value=stk.env)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        result = self.man.create_stack(self.ctx, stack_name,
                                       template, params, None, {})
        self.assertEqual(stk.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result['stack_id'])

        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(self.ctx, stack_name, stk.t,
                                           owner_id=None, nested_depth=0,
                                           user_creds_id=None,
                                           stack_user_project_id=None,
                                           convergence=False,
                                           parent_resource=None)
        mock_validate.assert_called_once_with()
    def test_stack_create_invalid_stack_name(self):
        stack_name = 'service_create_test_stack_invalid_name'
        stack = tools.get_stack('test_stack', self.ctx)

        self.assertRaises(dispatcher.ExpectedException,
                          self.man.create_stack,
                          self.ctx, stack_name, stack.t.t, {}, None, {})
    def test_stack_delete_other_engine_active_lock_failed(self, mock_alive,
                                                          mock_try, mock_load):
        OTHER_ENGINE = "other-engine-fake-uuid"
        self.man.start()
        stack_name = 'service_delete_test_stack_other_engine_lock_fail'
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(stack.id, OTHER_ENGINE)

        st = stack_object.Stack.get_by_id(self.ctx, sid)
        mock_load.return_value = stack
        mock_try.return_value = OTHER_ENGINE
        mock_alive.return_value = True

        mock_call = self.patchobject(self.man, '_remote_call',
                                     return_value=False)

        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.delete_stack,
                               self.ctx, stack.identifier())
        self.assertEqual(exception.StopActionFailed, ex.exc_info[0])

        mock_load.assert_called_once_with(self.ctx, stack=st)
        mock_try.assert_called_once_with()
        mock_alive.assert_called_once_with(self.ctx, OTHER_ENGINE)
        mock_call.assert_called_once_with(self.ctx, OTHER_ENGINE, "stop_stack",
                                          stack_identity=mock.ANY)
    def test_stack_delete_other_engine_active_lock_succeeded(
            self, mock_acquire, mock_alive, mock_try, mock_load):

        OTHER_ENGINE = "other-engine-fake-uuid"
        self.man.start()
        stack_name = 'service_delete_test_stack_other_engine_lock'
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(stack.id, OTHER_ENGINE)

        st = stack_object.Stack.get_by_id(self.ctx, sid)
        mock_load.return_value = stack
        mock_try.return_value = OTHER_ENGINE
        mock_alive.return_value = True
        mock_call = self.patchobject(self.man, '_remote_call',
                                     return_value=None)

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.man.thread_group_mgr.groups[sid].wait()

        self.assertEqual(2, len(mock_load.mock_calls))
        mock_load.assert_called_with(self.ctx, stack=st)
        mock_try.assert_called_once_with()
        mock_alive.assert_called_once_with(self.ctx, OTHER_ENGINE)
        mock_call.assert_called_once_with(self.ctx, OTHER_ENGINE, "stop_stack",
                                          stack_identity=mock.ANY)
        mock_acquire.assert_called_once_with()
Exemple #27
0
    def test_update_immutable_parameter_same_value(self):

        template = """
heat_template_version: 2014-10-16
parameters:
  param1:
    type: string
    immutable: true
    default: foo
"""

        self.ctx = utils.dummy_context(password=None)
        stack_name = "test_update_immutable_parameters"
        params = {}
        old_stack = tools.get_stack(stack_name, self.ctx, template=template)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id("1234")
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        # prepare mocks
        self.patchobject(self.man, "_get_stack", return_value=s)
        self.patchobject(stack, "Stack", return_value=old_stack)
        self.patchobject(stack.Stack, "load", return_value=old_stack)
        self.patchobject(templatem, "Template", return_value=old_stack.t)
        self.patchobject(environment, "Environment", return_value=old_stack.env)

        params = {"param1": "foo"}
        result = self.man.update_stack(self.ctx, old_stack.identifier(), templatem.Template(template), params, None, {})
        self.assertEqual(s.id, result["stack_id"])
    def test_stack_delete_current_engine_active_lock(self, mock_acquire,
                                                     mock_try, mock_load):
        self.man.start()
        stack_name = 'service_delete_test_stack_current_active_lock'
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(stack.id, self.man.engine_id)

        # Create a fake ThreadGroup too
        self.man.thread_group_mgr.groups[stack.id] = tools.DummyThreadGroup()
        st = stack_object.Stack.get_by_id(self.ctx, sid)

        mock_load.return_value = stack
        mock_try.return_value = self.man.engine_id
        mock_stop = self.patchobject(self.man.thread_group_mgr, 'stop')

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))

        mock_load.assert_called_with(self.ctx, stack=st)
        self.assertEqual(2, len(mock_load.mock_calls))
        mock_try.assert_called_once_with()
        mock_acquire.assert_called_once_with()
        mock_stop.assert_called_once_with(stack.id)
    def test_conv_wordpress_single_instance_stack_create(self, mock_cr):
        stack = tools.get_stack('test_stack', utils.dummy_context(),
                                convergence=True)
        stack.store()  # usually, stack is stored before converge is called

        stack.converge_stack(template=stack.t, action=stack.CREATE)
        self.assertIsNone(stack.ext_rsrcs_db)
        self.assertEqual('Dependencies([((1, True), None)])',
                         repr(stack.convergence_dependencies))

        stack_db = stack_object.Stack.get_by_id(stack.context, stack.id)
        self.assertIsNotNone(stack_db.current_traversal)
        self.assertIsNotNone(stack_db.raw_template_id)

        self.assertIsNone(stack_db.prev_raw_template_id)

        self.assertTrue(stack_db.convergence)
        self.assertEqual({'edges': [[[1, True], None]]}, stack_db.current_deps)
        leaves = stack.convergence_dependencies.leaves()
        expected_calls = []
        for rsrc_id, is_update in leaves:
            expected_calls.append(
                mock.call.worker_client.WorkerClient.check_resource(
                    stack.context, rsrc_id, stack.current_traversal,
                    {'input_data': {}},
                    is_update, None))
        self.assertEqual(expected_calls, mock_cr.mock_calls)
    def test_migration_to_convergence_engine(self):
        self.ctx = utils.dummy_context()
        self.stack = tools.get_stack('test_stack_convg', self.ctx,
                                     template=tools.string_template_five)
        self.stack.store()
        for r in self.stack.resources.values():
            r.store()
        self.stack.migrate_to_convergence()
        self.stack = self.stack.load(self.ctx, self.stack.id)

        self.assertTrue(self.stack.convergence)
        self.assertIsNone(self.stack.prev_raw_template_id)
        exp_required_by = {'A': ['C'], 'B': ['C'], 'C': ['D', 'E'],
                           'D': [], 'E': []}
        exp_requires = {'A': [], 'B': [], 'C': ['A', 'B'], 'D': ['C'],
                        'E': ['C']}
        exp_tmpl_id = self.stack.t.id

        def id_to_name(ids):
            names = []
            for r in self.stack.resources.values():
                if r.id in ids:
                    names.append(r.name)
            return names
        for r in self.stack.resources.values():
            self.assertEqual(sorted(exp_required_by[r.name]),
                             sorted(r.required_by()))
            self.assertEqual(sorted(exp_requires[r.name]),
                             sorted(id_to_name(r.requires)))
            self.assertEqual(exp_tmpl_id, r.current_template_id)
 def test_state_set_sets_empty_curr_trvsl_for_failed_stack(
         self, mock_cr):
     stack = tools.get_stack('test_stack', utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.status = stack.FAILED
     stack.store()
     stack.purge_db()
     self.assertEqual('', stack.current_traversal)
Exemple #32
0
 def setUp(self):
     super(MiscMethodsTest, self).setUp()
     cfg.CONF.set_default('convergence_engine', True)
     self.ctx = utils.dummy_context()
     self.stack = tools.get_stack(
         'check_workflow_create_stack', self.ctx,
         template=tools.attr_cache_template, convergence=True)
     self.stack.converge_stack(self.stack.t)
     self.resource = self.stack['A']
 def test_sync_with_time_throttle(self):
     ctx = utils.dummy_context()
     stack = tools.get_stack('test_stack',
                             utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.converge_stack(stack.t, action=stack.CREATE)
     mock_sleep_time = self.sync_with_sleep(ctx, stack)
     mock_sleep_time.assert_called_once_with(mock.ANY)
    def test_stack_update_no_credentials(self):
        cfg.CONF.set_default('deferred_auth_method', 'password')
        stack_name = 'test_stack_update_no_credentials'
        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'

        stk = tools.get_stack(stack_name, self.ctx)
        # force check for credentials on create
        stk['WebServer'].requires_deferred_auth = True

        sid = stk.store()
        stk.set_stack_user_project_id('1234')
        s = stack_object.Stack.get_by_id(self.ctx, sid)

        self.ctx = utils.dummy_context(password=None)

        # prepare mocks
        mock_get = self.patchobject(self.man, '_get_stack', return_value=s)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        mock_load = self.patchobject(stack.Stack, 'load', return_value=stk)
        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment,
                                    'Environment',
                                    return_value=stk.env)

        api_args = {'timeout_mins': 60}
        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.update_stack, self.ctx,
                               stk.identifier(), template, params, None,
                               api_args)
        self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
        self.assertEqual('Missing required credential: X-Auth-Key',
                         six.text_type(ex.exc_info[1]))

        mock_get.assert_called_once_with(self.ctx, stk.identifier())

        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(
            self.ctx,
            stk.name,
            stk.t,
            convergence=False,
            current_traversal=stk.current_traversal,
            prev_raw_template_id=None,
            current_deps=None,
            disable_rollback=True,
            nested_depth=0,
            owner_id=None,
            parent_resource=None,
            stack_user_project_id='1234',
            strict_validate=True,
            tenant_id='test_tenant_id',
            timeout_mins=60,
            user_creds_id=u'1',
            username='******')
        mock_load.assert_called_once_with(self.ctx, stack=s)
Exemple #35
0
 def test_purge_db_deletes_previous_template(self, mock_tmpl_delete,
                                             mock_cr):
     stack = tools.get_stack('test_stack',
                             utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.prev_raw_template_id = 10
     stack.purge_db()
     self.assertTrue(mock_tmpl_delete.called)
Exemple #36
0
 def test_mark_complete_purges_db(self, mock_cr):
     stack = tools.get_stack('test_stack',
                             utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.store()
     stack.purge_db = mock.Mock()
     stack.mark_complete()
     self.assertTrue(stack.purge_db.called)
Exemple #37
0
 def test_purge_db_calls_rsrc_purge_deleted(self, mock_rsrc_purge_delete,
                                            mock_cr):
     stack = tools.get_stack('test_stack',
                             utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.store()
     stack.purge_db()
     self.assertTrue(mock_rsrc_purge_delete.called)
 def test_purge_db_deletes_sync_points(self, mock_cr):
     stack = tools.get_stack('test_stack', utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.store()
     stack.purge_db()
     rows = sync_point_object.SyncPoint.delete_all_by_stack_and_traversal(
         stack.context, stack.id, stack.current_traversal)
     self.assertEqual(0, rows)
Exemple #39
0
 def test_purge_db_deletes_stack_for_deleted_stack(self, mock_stack_delete,
                                                   mock_cr):
     stack = tools.get_stack('test_stack', utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.store()
     stack.state_set(stack.DELETE, stack.COMPLETE, 'test reason')
     stack.purge_db()
     self.assertTrue(mock_stack_delete.called)
Exemple #40
0
    def test_validate_deferred_auth_context_not_required(self):
        stk = tools.get_stack('test_deferred_auth', self.ctx)
        stk['WebServer'].requires_deferred_auth = False
        ctx = utils.dummy_context(user=None, password=None)
        cfg.CONF.set_default('deferred_auth_method', 'password')

        # stack performs no deferred operations, so no username or
        # password required
        self.man._validate_deferred_auth_context(ctx, stk)
Exemple #41
0
 def test_purge_db_does_not_delete_previous_template_when_stack_fails(
         self, mock_tmpl_delete, mock_cr):
     stack = tools.get_stack('test_stack',
                             utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     stack.status = stack.FAILED
     stack.purge_db()
     self.assertFalse(mock_tmpl_delete.called)
Exemple #42
0
 def test_stack_create_authorization_failure(self, mock_create):
     stack_name = 'stack_create_authorization_failure'
     stk = tools.get_stack(stack_name, self.ctx)
     mock_create.side_effect = exception.AuthorizationFailure
     ex = self.assertRaises(dispatcher.ExpectedException,
                            self.man.create_stack,
                            self.ctx, stack_name,
                            stk.t.t, {}, None, {})
     self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
Exemple #43
0
    def test_conv_string_five_instance_stack_create(self, mock_cr):
        stack = tools.get_stack('test_stack', utils.dummy_context(),
                                template=tools.string_template_five,
                                convergence=True)
        stack.store()
        stack.converge_stack(template=stack.t, action=stack.CREATE)
        self.assertIsNone(stack.ext_rsrcs_db)
        self.assertEqual('Dependencies(['
                         '((1, True), (3, True)), '
                         '((2, True), (3, True)), '
                         '((3, True), (4, True)), '
                         '((3, True), (5, True))])',
                         repr(stack.convergence_dependencies))

        stack_db = stack_object.Stack.get_by_id(stack.context, stack.id)
        self.assertIsNotNone(stack_db.current_traversal)
        self.assertIsNotNone(stack_db.raw_template_id)
        self.assertIsNone(stack_db.prev_raw_template_id)
        self.assertTrue(stack_db.convergence)
        self.assertEqual(sorted([[[3, True], [5, True]],    # C, A
                                 [[3, True], [4, True]],    # C, B
                                 [[1, True], [3, True]],    # E, C
                                 [[2, True], [3, True]]]),  # D, C
                         sorted(stack_db.current_deps['edges']))

        # check if needed_by is stored properly
        expected_needed_by = {'A': [3], 'B': [3],
                              'C': [1, 2],
                              'D': [], 'E': []}
        rsrcs_db = resource_objects.Resource.get_all_by_stack(
            stack_db._context, stack_db.id
        )
        self.assertEqual(5, len(rsrcs_db))
        for rsrc_name, rsrc_obj in rsrcs_db.items():
            self.assertEqual(sorted(expected_needed_by[rsrc_name]),
                             sorted(rsrc_obj.needed_by))
            self.assertEqual(stack_db.raw_template_id,
                             rsrc_obj.current_template_id)

        # check if sync_points were stored
        for entity_id in [5, 4, 3, 2, 1, stack_db.id]:
            sync_point = sync_point_object.SyncPoint.get_by_key(
                stack_db._context, entity_id, stack_db.current_traversal, True
            )
            self.assertIsNotNone(sync_point)
            self.assertEqual(stack_db.id, sync_point.stack_id)

        leaves = stack.convergence_dependencies.leaves()
        expected_calls = []
        for rsrc_id, is_update in leaves:
            expected_calls.append(
                mock.call.worker_client.WorkerClient.check_resource(
                    stack.context, rsrc_id, stack.current_traversal,
                    {'input_data': {}},
                    is_update, None))
        self.assertEqual(expected_calls, mock_cr.mock_calls)
Exemple #44
0
    def test_stack_create_no_credentials(self):
        cfg.CONF.set_default('deferred_auth_method', 'password')
        stack_name = 'test_stack_create_no_credentials'
        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'

        stk = tools.get_stack(stack_name, self.ctx)
        # force check for credentials on create
        stk['WebServer'].requires_deferred_auth = True

        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment, 'Environment',
                                    return_value=stk.env)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)

        # test stack create using context without password
        ctx_no_pwd = utils.dummy_context(password=None)
        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.create_stack,
                               ctx_no_pwd, stack_name,
                               template, params, None, {}, None)
        self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
        self.assertEqual('Missing required credential: X-Auth-Key',
                         six.text_type(ex.exc_info[1]))

        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(ctx_no_pwd, stack_name, stk.t,
                                           owner_id=None, nested_depth=0,
                                           user_creds_id=None,
                                           stack_user_project_id=None,
                                           convergence=False,
                                           parent_resource=None)
        mock_tmpl.reset_mock()
        mock_env.reset_mock()
        mock_stack.reset_mock()

        # test stack create using context without user
        ctx_no_pwd = utils.dummy_context(password=None)
        ctx_no_user = utils.dummy_context(user=None)
        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.create_stack,
                               ctx_no_user, stack_name,
                               template, params, None, {})
        self.assertEqual(exception.MissingCredentialError, ex.exc_info[0])
        self.assertEqual('Missing required credential: X-Auth-User',
                         six.text_type(ex.exc_info[1]))

        mock_tmpl.assert_called_once_with(template, files=None, env=stk.env)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(ctx_no_user, stack_name, stk.t,
                                           owner_id=None, nested_depth=0,
                                           user_creds_id=None,
                                           stack_user_project_id=None,
                                           convergence=False,
                                           parent_resource=None)
Exemple #45
0
    def test_stack_update_nonexist(self):
        stack_name = 'service_update_nonexist_test_stack'
        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'
        stk = tools.get_stack(stack_name, self.ctx)

        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.update_stack, self.ctx,
                               stk.identifier(), template, params, None, {})
        self.assertEqual(exception.EntityNotFound, ex.exc_info[0])
Exemple #46
0
    def test_stack_create_nested(self, mock_validate, mock_tg):
        convergence_engine = cfg.CONF.convergence_engine
        stack_name = 'service_create_nested_test_stack'
        parent_stack = tools.get_stack(stack_name + '_parent', self.ctx)
        owner_id = parent_stack.store()
        mock_tg.return_value = tools.DummyThreadGroup()

        stk = tools.get_stack(stack_name,
                              self.ctx,
                              with_params=True,
                              owner_id=owner_id,
                              nested_depth=1)
        tmpl_id = stk.t.store(self.ctx)

        mock_load = self.patchobject(templatem.Template,
                                     'load',
                                     return_value=stk.t)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        result = self.man.create_stack(self.ctx,
                                       stack_name,
                                       None,
                                       None,
                                       None, {},
                                       owner_id=owner_id,
                                       nested_depth=1,
                                       template_id=tmpl_id)
        self.assertEqual(stk.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result['stack_id'])

        mock_load.assert_called_once_with(self.ctx, tmpl_id)
        mock_stack.assert_called_once_with(self.ctx,
                                           stack_name,
                                           stk.t,
                                           owner_id=owner_id,
                                           nested_depth=1,
                                           user_creds_id=None,
                                           stack_user_project_id=None,
                                           convergence=convergence_engine,
                                           parent_resource=None)

        mock_validate.assert_called_once_with(validate_resources=False)
Exemple #47
0
    def _stack_create(self, stack_name):
        self.patchobject(keystone.KeystoneClientPlugin, '_create',
                         return_value=fake_ks.FakeKeystoneClient())

        stk = tools.get_stack(stack_name, self.ctx, policy_template)
        stk.store()
        stk.create()

        s = stack_object.Stack.get_by_id(self.ctx, stk.id)
        self.patchobject(service.EngineService, '_get_stack', return_value=s)
        return stk
Exemple #48
0
 def test_purge_db_deletes_creds(self, mock_delete_stack,
                                 mock_creds_delete, mock_cr):
     stack = tools.get_stack('test_stack', utils.dummy_context(),
                             template=tools.string_template_five,
                             convergence=True)
     reason = 'stack delete complete'
     mock_creds_delete.return_value = (stack.COMPLETE, reason)
     stack.state_set(stack.DELETE, stack.COMPLETE, reason)
     stack.purge_db()
     self.assertTrue(mock_creds_delete.called)
     self.assertTrue(mock_delete_stack.called)
Exemple #49
0
    def test_stack_create_invalid_resource_name(self):
        stack_name = 'stack_create_invalid_resource_name'
        stk = tools.get_stack(stack_name, self.ctx)
        tmpl = dict(stk.t)
        tmpl['resources']['Web/Server'] = tmpl['resources']['WebServer']
        del tmpl['resources']['WebServer']

        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.create_stack, self.ctx, stack_name,
                               stk.t.t, {}, None, {})
        self.assertEqual(exception.StackValidationFailed, ex.exc_info[0])
Exemple #50
0
    def test_stack_delete(self, mock_load):
        stack_name = 'service_delete_test_stack'
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()
        mock_load.return_value = stack

        s = stack_object.Stack.get_by_id(self.ctx, sid)

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.man.thread_group_mgr.groups[sid].wait()
        mock_load.assert_called_once_with(self.ctx, stack=s)
Exemple #51
0
    def test_stack_cancel_update_wrong_state_fails(self):
        stack_name = 'service_update_cancel_test_stack'
        stk = tools.get_stack(stack_name, self.ctx)
        stk.state_set(stk.UPDATE, stk.COMPLETE, 'test_override')
        stk.store()
        self.patchobject(stack.Stack, 'load', return_value=stk)

        ex = self.assertRaises(dispatcher.ExpectedException,
                               self.man.stack_cancel_update, self.ctx,
                               stk.identifier())

        self.assertEqual(exception.NotSupported, ex.exc_info[0])
        self.assertIn("Cancelling update when stack is "
                      "UPDATE_COMPLETE", six.text_type(ex.exc_info[1]))
Exemple #52
0
    def test_purge_db_deletes_creds_failed(self, mock_delete_stack,
                                           mock_creds_delete, mock_cr):
        stack = tools.get_stack('test_stack', utils.dummy_context(),
                                template=tools.string_template_five,
                                convergence=True)

        reason = 'stack delete complete'
        failed_reason = 'Error deleting trust'
        mock_creds_delete.return_value = (stack.FAILED, failed_reason)
        stack.state_set(stack.DELETE, stack.COMPLETE, reason)
        stack.purge_db()
        self.assertTrue(mock_creds_delete.called)
        self.assertFalse(mock_delete_stack.called)
        self.assertEqual((stack.DELETE, stack.FAILED), stack.state)
Exemple #53
0
    def test_stack_update_with_environment_files(self):
        # Setup
        stack_name = 'service_update_env_files_stack'
        params = {}
        template = '{ "Template": "data" }'
        old_stack = tools.get_stack(stack_name, self.ctx)
        sid = old_stack.store()
        old_stack.set_stack_user_project_id('1234')
        stack_object.Stack.get_by_id(self.ctx, sid)

        stk = tools.get_stack(stack_name, self.ctx)

        # prepare mocks
        self.patchobject(stack, 'Stack', return_value=stk)
        self.patchobject(stack.Stack, 'load', return_value=old_stack)
        self.patchobject(templatem, 'Template', return_value=stk.t)
        self.patchobject(environment, 'Environment', return_value=stk.env)
        self.patchobject(stk, 'validate', return_value=None)
        self.patchobject(eventlet.queue,
                         'LightQueue',
                         return_value=mock.Mock())

        mock_merge = self.patchobject(env_util, 'merge_environments')

        # Test
        environment_files = ['env_1']
        self.man.update_stack(self.ctx,
                              old_stack.identifier(),
                              template,
                              params,
                              None, {},
                              environment_files=environment_files)

        # Verify
        mock_merge.assert_called_once_with(environment_files, None, params,
                                           mock.ANY)
 def setUp(self):
     super(CheckWorkflowUpdateTest, self).setUp()
     thread_group_mgr = mock.Mock()
     self.worker = worker.WorkerService('host-1',
                                        'topic-1',
                                        'engine_id',
                                        thread_group_mgr)
     self.worker._rpc_client = worker_client.WorkerClient()
     self.ctx = utils.dummy_context()
     self.stack = tools.get_stack(
         'check_workflow_create_stack', self.ctx,
         template=tools.string_template_five, convergence=True)
     self.stack.converge_stack(self.stack.t)
     self.resource = self.stack['A']
     self.is_update = True
     self.graph_key = (self.resource.id, self.is_update)
    def test_stack_cancel_update_no_lock(self):
        stack_name = 'service_update_stack_test_cancel_same_engine'
        stk = tools.get_stack(stack_name, self.ctx)
        stk.state_set(stk.UPDATE, stk.IN_PROGRESS, 'test_override')
        stk.disable_rollback = False
        stk.store()

        self.patchobject(stack.Stack, 'load', return_value=stk)
        self.patchobject(stack_lock.StackLock, 'get_engine_id',
                         return_value=None)
        self.patchobject(self.man.thread_group_mgr, 'send')

        self.man.stack_cancel_update(self.ctx, stk.identifier(),
                                     cancel_with_rollback=False)

        self.assertFalse(self.man.thread_group_mgr.send.called)
Exemple #56
0
    def test_stack_delete_other_engine_active_lock_succeeded(
            self, mock_expired, mock_acquire, mock_alive, mock_try, mock_load):
        cfg.CONF.set_override('error_wait_time', 0)

        OTHER_ENGINE = "other-engine-fake-uuid"
        self.man.engine_id = service_utils.generate_engine_id()
        self.man.listener = service.EngineListener(self.man.host,
                                                   self.man.engine_id,
                                                   self.man.thread_group_mgr)
        stack_name = 'service_delete_test_stack_other_engine_lock'
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()

        # Insert a fake lock into the db
        stack_lock_object.StackLock.create(self.ctx, stack.id, OTHER_ENGINE)

        st = stack_object.Stack.get_by_id(self.ctx, sid)
        mock_load.return_value = stack
        mock_try.return_value = OTHER_ENGINE
        mock_alive.return_value = True
        mock_expired.side_effect = [False, True]
        mock_call = self.patchobject(self.man,
                                     '_remote_call',
                                     return_value=None)

        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.man.thread_group_mgr.stop(sid, graceful=True)

        self.assertEqual(2, len(mock_load.mock_calls))
        mock_load.assert_called_with(self.ctx, stack=st)
        mock_try.assert_called_with()
        mock_alive.assert_called_with(self.ctx, OTHER_ENGINE)
        mock_call.assert_has_calls([
            mock.call(self.ctx,
                      OTHER_ENGINE,
                      mock.ANY,
                      "send",
                      message='cancel',
                      stack_identity=mock.ANY),
            mock.call(self.ctx,
                      OTHER_ENGINE,
                      mock.ANY,
                      "stop_stack",
                      stack_identity=mock.ANY)
        ])
        mock_acquire.assert_called_once_with(True)
Exemple #57
0
 def setUp(self):
     super(CheckWorkflowCleanupTest, self).setUp()
     thread_group_mgr = mock.Mock()
     self.worker = worker.WorkerService('host-1', 'topic-1', 'engine_id',
                                        thread_group_mgr)
     self.worker._rpc_client = worker_client.WorkerClient()
     self.ctx = utils.dummy_context()
     tstack = tools.get_stack('check_workflow_create_stack',
                              self.ctx,
                              template=tools.string_template_five,
                              convergence=True)
     tstack.converge_stack(tstack.t, action=tstack.CREATE)
     self.stack = stack.Stack.load(self.ctx, stack_id=tstack.id)
     self.stack.converge_stack(self.stack.t, action=self.stack.DELETE)
     self.resource = self.stack['A']
     self.is_update = False
     self.graph_key = (self.resource.id, self.is_update)
Exemple #58
0
    def _test_stack_create(self,
                           stack_name,
                           mock_validate,
                           mock_tg,
                           environment_files=None):
        mock_tg.return_value = tools.DummyThreadGroup()

        params = {'foo': 'bar'}
        template = '{ "Template": "data" }'

        stk = tools.get_stack(stack_name, self.ctx)

        mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t)
        mock_env = self.patchobject(environment,
                                    'Environment',
                                    return_value=stk.env)
        mock_stack = self.patchobject(stack, 'Stack', return_value=stk)
        mock_merge = self.patchobject(env_util, 'merge_environments')
        result = self.man.create_stack(self.ctx,
                                       stack_name,
                                       template,
                                       params,
                                       None, {},
                                       environment_files=environment_files)
        self.assertEqual(stk.identifier(), result)
        self.assertIsInstance(result, dict)
        self.assertTrue(result['stack_id'])

        mock_tmpl.assert_called_once_with(template, files=None)
        mock_env.assert_called_once_with(params)
        mock_stack.assert_called_once_with(
            self.ctx,
            stack_name,
            stk.t,
            owner_id=None,
            nested_depth=0,
            user_creds_id=None,
            stack_user_project_id=None,
            convergence=cfg.CONF.convergence_engine,
            parent_resource=None)

        if environment_files:
            mock_merge.assert_called_once_with(environment_files, None, params,
                                               mock.ANY)
        mock_validate.assert_called_once_with(validate_resources=True)
    def test_validate_deferred_auth_context_missing_credentials(self):
        stk = tools.get_stack('test_deferred_auth', self.ctx)
        stk['WebServer'].requires_deferred_auth = True
        cfg.CONF.set_default('deferred_auth_method', 'password')

        # missing username
        ctx = utils.dummy_context(user=None)
        ex = self.assertRaises(exception.MissingCredentialError,
                               self.man._validate_deferred_auth_context, ctx,
                               stk)
        self.assertEqual('Missing required credential: X-Auth-User', str(ex))

        # missing password
        ctx = utils.dummy_context(password=None)
        ex = self.assertRaises(exception.MissingCredentialError,
                               self.man._validate_deferred_auth_context, ctx,
                               stk)
        self.assertEqual('Missing required credential: X-Auth-Key', str(ex))
Exemple #60
0
    def test_stack_delete_acquired_lock_stop_timers(self, mock_acquire,
                                                    mock_load):
        mock_acquire.return_value = self.man.engine_id
        stack_name = 'service_delete_test_stack_stop_timers'
        stack = tools.get_stack(stack_name, self.ctx)
        sid = stack.store()
        mock_load.return_value = stack
        st = stack_object.Stack.get_by_id(self.ctx, sid)

        self.man.thread_group_mgr.add_timer(stack.id, 'test')

        self.assertEqual(1, len(self.man.thread_group_mgr.groups[sid].timers))
        self.assertIsNone(self.man.delete_stack(self.ctx, stack.identifier()))
        self.assertEqual(0, len(self.man.thread_group_mgr.groups[sid].timers))

        self.man.thread_group_mgr.groups[sid].wait()

        mock_acquire.assert_called_once_with()
        mock_load.assert_called_once_with(self.ctx, stack=st)