示例#1
0
    def _create_cifs_share(self, share_name, vdm):
        """Create cifs share."""
        # Get available CIFS Server and interface
        cifs_server = self._get_cifs_server_by_mover(vdm['id'])

        status, out = self._XMLAPI_helper.create_cifs_share(
            share_name, cifs_server['name'], vdm['id'])
        if constants.STATUS_OK != status:
            message = (_("Could not create CIFS share." " Reason: %s.") % out)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
        status, out = self._NASCmd_helper.disable_cifs_access(
            vdm['name'], share_name)
        if constants.STATUS_OK != status:
            message = _("Could not disable share access. Reason: %s.") % out
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        if len(cifs_server['interfaces']) == 0:
            message = (_("CIFS server %s doesn't have interface, "
                         "so the share is inaccessible.") %
                       cifs_server['name'])
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
        interface = cifs_server['interfaces'][0]

        location = '//%(interface)s/%(name)s' % {
            'interface': interface,
            'name': share_name
        }

        return location
示例#2
0
    def get_pool(self, share):
        """Get the pool name of the share."""
        share_name = share['id']
        status, filesystem = self._get_context('FileSystem').get(share_name)
        if status != constants.STATUS_OK:
            message = (_("File System %(name)s not found. "
                         "Reason: %(err)s") % {
                             'name': share_name,
                             'err': filesystem
                         })
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        pool_id = filesystem['pools_id'][0]

        # Get the real pools from the backend storage
        status, backend_pools = self._get_context('StoragePool').get_all()
        if status != constants.STATUS_OK:
            message = (_("Failed to get storage pool information. "
                         "Reason: %s") % backend_pools)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        for name, pool_info in backend_pools.items():
            if pool_info['id'] == pool_id:
                return name

        available_pools = [item for item in backend_pools]
        message = (_("No matched pool name for share: %(share)s. "
                     "Available pools: %(pools)s") % {
                         'share': share_name,
                         'pools': available_pools
                     })
        raise exception.EMCVnxXMLAPIError(err=message)
示例#3
0
    def _get_cifs_server_by_mover(self, mover_id):
        status, servers = self._XMLAPI_helper.get_cifs_servers(mover_id)
        if constants.STATUS_OK != status:
            message = _("Could not get CIFS server list for %s.") % mover_id
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        if len(servers) == 0:
            message = (_("Could not find the CIFS servers on VDM: %s.") %
                       mover_id)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return servers[0]
示例#4
0
    def _create_cifs_share(self, share_name, share_server):
        """Create CIFS share."""
        vdm_name = self._get_share_server_name(share_server)
        server_name = vdm_name

        # Get available CIFS Server and interface (one CIFS server per VDM)
        status, server = self._get_context('CIFSServer').get(
            server_name, vdm_name)

        if 'interfaces' not in server or len(server['interfaces']) == 0:
            message = (_("CIFS server %s doesn't have interface, "
                         "so the share is inaccessible.") % server['compName'])
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        interface = server['interfaces'][0]

        self._get_context('CIFSShare').create(share_name, server['name'],
                                              vdm_name)

        self._get_context('CIFSShare').disable_share_access(
            share_name, vdm_name)

        location = (r'\\%(interface)s\%(name)s' % {
            'interface': interface,
            'name': share_name
        })

        return location
示例#5
0
    def delete_snapshot(self,
                        emc_share_driver,
                        context,
                        snapshot,
                        share_server=None):
        """Remove share's snapshot."""

        ckpt_name = snapshot['name']

        status, ckpt = self._XMLAPI_helper.get_check_point_by_name(ckpt_name)
        if constants.STATUS_OK != status:
            LOG.warn(_LW("Check point not found. Reason: %s."), status)
            return

        if ckpt['id'] == '':
            LOG.warn(
                _LW("Snapshot: %(name)s not found. "
                    "Skip the deletion.") % {'name': snapshot['name']})
            return

        status, out = self._XMLAPI_helper.delete_check_point(ckpt['id'])
        if constants.STATUS_OK != status:
            message = (_("Could not delete check point. Reason: %s.") %
                       out['info'])
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#6
0
    def _cifs_deny_access(self, share, access, share_server):
        """Deny access to CIFS share."""
        vdm_name = self._get_share_server_name(share_server)
        share_name = share['id']

        if access['access_type'] != 'user':
            reason = _('Only user access type allowed for CIFS share')
            raise exception.InvalidShareAccess(reason=reason)

        user_name = access['access_to']

        access_level = access['access_level']
        if access_level == const.ACCESS_LEVEL_RW:
            cifs_access = constants.CIFS_ACL_FULLCONTROL
        else:
            cifs_access = constants.CIFS_ACL_READ

        # Check if CIFS server exists.
        server_name = vdm_name
        status, server = self._get_context('CIFSServer').get(
            server_name, vdm_name)
        if status != constants.STATUS_OK:
            message = (_("CIFS server %s not found.") % server_name)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        self._get_context('CIFSShare').deny_share_access(vdm_name,
                                                         share_name,
                                                         user_name,
                                                         server['domain'],
                                                         access=cifs_access)
