def _allow_access(self, context, share, access, share_server=None): if access['access_type'] != CEPHX_ACCESS_TYPE: raise exception.InvalidShareAccess( reason=_("Only 'cephx' access type allowed.")) ceph_auth_id = access['access_to'] # We need to check here rather than the API or Manila Client to see # if the ceph_auth_id is the same as the one specified for Manila's # usage. This is due to the fact that the API and the Manila client # cannot read the contents of the Manila configuration file. If it # is the same, we need to error out. if ceph_auth_id == CONF.cephfs_auth_id: error_message = (_('Ceph authentication ID %s must be different ' 'than the one the Manila service uses.') % ceph_auth_id) raise exception.InvalidInput(message=error_message) # TODO(rraja): Log the Ceph point release version, once available, in # which the volume client can enable read-only access. if not getattr(self.volume_client, 'version', None): if access['access_level'] == constants.ACCESS_LEVEL_RO: raise exception.InvalidShareAccessLevel( level=constants.ACCESS_LEVEL_RO) auth_result = self.volume_client.authorize( self._share_path(share), ceph_auth_id) else: readonly = access['access_level'] == constants.ACCESS_LEVEL_RO auth_result = self.volume_client.authorize( self._share_path(share), ceph_auth_id, readonly=readonly, tenant_id=share['project_id']) return auth_result['auth_key']
def _allow_access(self, context, share, access, share_server=None): if access['access_type'] != CEPHX_ACCESS_TYPE: raise exception.InvalidShareAccess( reason=_("Only 'cephx' access type allowed.")) if access['access_level'] == constants.ACCESS_LEVEL_RO: raise exception.InvalidShareAccessLevel( level=constants.ACCESS_LEVEL_RO) ceph_auth_id = access['access_to'] # We need to check here rather than the API or Manila Client to see # if the ceph_auth_id is the same as the one specified for Manila's # usage. This is due to the fact that the API and the Manila client # cannot read the contents of the Manila configuration file. If it # is the same, we need to error out. if ceph_auth_id == CONF.cephfs_auth_id: error_message = (_('Ceph authentication ID %s must be different ' 'than the one the Manila service uses.') % ceph_auth_id) raise exception.InvalidInput(message=error_message) auth_result = self.volume_client.authorize(self._share_path(share), ceph_auth_id) return auth_result['auth_key']
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.InvalidShareAccess(reason=msg) user_name = access['access_to'] if access['access_level'] == constants.ACCESS_LEVEL_RW: readonly = False elif access['access_level'] == constants.ACCESS_LEVEL_RO: readonly = True else: raise exception.InvalidShareAccessLevel( level=access['access_level']) target, share_name = self._get_export_location(share) try: self._client.add_cifs_share_access(share_name, user_name, readonly) 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
def _get_infinidat_access_level(self, access): """Translates between Manila access levels to INFINIDAT API ones""" access_level = access['access_level'] try: return _MANILA_TO_INFINIDAT_ACCESS_LEVEL[access_level] except KeyError: raise exception.InvalidShareAccessLevel(level=access_level)
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 _validate_access_rule(self, rule): """Checks whether access rule type and level are valid.""" if rule['access_type'] != 'ip': msg = _("Clustered Data ONTAP supports only 'ip' type for share " "access rules with NFS protocol.") raise exception.InvalidShareAccess(reason=msg) if rule['access_level'] not in constants.ACCESS_LEVELS: raise exception.InvalidShareAccessLevel(level=rule['access_level'])
def allow_access(self, context, share, access, share_server=None): """Allow access to the share.""" # NOTE(vponomaryov): use direct verification for case some additional # level is added. access_level = access['access_level'] if access_level not in (const.ACCESS_LEVEL_RW, const.ACCESS_LEVEL_RO): raise exception.InvalidShareAccessLevel(level=access_level) self._get_helper(share).allow_access( share_server['backend_details'], share['name'], access['access_type'], access['access_level'], access['access_to'])
def validate_access_rules(access_rules): allowed_types = {'ip'} allowed_levels = _MANILA_TO_VAST_ACCESS_LEVEL.keys() for access in (access_rules or []): access_type = access['access_type'] access_level = access['access_level'] if access_type not in allowed_types: reason = _("Only %s access type allowed.") % (', '.join( tuple(["'%s'" % x for x in allowed_types]))) raise exception.InvalidShareAccess(reason=reason) if access_level not in allowed_levels: raise exception.InvalidShareAccessLevel(level=access_level)
def allow_access(self, context, share, access, share_server=None): """Allow access to a share.""" access_level = access['access_level'] if access_level not in const.ACCESS_LEVELS: raise exception.InvalidShareAccessLevel(level=access_level) share_proto = share['share_proto'] if share_proto == 'NFS': self._nfs_allow_access(context, share, access, share_server) elif share_proto == 'CIFS': self._cifs_allow_access(context, share, access, share_server) else: raise exception.InvalidShare( reason=(_('Invalid NAS protocol supplied: %s.') % share_proto))
def _allow_access(self, context, share, access, share_server=None): if access['access_type'] != CEPHX_ACCESS_TYPE: raise exception.InvalidShareAccess( reason=_("Only 'cephx' access type allowed.")) if access['access_level'] == constants.ACCESS_LEVEL_RO: raise exception.InvalidShareAccessLevel( level=constants.ACCESS_LEVEL_RO) ceph_auth_id = access['access_to'] auth_result = self.volume_client.authorize(self._share_path(share), ceph_auth_id) return auth_result['auth_key']
def allow_access(self, server, share_name, access_type, access_level, access_to): """Add access for share.""" if access_type != 'ip': reason = _('Only ip access type allowed.') raise exception.InvalidShareAccess(reason=reason) if access_level != const.ACCESS_LEVEL_RW: raise exception.InvalidShareAccessLevel(level=access_level) hosts = self._get_allow_hosts(server, share_name) if access_to in hosts: raise exception.ShareAccessExists(access_type=access_type, access=access_to) hosts.append(access_to) self._set_allow_hosts(server, hosts, share_name)
def allow_access(self, context, share, access, share_server=None): """Allow access to a share.""" access_level = access['access_level'] if access_level not in const.ACCESS_LEVELS: raise exception.InvalidShareAccessLevel(level=access_level) share_proto = share['share_proto'].upper() self._validate_share_protocol(share_proto) self._validate_share_access_type(share, access) if share_proto == 'CIFS': self._cifs_allow_access(share, access) elif share_proto == 'NFS': self._nfs_allow_access(share, access)
def _allow_access(self, context, share, access, share_server=None): """Give access of a share to an IP.""" access_type = access['access_type'] server = access['access_to'] if access_type != 'ip': raise exception.InvalidShareAccess('Only ip access type ' 'supported.') access_level = access['access_level'] if access_level not in (const.ACCESS_LEVEL_RW, const.ACCESS_LEVEL_RO): raise exception.InvalidShareAccessLevel(level=access_level) export_path = share['export_locations'][0]['path'].split(':', 1) va_sharepath = six.text_type(export_path[1]) access_level = '%s,%s' % (six.text_type(access_level), 'sync,no_root_squash') path = self._nfs_add_str provider = '%s:%s' % (self.host, self._port) data = {} va_share_info = ("{\"share\":[{\"fileSystemPath\":\"" + va_sharepath + "\",\"shareType\":\"NFS\",\"shareDetails\":" + "[{\"client\":\"" + server + "\",\"exportOptions\":\"" + access_level + "\"}]}]}") data["shareDetails"] = va_share_info result = self._access_api(self.session, provider, path, json.dumps(data), 'POST') if not result: message = (('ACCESSShareDriver access failed sharepath %s ' 'server %s'), va_sharepath, server) LOG.error(message) raise exception.ShareBackendException(msg=message) LOG.debug("ACCESSShareDriver allow_access sharepath %s server %s", va_sharepath, server) data2 = {"type": "SHARE", "key": "manila"} data2["id"] = va_sharepath data2["value"] = 'manila_share' path = self._update_object result = self._access_api(self.session, provider, path, json.dumps(data2), 'POST')
def validate_access_rules(access_rules, allowed_types, allowed_levels): """Validates access rules according to access_type and access_level. :param access_rules: List of access rules to be validated. :param allowed_types: tuple of allowed type values. :param allowed_levels: tuple of allowed level values. """ for access in (access_rules or []): access_type = access['access_type'] access_level = access['access_level'] if access_type not in allowed_types: reason = _("Only %s access type allowed.") % ( ', '.join(tuple(["'%s'" % x for x in allowed_types]))) raise exception.InvalidShareAccess(reason=reason) if access_level not in allowed_levels: raise exception.InvalidShareAccessLevel(level=access_level)
def _allow_access(self, context, share, access, share_server=None): if access['access_type'] != CEPHX_ACCESS_TYPE: raise exception.InvalidShareAccessType(type=access['access_type']) ceph_auth_id = access['access_to'] # We need to check here rather than the API or Manila Client to see # if the ceph_auth_id is the same as the one specified for Manila's # usage. This is due to the fact that the API and the Manila client # cannot read the contents of the Manila configuration file. If it # is the same, we need to error out. if ceph_auth_id == CONF.cephfs_auth_id: error_message = (_('Ceph authentication ID %s must be different ' 'than the one the Manila service uses.') % ceph_auth_id) raise exception.InvalidShareAccess(reason=error_message) if not getattr(self.volume_client, 'version', None): if access['access_level'] == constants.ACCESS_LEVEL_RO: LOG.error("Need python-cephfs package version 10.2.3 or " "greater to enable read-only access.") raise exception.InvalidShareAccessLevel( level=constants.ACCESS_LEVEL_RO) auth_result = self.volume_client.authorize( cephfs_share_path(share), ceph_auth_id) else: readonly = access['access_level'] == constants.ACCESS_LEVEL_RO try: auth_result = self.volume_client.authorize( cephfs_share_path(share), ceph_auth_id, readonly=readonly, tenant_id=share['project_id']) except Exception as e: if 'not allowed' in str(e).lower(): msg = ("Access to client %(client)s is not allowed. " "Reason: %(reason)s") msg_payload = {'client': ceph_auth_id, 'reason': e} raise exception.InvalidShareAccess(reason=msg % msg_payload) raise return auth_result['auth_key']
def allow_access(self, context, share, share_name, access): """Allows access to a given NFS share.""" if access['access_type'] != 'ip': reason = _('Only ip access type allowed.') raise exception.InvalidShareAccess(reason) self._ensure_export_policy(share, share_name) export_policy_name = self._get_export_policy_name(share) rule = access['access_to'] if access['access_level'] == constants.ACCESS_LEVEL_RW: readonly = False elif access['access_level'] == constants.ACCESS_LEVEL_RO: readonly = True else: raise exception.InvalidShareAccessLevel( level=access['access_level']) self._client.add_nfs_export_rule(export_policy_name, rule, readonly)
def allow_access(self, context, share, share_name, access): """Allows access to a given NFS share.""" if access['access_type'] != 'ip': msg = _("Cluster Mode supports only 'ip' type for share access" " rules with NFS protocol.") raise exception.InvalidShareAccess(reason=msg) self._ensure_export_policy(share, share_name) export_policy_name = self._get_export_policy_name(share) rule = access['access_to'] if access['access_level'] == constants.ACCESS_LEVEL_RW: readonly = False elif access['access_level'] == constants.ACCESS_LEVEL_RO: readonly = True else: raise exception.InvalidShareAccessLevel( level=access['access_level']) self._client.add_nfs_export_rule(export_policy_name, rule, readonly)
def test_update_access_add_rm(self): alice = { 'id': 'instance_mapping_id1', 'access_id': 'accessid1', 'access_level': 'rw', 'access_type': 'cephx', 'access_to': 'alice' } bob = { 'id': 'instance_mapping_id2', 'access_id': 'accessid2', 'access_level': 'ro', 'access_type': 'cephx', 'access_to': 'bob' } manila = { 'id': 'instance_mapping_id3', 'access_id': 'accessid3', 'access_level': 'ro', 'access_type': 'cephx', 'access_to': 'manila' } admin = { 'id': 'instance_mapping_id4', 'access_id': 'accessid4', 'access_level': 'rw', 'access_type': 'cephx', 'access_to': 'admin' } dabo = { 'id': 'instance_mapping_id5', 'access_id': 'accessid5', 'access_level': 'rwx', 'access_type': 'cephx', 'access_to': 'dabo' } allow_access_side_effects = [ 'abc123', exception.InvalidShareAccess(reason='not'), exception.InvalidShareAccess(reason='allowed'), exception.InvalidShareAccessLevel(level='rwx') ] self.mock_object(self._native_protocol_helper.message_api, 'create') self.mock_object(self._native_protocol_helper, '_deny_access') self.mock_object(self._native_protocol_helper, '_allow_access', mock.Mock(side_effect=allow_access_side_effects)) access_updates = self._native_protocol_helper.update_access( self._context, self._share, access_rules=[alice, manila, admin, dabo], add_rules=[alice, manila, admin, dabo], delete_rules=[bob]) expected_access_updates = { 'accessid1': {'access_key': 'abc123'}, 'accessid3': {'state': 'error'}, 'accessid4': {'state': 'error'}, 'accessid5': {'state': 'error'} } self.assertEqual(expected_access_updates, access_updates) self._native_protocol_helper._allow_access.assert_has_calls( [mock.call(self._context, self._share, alice), mock.call(self._context, self._share, manila), mock.call(self._context, self._share, admin)]) self._native_protocol_helper._deny_access.assert_called_once_with( self._context, self._share, bob) self.assertEqual( 3, self._native_protocol_helper.message_api.create.call_count)