Skip to content

Commit

Permalink
update access_rule
Browse files Browse the repository at this point in the history
Change-Id: I5127bf64bfa39ed20e0dac58b6be31924c5faaba
  • Loading branch information
kpawar-sap committed Oct 10, 2024
1 parent 00b8c6f commit 094f3c6
Show file tree
Hide file tree
Showing 70 changed files with 352 additions and 147 deletions.
36 changes: 36 additions & 0 deletions manila/api/v2/share_accesses.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from manila.api.openstack import wsgi
from manila.api.views import share_accesses as share_access_views
from manila.common import constants
from manila import exception
from manila.i18n import _
from manila import share
Expand Down Expand Up @@ -76,6 +77,41 @@ def index(self, req):

return self._view_builder.list_view(req, access_rules)

def update(self, req, id, body):
"""Update access level of the given share access rule."""
context = req.environ['manila.context']
if not self.is_valid_body(body, 'update_access'):
raise webob.exc.HTTPBadRequest()

access_data = body['update_access']
share_access = self._get_share_access(context, id)
if share_access['access_type'] != 'ip':
msg = _("Invalid access_type. Only allowed to "
"update 'ip' access_type.")
raise webob.exc.HTTPBadRequest(explanation=msg)

access_level = access_data.get('access_level', None)
if not access_level:
msg = _("Invalid input. Missing 'access_level' in "
"update request.")
raise webob.exc.HTTPBadRequest(explanation=msg)

if access_level not in constants.ACCESS_LEVELS:
msg = _("Invalid or unsupported share access "
"level: %s.") % access_level
raise webob.exc.HTTPBadRequest(explanation=msg)

if access_level == share_access.access_level:
return self._view_builder.view(req, share_access)

share = self.share_api.get(context, share_access.share_id)
values = {
'access_level': access_level,
}
access = self.share_api.update_access(
context, share, share_access, values)
return self._view_builder.view(req, access)


