Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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
Beispiel #4
0
    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)
Beispiel #5
0
 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
Beispiel #6
0
    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)
Beispiel #7
0
 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)
Beispiel #8
0
 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
Beispiel #9
0
 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'])
Beispiel #10
0
    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}
Beispiel #11
0
    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})
Beispiel #12
0
 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
Beispiel #13
0
    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)
Beispiel #14
0
    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)
Beispiel #15
0
    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)
Beispiel #16
0
 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)
Beispiel #17
0
    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']})