示例#7
0
    def _delete_nfs_share(self, share, share_server):
        """Remove nfs share."""
        name = share['name']
        path = '/' + name
        mover_name = self._get_vdm_name(share_server)
        mover_id = self._get_vdm_id(share_server)

        status, share_obj = self._NASCmd_helper.get_nfs_share_by_path(
            path, mover_name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warn(_LW("NFS share %s not found. Skip the deletion"), name)
        else:
            # Delete NFS export if it is present
            status, out = self._NASCmd_helper.delete_nfs_share(
                path, mover_name)
            if constants.STATUS_OK != status:
                error = (_("Deleting NFS share %(share_name)s on "
                           "%(mover_name)s failed. Reason: %(err)s") % {
                               'share_name': name,
                               'mover_name': mover_name,
                               'err': out
                           })
                LOG.error(error)
                raise exception.EMCVnxXMLAPIError(err=error)

        self._deallocate_container(name, mover_name, mover_id)
示例#8
0
    def _delete_cifs_share(self, share, share_server):
        """Remove cifs share."""

        name = share['name']
        mover_name = self._get_vdm_name(share_server)
        mover_id = self._get_vdm_id(share_server)
        status, share_obj = self._XMLAPI_helper.get_cifs_share_by_name(name)
        if constants.STATUS_NOT_FOUND == status:
            LOG.warn(_LW("CIFS share %s not found. Skip the deletion"), name)
        else:
            mover_id = share_obj['mover']
            # Delete CIFS export
            status, out = self._XMLAPI_helper.delete_cifs_share(
                name, mover_id, share_obj['CifsServers'],
                share_obj['moverIdIsVdm'])
            if constants.STATUS_OK != status:
                error = (_("Deleting CIFS share %(share_name)s on "
                           "%(mover)s failed."
                           " Reason: %(err)s") % {
                               'share_name': name,
                               'mover': mover_name,
                               'err': out
                           })
                LOG.error(error)
                raise exception.EMCVnxXMLAPIError(err=error)

        self._deallocate_container(name, mover_name, mover_id)
示例#9
0
    def _get_managed_storage_pools(self, pools):
        matched_pools = set()
        if pools:
            # Get the real pools from the backend storage
            status, backend_pools = self._get_context('StoragePool').get_all()
            if status != constants.STATUS_OK:
                message = (_("Failed to get storage pool information. "
                             "Reason: %s") % backend_pools)
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

            real_pools = set([item for item in backend_pools])
            conf_pools = set([item.strip() for item in pools])
            matched_pools, unmatched_pools = vnx_utils.do_match_any(
                real_pools, conf_pools)

            if not matched_pools:
                msg = (_("None of the specified storage pools to be managed "
                         "exist. Please check your configuration "
                         "vnx_share_data_pools in manila.conf. "
                         "The available pools in the backend are %s.") %
                       ",".join(real_pools))
                raise exception.InvalidParameterValue(err=msg)

            LOG.info("Storage pools: %s will be managed.",
                     ",".join(matched_pools))
        else:
            LOG.debug("No storage pool is specified, so all pools "
                      "in storage system will be managed.")
        return matched_pools
示例#10
0
    def update_share_stats(self, stats_dict):
        """Communicate with EMCNASClient to get the stats."""
        stats_dict['driver_version'] = VERSION

        self._get_context('Mover').get_ref(self.mover_name, True)

        stats_dict['pools'] = []

        status, pools = self._get_context('StoragePool').get_all()
        for name, pool in pools.items():
            if not self.pools or pool['name'] in self.pools:
                total_size = float(pool['total_size'])
                used_size = float(pool['used_size'])

                pool_stat = dict(
                    pool_name=pool['name'],
                    total_capacity_gb=total_size,
                    free_capacity_gb=total_size - used_size,
                    qos=False,
                    reserved_percentage=self.reserved_percentage,
                )
                stats_dict['pools'].append(pool_stat)

        if not stats_dict['pools']:
            message = _("Failed to update storage pool.")
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#11
0
    def _cifs_deny_access(self, context, share, access, share_server):
        """Deny access to cifs share."""
        self._ensure_access_type_for_cifs(access)

        network_id = share['share_network_id']
        share_network = manila_db.share_network_get(context, network_id)
        security_services = share_network['security_services']
        self._ensure_security_service_for_cifs(security_services)

        share_name = share['name']
        mover_name = self._get_vdm_name(share_server)
        user_name = access['access_to']
        access_level = access['access_level']
        if access_level == const.ACCESS_LEVEL_RW:
            cifs_access = constants.CIFS_ACL_FULLCONTROL
        else:
            cifs_access = constants.CIFS_ACL_READ
        status, out = self._NASCmd_helper.deny_cifs_access(
            mover_name,
            share_name,
            user_name,
            security_services[0]['domain'],
            access=cifs_access)
        if constants.STATUS_OK != status:
            message = (_("Could not deny access to CIFS share. Reason: %s.") %
                       out)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#12
0
    def _configure_active_directory(self, security_service, vdmRef, interface):

        moverRef = self.get_mover_ref_by_name(self._mover_name)
        self._configure_dns(security_service, moverRef)

        data = {
            'mover_id': vdmRef['id'],
            'compName': vdmRef['name'],
            'netbios': vdmRef['name'][-14:],
            'domain': security_service['domain'],
            'admin_username': security_service['user'],
            'admin_password': security_service['password'],
            'interface': interface['ip'],
            'alias': [vdmRef['name'][-12:]],
        }

        status, out = self._XMLAPI_helper.create_cifs_server(data)
        if constants.STATUS_ERROR == status:
            message = (_('Failed to create cifs server %(name)s.'
                         'Reason: %(err)s.') % {
                             'name': data['compName'],
                             'err': out
                         })
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#13
0
    def _create_vdm(self, vdm_name, moverRef):
        """Create a new VDM as a share sever."""

        status, out = self._XMLAPI_helper.create_vdm(vdm_name, moverRef['id'])
        if constants.STATUS_OK != status:
            message = _('Could not create VDM %s.') % vdm_name
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#14
0
 def allocate_container(self, share_name, size, vdm_id):
     """Is called to allocate container for share."""
     status, out = self._XMLAPI_helper.create_file_system(
         share_name, size, self._pool['id'], vdm_id)
     if constants.STATUS_OK != status:
         message = _("Could not create file system for %s.") % share_name
         LOG.error(message)
         raise exception.EMCVnxXMLAPIError(err=message)
示例#15
0
    def _get_physical_devices(self, mover_name):
        """Get a proper network device to create interface."""
        devices = self._get_context('Mover').get_physical_devices(mover_name)
        if not devices:
            message = (_("Could not get physical device port on mover %s.") %
                       self.mover_name)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return devices
示例#16
0
    def _configure_dns(self, security_service, moverRef):
        domain = security_service['domain']
        server = security_service['dns_ip']

        status, out = self._XMLAPI_helper.create_dns_domain(
            moverRef['id'], domain, server)
        if constants.STATUS_OK != status:
            message = _("Could not create DNS domain. Reason: %s.") % out
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#17
0
    def _replicate_snapshot(self, share, snapshot, mover_name, vdm_ref):

        # Source snapshot name
        ckpt_name = snapshot['name']

        # Source file system name
        source_share = snapshot['share_name']

        # Target file system name
        fs_name = share['name']

        fs_size = share['size'] * units.Ki

        interconn_id = self._NASCmd_helper.get_interconnect_id(
            mover_name, mover_name)
        # Run NAS command to copy ckpt to a fs
        status, msg = self._NASCmd_helper.create_fs_from_ckpt(
            fs_name, vdm_ref['name'], ckpt_name, source_share,
            self._pool['name'], interconn_id)
        if constants.STATUS_OK != status:
            message = _("Copy content from checkpoint to"
                        " file system failed. Reason: %s.") % msg
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
        # Query the new created file system
        filesystem = self._get_file_system_by_name(fs_name)

        # Keep the compatibility for both Python2.x and Python 3.x
        if six.PY2:
            source_fs_size = long(filesystem['size'])
        else:
            source_fs_size = int(filesystem['size'])

        if source_fs_size < fs_size:
            status, out = self._XMLAPI_helper.extend_file_system(
                filesystem['id'], self._pool['id'], fs_size - source_fs_size)
            if constants.STATUS_OK != status:
                message = (_("Extend the file system failed. Reason: %s.") %
                           out)
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)
示例#18
0
    def _get_file_system_by_name(self, name, allow_absence=False):

        status, filesystem = self._XMLAPI_helper.get_file_system_by_name(name)
        if constants.STATUS_OK != status:
            if allow_absence and constants.STATUS_NOT_FOUND == status:
                return None
            else:
                message = _("Could not get file system by name: %s.") % name
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

        return filesystem