def create_resource():
return wsgi.Resource(ShareAccessesController())
4 changes: 4 additions & 0 deletions manila/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@
# Access rule states
ACCESS_STATE_QUEUED_TO_APPLY = 'queued_to_apply'
ACCESS_STATE_QUEUED_TO_DENY = 'queued_to_deny'
ACCESS_STATE_QUEUED_TO_UPDATE = 'queued_to_update'
ACCESS_STATE_APPLYING = 'applying'
ACCESS_STATE_DENYING = 'denying'
ACCESS_STATE_UPDATING = 'updating'
ACCESS_STATE_ACTIVE = 'active'
ACCESS_STATE_ERROR = 'error'
ACCESS_STATE_DELETED = 'deleted'
Expand Down Expand Up @@ -82,8 +84,10 @@
ACCESS_RULES_STATES = (
ACCESS_STATE_QUEUED_TO_APPLY,
ACCESS_STATE_QUEUED_TO_DENY,
ACCESS_STATE_QUEUED_TO_UPDATE,
ACCESS_STATE_APPLYING,
ACCESS_STATE_DENYING,
ACCESS_STATE_UPDATING,
ACCESS_STATE_ACTIVE,
ACCESS_STATE_ERROR,
ACCESS_STATE_DELETED,
Expand Down
5 changes: 5 additions & 0 deletions manila/db/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,11 @@ def share_access_create(context, values):
return IMPL.share_access_create(context, values)


def share_access_update(context, access_id, values):
"""Update access to share."""
return IMPL.share_access_update(context, access_id, values)


def share_access_get(context, access_id):
"""Get share access rule."""
return IMPL.share_access_get(context, access_id)
Expand Down
9 changes: 9 additions & 0 deletions manila/db/sqlalchemy/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2804,6 +2804,15 @@ def share_access_create(context, values):
return share_access_get(context, access_ref['id'])


@require_context
@context_manager.writer
def share_access_update(context, access_id, values):
access_ref = share_access_get(context, access_id)
access_ref.update(values)
access_ref.save(session=context.session)
return access_ref


@require_context
def share_instance_access_create(context, values, share_instance_id):
values = ensure_model_dict_has_id(values)
Expand Down
30 changes: 24 additions & 6 deletions manila/share/access.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,8 @@ def update_access_rules(self, context, share_instance_id,
# Is there a sync in progress? If yes, ignore the incoming request.
rule_filter = {
'state': (constants.ACCESS_STATE_APPLYING,
constants.ACCESS_STATE_DENYING),
constants.ACCESS_STATE_DENYING,
constants.ACCESS_STATE_UPDATING),
}
syncing_rules = self.get_and_update_share_instance_access_rules(
context, filters=rule_filter, share_instance_id=share_instance_id)
Expand Down Expand Up @@ -332,7 +333,8 @@ def _update_access_rules(self, context, share_instance_id,

rules_to_be_removed_from_db = []
# Populate rules to send to the driver
(access_rules_to_be_on_share, add_rules, delete_rules) = (
(access_rules_to_be_on_share, add_rules,
delete_rules, update_rules) = (
self._get_rules_to_send_to_driver(context, share_instance)
)

Expand All @@ -343,11 +345,13 @@ def _update_access_rules(self, context, share_instance_id,
add_rules = []
rules_to_be_removed_from_db = delete_rules
delete_rules = []
update_rules = []

try:
driver_rule_updates = self._update_rules_through_share_driver(
context, share_instance, access_rules_to_be_on_share,
add_rules, delete_rules, rules_to_be_removed_from_db,
add_rules, delete_rules, update_rules,
rules_to_be_removed_from_db,
share_server)

self.process_driver_rule_updates(
Expand All @@ -356,6 +360,7 @@ def _update_access_rules(self, context, share_instance_id,
# Update access rules that are still in 'applying' state
conditionally_change = {
constants.ACCESS_STATE_APPLYING: constants.ACCESS_STATE_ACTIVE,
constants.ACCESS_STATE_UPDATING: constants.ACCESS_STATE_ACTIVE
}
self.get_and_update_share_instance_access_rules(
context, share_instance_id=share_instance_id,
Expand All @@ -365,6 +370,7 @@ def _update_access_rules(self, context, share_instance_id,
conditionally_change_rule_state = {
constants.ACCESS_STATE_APPLYING: constants.ACCESS_STATE_ERROR,
constants.ACCESS_STATE_DENYING: constants.ACCESS_STATE_ERROR,
constants.ACCESS_STATE_UPDATING: constants.ACCESS_STATE_ERROR,
}
self.get_and_update_share_instance_access_rules(
context, share_instance_id=share_instance_id,
Expand Down Expand Up @@ -399,6 +405,7 @@ def _update_access_rules(self, context, share_instance_id,
def _update_rules_through_share_driver(self, context, share_instance,
access_rules_to_be_on_share,
add_rules, delete_rules,
update_rules,
rules_to_be_removed_from_db,
share_server):
driver_rule_updates = {}
Expand All @@ -407,6 +414,7 @@ def _update_rules_through_share_driver(self, context, share_instance,
share_protocol == 'nfs'):
add_rules = self._filter_ipv6_rules(add_rules)
delete_rules = self._filter_ipv6_rules(delete_rules)
update_rules = self._filter_ipv6_rules(update_rules)
access_rules_to_be_on_share = self._filter_ipv6_rules(
access_rules_to_be_on_share)
try:
Expand All @@ -416,6 +424,7 @@ def _update_rules_through_share_driver(self, context, share_instance,
access_rules_to_be_on_share,
add_rules=add_rules,
delete_rules=delete_rules,
update_rules=update_rules,
share_server=share_server
) or {}
except NotImplementedError:
Expand Down Expand Up @@ -476,6 +485,7 @@ def process_driver_rule_updates(self, context, driver_rule_updates,
conditional_state_updates = {
constants.ACCESS_STATE_APPLYING: state,
constants.ACCESS_STATE_DENYING: state,
constants.ACCESS_STATE_UPDATING: state,
constants.ACCESS_STATE_ACTIVE: state,
}
else:
Expand Down Expand Up @@ -513,10 +523,12 @@ def _filter_ipv6_rules(rules):
def _get_rules_to_send_to_driver(self, context, share_instance):
add_rules = []
delete_rules = []
update_rules = []
access_filters = {
'state': (constants.ACCESS_STATE_APPLYING,
constants.ACCESS_STATE_ACTIVE,
constants.ACCESS_STATE_DENYING),
constants.ACCESS_STATE_DENYING,
constants.ACCESS_STATE_UPDATING),
}
existing_rules_in_db = self.get_and_update_share_instance_access_rules(
context, filters=access_filters,
Expand All @@ -528,11 +540,14 @@ def _get_rules_to_send_to_driver(self, context, share_instance):
add_rules.append(rule)
elif rule['state'] == constants.ACCESS_STATE_DENYING:
delete_rules.append(rule)
elif rule['state'] == constants.ACCESS_STATE_UPDATING:
update_rules.append(rule)
delete_rule_ids = [r['id'] for r in delete_rules]
access_rules_to_be_on_share = [
r for r in existing_rules_in_db if r['id'] not in delete_rule_ids
]
return access_rules_to_be_on_share, add_rules, delete_rules
return (access_rules_to_be_on_share, add_rules,
delete_rules, update_rules)

def _check_needs_refresh(self, context, share_instance_id):
rules_to_apply_or_deny = (
Expand Down Expand Up @@ -579,13 +594,16 @@ def _update_and_get_unsynced_access_rules_from_db(self, context,
share_instance_id):
rule_filter = {
'state': (constants.ACCESS_STATE_QUEUED_TO_APPLY,
constants.ACCESS_STATE_QUEUED_TO_DENY),
constants.ACCESS_STATE_QUEUED_TO_DENY,
constants.ACCESS_STATE_QUEUED_TO_UPDATE),
}
conditionally_change = {
constants.ACCESS_STATE_QUEUED_TO_APPLY:
constants.ACCESS_STATE_APPLYING,
constants.ACCESS_STATE_QUEUED_TO_DENY:
constants.ACCESS_STATE_DENYING,
constants.ACCESS_STATE_QUEUED_TO_UPDATE:
constants.ACCESS_STATE_UPDATING,
}
rules_to_apply_or_deny = (
self.get_and_update_share_instance_access_rules(
Expand Down
24 changes: 24 additions & 0 deletions manila/share/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,30 @@ def _conditionally_transition_share_instance_access_rules_status(
context, conditionally_change=conditionally_change,
share_instance_id=share_instance['id'])

def update_access(self, ctx, share, access, values):

if self._any_invalid_share_instance(share, allow_on_error_state=True):
msg = _("Access rules cannot be updated while the share, "
"any of its replicas or migration copies lacks a valid "
"host or is in an invalid state.")
raise exception.InvalidShare(message=msg)

access = self.db.share_access_update(ctx, access['id'], values)
for share_instance in share.instances:
self.update_access_to_instance(ctx, share_instance, access)

return access

def update_access_to_instance(self, context, share_instance, access):
self._conditionally_transition_share_instance_access_rules_status(
context, share_instance)
updates = {'state': constants.ACCESS_STATE_QUEUED_TO_UPDATE}
self.access_helper.get_and_update_share_instance_access_rule(
context, access['id'], updates=updates,
share_instance_id=share_instance['id'])

self.share_rpcapi.update_access(context, share_instance)

def deny_access(self, ctx, share, access, allow_on_error_state=False):
"""Deny access to share."""

Expand Down
2 changes: 1 addition & 1 deletion manila/share/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,7 +801,7 @@ def deny_access(self, context, share, access, share_server=None):
raise NotImplementedError()

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules for given share.
``access_rules`` contains all access_rules that need to be on the
Expand Down
4 changes: 2 additions & 2 deletions manila/share/drivers/cephfs/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ def delete_share(self, context, share, share_server=None):
rados_command(self.rados_client, "fs subvolume rm", argdict)

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_access, share_server=None):
return self.protocol_helper.update_access(
context, share, access_rules, add_rules, delete_rules,
share_server=share_server)
Expand Down Expand Up @@ -895,7 +895,7 @@ def _deny_access(self, context, share, access, share_server=None):
rados_command(self.rados_client, "fs subvolume evict", argdict)

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
access_updates = {}

argdict = {
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/container/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def ensure_share(self, context, share, share_server=None):
pass

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
server_id = self._get_container_name(share_server["id"])
share_name = self._get_share_name(share)
LOG.debug("Updating access to share %(share)s at "
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/dell_emc/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def deny_access(self, context, share, access, share_server=None):
self.plugin.deny_access(context, share, access, share_server)

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access to the share."""
self.plugin.update_access(context, share, access_rules, add_rules,
delete_rules, share_server)
Expand Down
6 changes: 3 additions & 3 deletions manila/share/drivers/ganesha/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def init_helper(self):

@abc.abstractmethod
def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules of share."""


Expand Down Expand Up @@ -155,7 +155,7 @@ def _deny_access(self, base_path, share, access):
self.ganesha.remove_export("%s--%s" % (share['name'], access['id']))

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules of share."""
rule_state_map = {}
if not (add_rules or delete_rules):
Expand Down Expand Up @@ -226,7 +226,7 @@ def _get_export_pseudo_path(self, share):
raise NotImplementedError()

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules of share.
Creates an export per share. Modifies access rules of shares by
Expand Down
5 changes: 3 additions & 2 deletions manila/share/drivers/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ def ensure_share(self, context, share, share_server=None):

@ensure_server
def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules for given share.
This driver has two different behaviors according to parameters:
Expand All @@ -877,7 +877,8 @@ def update_access(self, context, share, access_rules, add_rules,
self._get_helper(share).update_access(share_server['backend_details'],
share['name'], access_rules,
add_rules=add_rules,
delete_rules=delete_rules)
delete_rules=delete_rules,
update_rules=update_rules)

def _get_helper(self, share):
helper = self._helpers.get(share['share_proto'])
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/glusterfs/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def validator(rule):
return validator

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules for given share.
Driver supports 2 different cases in this method:
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/hitachi/hnas/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def __init__(self, *args, **kwargs):
job_timeout)

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access rules for given share.
:param context: The `context.RequestContext` object for the request
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/hitachi/hsp/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def delete_share(self, context, share, share_server=None):
{'shr': share['id']})

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):

LOG.debug("Updating access rules for share: %(shr)s.",
{'shr': share['id']})
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/hpe/hpe_3par_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ def ensure_share(self, context, share, share_server=None):
pass

def update_access(self, context, share, access_rules, add_rules,
delete_rules, share_server=None):
delete_rules, update_rules, share_server=None):
"""Update access to the share."""
extra_specs = None
if 'NFS' == share['share_proto']: # Avoiding DB call otherwise
Expand Down
2 changes: 1 addition & 1 deletion manila/share/drivers/huawei/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def ensure_share(self, share, share_server=None):

@abc.abstractmethod
def update_access(self, share, access_rules, add_rules,
delete_rules, share_server):
delete_rules, update_rules, share_server):
"""Update access rules list."""

@abc.abstractmethod
Expand Down
Loading

0 comments on commit 094f3c6

Please sign in to comment.