コード例 #1
0
ファイル: base.py プロジェクト: bharaththiruveedula/tacker
    def delete(self, request, id, **kwargs):
        """Deletes the specified entity."""
        self._notifier.info(request.context,
                            self._resource + '.delete.start',
                            {self._resource + '_id': id})
        action = self._plugin_handlers[self.DELETE]

        # Check authz
        policy.init()
        parent_id = kwargs.get(self._parent_id_name)
        obj = self._item(request, id, parent_id=parent_id)
        try:
            policy.enforce(request.context,
                           action,
                           obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_deleter = getattr(self._plugin, action)
        obj_deleter(request.context, id, **kwargs)
        notifier_method = self._resource + '.delete.end'
        self._notifier.info(request.context,
                            notifier_method,
                            {self._resource + '_id': id})
コード例 #2
0
ファイル: test_policy.py プロジェクト: trozet/tacker
 def _test_enforce_tenant_id_raises(self, bad_rule):
     self.rules["admin_or_owner"] = common_policy.parse_rule(bad_rule)
     # Trigger a policy with rule admin_or_owner
     action = "create_network"
     target = {"tenant_id": "fake"}
     policy.init()
     self.assertRaises(exceptions.PolicyCheckError, policy.enforce, self.context, action, target)
コード例 #3
0
ファイル: test_policy.py プロジェクト: openstack/tacker
    def setUp(self):
        super(TackerPolicyTestCase, self).setUp()
        self.skipTest("Not ready yet")
        policy.reset()
        policy.init()
        self.addCleanup(policy.reset)
        self.admin_only_legacy = "role:admin"
        self.admin_or_owner_legacy = "role:admin or tenant_id:%(tenant_id)s"
        # Add a Fake 'something' resource to RESOURCE_ATTRIBUTE_MAP
        attributes.RESOURCE_ATTRIBUTE_MAP.update(FAKE_RESOURCE)
        self.rules = dict((k, common_policy.parse_rule(v)) for k, v in {
            "context_is_admin": "role:admin",
            "admin_or_network_owner": "rule:context_is_admin or "
                                      "tenant_id:%(network:tenant_id)s",
            "admin_or_owner": ("rule:context_is_admin or "
                               "tenant_id:%(tenant_id)s"),
            "admin_only": "rule:context_is_admin",
            "regular_user": "******",
            "shared": "field:networks:shared=True",
            "external": "field:networks:router:external=True",
            "default": '@',

            "create_network": "rule:admin_or_owner",
            "create_network:shared": "rule:admin_only",
            "update_network": '@',
            "update_network:shared": "rule:admin_only",

            "get_network": "rule:admin_or_owner or "
                           "rule:shared or "
                           "rule:external",
            "create_port:mac": "rule:admin_or_network_owner",
            "create_something": "rule:admin_or_owner",
            "create_something:attr": "rule:admin_or_owner",
            "create_something:attr:sub_attr_1": "rule:admin_or_owner",
            "create_something:attr:sub_attr_2": "rule:admin_only",

            "get_firewall_policy": "rule:admin_or_owner or "
                            "rule:shared",
            "get_firewall_rule": "rule:admin_or_owner or "
                            "rule:shared"
        }.items())

        def fakepolicyinit():
            common_policy.set_rules(common_policy.Rules(self.rules))

        def remove_fake_resource():
            del attributes.RESOURCE_ATTRIBUTE_MAP["%ss" % FAKE_RESOURCE_NAME]

        self.patcher = mock.patch.object(tacker.policy,
                                         'init',
                                         new=fakepolicyinit)
        self.patcher.start()
        self.addCleanup(remove_fake_resource)
        self.context = context.Context('fake', 'fake', roles=['user'])
        plugin_klass = importutils.import_class(
            "tacker.db.db_base_plugin_v2.TackerDbPluginV2")
        self.manager_patcher = mock.patch('tacker.manager.TackerManager')
        fake_manager = self.manager_patcher.start()
        fake_manager_instance = fake_manager.return_value
        fake_manager_instance.plugin = plugin_klass()
コード例 #4
0
ファイル: test_policy.py プロジェクト: trozet/tacker
    def setUp(self):
        super(DefaultPolicyTestCase, self).setUp()
        policy.reset()
        policy.init()
        self.addCleanup(policy.reset)

        self.rules = {"default": "", "example:exist": "!"}

        self._set_rules("default")

        self.context = context.Context("fake", "fake")
コード例 #5
0
ファイル: base.py プロジェクト: bharaththiruveedula/tacker
    def create(self, request, body=None, **kwargs):
        """Creates a new instance of the requested entity."""
        parent_id = kwargs.get(self._parent_id_name)
        self._notifier.info(request.context,
                            self._resource + '.create.start',
                            body)
        body = Controller.prepare_request_body(request.context, body, True,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.CREATE]
        # Check authz
        if self._collection in body:
            # Have to account for bulk create
            items = body[self._collection]
        else:
            items = [body]
        # Ensure policy engine is initialized
        policy.init()
        for item in items:
            policy.enforce(request.context,
                           action,
                           item[self._resource])

        def notify(create_result):
            notifier_method = self._resource + '.create.end'
            self._notifier.info(request.context,
                                notifier_method,
                                create_result)
            return create_result

        kwargs = {self._parent_id_name: parent_id} if parent_id else {}
        if self._collection in body and self._native_bulk:
            # plugin does atomic bulk create operations
            obj_creator = getattr(self._plugin, "%s_bulk" % action)
            objs = obj_creator(request.context, body, **kwargs)
            # Use first element of list to discriminate attributes which
            # should be removed because of authZ policies
            fields_to_strip = self._exclude_attributes_by_policy(
                request.context, objs[0])
            return notify({self._collection: [self._filter_attributes(
                request.context, obj, fields_to_strip=fields_to_strip)
                for obj in objs]})
        else:
            obj_creator = getattr(self._plugin, action)
            if self._collection in body:
                # Emulate atomic bulk behavior
                objs = self._emulate_bulk_create(obj_creator, request,
                                                 body, parent_id)
                return notify({self._collection: objs})
            else:
                kwargs.update({self._resource: body})
                obj = obj_creator(request.context, **kwargs)
                return notify({self._resource: self._view(request.context,
                                                          obj)})
コード例 #6
0
    def setUp(self):
        super(DefaultPolicyTestCase, self).setUp()
        policy.reset()
        policy.init()
        self.addCleanup(policy.reset)

        self.rules = {
            "default": '',
            "example:exist": '!',
        }

        self._set_rules('default')

        self.context = context.Context('fake', 'fake')
コード例 #7
0
ファイル: base.py プロジェクト: openstack/tacker
    def update(self, request, id, body=None, **kwargs):
        """Updates the specified entity's attributes."""
        parent_id = kwargs.get(self._parent_id_name)
        try:
            payload = body.copy()
        except AttributeError:
            msg = _("Invalid format: %s") % request.body
            raise exceptions.BadRequest(resource='body', msg=msg)
        payload['id'] = id
        self._notifier.info(request.context,
                            self._resource + '.update.start',
                            payload)
        body = Controller.prepare_request_body(request.context, body, False,
                                               self._resource, self._attr_info,
                                               allow_bulk=self._allow_bulk)
        action = self._plugin_handlers[self.UPDATE]
        # Load object to check authz
        # but pass only attributes in the original body and required
        # by the policy engine to the policy 'brain'
        field_list = [name for (name, value) in (self._attr_info).items()
                      if (value.get('required_by_policy') or
                          value.get('primary_key') or
                          'default' not in value)]
        # Ensure policy engine is initialized
        policy.init()
        orig_obj = self._item(request, id, field_list=field_list,
                              parent_id=parent_id)
        orig_obj.update(body[self._resource])
        attribs = attributes.ATTRIBUTES_TO_UPDATE
        orig_obj[attribs] = body[self._resource].keys()
        try:
            policy.enforce(request.context,
                           action,
                           orig_obj)
        except exceptions.PolicyNotAuthorized:
            # To avoid giving away information, pretend that it
            # doesn't exist
            msg = _('The resource could not be found.')
            raise webob.exc.HTTPNotFound(msg)

        obj_updater = getattr(self._plugin, action)
        kwargs = {self._resource: body}
        if parent_id:
            kwargs[self._parent_id_name] = parent_id
        obj = obj_updater(request.context, id, **kwargs)
        result = {self._resource: self._view(request.context, obj)}
        notifier_method = self._resource + '.update.end'
        self._notifier.info(request.context, notifier_method, result)
        return result
コード例 #8
0
ファイル: base.py プロジェクト: bharaththiruveedula/tacker
 def _handle_action(request, id, **kwargs):
     arg_list = [request.context, id]
     # Ensure policy engine is initialized
     policy.init()
     # Fetch the resource and verify if the user can access it
     try:
         resource = self._item(request, id, True)
     except exceptions.PolicyNotAuthorized:
         msg = _('The resource could not be found.')
         raise webob.exc.HTTPNotFound(msg)
     body = kwargs.pop('body', None)
     # Explicit comparison with None to distinguish from {}
     if body is not None:
         arg_list.append(body)
     # It is ok to raise a 403 because accessibility to the
     # object was checked earlier in this method
     policy.enforce(request.context, name, resource)
     return getattr(self._plugin, name)(*arg_list, **kwargs)
コード例 #9
0
ファイル: test_policy.py プロジェクト: trozet/tacker
    def test_modified_policy_reloads(self):
        def fake_find_config_file(_1, _2):
            return self.tempdir.join("policy")

        with mock.patch.object(tacker.common.utils, "find_config_file", new=fake_find_config_file):
            tmpfilename = fake_find_config_file(None, None)
            action = "example:test"
            with open(tmpfilename, "w") as policyfile:
                policyfile.write("""{"example:test": ""}""")
            policy.init()
            policy.enforce(self.context, action, self.target)
            with open(tmpfilename, "w") as policyfile:
                policyfile.write("""{"example:test": "!"}""")
            # NOTE(vish): reset stored policy cache so we don't have to
            # sleep(1)
            policy._POLICY_CACHE = {}
            policy.init()
            self.assertRaises(exceptions.PolicyNotAuthorized, policy.enforce, self.context, action, self.target)
コード例 #10
0
ファイル: test_policy.py プロジェクト: trozet/tacker
 def setUp(self):
     super(PolicyTestCase, self).setUp()
     policy.reset()
     self.addCleanup(policy.reset)
     # NOTE(vish): preload rules to circumvent reloading from file
     policy.init()
     rules = {
         "true": "@",
         "example:allowed": "@",
         "example:denied": "!",
         "example:get_http": "http:http://www.example.com",
         "example:my_file": "role:compute_admin or tenant_id:%(tenant_id)s",
         "example:early_and_fail": "! and @",
         "example:early_or_success": "@ or !",
         "example:lowercase_admin": "role:admin or role:sysadmin",
         "example:uppercase_admin": "role:ADMIN or role:sysadmin",
     }
     # NOTE(vish): then overload underlying rules
     common_policy.set_rules(common_policy.Rules(dict((k, common_policy.parse_rule(v)) for k, v in rules.items())))
     self.context = context.Context("fake", "fake", roles=["member"])
     self.target = {}
コード例 #11
0
ファイル: test_policy.py プロジェクト: shuwenCai/tacker
    def test_modified_policy_reloads(self):
        def fake_find_config_file(_1, _2):
            return self.tempdir.join('policy')

        with mock.patch.object(tacker.common.utils,
                               'find_config_file',
                               new=fake_find_config_file):
            tmpfilename = fake_find_config_file(None, None)
            action = "example:test"
            with open(tmpfilename, "w") as policyfile:
                policyfile.write("""{"example:test": ""}""")
            policy.init()
            policy.enforce(self.context, action, self.target)
            with open(tmpfilename, "w") as policyfile:
                policyfile.write("""{"example:test": "!"}""")
            # NOTE(vish): reset stored policy cache so we don't have to
            # sleep(1)
            policy._POLICY_CACHE = {}
            policy.init()
            self.assertRaises(exceptions.PolicyNotAuthorized,
                              policy.enforce,
                              self.context,
                              action,
                              self.target)
コード例 #12
0
ファイル: test_policy.py プロジェクト: paperandsoap/tacker
 def setUp(self):
     super(PolicyTestCase, self).setUp()
     policy.reset()
     self.addCleanup(policy.reset)
     # NOTE(vish): preload rules to circumvent reloading from file
     policy.init()
     rules = {
         "true": '@',
         "example:allowed": '@',
         "example:denied": '!',
         "example:get_http": "http:http://www.example.com",
         "example:my_file": "role:compute_admin or tenant_id:%(tenant_id)s",
         "example:early_and_fail": "! and @",
         "example:early_or_success": "@ or !",
         "example:lowercase_admin": "role:admin or role:sysadmin",
         "example:uppercase_admin": "role:ADMIN or role:sysadmin",
     }
     # NOTE(vish): then overload underlying rules
     common_policy.set_rules(
         common_policy.Rules(
             dict((k, common_policy.parse_rule(v))
                  for k, v in rules.items())))
     self.context = context.Context('fake', 'fake', roles=['member'])
     self.target = {}
コード例 #13
0
ファイル: base.py プロジェクト: vutuong/tacker
 def show(self, request, id, **kwargs):
     """Returns detailed information about the requested entity."""
     try:
         # NOTE(salvatore-orlando): The following ensures that fields
         # which are needed for authZ policy validation are not stripped
         # away by the plugin before returning.
         field_list, added_fields = self._do_field_list(
             api_common.list_args(request, "fields"))
         parent_id = kwargs.get(self._parent_id_name)
         # Ensure policy engine is initialized
         policy.init()
         return {self._resource:
                 self._view(request.context,
                            self._item(request,
                                       id,
                                       do_authz=True,
                                       field_list=field_list,
                                       parent_id=parent_id),
                            fields_to_strip=added_fields)}
     except exceptions.PolicyNotAuthorized:
         # To avoid giving away information, pretend that it
         # doesn't exist
         msg = _('The resource could not be found.')
         raise webob.exc.HTTPNotFound(msg)
コード例 #14
0
ファイル: base.py プロジェクト: bharaththiruveedula/tacker
 def show(self, request, id, **kwargs):
     """Returns detailed information about the requested entity."""
     try:
         # NOTE(salvatore-orlando): The following ensures that fields
         # which are needed for authZ policy validation are not stripped
         # away by the plugin before returning.
         field_list, added_fields = self._do_field_list(
             api_common.list_args(request, "fields"))
         parent_id = kwargs.get(self._parent_id_name)
         # Ensure policy engine is initialized
         policy.init()
         return {self._resource:
                 self._view(request.context,
                            self._item(request,
                                       id,
                                       do_authz=True,
                                       field_list=field_list,
                                       parent_id=parent_id),
                            fields_to_strip=added_fields)}
     except exceptions.PolicyNotAuthorized:
         # To avoid giving away information, pretend that it
         # doesn't exist
         msg = _('The resource could not be found.')
         raise webob.exc.HTTPNotFound(msg)
コード例 #15
0
 def index(self, request, **kwargs):
     """Returns a list of the requested entity."""
     parent_id = kwargs.get(self._parent_id_name)
     # Ensure policy engine is initialized
     policy.init()
     return self._items(request, True, parent_id)
コード例 #16
0
ファイル: base.py プロジェクト: bharaththiruveedula/tacker
 def index(self, request, **kwargs):
     """Returns a list of the requested entity."""
     parent_id = kwargs.get(self._parent_id_name)
     # Ensure policy engine is initialized
     policy.init()
     return self._items(request, True, parent_id)
コード例 #17
0
ファイル: base.py プロジェクト: vutuong/tacker
    def setUp(self):
        super(BaseTestCase, self).setUp()

        # Ensure plugin cleanup is triggered last so that
        # test-specific cleanup has a chance to release references.
        self.addCleanup(self.cleanup_core_plugin)

        # Configure this first to ensure pm debugging support for setUp()
        if os.environ.get('OS_POST_MORTEM_DEBUG') in TRUE_STRING:
            self.addOnException(post_mortem_debug.exception_handler)

        if os.environ.get('OS_DEBUG') in TRUE_STRING:
            _level = logging.DEBUG
        else:
            _level = logging.INFO
        capture_logs = os.environ.get('OS_LOG_CAPTURE') in TRUE_STRING
        if not capture_logs:
            logging.basicConfig(format=LOG_FORMAT, level=_level)
        self.log_fixture = self.useFixture(
            fixtures.FakeLogger(
                format=LOG_FORMAT,
                level=_level,
                nuke_handlers=capture_logs,
            ))

        # suppress all but errors here
        self.useFixture(
            fixtures.FakeLogger(
                name='tacker.api.extensions',
                format=LOG_FORMAT,
                level=logging.ERROR,
                nuke_handlers=capture_logs,
            ))

        test_timeout = int(os.environ.get('OS_TEST_TIMEOUT', 0))
        if test_timeout == -1:
            test_timeout = 0
        if test_timeout > 0:
            self.useFixture(fixtures.Timeout(test_timeout, gentle=True))

        # If someone does use tempfile directly, ensure that it's cleaned up
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        self.temp_dir = self.useFixture(fixtures.TempDir()).path
        cfg.CONF.set_override('state_path', self.temp_dir)

        self.setup_config()
        policy.init()
        self.addCleanup(policy.reset)
        self.addCleanup(mock.patch.stopall)
        self.addCleanup(CONF.reset)

        if os.environ.get('OS_STDOUT_CAPTURE') in TRUE_STRING:
            stdout = self.useFixture(fixtures.StringStream('stdout')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
        if os.environ.get('OS_STDERR_CAPTURE') in TRUE_STRING:
            stderr = self.useFixture(fixtures.StringStream('stderr')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
        self.useFixture(
            fixtures.MonkeyPatch(
                'tacker.common.exceptions.TackerException.use_fatal_exceptions',
                fake_use_fatal_exceptions))

        self.useFixture(
            fixtures.MonkeyPatch('oslo_messaging.Notifier',
                                 fake_notifier.FakeNotifier))

        self.messaging_conf = messaging_conffixture.ConfFixture(CONF)
        self.messaging_conf.transport_url = 'fake:/'
        self.messaging_conf.response_timeout = 15
        self.useFixture(self.messaging_conf)

        self.addCleanup(n_rpc.clear_extra_exmods)
        n_rpc.add_extra_exmods('tacker.test')

        self.addCleanup(n_rpc.cleanup)
        n_rpc.init(CONF)

        if sys.version_info < (2, 7) and getattr(self, 'fmt', '') == 'xml':
            raise self.skipException('XML Testing Skipped in Py26')
コード例 #18
0
ファイル: base.py プロジェクト: openstack/tacker
    def setUp(self):
        super(BaseTestCase, self).setUp()

        # Ensure plugin cleanup is triggered last so that
        # test-specific cleanup has a chance to release references.
        self.addCleanup(self.cleanup_core_plugin)

        # Configure this first to ensure pm debugging support for setUp()
        if os.environ.get('OS_POST_MORTEM_DEBUG') in TRUE_STRING:
            self.addOnException(post_mortem_debug.exception_handler)

        if os.environ.get('OS_DEBUG') in TRUE_STRING:
            _level = logging.DEBUG
        else:
            _level = logging.INFO
        capture_logs = os.environ.get('OS_LOG_CAPTURE') in TRUE_STRING
        if not capture_logs:
            logging.basicConfig(format=LOG_FORMAT, level=_level)
        self.log_fixture = self.useFixture(
            fixtures.FakeLogger(
                format=LOG_FORMAT,
                level=_level,
                nuke_handlers=capture_logs,
            ))

        # suppress all but errors here
        self.useFixture(
            fixtures.FakeLogger(
                name='tacker.api.extensions',
                format=LOG_FORMAT,
                level=logging.ERROR,
                nuke_handlers=capture_logs,
            ))

        test_timeout = int(os.environ.get('OS_TEST_TIMEOUT', 0))
        if test_timeout == -1:
            test_timeout = 0
        if test_timeout > 0:
            self.useFixture(fixtures.Timeout(test_timeout, gentle=True))

        # If someone does use tempfile directly, ensure that it's cleaned up
        self.useFixture(fixtures.NestedTempfile())
        self.useFixture(fixtures.TempHomeDir())

        self.temp_dir = self.useFixture(fixtures.TempDir()).path
        cfg.CONF.set_override('state_path', self.temp_dir)

        self.setup_config()
        policy.init()
        self.addCleanup(policy.reset)
        self.addCleanup(mock.patch.stopall)
        self.addCleanup(CONF.reset)

        if os.environ.get('OS_STDOUT_CAPTURE') in TRUE_STRING:
            stdout = self.useFixture(fixtures.StringStream('stdout')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stdout', stdout))
        if os.environ.get('OS_STDERR_CAPTURE') in TRUE_STRING:
            stderr = self.useFixture(fixtures.StringStream('stderr')).stream
            self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
        self.useFixture(fixtures.MonkeyPatch(
            'tacker.common.exceptions.TackerException.use_fatal_exceptions',
            fake_use_fatal_exceptions))

        self.useFixture(fixtures.MonkeyPatch(
            'oslo_messaging.Notifier', fake_notifier.FakeNotifier))

        self.messaging_conf = messaging_conffixture.ConfFixture(CONF)
        self.messaging_conf.transport_url = 'fake:/'
        self.messaging_conf.response_timeout = 15
        self.useFixture(self.messaging_conf)

        self.addCleanup(n_rpc.clear_extra_exmods)
        n_rpc.add_extra_exmods('tacker.test')

        self.addCleanup(n_rpc.cleanup)
        n_rpc.init(CONF)

        if sys.version_info < (2, 7) and getattr(self, 'fmt', '') == 'xml':
            raise self.skipException('XML Testing Skipped in Py26')
コード例 #19
0
ファイル: test_policy.py プロジェクト: vintej/tacker
    def setUp(self):
        super(TackerPolicyTestCase, self).setUp()
        self.skipTest("Not ready yet")
        policy.reset()
        policy.init()
        self.addCleanup(policy.reset)
        self.admin_only_legacy = "role:admin"
        self.admin_or_owner_legacy = "role:admin or tenant_id:%(tenant_id)s"
        # Add a Fake 'something' resource to RESOURCE_ATTRIBUTE_MAP
        attributes.RESOURCE_ATTRIBUTE_MAP.update(FAKE_RESOURCE)
        self.rules = dict(
            (k, common_policy.parse_rule(v)) for k, v in {
                "context_is_admin":
                "role:admin",
                "admin_or_network_owner":
                "rule:context_is_admin or "
                "tenant_id:%(network:tenant_id)s",
                "admin_or_owner": ("rule:context_is_admin or "
                                   "tenant_id:%(tenant_id)s"),
                "admin_only":
                "rule:context_is_admin",
                "regular_user":
                "******",
                "shared":
                "field:networks:shared=True",
                "external":
                "field:networks:router:external=True",
                "default":
                '@',
                "create_network":
                "rule:admin_or_owner",
                "create_network:shared":
                "rule:admin_only",
                "update_network":
                '@',
                "update_network:shared":
                "rule:admin_only",
                "get_network":
                "rule:admin_or_owner or "
                "rule:shared or "
                "rule:external",
                "create_port:mac":
                "rule:admin_or_network_owner",
                "create_something":
                "rule:admin_or_owner",
                "create_something:attr":
                "rule:admin_or_owner",
                "create_something:attr:sub_attr_1":
                "rule:admin_or_owner",
                "create_something:attr:sub_attr_2":
                "rule:admin_only",
                "get_firewall_policy":
                "rule:admin_or_owner or "
                "rule:shared",
                "get_firewall_rule":
                "rule:admin_or_owner or "
                "rule:shared"
            }.items())

        def fakepolicyinit():
            common_policy.set_rules(common_policy.Rules(self.rules))

        def remove_fake_resource():
            del attributes.RESOURCE_ATTRIBUTE_MAP["%ss" % FAKE_RESOURCE_NAME]

        self.patcher = mock.patch.object(tacker.policy,
                                         'init',
                                         new=fakepolicyinit)
        self.patcher.start()
        self.addCleanup(remove_fake_resource)
        self.context = context.Context('fake', 'fake', roles=['user'])
        plugin_klass = importutils.import_class(
            "tacker.db.db_base_plugin_v2.TackerDbPluginV2")
        self.manager_patcher = mock.patch('tacker.manager.TackerManager')
        fake_manager = self.manager_patcher.start()
        fake_manager_instance = fake_manager.return_value
        fake_manager_instance.plugin = plugin_klass()