Coverage for manila/share/drivers/container/security_service_helper.py: 100%
54 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
1# Copyright (c) 2021 NetApp, Inc.
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
17from oslo_log import log as logging
19from manila import exception
20from manila.i18n import _
21from manila.share import driver
22from manila import utils as manila_utils
24# LDAP error codes
25LDAP_INVALID_CREDENTIALS = 49
27LOG = logging.getLogger(__name__)
30class SecurityServiceHelper(driver.ExecuteMixin):
31 def __init__(self, *args, **kwargs):
32 self.configuration = kwargs.pop("configuration", None)
33 super(SecurityServiceHelper, self).__init__(*args, **kwargs)
34 self.init_execute_mixin()
36 def setup_security_service(self, share_server_id, security_service):
37 msg = ("Setting up the security service %(service)s for share server "
38 "%(server_id)s")
39 msg_args = {
40 'service': security_service['id'],
41 'server_id': share_server_id
42 }
43 LOG.debug(msg, msg_args)
44 self.ldap_bind(share_server_id, security_service)
46 def update_security_service(self, server_id, current_security_service,
47 new_security_service):
48 msg = ("Updating the security service %(service)s for share server "
49 "%(server_id)s")
50 msg_args = {
51 'service': new_security_service['id'],
52 'server_id': server_id
53 }
54 LOG.debug(msg, msg_args)
55 self.ldap_bind(server_id, new_security_service)
57 def ldap_bind(self, share_server_id, security_service):
58 ss_info = self.ldap_get_info(security_service)
59 cmd = ["docker", "exec", "%s" % share_server_id, "ldapwhoami", "-x",
60 "-H", "ldap://localhost:389", "-D",
61 "cn=%s,dc=example,dc=com" % ss_info["ss_user"], "-w", "%s" %
62 ss_info["ss_password"]]
63 self.ldap_retry_operation(cmd, run_as_root=True)
65 def ldap_get_info(self, security_service):
66 if all(info in security_service for info in ("user", "password")):
67 ss_user = security_service["user"]
68 ss_password = security_service["password"]
69 else:
70 raise exception.ShareBackendException(
71 _("LDAP requires user and password to be set for the bind "
72 "operation."))
73 ss_info = {
74 "ss_user": ss_user,
75 "ss_password": ss_password,
76 }
77 return ss_info
79 def ldap_retry_operation(self, cmd, run_as_root=True, timeout=30):
80 interval = 5
81 retries = int(timeout / interval) or 1
83 @manila_utils.retry(retry_param=exception.ProcessExecutionError,
84 interval=interval,
85 retries=retries, backoff_rate=1)
86 def try_ldap_operation():
87 try:
88 self._execute(*cmd, run_as_root=run_as_root)
89 except exception.ProcessExecutionError as e:
90 if e.exit_code == LDAP_INVALID_CREDENTIALS:
91 msg = _('LDAP credentials are invalid. '
92 'Aborting operation.')
93 LOG.warning(msg)
94 raise exception.ShareBackendException(msg=msg)
95 else:
96 msg = _('Command has returned execution error.'
97 ' Will retry the operation.'
98 ' Error details: %s') % e.stderr
99 LOG.warning(msg)
100 raise exception.ProcessExecutionError()
102 try:
103 try_ldap_operation()
104 except exception.ProcessExecutionError as e:
105 msg = _("Unable to execute LDAP operation with success. "
106 "Retries exhausted. Error details: %s") % e.stderr
107 LOG.exception(msg)
108 raise exception.ShareBackendException(msg=msg)