"Fossies" - the Fresh Open Source Software Archive

Member "manila-8.1.4/manila/share/drivers/netapp/dataontap/protocols/cifs_cmode.py" (19 Nov 2020, 7286 Bytes) of package /linux/misc/openstack/manila-8.1.4.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "cifs_cmode.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 8.1.3_vs_8.1.4.

    1 # Copyright (c) 2015 Clinton Knight.  All rights reserved.
    2 #
    3 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    4 #    not use this file except in compliance with the License. You may obtain
    5 #    a copy of the License at
    6 #
    7 #         http://www.apache.org/licenses/LICENSE-2.0
    8 #
    9 #    Unless required by applicable law or agreed to in writing, software
   10 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   11 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   12 #    License for the specific language governing permissions and limitations
   13 #    under the License.
   14 """
   15 NetApp cDOT CIFS protocol helper class.
   16 """
   17 
   18 import re
   19 
   20 from manila.common import constants
   21 from manila import exception
   22 from manila.i18n import _
   23 from manila.share.drivers.netapp.dataontap.protocols import base
   24 from manila.share.drivers.netapp import utils as na_utils
   25 
   26 
   27 class NetAppCmodeCIFSHelper(base.NetAppBaseHelper):
   28     """NetApp cDOT CIFS protocol helper class."""
   29 
   30     @na_utils.trace
   31     def create_share(self, share, share_name,
   32                      clear_current_export_policy=True):
   33         """Creates CIFS share on Data ONTAP Vserver."""
   34         self._client.create_cifs_share(share_name)
   35         if clear_current_export_policy:
   36             self._client.remove_cifs_share_access(share_name, 'Everyone')
   37 
   38         # Ensure 'ntfs' security style
   39         self._client.set_volume_security_style(share_name,
   40                                                security_style='ntfs')
   41 
   42         # Return a callback that may be used for generating export paths
   43         # for this share.
   44         return (lambda export_address, share_name=share_name:
   45                 r'\\%s\%s' % (export_address, share_name))
   46 
   47     @na_utils.trace
   48     def delete_share(self, share, share_name):
   49         """Deletes CIFS share on Data ONTAP Vserver."""
   50         host_ip, share_name = self._get_export_location(share)
   51         self._client.remove_cifs_share(share_name)
   52 
   53     @na_utils.trace
   54     @base.access_rules_synchronized
   55     def update_access(self, share, share_name, rules):
   56         """Replaces the list of access rules known to the backend storage."""
   57 
   58         # Ensure rules are valid
   59         for rule in rules:
   60             self._validate_access_rule(rule)
   61 
   62         new_rules = {rule['access_to']: rule['access_level'] for rule in rules}
   63 
   64         # Get rules from share
   65         existing_rules = self._get_access_rules(share, share_name)
   66 
   67         # Update rules in an order that will prevent transient disruptions
   68         self._handle_added_rules(share_name, existing_rules, new_rules)
   69         self._handle_ro_to_rw_rules(share_name, existing_rules, new_rules)
   70         self._handle_rw_to_ro_rules(share_name, existing_rules, new_rules)
   71         self._handle_deleted_rules(share_name, existing_rules, new_rules)
   72 
   73     @na_utils.trace
   74     def _validate_access_rule(self, rule):
   75         """Checks whether access rule type and level are valid."""
   76 
   77         if rule['access_type'] != 'user':
   78             msg = _("Clustered Data ONTAP supports only 'user' type for "
   79                     "share access rules with CIFS protocol.")
   80             raise exception.InvalidShareAccess(reason=msg)
   81 
   82         if rule['access_level'] not in constants.ACCESS_LEVELS:
   83             raise exception.InvalidShareAccessLevel(level=rule['access_level'])
   84 
   85     @na_utils.trace
   86     def _handle_added_rules(self, share_name, existing_rules, new_rules):
   87         """Updates access rules added between two rule sets."""
   88         added_rules = {
   89             user_or_group: permission
   90             for user_or_group, permission in new_rules.items()
   91             if user_or_group not in existing_rules
   92         }
   93 
   94         for user_or_group, permission in added_rules.items():
   95             self._client.add_cifs_share_access(
   96                 share_name, user_or_group, self._is_readonly(permission))
   97 
   98     @na_utils.trace
   99     def _handle_ro_to_rw_rules(self, share_name, existing_rules, new_rules):
  100         """Updates access rules modified (RO-->RW) between two rule sets."""
  101         modified_rules = {
  102             user_or_group: permission
  103             for user_or_group, permission in new_rules.items()
  104             if (user_or_group in existing_rules and
  105                 permission == constants.ACCESS_LEVEL_RW and
  106                 existing_rules[user_or_group] != 'full_control')
  107         }
  108 
  109         for user_or_group, permission in modified_rules.items():
  110             self._client.modify_cifs_share_access(
  111                 share_name, user_or_group, self._is_readonly(permission))
  112 
  113     @na_utils.trace
  114     def _handle_rw_to_ro_rules(self, share_name, existing_rules, new_rules):
  115         """Returns access rules modified (RW-->RO) between two rule sets."""
  116         modified_rules = {
  117             user_or_group: permission
  118             for user_or_group, permission in new_rules.items()
  119             if (user_or_group in existing_rules and
  120                 permission == constants.ACCESS_LEVEL_RO and
  121                 existing_rules[user_or_group] != 'read')
  122         }
  123 
  124         for user_or_group, permission in modified_rules.items():
  125             self._client.modify_cifs_share_access(
  126                 share_name, user_or_group, self._is_readonly(permission))
  127 
  128     @na_utils.trace
  129     def _handle_deleted_rules(self, share_name, existing_rules, new_rules):
  130         """Returns access rules deleted between two rule sets."""
  131         deleted_rules = {
  132             user_or_group: permission
  133             for user_or_group, permission in existing_rules.items()
  134             if user_or_group not in new_rules
  135         }
  136 
  137         for user_or_group, permission in deleted_rules.items():
  138             self._client.remove_cifs_share_access(share_name, user_or_group)
  139 
  140     @na_utils.trace
  141     def _get_access_rules(self, share, share_name):
  142         """Returns the list of access rules known to the backend storage."""
  143         return self._client.get_cifs_share_access(share_name)
  144 
  145     @na_utils.trace
  146     def get_target(self, share):
  147         """Returns OnTap target IP based on share export location."""
  148         return self._get_export_location(share)[0]
  149 
  150     @na_utils.trace
  151     def get_share_name_for_share(self, share):
  152         """Returns the flexvol name that hosts a share."""
  153         _, share_name = self._get_export_location(share)
  154         return share_name
  155 
  156     @staticmethod
  157     def _get_export_location(share):
  158         """Returns host ip and share name for a given CIFS share."""
  159         export_location = share['export_location'] or '\\\\\\'
  160         regex = r'^(?:\\\\|//)(?P<host_ip>.*)(?:\\|/)(?P<share_name>.*)$'
  161         match = re.match(regex, export_location)
  162         if match:
  163             return match.group('host_ip'), match.group('share_name')
  164         else:
  165             return '', ''
  166 
  167     @na_utils.trace
  168     def cleanup_demoted_replica(self, share, share_name):
  169         """Cleans up some things regarding a demoted replica."""
  170         # NOTE(carloss): This is necessary due to bug 1879368. If we do not
  171         # remove this CIFS share, in case the demoted replica is promoted
  172         # back, the promotion will fail due to a duplicated entry for the
  173         # share, since a create share request is sent to the backend every
  174         # time a promotion occurs.
  175         self._client.remove_cifs_share(share_name)