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.EMCPowerMaxXMLAPIError(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.EMCPowerMaxXMLAPIError(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.EMCPowerMaxXMLAPIError(err=message)
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.EMCPowerMaxXMLAPIError(err=message) real_pools = set([item for item in backend_pools]) conf_pools = set([item.strip() for item in pools]) matched_pools, unmatched_pools = enas_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 " "emc_nas_pool_names 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
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 = { 'pool_name': pool['name'], 'total_capacity_gb': total_size, 'free_capacity_gb': total_size - used_size, 'qos': False, 'reserved_percentage': self.reserved_percentage, 'snapshot_support': True, 'create_share_from_snapshot_support': True, 'revert_to_snapshot_support': False, 'ipv6_support': True } stats_dict['pools'].append(pool_stat) if not stats_dict['pools']: message = _("Failed to update storage pool.") LOG.error(message) raise exception.EMCPowerMaxXMLAPIError(err=message)
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': LOG.warning("Only user access type allowed for CIFS share.") return 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.EMCPowerMaxXMLAPIError(err=message) self._get_context('CIFSShare').deny_share_access(vdm_name, share_name, user_name, server['domain'], access=cifs_access)
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.EMCPowerMaxXMLAPIError(err=message) interface = enas_utils.export_unc_path(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) locations = [] location = (r'\\%(interface)s\%(name)s' % { 'interface': interface, 'name': share_name }) locations.append(location) return locations
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.EMCPowerMaxXMLAPIError(err=message) return devices
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.EMCPowerMaxXMLAPIError(err=message) pool_id = filesystem['pools_id'][0] self._get_context('Snapshot').create(snapshot['id'], snapshot['share_id'], pool_id)
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.EMCPowerMaxXMLAPIError(err=message)
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'].upper() # Validate the share protocol if share_proto 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.EMCPowerMaxXMLAPIError(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 location
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.EMCPowerMaxXMLAPIError(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)
def setup_server(self, network_info, metadata=None): """Set up and configure share server. Sets up and configures share server with given network parameters. """ # Only support single security service with type 'active_directory' vdm_name = network_info['server_id'] vlan_id = network_info['segmentation_id'] active_directory = None allocated_interfaces = [] if network_info.get('security_services'): is_valid, active_directory = self._get_valid_security_service( network_info['security_services']) if not is_valid: raise exception.EMCPowerMaxXMLAPIError(err=active_directory) try: if not self._vdm_exist(vdm_name): LOG.debug( 'Share server %s not found, creating ' 'share server...', vdm_name) self._get_context('VDM').create(vdm_name, self.mover_name) devices = self.get_managed_ports() for net_info in network_info['network_allocations']: random.shuffle(devices) ip_version = net_info['ip_version'] interface = { 'name': net_info['id'][-12:], 'device_name': devices[0], 'ip': net_info['ip_address'], 'mover_name': self.mover_name, 'vlan_id': vlan_id if vlan_id else -1, } if ip_version == 6: interface['ip_version'] = ip_version interface['net_mask'] = six.text_type( utils.cidr_to_prefixlen(network_info['cidr'])) else: interface['net_mask'] = utils.cidr_to_netmask( network_info['cidr']) self._get_context('MoverInterface').create(interface) allocated_interfaces.append(interface) cifs_interface = allocated_interfaces[0] nfs_interface = allocated_interfaces[1] if active_directory: self._configure_active_directory(active_directory, vdm_name, cifs_interface) self._get_context('VDM').attach_nfs_interface( vdm_name, nfs_interface['name']) return { 'share_server_name': vdm_name, 'cifs_if': cifs_interface['ip'], 'nfs_if': nfs_interface['ip'], } except Exception: with excutils.save_and_reraise_exception(): LOG.exception('Could not setup server') server_details = self._construct_backend_details( vdm_name, allocated_interfaces) self.teardown_server(server_details, network_info['security_services'])