def update_access(self, context, share, access_rules, add_rules, delete_rules, share_server=None): if not (add_rules or delete_rules): volName = self.private_storage.get(share['id'], 'volName') LOG.debug('volName: %s', volName) if volName is None: LOG.debug('Share %s does not exist', share['id']) raise exception.ShareResourceNotFound(share_id=share['id']) # Clear all current ACLs self.api_executor.set_nfs_access(volName, 2, "all") vol_name_timestamp = self._get_timestamp_from_vol_name(volName) host_list = self.api_executor.get_host_list() LOG.debug('host_list:%s', host_list) vol_host_list = self._get_vol_host(host_list, vol_name_timestamp) # If host already exist, delete the host if len(vol_host_list) > 0: for vol_host in vol_host_list: self.api_executor.delete_host(vol_host['name']) # Add each one through all rules. for access in access_rules: self._allow_access(context, share, access, share_server) else: # Adding/Deleting specific rules for access in delete_rules: self._deny_access(context, share, access, share_server) for access in add_rules: self._allow_access(context, share, access, share_server)
def update_access(self, context, share, access_rules, add_rules, delete_rules, share_server=None): if not (add_rules or delete_rules): volName = self.private_storage.get(share['id'], 'volName') LOG.debug('volName: %s', volName) if volName is None: LOG.debug('Share %s does not exist', share['id']) raise exception.ShareResourceNotFound(share_id=share['id']) # Clear all current ACLs self.api_executor.set_nfs_access(volName, 2, "all") # Add each one through all rules. for access in access_rules: self._allow_access(context, share, access, share_server) else: # Adding/Deleting specific rules for access in delete_rules: self._deny_access(context, share, access, share_server) for access in add_rules: self._allow_access(context, share, access, share_server)
def ensure_share(self, context, share, share_server=None): """Invoked to ensure that share is exported. :param context: The `context.RequestContext` object for the request :param share: Share instance that will be checked. :param share_server: Data structure with share server information. Not used by this driver. :returns: IP:<nfs_export_path> of share :raises: :ShareResourceNotFound: If the share instance cannot be found in the backend """ volume_uuid = self._resolve_volume_name( share['name'], self._get_project_name(context, share['project_id'])) LOG.debug("Ensuring Quobyte share %s", share['name']) if not volume_uuid: raise (exception.ShareResourceNotFound(share_id=share['id'])) result = self.rpc.call('exportVolume', dict(volume_uuid=volume_uuid, protocol='NFS')) return '%(nfs_server_ip)s:%(nfs_export_path)s' % result
def extend_share(self, share, new_size, share_server=None): """Extend an existing share.""" LOG.debug( 'Entering extend_share share_name=%(share_name)s ' 'share_id=%(share_id)s ' 'new_size=%(size)s', { 'share_name': share['display_name'], 'share_id': share['id'], 'size': new_size }) # Use private_storage to retrieve volume Name created in the NAS. volName = self.private_storage.get(share['id'], 'volName') if not volName: LOG.debug('Share %s does not exist', share['id']) raise exception.ShareResourceNotFound(share_id=share['id']) LOG.debug('volName: %s', volName) share_dict = { 'sharename': volName, 'old_sharename': volName, 'new_size': new_size, 'share_proto': share['share_proto'] } self.api_executor.edit_share(share_dict)
def _get_infinidat_filesystem_by_name(self, name): filesystem = self._system.filesystems.safe_get(name=name) if filesystem is None: msg = (_('Filesystem not found on the Infinibox by its name: %s') % name) LOG.error(msg) raise exception.ShareResourceNotFound(share_id=name) return filesystem
def test_manage_no_share_details(self): self.mock_object(self._driver, '_get_share_details') self._driver._get_share_details.side_effect = ( exception.ShareResourceNotFound(share_id=self.share['name'])) self.assertRaises(exception.ShareResourceNotFound, self._driver.manage_existing, self.share, self.driver_options)
def test_delete_snapshot_not_found(self): self.mock_object( self.driver, "_get_flashblade_snapshot_by_name", mock.Mock(side_effect=exception.ShareResourceNotFound( share_id=test_nfs_share["id"])), ) mock_result = self.driver.delete_snapshot(None, test_snapshot) self.assertIsNone(mock_result)
def _get_share_details(self, name): lcfg = self.configuration details = self.zfssa.get_share(lcfg.zfssa_pool, lcfg.zfssa_project, name) if not details: msg = (_("Share %s doesn't exist in ZFSSA.") % name) LOG.error(msg) raise exception.ShareResourceNotFound(share_id=name) return details
def ensure_share(self, context, share, share_server=None): """Updates export location if it is changes.""" volume_name = self._get_volume_name(context, share) if self._maprfs_util.volume_exists(volume_name): info = self._maprfs_util.get_volume_info(volume_name) path = info['mountdir'] old_location = share['export_locations'][0] new_location = self._get_share_export_locations(share, path=path) if new_location[0]['path'] != old_location['path']: return new_location else: raise exception.ShareResourceNotFound(share_id=share['share_id'])
def create_snapshot(self, context, snapshot, share_server=None): """Create a snapshot.""" LOG.debug('snapshot[share][share_id]: %s', snapshot['share']['share_id']) LOG.debug('snapshot id: %s', snapshot['id']) # Use private_storage to retrieve volume ID created in the NAS. volID = self.private_storage.get(snapshot['share']['id'], 'volID') if not volID: LOG.warning( 'volID for Share %s does not exist', snapshot['share']['id']) raise exception.ShareResourceNotFound( share_id=snapshot['share']['id']) LOG.debug('volID: %s', volID) # User could create two snapshot with the same name on horizon. # Therefore, we should not use displayname to create snapshot on NAS. # if snapshot exist, need to change another create_snapshot_name = self._gen_random_name("snapshot") LOG.debug('create_snapshot_name: %s', create_snapshot_name) check_snapshot = self.api_executor.get_snapshot_info( volID=volID, snapshot_name=create_snapshot_name) if check_snapshot is not None: msg = _("Failed to create an unused snapshot name.") raise exception.ShareBackendException(msg=msg) LOG.debug('create_snapshot_name: %s', create_snapshot_name) self.api_executor.create_snapshot_api(volID, create_snapshot_name) snapshot_id = "" created_snapshot = self.api_executor.get_snapshot_info( volID=volID, snapshot_name=create_snapshot_name) if created_snapshot is not None: snapshot_id = created_snapshot.find('snapshot_id').text else: msg = _("Failed to get snapshot information.") raise exception.ShareBackendException(msg=msg) LOG.debug('created_snapshot: %s', created_snapshot) LOG.debug('snapshot_id: %s', snapshot_id) # Use private_storage to record data instead of metadata. _metadata = {'snapshot_id': snapshot_id} self.private_storage.update(snapshot['id'], _metadata) # Test to get value from private_storage. snapshot_id = self.private_storage.get(snapshot['id'], 'snapshot_id') LOG.debug('snapshot_id: %s', snapshot_id) return {'provider_location': snapshot_id}
def update_access(self, context, share, access_rules, add_rules, delete_rules, share_server=None): """Update access rules for given share. :param context: The `context.RequestContext` object for the request :param share: Share that will have its access rules updated. :param access_rules: All access rules for given share. This list is enough to update the access rules for given share. :param add_rules: Empty List or List of access rules which should be added. access_rules already contains these rules. Not used by this driver. :param delete_rules: Empty List or List of access rules which should be removed. access_rules doesn't contain these rules. Not used by this driver. :param share_server: Data structure with share server information. Not used by this driver. """ try: self._ensure_share(share['id']) except exception.HNASItemNotFoundException: raise exception.ShareResourceNotFound(share_id=share['id']) host_list = [] share_id = self._get_hnas_share_id(share['id']) for rule in access_rules: if rule['access_type'].lower() != 'ip': msg = _("Only IP access type currently supported.") raise exception.InvalidShareAccess(reason=msg) if rule['access_level'] == constants.ACCESS_LEVEL_RW: host_list.append(rule['access_to'] + '(' + rule['access_level'] + ',norootsquash)') else: host_list.append(rule['access_to'] + '(' + rule['access_level'] + ')') self.hnas.update_access_rule(share_id, host_list) if host_list: LOG.debug("Share %(share)s has the rules: %(rules)s", { 'share': share_id, 'rules': ', '.join(host_list) }) else: LOG.debug("Share %(share)s has no rules.", {'share': share_id})
def ensure_share(self, context, share, share_server=None): """Ensure that share is exported.""" pool, share_name, share_size, share_proto = self._get_share_pnsp(share) share_path = '/%s/%s' % (pool, share_name) if share_proto == 'nfs': share_backend = self._get_nfs_share(share_path) elif share_proto == 'cifs': share_backend = self._get_cifs_share(share_name) else: msg = 'Invalid NAS protocol supplied: %s.' % share_proto LOG.error(msg) raise exception.InvalidInput(msg) if len(share_backend) == 0: raise exception.ShareResourceNotFound(share_id=share['share_id']) else: location = self._get_location_path(share_name, share_path, share_proto) return location
def ensure_share(self, context, share, share_server=None): """Ensure that share is exported.""" pool, name, size, proto = self._get_share_instance_pnsp(share) share_path = self._generate_share_path(pool, name) if proto == 'nfs': share_backend = self._get_nfs_share(share_path) elif proto == 'cifs': share_backend = self._get_cifs_share(name) else: msg = (_('Invalid NAS protocol supplied: %s.') % proto) LOG.error(msg) raise exception.InvalidInput(msg) if len(share_backend) == 0: raise exception.ShareResourceNotFound(share_id=share['share_id']) return self._get_location_path(name, share_path, proto)
def extend_share(self, share, new_size, share_server=None): """Extend an existing share.""" LOG.debug( 'Entering extend_share share_name=%(share_name)s ' 'share_id=%(share_id)s ' 'new_size=%(size)s', { 'share_name': share['display_name'], 'share_id': share['id'], 'size': new_size }) # Use private_storage to retrieve volume Name created in the NAS. volName = self.private_storage.get(share['id'], 'volName') if not volName: LOG.debug('Share %s does not exist', share['id']) raise exception.ShareResourceNotFound(share_id=share['id']) LOG.debug('volName: %s', volName) thin_provision = self.private_storage.get(share['id'], 'thin_provision') compression = self.private_storage.get(share['id'], 'compression') deduplication = self.private_storage.get(share['id'], 'deduplication') ssd_cache = self.private_storage.get(share['id'], 'ssd_cache') LOG.debug( 'thin_provision: %(thin_provision)s ' 'compression: %(compression)s ' 'deduplication: %(deduplication)s ' 'ssd_cache: %(ssd_cache)s', { 'thin_provision': thin_provision, 'compression': compression, 'deduplication': deduplication, 'ssd_cache': ssd_cache }) share_dict = { 'sharename': volName, 'old_sharename': volName, 'new_size': new_size, 'thin_provision': thin_provision == 'True', 'compression': compression == 'True', 'deduplication': deduplication == 'True', 'ssd_cache': ssd_cache == 'True', 'share_proto': share['share_proto'] } self.api_executor.edit_share(share_dict)
def update_access(self, context, share, access_rules, add_rules, delete_rules, share_server=None): """Update access rules for given share. :param context: The `context.RequestContext` object for the request :param share: Share that will have its access rules updated. :param access_rules: All access rules for given share. :param add_rules: Empty List or List of access rules which should be added. access_rules already contains these rules. :param delete_rules: Empty List or List of access rules which should be removed. access_rules doesn't contain these rules. :param share_server: Data structure with share server information. Not used by this driver. """ hnas_share_id = self._get_hnas_share_id(share['id']) try: self._ensure_share(share, hnas_share_id) except exception.HNASItemNotFoundException: raise exception.ShareResourceNotFound(share_id=share['id']) self._check_protocol(share['id'], share['share_proto']) if share['share_proto'].lower() == 'nfs': self._nfs_update_access(share, hnas_share_id, access_rules) else: if not (add_rules or delete_rules): # recovery mode self._clean_cifs_access_list(hnas_share_id) self._cifs_allow_access(share, hnas_share_id, access_rules) else: self._cifs_deny_access(share, hnas_share_id, delete_rules) self._cifs_allow_access(share, hnas_share_id, add_rules)
def test_share_resource_not_found(self): # verify response code for exception.ShareResourceNotFound share_id = "fake_share_id" e = exception.ShareResourceNotFound(share_id=share_id) self.assertEqual(404, e.code) self.assertIn(share_id, e.msg)
def update_access(self, context, share, access_rules, add_rules, delete_rules, share_server=None): LOG.debug("Updating access rules for share: %(shr)s.", {'shr': share['id']}) try: filesystem_id = self.hsp.get_file_system(share['id'])['id'] hsp_share_id = self.hsp.get_share(filesystem_id)['id'] except exception.HSPItemNotFoundException: raise exception.ShareResourceNotFound(share_id=share['id']) if not (add_rules or delete_rules): # Recovery mode current_rules = self.hsp.get_access_rules(hsp_share_id) # Indexing the rules for faster searching hsp_rules_dict = { rule['host-specification']: rule['read-write'] for rule in current_rules } manila_rules_dict = {} for rule in access_rules: if rule['access_type'].lower() != 'ip': msg = _("Only IP access type currently supported.") raise exception.InvalidShareAccess(reason=msg) access_to = rule['access_to'] is_rw = rule['access_level'] == constants.ACCESS_LEVEL_RW manila_rules_dict[access_to] = is_rw # Remove the rules that exist on HSP but not on manila remove_rules = self._get_complement(hsp_rules_dict, manila_rules_dict) # Add the rules that exist on manila but not on HSP add_rules = self._get_complement(manila_rules_dict, hsp_rules_dict) for rule in remove_rules: rule_name = self._get_hsp_rule_name(hsp_share_id, rule[0]) self.hsp.delete_access_rule(hsp_share_id, rule_name) for rule in add_rules: self.hsp.add_access_rule(hsp_share_id, rule[0], rule[1]) else: for rule in delete_rules: if rule['access_type'].lower() != 'ip': continue # get the real rule name in HSP rule_name = self._get_hsp_rule_name(hsp_share_id, rule['access_to']) try: self.hsp.delete_access_rule(hsp_share_id, rule_name) except exception.HSPBackendException as e: if 'No matching access rule found.' in e.msg: LOG.debug( "Rule %(rule)s already deleted in " "backend.", {'rule': rule['access_to']}) else: raise for rule in add_rules: if rule['access_type'].lower() != 'ip': msg = _("Only IP access type currently supported.") raise exception.InvalidShareAccess(reason=msg) try: self.hsp.add_access_rule( hsp_share_id, rule['access_to'], (rule['access_level'] == constants.ACCESS_LEVEL_RW)) except exception.HSPBackendException as e: if 'Duplicate NFS access rule exists' in e.msg: LOG.debug( "Rule %(rule)s already exists in " "backend.", {'rule': rule['access_to']}) else: raise LOG.debug("Successfully updated share %(shr)s rules.", {'shr': share['id']})