Inject os_glance.* section in the property protection file
Users who use a property protection file and use either the import workflow or the metadata injection plugin will get a glance.common.exception.ReservedProperty exception because we try to add os_glance_* properties to their images. To work around this issue, users could add the following lines to their property protection file: [os_glance.*] create = @ read = @ update = @ delete = @ However, it is not something users should have to do. This patch automatically injects this section into the config we read from the property protection file. Change-Id: Iea2fffa75b973b5a34da6fc4145841888ea19034 Closes-Bug: #2085321 Signed-off-by: Cyril Roelandt <cyril@redhat.com>
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
import configparser
|
||||
import io
|
||||
import re
|
||||
|
||||
from oslo_config import cfg
|
||||
@@ -108,10 +109,51 @@ class PropertyRules(object):
|
||||
self.prop_prot_rule_format = self.prop_prot_rule_format.lower()
|
||||
self._load_rules()
|
||||
|
||||
def _inject_os_glance_section(self):
|
||||
# Inject an 'os_glance.*' section to work around bug #2085321.
|
||||
# https://bugs.launchpad.net/glance/+bug/2085321
|
||||
# An exception will be raised if a property protection file is in
|
||||
# use and does not contain the os_glance.* section. Since this is
|
||||
# internal to Glance, the users should not have to specify that
|
||||
# section in the config file themselves. We therefore inject it
|
||||
# here on their behalf.
|
||||
#
|
||||
# We also remove all sections starting with 'os_glance' since the
|
||||
# keyword is reserved for internal use.
|
||||
#
|
||||
# See:
|
||||
# glance/tests/etc/property-protections-policies.conf
|
||||
# glance/tests/etc/property-protections.conf
|
||||
global CONFIG
|
||||
|
||||
for section in CONFIG.sections():
|
||||
if section.startswith('os_glance'):
|
||||
CONFIG.remove_section(section)
|
||||
|
||||
# We want to insert the [os_glance.*] section at the top of the config,
|
||||
# so it is not shadowed by sections such as [.*]. To do this, we:
|
||||
# 1) Dump the user config into a StringIO
|
||||
# 2) Init a new ConfigParser object
|
||||
# 3) Read our [os_glance.*] section
|
||||
# 4) Read the user config
|
||||
txt_config = io.StringIO()
|
||||
CONFIG.write(txt_config)
|
||||
CONFIG = configparser.ConfigParser()
|
||||
CONFIG.read_dict({
|
||||
'os_glance.*': {
|
||||
'create': '@',
|
||||
'read': '@',
|
||||
'update': '@',
|
||||
'delete': '@',
|
||||
}
|
||||
})
|
||||
CONFIG.read_string(txt_config.getvalue())
|
||||
|
||||
def _load_rules(self):
|
||||
try:
|
||||
conf_file = CONF.find_file(CONF.property_protection_file)
|
||||
CONFIG.read(conf_file)
|
||||
self._inject_os_glance_section()
|
||||
except Exception as e:
|
||||
msg = (_LE("Couldn't find property protection file %(file)s: "
|
||||
"%(error)s.") % {'file': CONF.property_protection_file,
|
||||
|
||||
@@ -20,6 +20,7 @@ import glance.context
|
||||
from glance.tests.unit import base
|
||||
|
||||
CONFIG_SECTIONS = [
|
||||
'os_glance.*', # Automatically injected at the top
|
||||
'^x_owner_.*',
|
||||
'spl_create_prop',
|
||||
'spl_read_prop',
|
||||
@@ -47,7 +48,40 @@ def create_context(policy, roles=None):
|
||||
policy_enforcer=policy)
|
||||
|
||||
|
||||
class TestPropertyRulesWithRoles(base.IsolatedUnitTest):
|
||||
class TestPropertyRules():
|
||||
def test_inject_os_glance(self):
|
||||
'''Test that the os_glance.* section has been injected.'''
|
||||
rules = {'x_foo': {'create': ['fake-role'],
|
||||
'read': ['member'],
|
||||
'update': ['fake-role'],
|
||||
'delete': ['fake-role']},
|
||||
'os_glance_store': {'create': '!',
|
||||
'read': '!',
|
||||
'update': '!',
|
||||
'delete': '!'}}
|
||||
self.set_property_protection_rules(rules)
|
||||
self.rules_checker = property_utils.PropertyRules()
|
||||
|
||||
# The x_foo section should still be here
|
||||
self.assertTrue(self.rules_checker.check_property_rules('x_foo',
|
||||
'read', create_context(self.policy, ['member'])))
|
||||
|
||||
# The os_glance_store section should not have been here (users must not
|
||||
# specify any section that starts with 'os_glance'. Our 'os_glance.*'
|
||||
# section should now be here.
|
||||
self.assertIn('os_glance.*', property_utils.CONFIG.sections())
|
||||
self.assertNotIn('os_glance_store', property_utils.CONFIG.sections())
|
||||
|
||||
# And we should have the right permissions for all operations in the
|
||||
# os_glance.* section.
|
||||
context = create_context(self.policy, [''])
|
||||
for operation in ['create', 'read', 'update', 'delete']:
|
||||
self.assertTrue(
|
||||
self.rules_checker.check_property_rules(
|
||||
'os_glance.*', operation, context))
|
||||
|
||||
|
||||
class TestPropertyRulesWithRoles(base.IsolatedUnitTest, TestPropertyRules):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPropertyRulesWithRoles, self).setUp()
|
||||
@@ -321,7 +355,7 @@ class TestPropertyRulesWithRoles(base.IsolatedUnitTest):
|
||||
create_context(self.policy, ['member'])))
|
||||
|
||||
|
||||
class TestPropertyRulesWithPolicies(base.IsolatedUnitTest):
|
||||
class TestPropertyRulesWithPolicies(base.IsolatedUnitTest, TestPropertyRules):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPropertyRulesWithPolicies, self).setUp()
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
`Bug #2085321 <https://bugs.launchpad.net/glance/+bug/2085321>`_:
|
||||
Fixed an issue that prevented users from using property protection files
|
||||
and image import or the inject metadata plugin. A valid "os_glance.*"
|
||||
section is now automatically added to the property protection file.
|
||||
Reference in New Issue
Block a user