From 96b0b90b89ceb8efe51f9b2270401cca2956079a Mon Sep 17 00:00:00 2001 From: Nate Johnston Date: Mon, 25 Mar 2019 16:04:22 -0400 Subject: [PATCH] Add enforcer logic for neutron policy The oslopolicy-policy-generator command line tool does not run currently, throwing a KeyError. This is because a policy enforcer needs to be added to Neutron for the command to run. This change is a limited backport of "Convert policy.json into policy-in-code" [1]. The feature of policy-in-code is not backported; all that is backported is the changes needed for the oslopolicy-policy-generator command line tool to function properly, which were bundled in with the rest of the policy-in-code feature. For reference, an analogous change was merged in keystone to solve the same problem [2]. [1] https://review.openstack.org/585037 [2] https://review.openstack.org/530828 Change-Id: I912f23e9c6800b71672507c548cfab3f094de9c7 Closes-Bug: #1817953 --- neutron/policy.py | 22 +++++++++++++++++++ .../tests/unit/db/test_db_base_plugin_v2.py | 12 ++++++++++ setup.cfg | 2 ++ 3 files changed, 36 insertions(+) diff --git a/neutron/policy.py b/neutron/policy.py index e6f1eb5ccae..a5cdc6a13a7 100644 --- a/neutron/policy.py +++ b/neutron/policy.py @@ -15,6 +15,7 @@ import collections import re +import sys from neutron_lib.api import attributes from neutron_lib.api.definitions import network as net_apidef @@ -421,3 +422,24 @@ def enforce(context, action, target, plugin=None, pluralized=None): log_rule_list(rule) LOG.debug("Failed policy check for '%s'", action) return result + + +def get_enforcer(): + # NOTE(amotoki): This was borrowed from nova/policy.py. + # This method is for use by oslo.policy CLI scripts. Those scripts need the + # 'output-file' and 'namespace' options, but having those in sys.argv means + # loading the neutron config options will fail as those are not expected to + # be present. So we pass in an arg list with those stripped out. + conf_args = [] + # Start at 1 because cfg.CONF expects the equivalent of sys.argv[1:] + i = 1 + while i < len(sys.argv): + if sys.argv[i].strip('-') in ['namespace', 'output-file']: + i += 2 + continue + conf_args.append(sys.argv[i]) + i += 1 + + cfg.CONF(conf_args, project='neutron') + init() + return _ENFORCER diff --git a/neutron/tests/unit/db/test_db_base_plugin_v2.py b/neutron/tests/unit/db/test_db_base_plugin_v2.py index 14a80b764b9..fe90320cec8 100644 --- a/neutron/tests/unit/db/test_db_base_plugin_v2.py +++ b/neutron/tests/unit/db/test_db_base_plugin_v2.py @@ -60,6 +60,7 @@ from neutron.db import standard_attr from neutron.ipam.drivers.neutrondb_ipam import driver as ipam_driver from neutron.ipam import exceptions as ipam_exc from neutron.objects import router as l3_obj +from neutron import policy from neutron.tests import base from neutron.tests import tools from neutron.tests.unit.api import test_extensions @@ -176,6 +177,17 @@ class NeutronDbPluginV2TestCase(testlib_api.WebTestCase): self._skip_native_sorting = not _is_native_sorting_support() if ext_mgr: self.ext_api = test_extensions.setup_extensions_middleware(ext_mgr) + # NOTE(amotoki): policy._ENFORCER is initialized in + # neutron.tests.base.BaseTestCase.setUp() but this is too early + # and neutron.policy.FieldCheck conv_func does not work + # because extended resources are not populated to + # attributes.RESOURCES yet. + # Thus we need to refresh the default policy rules after loading + # extensions. Especially it is important to re-instantiate + # DefaultRule() under neutron.conf.policies. To do this, + # we need to reload the default policy modules. + policy.reset() + policy.init() def setup_config(self): # Create the default configurations diff --git a/setup.cfg b/setup.cfg index 5415645b5f6..200b5596187 100644 --- a/setup.cfg +++ b/setup.cfg @@ -139,6 +139,8 @@ oslo.config.opts = nova.auth = neutron.opts:list_auth_opts oslo.config.opts.defaults = neutron = neutron.common.config:set_cors_middleware_defaults +oslo.policy.enforcer = + neutron = neutron.policy:get_enforcer neutron.db.alembic_migrations = neutron = neutron.db.migration:alembic_migrations neutron.interface_drivers =