]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Deprecate "extension:xxx" policies but preserve bw compatibility
authorSalvatore Orlando <salv.orlando@gmail.com>
Tue, 14 May 2013 23:46:13 +0000 (01:46 +0200)
committerSalvatore Orlando <salv.orlando@gmail.com>
Thu, 16 May 2013 14:17:50 +0000 (16:17 +0200)
Blueprint make-authz-orthogonal

Patch #4 for this blueprint.
With this change, if policies starting with 'extension' are still
present in policy.json, a deprecation warning will be emitted, and
the policy will be translated in the corresponding, new-style,
policy(ies).

Change-Id: Iccf0f36cc2547c35c66854b8a3fdb7185b5214bd

quantum/policy.py
quantum/tests/unit/test_policy.py

index eb6df91d5c54f8a04169cac97d5981cfd375959c..05e11ec10339efc053b3d3f819adcb565ba0b2dc 100644 (file)
@@ -18,6 +18,7 @@
 """
 Policy engine for quantum.  Largely copied from nova.
 """
+import itertools
 
 from oslo.config import cfg
 
@@ -32,6 +33,23 @@ LOG = logging.getLogger(__name__)
 _POLICY_PATH = None
 _POLICY_CACHE = {}
 ADMIN_CTX_POLICY = 'context_is_admin'
+# Maps deprecated 'extension' policies to new-style policies
+DEPRECATED_POLICY_MAP = {
+    'extension:provider_network':
+    ['network:provider:network_type',
+     'network:provider:physical_network',
+     'network:provider:segmentation_id'],
+    'extension:router':
+    ['network:router:external'],
+    'extension:port_binding':
+    ['port:binding:vif_type', 'port:binding:capabilities',
+     'port:binding:profile', 'port:binding:host_id']
+}
+DEPRECATED_ACTION_MAP = {
+    'view': ['get'],
+    'set': ['create', 'update']
+}
+
 cfg.CONF.import_opt('policy_file', 'quantum.common.config')
 
 
@@ -65,9 +83,36 @@ def get_resource_and_action(action):
 def _set_rules(data):
     default_rule = 'default'
     LOG.debug(_("loading policies from file: %s"), _POLICY_PATH)
-    # TODO(salvatore-orlando): Ensure backward compatibility with
-    # folsom/grizzly style for extension rules (bp/make-authz-orthogonal)
-    policy.set_rules(policy.Rules.load_json(data, default_rule))
+    # Ensure backward compatibility with folsom/grizzly convention
+    # for extension rules
+    policies = policy.Rules.load_json(data, default_rule)
+    for pol in policies.keys():
+        if any([pol.startswith(depr_pol) for depr_pol in
+                DEPRECATED_POLICY_MAP.keys()]):
+            LOG.warn(_("Found deprecated policy rule:%s. Please consider "
+                       "upgrading your policy configuration file"), pol)
+            pol_name, action = pol.rsplit(':', 1)
+            try:
+                new_actions = DEPRECATED_ACTION_MAP[action]
+                new_policies = DEPRECATED_POLICY_MAP[pol_name]
+                # bind new actions and policies together
+                for actual_policy in ['_'.join(item) for item in
+                                      itertools.product(new_actions,
+                                                        new_policies)]:
+                    if not actual_policy in policies:
+                        # New policy, same rule
+                        LOG.info(_("Inserting policy:%(new_policy)s in place "
+                                   "of deprecated policy:%(old_policy)s"),
+                                 {'new_policy': actual_policy,
+                                  'old_policy': pol})
+                        policies[actual_policy] = policies[pol]
+                # Remove old-style policy
+                del policies[pol]
+            except KeyError:
+                LOG.error(_("Backward compatibility unavailable for "
+                            "deprecated policy %s. The policy will "
+                            "not be enforced"), pol)
+    policy.set_rules(policies)
 
 
 def _is_attribute_explicitly_set(attribute_name, resource, target):
index 9e3ce072c98b6954f5c11899973ff97d9517c9db..604300b4507e2e8d7264878c9601107d985860e2 100644 (file)
@@ -15,6 +15,7 @@
 
 """Test of Policy Engine For Quantum"""
 
+import json
 import StringIO
 import urllib2
 
@@ -367,3 +368,33 @@ class QuantumPolicyTestCase(base.BaseTestCase):
             policy.ADMIN_CTX_POLICY: "role:xxx or other:value",
         }.items())
         self.assertEqual(['xxx'], policy.get_admin_roles())
+
+    def _test_set_rules_with_deprecated_policy(self, input_rules,
+                                               expected_rules):
+        policy._set_rules(json.dumps(input_rules))
+        # verify deprecated policy has been removed
+        for pol in input_rules.keys():
+            self.assertNotIn(pol, common_policy._rules)
+        # verify deprecated policy was correctly translated. Iterate
+        # over items for compatibility with unittest2 in python 2.6
+        for rule in expected_rules:
+            self.assertIn(rule, common_policy._rules)
+            self.assertEqual(str(common_policy._rules[rule]),
+                             expected_rules[rule])
+
+    def test_set_rules_with_deprecated_view_policy(self):
+        self._test_set_rules_with_deprecated_policy(
+            {'extension:router:view': 'rule:admin_or_owner'},
+            {'get_network:router:external': 'rule:admin_or_owner'})
+
+    def test_set_rules_with_deprecated_set_policy(self):
+        expected_policies = ['create_network:provider:network_type',
+                             'create_network:provider:physical_network',
+                             'create_network:provider:segmentation_id',
+                             'update_network:provider:network_type',
+                             'update_network:provider:physical_network',
+                             'update_network:provider:segmentation_id']
+        self._test_set_rules_with_deprecated_policy(
+            {'extension:provider_network:set': 'rule:admin_only'},
+            dict((policy, 'rule:admin_only') for policy in
+                 expected_policies))