示例#19
0
    def create_snapshot(self, context, snapshot, share_server=None):
        """Create snapshot from share."""
        share_name = snapshot['share_id']
        status, filesystem = self._get_context('FileSystem').get(share_name)
        if status != constants.STATUS_OK:
            message = (_("File System %s not found.") % share_name)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        pool_id = filesystem['pools_id'][0]

        self._get_context('Snapshot').create(snapshot['id'],
                                             snapshot['share_id'], pool_id)
示例#20
0
    def _get_device_port(self, moverRef):
        """Get a proper network device to create interface."""

        status, mover = self._XMLAPI_helper.get_mover_by_id(moverRef['id'])
        if constants.STATUS_OK != status:
            message = (_("Could not get physical device port "
                         "on mover (id:%s).") % moverRef['id'])
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        device_ports = mover['devices']

        return device_ports[0]
示例#21
0
    def _create_nfs_share(self, share_name, vdm_name, share_server):
        """Is called to create nfs share."""
        status, out = self._NASCmd_helper.create_nfs_share(
            share_name, vdm_name)
        if constants.STATUS_OK != status:
            message = (_("Could not create NFS export for share %s.") %
                       share_name)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return ('%(nfs_if)s:/%(share_name)s' % {
            'nfs_if': share_server['backend_details']['nfs_if'],
            'share_name': share_name
        })
