156 lines
5.7 KiB
Python
156 lines
5.7 KiB
Python
# Copyright (c) 2015 Mirantis 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.
|
|
|
|
from oslo_log import log
|
|
import six
|
|
|
|
from manila.common import constants
|
|
from manila import exception
|
|
from manila.i18n import _LI
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class ShareInstanceAccess(object):
|
|
|
|
def __init__(self, db, driver):
|
|
self.db = db
|
|
self.driver = driver
|
|
|
|
def update_access_rules(self, context, share_instance_id, add_rules=None,
|
|
delete_rules=None, share_server=None):
|
|
"""Update access rules in driver and database for given share instance.
|
|
|
|
:param context: current context
|
|
:param share_instance_id: Id of the share instance model
|
|
:param add_rules: list with ShareAccessMapping models or None - rules
|
|
which should be added
|
|
:param delete_rules: list with ShareAccessMapping models, "all", None
|
|
- rules which should be deleted. If "all" is provided - all rules will
|
|
be deleted.
|
|
:param share_server: Share server model or None
|
|
"""
|
|
share_instance = self.db.share_instance_get(
|
|
context, share_instance_id, with_share_data=True)
|
|
|
|
add_rules = add_rules or []
|
|
delete_rules = delete_rules or []
|
|
remove_rules = None
|
|
|
|
if six.text_type(delete_rules).lower() == "all":
|
|
# NOTE(ganso): if we are deleting an instance or clearing all
|
|
# the rules, we want to remove only the ones related
|
|
# to this instance.
|
|
delete_rules = self.db.share_access_get_all_for_instance(
|
|
context, share_instance['id'])
|
|
rules = []
|
|
else:
|
|
rules = self.db.share_access_get_all_for_share(
|
|
context, share_instance['share_id'])
|
|
if delete_rules:
|
|
delete_ids = [rule['id'] for rule in delete_rules]
|
|
rules = list(filter(lambda r: r['id'] not in delete_ids,
|
|
rules))
|
|
# NOTE(ganso): trigger maintenance mode
|
|
if share_instance['access_rules_status'] == (
|
|
constants.STATUS_ERROR):
|
|
remove_rules = delete_rules
|
|
delete_rules = []
|
|
|
|
try:
|
|
try:
|
|
self.driver.update_access(
|
|
context,
|
|
share_instance,
|
|
rules,
|
|
add_rules=add_rules,
|
|
delete_rules=delete_rules,
|
|
share_server=share_server
|
|
)
|
|
except NotImplementedError:
|
|
# NOTE(u_glide): Fallback to legacy allow_access/deny_access
|
|
# for drivers without update_access() method support
|
|
|
|
self._update_access_fallback(add_rules, context, delete_rules,
|
|
remove_rules, share_instance,
|
|
share_server)
|
|
except Exception as e:
|
|
error = six.text_type(e)
|
|
LOG.exception(error)
|
|
self.db.share_instance_update_access_status(
|
|
context,
|
|
share_instance['id'],
|
|
constants.STATUS_ERROR)
|
|
raise exception.ManilaException(message=error)
|
|
|
|
# NOTE(ganso): remove rules after maintenance is complete
|
|
if remove_rules:
|
|
delete_rules = remove_rules
|
|
|
|
self._remove_access_rules(context, delete_rules, share_instance['id'])
|
|
|
|
self.db.share_instance_update_access_status(
|
|
context,
|
|
share_instance['id'],
|
|
constants.STATUS_ACTIVE
|
|
)
|
|
|
|
LOG.info(_LI("Access rules were successfully applied for "
|
|
"share instance: %s"),
|
|
share_instance['id'])
|
|
|
|
def _update_access_fallback(self, add_rules, context, delete_rules,
|
|
remove_rules, share_instance, share_server):
|
|
for rule in add_rules:
|
|
LOG.info(
|
|
_LI("Applying access rule '%(rule)s' for share "
|
|
"instance '%(instance)s'"),
|
|
{'rule': rule['id'], 'instance': share_instance['id']}
|
|
)
|
|
|
|
self.driver.allow_access(
|
|
context,
|
|
share_instance,
|
|
rule,
|
|
share_server=share_server
|
|
)
|
|
|
|
# NOTE(ganso): Fallback mode temporary compatibility workaround
|
|
if remove_rules:
|
|
delete_rules = remove_rules
|
|
for rule in delete_rules:
|
|
LOG.info(
|
|
_LI("Denying access rule '%(rule)s' from share "
|
|
"instance '%(instance)s'"),
|
|
{'rule': rule['id'], 'instance': share_instance['id']}
|
|
)
|
|
|
|
self.driver.deny_access(
|
|
context,
|
|
share_instance,
|
|
rule,
|
|
share_server=share_server
|
|
)
|
|
|
|
def _remove_access_rules(self, context, access_rules, share_instance_id):
|
|
if not access_rules:
|
|
return
|
|
|
|
for rule in access_rules:
|
|
access_mapping = self.db.share_instance_access_get(
|
|
context, rule['id'], share_instance_id)
|
|
|
|
self.db.share_instance_access_delete(context, access_mapping['id'])
|