103 lines
4.0 KiB
Python
103 lines
4.0 KiB
Python
# Copyright (c) 2015 Clinton Knight. 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.
|
|
"""
|
|
NetApp CIFS protocol helper class.
|
|
"""
|
|
|
|
import re
|
|
|
|
from oslo_log import log
|
|
|
|
from manila import exception
|
|
from manila.i18n import _, _LE
|
|
from manila.share.drivers.netapp.dataontap.client import api as netapp_api
|
|
from manila.share.drivers.netapp.dataontap.protocols import base
|
|
from manila.share.drivers.netapp import utils as na_utils
|
|
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class NetAppCmodeCIFSHelper(base.NetAppBaseHelper):
|
|
"""Netapp specific cluster-mode CIFS sharing driver."""
|
|
|
|
@na_utils.trace
|
|
def create_share(self, share, share_name, export_addresses):
|
|
"""Creates CIFS share on Data ONTAP Vserver."""
|
|
self._client.create_cifs_share(share_name)
|
|
self._client.remove_cifs_share_access(share_name, 'Everyone')
|
|
return [r'\\%s\%s' % (export_address, share_name)
|
|
for export_address in export_addresses]
|
|
|
|
@na_utils.trace
|
|
def delete_share(self, share, share_name):
|
|
"""Deletes CIFS share on Data ONTAP Vserver."""
|
|
host_ip, share_name = self._get_export_location(share)
|
|
self._client.remove_cifs_share(share_name)
|
|
|
|
@na_utils.trace
|
|
def allow_access(self, context, share, share_name, access):
|
|
"""Allows access to the CIFS share for a given user."""
|
|
if access['access_type'] != 'user':
|
|
msg = _("Cluster Mode supports only 'user' type for share access"
|
|
" rules with CIFS protocol.")
|
|
raise exception.NetAppException(msg)
|
|
|
|
target, share_name = self._get_export_location(share)
|
|
try:
|
|
self._client.add_cifs_share_access(share_name, access['access_to'])
|
|
except netapp_api.NaApiError as e:
|
|
if e.code == netapp_api.EDUPLICATEENTRY:
|
|
# Duplicate entry, so use specific exception.
|
|
raise exception.ShareAccessExists(
|
|
access_type=access['access_type'], access=access)
|
|
raise e
|
|
|
|
@na_utils.trace
|
|
def deny_access(self, context, share, share_name, access):
|
|
"""Denies access to the CIFS share for a given user."""
|
|
host_ip, share_name = self._get_export_location(share)
|
|
user_name = access['access_to']
|
|
try:
|
|
self._client.remove_cifs_share_access(share_name, user_name)
|
|
except netapp_api.NaApiError as e:
|
|
if e.code == netapp_api.EONTAPI_EINVAL:
|
|
LOG.error(_LE("User %s does not exist."), user_name)
|
|
elif e.code == netapp_api.EOBJECTNOTFOUND:
|
|
LOG.error(_LE("Rule %s does not exist."), user_name)
|
|
else:
|
|
raise e
|
|
|
|
@na_utils.trace
|
|
def get_target(self, share):
|
|
"""Returns OnTap target IP based on share export location."""
|
|
return self._get_export_location(share)[0]
|
|
|
|
@na_utils.trace
|
|
def get_share_name_for_share(self, share):
|
|
"""Returns the flexvol name that hosts a share."""
|
|
_, share_name = self._get_export_location(share)
|
|
return share_name
|
|
|
|
@staticmethod
|
|
def _get_export_location(share):
|
|
"""Returns host ip and share name for a given CIFS share."""
|
|
export_location = share['export_location'] or '\\\\\\'
|
|
regex = r'^(?:\\\\|//)(?P<host_ip>.*)(?:\\|/)(?P<share_name>.*)$'
|
|
match = re.match(regex, export_location)
|
|
if match:
|
|
return match.group('host_ip'), match.group('share_name')
|
|
else:
|
|
return '', ''
|