示例#22
0
    def _share_server_validation(self, share_server):
        """Validate the share server."""
        if not share_server:
            msg = _('Share server not provided')
            raise exception.InvalidInput(reason=msg)

        backend_details = share_server.get('backend_details')
        vdm = backend_details.get(
            'share_server_name') if backend_details else None

        if vdm is None:
            message = _("No share server found.")
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#23
0
    def _delete_filesystem(self, name):
        filesystem = self._get_file_system_by_name(name, allow_absence=True)

        if not filesystem:
            LOG.warn(_LW("File system %s not found. Skip the deletion"), name)
            return

        # Delete file system
        status, out = self._XMLAPI_helper.delete_file_system(filesystem['id'])
        if constants.STATUS_OK != status:
            message = (_("Failed to delete file system %(fsid)s. "
                         "Reason: %(err)s.") % {
                             'fsid': filesystem['id'],
                             'err': out
                         })
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#24
0
    def _nfs_allow_access(self, context, share, access, share_server):
        """Allow access to nfs share."""
        share_path = '/' + share['name']
        access_type = access['access_type']
        if access_type != 'ip':
            reason = _('Only ip access type allowed.')
            raise exception.InvalidShareAccess(reason)

        host_ip = access['access_to']
        mover_name = self._get_vdm_name(share_server)
        status, reason = self._NASCmd_helper.allow_nfs_share_access(
            share_path, host_ip, mover_name)
        if constants.STATUS_OK != status:
            message = (_("Could not allow access to NFS share. Reason: %s.") %
                       reason)
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#25
0
    def share_server_validation(self, share_server):
        """Is called to validate the share server."""
        vdm_name = None
        vdm_id = None

        if share_server:
            backend_detail = share_server.get('backend_details')
            if backend_detail:
                vdm_name = backend_detail.get('share_server_name')
                vdm_id = backend_detail.get('share_server_id')

        if vdm_name is None or vdm_id is None:
            message = _("No share server found.")
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)

        return {'id': vdm_id, 'name': vdm_name}
