manila/manila/share/drivers/container/protocol_helper.py

144 lines
5.5 KiB
Python

# Copyright (c) 2016 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.
import re
from oslo_log import log
from manila.common import constants as const
from manila import exception
from manila.i18n import _, _LW
LOG = log.getLogger(__name__)
class DockerCIFSHelper(object):
def __init__(self, container_helper, *args, **kwargs):
super(DockerCIFSHelper, self).__init__()
self.share = kwargs.get("share")
self.conf = kwargs.get("config")
self.container = container_helper
def create_share(self, server_id):
share_name = self.share.share_id
cmd = ["net", "conf", "addshare", share_name,
"/shares/%s" % share_name, "writeable=y"]
if self.conf.container_cifs_guest_ok:
cmd.append("guest_ok=y")
else:
cmd.append("guest_ok=n")
self.container.execute(server_id, cmd)
parameters = {
"browseable": "yes",
"create mask": "0755",
"read only": "no",
}
for param, value in parameters.items():
self.container.execute(
server_id,
["net", "conf", "setparm", share_name, param, value]
)
result = self.container.execute(
server_id,
["ip", "addr", "show", "eth0"]
)[0].split('\n')[2]
address = re.findall("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", result)[0]
return r"//%(addr)s/%(name)s" % {"addr": address, "name": share_name}
def delete_share(self, server_id):
self.container.execute(
server_id,
["net", "conf", "delshare", self.share.share_id]
)
def _get_access_group(self, access_level):
if access_level == const.ACCESS_LEVEL_RO:
access = "read list"
elif access_level == const.ACCESS_LEVEL_RW:
access = "valid users"
else:
raise exception.InvalidShareAccessLevel(level=access_level)
return access
def _get_existing_users(self, server_id, share_name, access):
result = self.container.execute(
server_id,
["net", "conf", "getparm", share_name, access]
)[0].rstrip('\n')
return result
def _set_users(self, server_id, share_name, access, users_to_set):
self.container.execute(
server_id,
["net", "conf", "setparm", share_name, access, users_to_set]
)
def _allow_access(self, share_name, server_id, user_to_allow,
access_level):
access = self._get_access_group(access_level)
try:
existing_users = self._get_existing_users(server_id, share_name,
access)
except TypeError:
users_to_allow = user_to_allow
else:
users_to_allow = " ".join([existing_users, user_to_allow])
self._set_users(server_id, share_name, access, users_to_allow)
def _deny_access(self, share_name, server_id, user_to_deny,
access_level):
access = self._get_access_group(access_level)
try:
existing_users = self._get_existing_users(server_id, share_name,
access)
except TypeError:
LOG.warning(_LW("Can't access smbd at share %s.") % share_name)
return
else:
allowed_users = " ".join(sorted(set(existing_users.split()) -
set([user_to_deny])))
if allowed_users != existing_users:
self._set_users(server_id, share_name, access, allowed_users)
def update_access(self, server_id, access_rules,
add_rules=None, delete_rules=None):
def _rule_updater(rules, action, override_type_check=False):
for rule in rules:
access_level = rule['access_level']
access_type = rule['access_type']
# (aovchinnikov): override_type_check is used to ensure
# broken rules deletion.
if access_type == 'user' or override_type_check:
action(share_name, server_id, rule['access_to'],
access_level)
else:
msg = _("Access type '%s' is not supported by the "
"driver.") % access_type
raise exception.InvalidShareAccess(reason=msg)
share_name = self.share.share_id
if not (add_rules or delete_rules):
# clean all users first.
self.container.execute(
server_id,
["net", "conf", "setparm", share_name, "valid users", ""]
)
_rule_updater(access_rules or [], self._allow_access)
return
_rule_updater(add_rules or [], self._allow_access)
_rule_updater(delete_rules or [], self._deny_access,
override_type_check=True)