manila/manila/share/drivers/ganesha/utils.py

150 lines
4.7 KiB
Python

# Copyright (c) 2014 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import os
import pipes
from oslo_concurrency import processutils
from oslo_log import log
from manila import exception
from manila.i18n import _
from manila import utils
LOG = log.getLogger(__name__)
def patch(base, *overlays):
"""Recursive dictionary patching."""
for ovl in overlays:
for k, v in ovl.items():
if isinstance(v, dict) and isinstance(base.get(k), dict):
patch(base[k], v)
else:
base[k] = v
return base
def walk(dct):
"""Recursive iteration over dictionary."""
for k, v in dct.items():
if isinstance(v, dict):
for w in walk(v):
yield w
else:
yield k, v
class RootExecutor(object):
"""Execute wrapper defaulting to root execution."""
def __init__(self, execute=utils.execute):
self.execute = execute
def __call__(self, *args, **kwargs):
exkwargs = {"run_as_root": True}
exkwargs.update(kwargs)
return self.execute(*args, **exkwargs)
class SSHExecutor(object):
"""Callable encapsulating exec through ssh."""
def __init__(self, *args, **kwargs):
self.pool = utils.SSHPool(*args, **kwargs)
def __call__(self, *args, **kwargs):
# argument with identifier 'run_as_root=' is not accepted by
# processutils's ssh_execute() method unlike processutils's execute()
# method. So implement workaround to enable or disable 'run as root'
# behavior.
run_as_root = kwargs.pop('run_as_root', False)
cmd = ' '.join(pipes.quote(a) for a in args)
if run_as_root:
cmd = ' '.join(['sudo', cmd])
ssh = self.pool.get()
try:
ret = processutils.ssh_execute(ssh, cmd, **kwargs)
finally:
self.pool.put(ssh)
return ret
def path_from(fpath, *rpath):
"""Return the join of the dir of fpath and rpath in absolute form."""
return os.path.join(os.path.abspath(os.path.dirname(fpath)), *rpath)
def validate_access_rule(supported_access_types, supported_access_levels,
access_rule, abort=False):
"""Validate an access rule.
:param access_rule: Access rules to be validated.
:param supported_access_types: List of access types that are regarded
valid.
:param supported_access_levels: List of access levels that are
regarded valid.
:param abort: a boolean value that indicates if an exception should
be raised whether the rule is invalid.
:return: Boolean.
"""
errmsg = _("Unsupported access rule of 'type' %(access_type)s, "
"'level' %(access_level)s, 'to' %(access_to)s: "
"%(field)s should be one of %(supported)s.")
access_param = access_rule.to_dict()
def validate(field, supported_tokens, excinfo):
if access_rule['access_%s' % field] in supported_tokens:
return True
access_param['field'] = field
access_param['supported'] = ', '.join(
"'%s'" % x for x in supported_tokens)
if abort:
LOG.error(errmsg, access_param)
raise excinfo['type'](
**{excinfo['about']: excinfo['details'] % access_param})
else:
LOG.warning(errmsg, access_param)
return False
valid = True
valid &= validate(
'type', supported_access_types,
{'type': exception.InvalidShareAccess, 'about': "reason",
'details': _(
"%(access_type)s; only %(supported)s access type is allowed")})
valid &= validate(
'level', supported_access_levels,
{'type': exception.InvalidShareAccessLevel, 'about': "level",
'details': "%(access_level)s"})
return valid
def fixup_access_rule(access_rule):
"""Adjust access rule as required for ganesha to handle it properly.
:param access_rule: Access rules to be fixed up.
:return: access_rule
"""
if access_rule['access_to'] == '0.0.0.0/0':
access_rule['access_to'] = '0.0.0.0'
LOG.debug("Set access_to field to '0.0.0.0' in ganesha back end.")
return access_rule