示例#26
0
    def _get_managed_storage_pools(self, pools):
        matched_pools = set()
        if pools:
            # Get the real pools from the backend storage
            status, backend_pools = self._get_context('StoragePool').get_all()
            if status != constants.STATUS_OK:
                message = (_("Failed to get storage pool information. "
                             "Reason: %s") % backend_pools)
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

            real_pools = set([item for item in backend_pools])

            conf_pools = set([item.strip() for item in pools.split(",")])

            for pool in real_pools:
                for matcher in conf_pools:
                    if fnmatch.fnmatchcase(pool, matcher):
                        matched_pools.add(pool)

            nonexistent_pools = real_pools.difference(matched_pools)

            if not matched_pools:
                msg = (_("All the specified storage pools to be managed "
                         "do not exist. Please check your configuration "
                         "emc_nas_pool_names in manila.conf. "
                         "The available pools in the backend are %s") %
                       ",".join(real_pools))
                raise exception.InvalidParameterValue(err=msg)
            if nonexistent_pools:
                LOG.warning(
                    _LW("The following specified storage pools "
                        "do not exist: %(unexist)s. "
                        "This host will only manage the storage "
                        "pools: %(exist)s"), {
                            'unexist': ",".join(nonexistent_pools),
                            'exist': ",".join(matched_pools)
                        })
            else:
                LOG.debug("Storage pools: %s will be managed.",
                          ",".join(matched_pools))
        else:
            LOG.debug("No storage pool is specified, so all pools "
                      "in storage system will be managed.")
        return matched_pools
示例#27
0
    def create_share(self, context, share, share_server=None):
        """Create a share and export it based on protocol used."""
        share_name = share['id']
        size = share['size'] * units.Ki

        share_proto = share['share_proto']

        # Validate the share protocol
        if share_proto.upper() not in ('NFS', 'CIFS'):
            raise exception.InvalidShare(
                reason=(_('Invalid NAS protocol supplied: %s.')
                        % share_proto))

        # Get the pool name from share host field
        pool_name = share_utils.extract_host(share['host'], level='pool')
        if not pool_name:
            message = (_("Pool is not available in the share host %s.") %
                       share['host'])
            raise exception.InvalidHost(reason=message)

        # Validate share server
        self._share_server_validation(share_server)

        if share_proto == 'CIFS':
            vdm_name = self._get_share_server_name(share_server)
            server_name = vdm_name

            # Check if CIFS server exists.
            status, server = self._get_context('CIFSServer').get(server_name,
                                                                 vdm_name)
            if status != constants.STATUS_OK:
                message = (_("CIFS server %s not found.") % server_name)
                LOG.error(message)
                raise exception.EMCVnxXMLAPIError(err=message)

        self._allocate_container(share_name, size, share_server, pool_name)

        if share_proto == 'NFS':
            location = self._create_nfs_share(share_name, share_server)
        elif share_proto == 'CIFS':
            location = self._create_cifs_share(share_name, share_server)

        return [
            {'path': location}
        ]
示例#28
0
    def create_snapshot(self,
                        emc_share_driver,
                        context,
                        snapshot,
                        share_server=None):
        """Create snapshot from share."""

        ckpt_name = snapshot['name']

        fs_name = snapshot['share_name']

        filesystem = self._get_file_system_by_name(fs_name)
        status, out = self._XMLAPI_helper.create_check_point(
            filesystem['id'], ckpt_name, self._pool['id'])
        if constants.STATUS_ERROR == status:
            message = (_("Could not create check point. Reason: %s.") %
                       out['info'])
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#29
0
    def _cifs_allow_access(self, context, share, access, share_server):
        """Allow access to cifs share."""
        self._ensure_access_type_for_cifs(access)

        network_id = share['share_network_id']
        share_network = manila_db.share_network_get(context, network_id)
        security_services = share_network['security_services']
        self._ensure_security_service_for_cifs(security_services)

        share_name = share['name']
        mover_name = self._get_vdm_name(share_server)
        user_name = access['access_to']

        status, out = self._NASCmd_helper.allow_cifs_access(
            mover_name, share_name, user_name, security_services[0]['domain'])
        if constants.STATUS_OK != status:
            message = _("Could not allow CIFS access. Reason: %s.") % out
            LOG.error(message)
            raise exception.EMCVnxXMLAPIError(err=message)
示例#30
0
    def _cifs_clear_access(self, share_name, share_server, white_list):
        """Clear access for CIFS share except hosts in the white list."""
        vdm_name = self._get_share_server_name(share_server)

        # Check if CIFS server exists.
        server_name = vdm_name
        status, server = self._get_context('CIFSServer').get(server_name,
                                                             vdm_name)
        if status != constants.STATUS_OK:
            message = (_("CIFS server %(server_name)s has issue. "
                         "Detail: %(status)s") %
                       {'server_name': server_name, 'status': status})
            raise exception.EMCVnxXMLAPIError(err=message)

        self._get_context('CIFSShare').clear_share_access(
            share_name=share_name,
            mover_name=vdm_name,
            domain=server['domain'],
            white_list_users=white_list)