Merge "Switch to latest oslo-incubator"
This commit is contained in:
commit
8a2be34e7e
@ -16,25 +16,30 @@ See http://docs.openstack.org/developer/oslo.i18n/usage.html
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import oslo.i18n
|
try:
|
||||||
|
import oslo_i18n
|
||||||
|
|
||||||
|
# NOTE(dhellmann): This reference to o-s-l-o will be replaced by the
|
||||||
|
# application name when this module is synced into the separate
|
||||||
|
# repository. It is OK to have more than one translation function
|
||||||
|
# using the same domain, since there will still only be one message
|
||||||
|
# catalog.
|
||||||
|
_translators = oslo_i18n.TranslatorFactory(domain='glance')
|
||||||
|
|
||||||
# NOTE(dhellmann): This reference to o-s-l-o will be replaced by the
|
# The primary translation function using the well-known name "_"
|
||||||
# application name when this module is synced into the separate
|
_ = _translators.primary
|
||||||
# repository. It is OK to have more than one translation function
|
|
||||||
# using the same domain, since there will still only be one message
|
|
||||||
# catalog.
|
|
||||||
_translators = oslo.i18n.TranslatorFactory(domain='glance')
|
|
||||||
|
|
||||||
# The primary translation function using the well-known name "_"
|
# Translators for log levels.
|
||||||
_ = _translators.primary
|
#
|
||||||
|
# The abbreviated names are meant to reflect the usual use of a short
|
||||||
# Translators for log levels.
|
# name like '_'. The "L" is for "log" and the other letter comes from
|
||||||
#
|
# the level.
|
||||||
# The abbreviated names are meant to reflect the usual use of a short
|
_LI = _translators.log_info
|
||||||
# name like '_'. The "L" is for "log" and the other letter comes from
|
_LW = _translators.log_warning
|
||||||
# the level.
|
_LE = _translators.log_error
|
||||||
_LI = _translators.log_info
|
_LC = _translators.log_critical
|
||||||
_LW = _translators.log_warning
|
except ImportError:
|
||||||
_LE = _translators.log_error
|
# NOTE(dims): Support for cases where a project wants to use
|
||||||
_LC = _translators.log_critical
|
# code from oslo-incubator, but is not ready to be internationalized
|
||||||
|
# (like tempest)
|
||||||
|
_ = _LI = _LW = _LE = _LC = lambda x: x
|
||||||
|
@ -28,7 +28,7 @@ import traceback
|
|||||||
|
|
||||||
import eventlet.backdoor
|
import eventlet.backdoor
|
||||||
import greenlet
|
import greenlet
|
||||||
from oslo.config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from glance.openstack.common._i18n import _LI
|
from glance.openstack.common._i18n import _LI
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def list_opts():
|
def list_opts():
|
||||||
"""Entry point for oslo.config-generator.
|
"""Entry point for oslo-config-generator.
|
||||||
"""
|
"""
|
||||||
return [(None, copy.deepcopy(eventlet_backdoor_opts))]
|
return [(None, copy.deepcopy(eventlet_backdoor_opts))]
|
||||||
|
|
||||||
|
@ -15,25 +15,27 @@
|
|||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import errno
|
import errno
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import stat
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
|
|
||||||
from glance.openstack.common import log as logging
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
_FILE_CACHE = {}
|
_FILE_CACHE = {}
|
||||||
|
DEFAULT_MODE = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
|
||||||
|
|
||||||
|
|
||||||
def ensure_tree(path):
|
def ensure_tree(path, mode=DEFAULT_MODE):
|
||||||
"""Create a directory (and any ancestor directories required)
|
"""Create a directory (and any ancestor directories required)
|
||||||
|
|
||||||
:param path: Directory to create
|
:param path: Directory to create
|
||||||
|
:param mode: Directory creation permissions
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
os.makedirs(path)
|
os.makedirs(path, mode)
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
if exc.errno == errno.EEXIST:
|
if exc.errno == errno.EEXIST:
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
# Copyright (c) 2012 OpenStack Foundation.
|
# Copyright (c) 2012 OpenStack Foundation.
|
||||||
# All Rights Reserved.
|
# All Rights Reserved.
|
||||||
#
|
#
|
||||||
@ -22,22 +24,43 @@ string written in the new policy language.
|
|||||||
In the list-of-lists representation, each check inside the innermost
|
In the list-of-lists representation, each check inside the innermost
|
||||||
list is combined as with an "and" conjunction--for that check to pass,
|
list is combined as with an "and" conjunction--for that check to pass,
|
||||||
all the specified checks must pass. These innermost lists are then
|
all the specified checks must pass. These innermost lists are then
|
||||||
combined as with an "or" conjunction. This is the original way of
|
combined as with an "or" conjunction. As an example, take the following
|
||||||
expressing policies, but there now exists a new way: the policy
|
rule, expressed in the list-of-lists representation::
|
||||||
language.
|
|
||||||
|
|
||||||
In the policy language, each check is specified the same way as in the
|
|
||||||
list-of-lists representation: a simple "a:b" pair that is matched to
|
|
||||||
the correct code to perform that check. However, conjunction
|
|
||||||
operators are available, allowing for more expressiveness in crafting
|
|
||||||
policies.
|
|
||||||
|
|
||||||
As an example, take the following rule, expressed in the list-of-lists
|
|
||||||
representation::
|
|
||||||
|
|
||||||
[["role:admin"], ["project_id:%(project_id)s", "role:projectadmin"]]
|
[["role:admin"], ["project_id:%(project_id)s", "role:projectadmin"]]
|
||||||
|
|
||||||
In the policy language, this becomes::
|
This is the original way of expressing policies, but there now exists a
|
||||||
|
new way: the policy language.
|
||||||
|
|
||||||
|
In the policy language, each check is specified the same way as in the
|
||||||
|
list-of-lists representation: a simple "a:b" pair that is matched to
|
||||||
|
the correct class to perform that check::
|
||||||
|
|
||||||
|
+===========================================================================+
|
||||||
|
| TYPE | SYNTAX |
|
||||||
|
+===========================================================================+
|
||||||
|
|User's Role | role:admin |
|
||||||
|
+---------------------------------------------------------------------------+
|
||||||
|
|Rules already defined on policy | rule:admin_required |
|
||||||
|
+---------------------------------------------------------------------------+
|
||||||
|
|Against URL's¹ | http://my-url.org/check |
|
||||||
|
+---------------------------------------------------------------------------+
|
||||||
|
|User attributes² | project_id:%(target.project.id)s |
|
||||||
|
+---------------------------------------------------------------------------+
|
||||||
|
|Strings | <variable>:'xpto2035abc' |
|
||||||
|
| | 'myproject':<variable> |
|
||||||
|
+---------------------------------------------------------------------------+
|
||||||
|
| | project_id:xpto2035abc |
|
||||||
|
|Literals | domain_id:20 |
|
||||||
|
| | True:%(user.enabled)s |
|
||||||
|
+===========================================================================+
|
||||||
|
|
||||||
|
¹URL checking must return 'True' to be valid
|
||||||
|
²User attributes (obtained through the token): user_id, domain_id or project_id
|
||||||
|
|
||||||
|
Conjunction operators are available, allowing for more expressiveness
|
||||||
|
in crafting policies. So, in the policy language, the previous check in
|
||||||
|
list-of-lists becomes::
|
||||||
|
|
||||||
role:admin or (project_id:%(project_id)s and role:projectadmin)
|
role:admin or (project_id:%(project_id)s and role:projectadmin)
|
||||||
|
|
||||||
@ -46,26 +69,16 @@ policy rule::
|
|||||||
|
|
||||||
project_id:%(project_id)s and not role:dunce
|
project_id:%(project_id)s and not role:dunce
|
||||||
|
|
||||||
It is possible to perform policy checks on the following user
|
|
||||||
attributes (obtained through the token): user_id, domain_id or
|
|
||||||
project_id::
|
|
||||||
|
|
||||||
domain_id:<some_value>
|
|
||||||
|
|
||||||
Attributes sent along with API calls can be used by the policy engine
|
Attributes sent along with API calls can be used by the policy engine
|
||||||
(on the right side of the expression), by using the following syntax::
|
(on the right side of the expression), by using the following syntax::
|
||||||
|
|
||||||
<some_value>:user.id
|
<some_value>:%(user.id)s
|
||||||
|
|
||||||
Contextual attributes of objects identified by their IDs are loaded
|
Contextual attributes of objects identified by their IDs are loaded
|
||||||
from the database. They are also available to the policy engine and
|
from the database. They are also available to the policy engine and
|
||||||
can be checked through the `target` keyword::
|
can be checked through the `target` keyword::
|
||||||
|
|
||||||
<some_value>:target.role.name
|
<some_value>:%(target.role.name)s
|
||||||
|
|
||||||
All these attributes (related to users, API calls, and context) can be
|
|
||||||
checked against each other or against constants, be it literals (True,
|
|
||||||
<a_number>) or strings.
|
|
||||||
|
|
||||||
Finally, two special policy checks should be mentioned; the policy
|
Finally, two special policy checks should be mentioned; the policy
|
||||||
check "@" will always accept an access, and the policy check "!" will
|
check "@" will always accept an access, and the policy check "!" will
|
||||||
@ -78,18 +91,18 @@ as it allows particular rules to be explicitly disabled.
|
|||||||
import abc
|
import abc
|
||||||
import ast
|
import ast
|
||||||
import copy
|
import copy
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo.serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
import six
|
import six
|
||||||
import six.moves.urllib.parse as urlparse
|
import six.moves.urllib.parse as urlparse
|
||||||
import six.moves.urllib.request as urlrequest
|
import six.moves.urllib.request as urlrequest
|
||||||
|
|
||||||
from glance.openstack.common import fileutils
|
from glance.openstack.common import fileutils
|
||||||
from glance.openstack.common._i18n import _, _LE, _LW
|
from glance.openstack.common._i18n import _, _LE
|
||||||
from glance.openstack.common import log as logging
|
|
||||||
|
|
||||||
|
|
||||||
policy_opts = [
|
policy_opts = [
|
||||||
@ -107,7 +120,8 @@ policy_opts = [
|
|||||||
'in the search path defined by the config_dir '
|
'in the search path defined by the config_dir '
|
||||||
'option, or absolute paths. The file defined by '
|
'option, or absolute paths. The file defined by '
|
||||||
'policy_file must exist for these directories to '
|
'policy_file must exist for these directories to '
|
||||||
'be searched.')),
|
'be searched. Missing or empty directories are '
|
||||||
|
'ignored.')),
|
||||||
]
|
]
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
@ -259,7 +273,6 @@ class Enforcer(object):
|
|||||||
try:
|
try:
|
||||||
path = self._get_policy_path(path)
|
path = self._get_policy_path(path)
|
||||||
except cfg.ConfigFilesNotFoundError:
|
except cfg.ConfigFilesNotFoundError:
|
||||||
LOG.warn(_LW("Can not find policy directory: %s"), path)
|
|
||||||
continue
|
continue
|
||||||
self._walk_through_policy_directory(path,
|
self._walk_through_policy_directory(path,
|
||||||
self._load_policy_file,
|
self._load_policy_file,
|
||||||
@ -279,7 +292,8 @@ class Enforcer(object):
|
|||||||
if reloaded or not self.rules or not overwrite:
|
if reloaded or not self.rules or not overwrite:
|
||||||
rules = Rules.load_json(data, self.default_rule)
|
rules = Rules.load_json(data, self.default_rule)
|
||||||
self.set_rules(rules, overwrite=overwrite, use_conf=True)
|
self.set_rules(rules, overwrite=overwrite, use_conf=True)
|
||||||
LOG.debug("Rules successfully reloaded")
|
LOG.debug("Reloaded policy file: %(path)s",
|
||||||
|
{'path': path})
|
||||||
|
|
||||||
def _get_policy_path(self, path):
|
def _get_policy_path(self, path):
|
||||||
"""Locate the policy json data file/path.
|
"""Locate the policy json data file/path.
|
||||||
@ -898,7 +912,17 @@ class HttpCheck(Check):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
url = ('http:' + self.match) % target
|
url = ('http:' + self.match) % target
|
||||||
data = {'target': jsonutils.dumps(target),
|
|
||||||
|
# Convert instances of object() in target temporarily to
|
||||||
|
# empty dict to avoid circular reference detection
|
||||||
|
# errors in jsonutils.dumps().
|
||||||
|
temp_target = copy.deepcopy(target)
|
||||||
|
for key in target.keys():
|
||||||
|
element = target.get(key)
|
||||||
|
if type(element) is object:
|
||||||
|
temp_target[key] = {}
|
||||||
|
|
||||||
|
data = {'target': jsonutils.dumps(temp_target),
|
||||||
'credentials': jsonutils.dumps(creds)}
|
'credentials': jsonutils.dumps(creds)}
|
||||||
post_data = urlparse.urlencode(data)
|
post_data = urlparse.urlencode(data)
|
||||||
f = urlrequest.urlopen(url, post_data)
|
f = urlrequest.urlopen(url, post_data)
|
||||||
|
@ -35,7 +35,7 @@ except ImportError:
|
|||||||
|
|
||||||
import eventlet
|
import eventlet
|
||||||
from eventlet import event
|
from eventlet import event
|
||||||
from oslo.config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from glance.openstack.common import eventlet_backdoor
|
from glance.openstack.common import eventlet_backdoor
|
||||||
from glance.openstack.common._i18n import _LE, _LI, _LW
|
from glance.openstack.common._i18n import _LE, _LI, _LW
|
||||||
@ -199,16 +199,12 @@ class ServiceWrapper(object):
|
|||||||
|
|
||||||
|
|
||||||
class ProcessLauncher(object):
|
class ProcessLauncher(object):
|
||||||
def __init__(self, wait_interval=0.01):
|
def __init__(self):
|
||||||
"""Constructor.
|
"""Constructor."""
|
||||||
|
|
||||||
:param wait_interval: The interval to sleep for between checks
|
|
||||||
of child process exit.
|
|
||||||
"""
|
|
||||||
self.children = {}
|
self.children = {}
|
||||||
self.sigcaught = None
|
self.sigcaught = None
|
||||||
self.running = True
|
self.running = True
|
||||||
self.wait_interval = wait_interval
|
|
||||||
rfd, self.writepipe = os.pipe()
|
rfd, self.writepipe = os.pipe()
|
||||||
self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r')
|
self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r')
|
||||||
self.handle_signal()
|
self.handle_signal()
|
||||||
@ -333,8 +329,8 @@ class ProcessLauncher(object):
|
|||||||
|
|
||||||
def _wait_child(self):
|
def _wait_child(self):
|
||||||
try:
|
try:
|
||||||
# Don't block if no child processes have exited
|
# Block while any of child processes have exited
|
||||||
pid, status = os.waitpid(0, os.WNOHANG)
|
pid, status = os.waitpid(0, 0)
|
||||||
if not pid:
|
if not pid:
|
||||||
return None
|
return None
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
@ -363,10 +359,6 @@ class ProcessLauncher(object):
|
|||||||
while self.running:
|
while self.running:
|
||||||
wrap = self._wait_child()
|
wrap = self._wait_child()
|
||||||
if not wrap:
|
if not wrap:
|
||||||
# Yield to other threads if no children have exited
|
|
||||||
# Sleep for a short time to avoid excessive CPU usage
|
|
||||||
# (see bug #1095346)
|
|
||||||
eventlet.greenthread.sleep(self.wait_interval)
|
|
||||||
continue
|
continue
|
||||||
while self.running and len(wrap.children) < wrap.workers:
|
while self.running and len(wrap.children) < wrap.workers:
|
||||||
self._start_child(wrap)
|
self._start_child(wrap)
|
||||||
|
Loading…
Reference in New Issue
Block a user