def _check_pool_and_fs(self, volume, fs_label): """Validates pool and file system of a volume being managed. Checks if the file system for the volume-type chosen matches the one passed in the volume reference. Also, checks if the pool for the volume type matches the pool for the host passed. :param volume: Reference to the volume. :param fs_label: Label of the file system. :raises: ManageExistingVolumeTypeMismatch """ pool_from_vol_type = hnas_utils.get_pool(self.config, volume) pool_from_host = utils.extract_host(volume.host, level='pool') pool = self.config['services'][pool_from_vol_type]['hdp'] if pool != fs_label: msg = (_("Failed to manage existing volume because the " "pool %(pool)s of the volume type chosen does not " "match the file system %(fs_label)s passed in the " "volume reference.") % { 'pool': pool, 'fs_label': fs_label }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) if pool_from_host != pool_from_vol_type: msg = (_("Failed to manage existing volume because the pool " "%(pool)s of the volume type chosen does not match the " "pool %(pool_host)s of the host.") % { 'pool': pool_from_vol_type, 'pool_host': pool_from_host }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
def _check_pool_and_fs(self, volume, fs_label): """Validation of the pool and filesystem. Checks if the file system for the volume-type chosen matches the one passed in the volume reference. Also, checks if the pool for the volume type matches the pool for the host passed. :param volume: Reference to the volume. :param fs_label: Label of the file system. """ pool_from_vol_type = self.get_pool(volume) pool_from_host = utils.extract_host(volume['host'], level='pool') if self.config['services'][pool_from_vol_type]['hdp'] != fs_label: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen does not match the file system " "passed in the volume reference."), { 'File System passed': fs_label, 'File System for volume type': self.config['services'][pool_from_vol_type]['hdp'] }) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) if pool_from_host != pool_from_vol_type: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen does not match the pool of " "the host."), { 'Pool of the volume type': pool_from_vol_type, 'Pool of the host': pool_from_host }) raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
def _check_pool_and_share(self, volume, nfs_share): """Validates the pool and the NFS share. Checks if the NFS share for the volume-type chosen matches the one passed in the volume reference. Also, checks if the pool for the volume type matches the pool for the host passed. :param volume: cinder volume reference :param nfs_share: NFS share passed to manage """ pool_from_vol_type = self.get_pool(volume) pool_from_host = utils.extract_host(volume['host'], level='pool') if self.config['services'][pool_from_vol_type]['hdp'] != nfs_share: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen does not match the NFS share " "passed in the volume reference."), { 'Share passed': nfs_share, 'Share for volume type': self.config['services'][pool_from_vol_type]['hdp'] }) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) if pool_from_host != pool_from_vol_type: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen does not match the pool of " "the host."), { 'Pool of the volume type': pool_from_vol_type, 'Pool of the host': pool_from_host }) raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
def _check_pool_and_share(self, volume, nfs_share): """Validates the pool and the NFS share. Checks if the NFS share for the volume-type chosen matches the one passed in the volume reference. Also, checks if the pool for the volume type matches the pool for the host passed. :param volume: cinder volume reference :param nfs_share: NFS share passed to manage :raises: ManageExistingVolumeTypeMismatch """ pool_from_vol_type = hnas_utils.get_pool(self.config, volume) pool_from_host = utils.extract_host(volume.host, level='pool') pool = self.config['services'][pool_from_vol_type]['hdp'] if pool != nfs_share: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen (%(pool)s) does not match the " "NFS share passed in the volume reference (%(share)s).") % { 'share': nfs_share, 'pool': pool }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) if pool_from_host != pool_from_vol_type: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen (%(pool)s) does not match the " "pool of the host %(pool_host)s") % { 'pool': pool_from_vol_type, 'pool_host': pool_from_host }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
def _check_volume_type(self, volume, share, file_name, extra_specs): """Matches a volume type for share file.""" qos_policy_group = extra_specs.pop('netapp:qos_policy_group', None) \ if extra_specs else None if qos_policy_group: raise exception.ManageExistingVolumeTypeMismatch( reason=(_("Setting file qos policy group is not supported" " on this storage family and ontap version."))) volume_type = na_utils.get_volume_type_from_volume(volume) if volume_type and 'qos_spec_id' in volume_type: raise exception.ManageExistingVolumeTypeMismatch( reason=_("QoS specs are not supported" " on this storage family and ONTAP version."))
def _check_pool_and_share(self, volume, nfs_share): """Validates the pool and the NFS share. Checks if the NFS share for the volume-type chosen matches the one passed in the volume reference. Also, checks if the pool for the volume type matches the pool for the host passed. :param volume: cinder volume reference :param nfs_share: NFS share passed to manage :raises ManageExistingVolumeTypeMismatch: """ pool_from_vol_type = hnas_utils.get_pool(self.config, volume) pool_from_host = utils.extract_host(volume.host, level='pool') if (pool_from_vol_type == 'default' and 'default' not in self.config['services']): msg = (_("Failed to manage existing volume %(volume)s because the " "chosen volume type %(vol_type)s does not have a " "service_label configured in its extra-specs and there " "is no pool configured with hnas_svcX_volume_type as " "'default' in cinder.conf.") % { 'volume': volume.id, 'vol_type': getattr(volume.volume_type, 'id', None) }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) pool = self.config['services'][pool_from_vol_type]['hdp'] if pool != nfs_share: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen (%(pool)s) does not match the " "NFS share passed in the volume reference (%(share)s).") % { 'share': nfs_share, 'pool': pool }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) if pool_from_host != pool_from_vol_type: msg = (_("Failed to manage existing volume because the pool of " "the volume type chosen (%(pool)s) does not match the " "pool of the host %(pool_host)s") % { 'pool': pool_from_vol_type, 'pool_host': pool_from_host }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
def _check_pool_and_fs(self, volume, fs_label): """Validates pool and file system of a volume being managed. Checks if the file system for the volume-type chosen matches the one passed in the volume reference. Also, checks if the pool for the volume type matches the pool for the host passed. :param volume: Reference to the volume. :param fs_label: Label of the file system. :raises: ManageExistingVolumeTypeMismatch """ pool_from_vol_type = hnas_utils.get_pool(self.config, volume) if (pool_from_vol_type == 'default' and 'default' not in self.config['services']): msg = (_("Failed to manage existing volume %(volume)s because the " "chosen volume type %(vol_type)s does not have a " "service_label configured in its extra-specs and there " "is no pool configured with hnas_svcX_volume_type as " "'default' in cinder.conf.") % { 'volume': volume.id, 'vol_type': getattr(volume.volume_type, 'id', None) }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) pool = self.config['services'][pool_from_vol_type]['hdp'] if pool != fs_label: msg = (_("Failed to manage existing volume because the " "pool %(pool)s of the volume type chosen does not " "match the file system %(fs_label)s passed in the " "volume reference.") % { 'pool': pool, 'fs_label': fs_label }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg) pool_from_host = utils.extract_host(volume.host, level='pool') if pool_from_host != pool_from_vol_type: msg = (_("Failed to manage existing volume because the pool " "%(pool)s of the volume type chosen does not match the " "pool %(pool_host)s of the host.") % { 'pool': pool_from_vol_type, 'pool_host': pool_from_host }) LOG.error(msg) raise exception.ManageExistingVolumeTypeMismatch(reason=msg)
def _check_volume_type_for_lun(self, volume, lun, existing_ref, extra_specs): """Check if LUN satisfies volume type.""" def scan_ssc_data(): volumes = ssc_cmode.get_volumes_for_specs(self.ssc_vols, extra_specs) for vol in volumes: if lun.get_metadata_property('Volume') == vol.id['name']: return True return False match_read = scan_ssc_data() if not match_read: ssc_cmode.get_cluster_latest_ssc(self, self.zapi_client.get_connection(), self.vserver) match_read = scan_ssc_data() if not match_read: raise exception.ManageExistingVolumeTypeMismatch( reason=(_("LUN with given ref %(ref)s does not satisfy volume" " type. Ensure LUN volume with ssc features is" " present on vserver %(vs)s.") % { 'ref': existing_ref, 'vs': self.vserver }))
def _check_volume_type_for_lun(self, volume, lun, existing_ref): """Check if lun satisfies volume type.""" extra_specs = na_utils.get_volume_extra_specs(volume) if extra_specs and extra_specs.pop('netapp:qos_policy_group', None): raise exception.ManageExistingVolumeTypeMismatch( reason=_("Setting LUN QoS policy group is not supported" " on this storage family and ONTAP version."))
def _check_volume_type_for_lun(self, volume, lun, existing_ref, extra_specs): """Check if LUN satisfies volume type.""" if extra_specs: legacy_policy = extra_specs.get('netapp:qos_policy_group') if legacy_policy is not None: raise exception.ManageExistingVolumeTypeMismatch( reason=_("Setting LUN QoS policy group is not supported " "on this storage family and ONTAP version.")) volume_type = na_utils.get_volume_type_from_volume(volume) if volume_type is None: return spec = na_utils.get_backend_qos_spec_from_volume_type(volume_type) if spec is not None: raise exception.ManageExistingVolumeTypeMismatch( reason=_("Back-end QoS specs are not supported on this " "storage family and ONTAP version."))
def _check_volume_type(self, volume, share, file_name): """Matches a volume type for share file.""" extra_specs = na_utils.get_volume_extra_specs(volume) qos_policy_group = extra_specs.pop('netapp:qos_policy_group', None) \ if extra_specs else None if qos_policy_group: raise exception.ManageExistingVolumeTypeMismatch( reason=(_("Setting file qos policy group is not supported" " on this storage family and ontap version.")))
def _check_volume_type(self, volume, share, file_name): """Match volume type for share file.""" extra_specs = na_utils.get_volume_extra_specs(volume) qos_policy_group = extra_specs.pop('netapp:qos_policy_group', None) \ if extra_specs else None if not self._is_share_vol_type_match(volume, share): raise exception.ManageExistingVolumeTypeMismatch( reason=(_("Volume type does not match for share %s."), share)) if qos_policy_group: try: vserver, flex_vol_name = self._get_vserver_and_exp_vol( share=share) self.zapi_client.file_assign_qos(flex_vol_name, qos_policy_group, file_name) except na_api.NaApiError as ex: LOG.exception(_LE('Setting file QoS policy group failed. %s'), ex) raise exception.NetAppDriverException( reason=(_('Setting file QoS policy group failed. %s'), ex))
def _check_volume_type_for_lun(self, volume, lun, existing_ref): """Check if LUN satisfies volume type.""" extra_specs = na_utils.get_volume_extra_specs(volume) match_write = False def scan_ssc_data(): volumes = ssc_cmode.get_volumes_for_specs(self.ssc_vols, extra_specs) for vol in volumes: if lun.get_metadata_property('Volume') == vol.id['name']: return True return False match_read = scan_ssc_data() if not match_read: ssc_cmode.get_cluster_latest_ssc(self, self.zapi_client.get_connection(), self.vserver) match_read = scan_ssc_data() qos_policy_group = extra_specs.pop('netapp:qos_policy_group', None) \ if extra_specs else None if qos_policy_group: if match_read: try: path = lun.get_metadata_property('Path') self.zapi_client.set_lun_qos_policy_group( path, qos_policy_group) match_write = True except netapp_api.NaApiError as nae: LOG.error(_LE("Failure setting QoS policy group. %s"), nae) else: match_write = True if not (match_read and match_write): raise exception.ManageExistingVolumeTypeMismatch( reason=(_("LUN with given ref %(ref)s does not satisfy volume" " type. Ensure LUN volume with ssc features is" " present on vserver %(vs)s.") % { 'ref': existing_ref, 'vs': self.vserver }))
def _check_volume_type(self, volume, share, file_name, extra_specs): """Match volume type for share file.""" if not self._is_share_vol_type_match(volume, share): raise exception.ManageExistingVolumeTypeMismatch( reason=(_("Volume type does not match for share %s."), share))
def manage_existing(self, volume, existing_ref): """Manage an existing LeftHand volume. existing_ref is a dictionary of the form: {'source-name': <name of the virtual volume>} """ # Check API Version self._check_api_version() target_vol_name = self._get_existing_volume_ref_name(existing_ref) # Check for the existence of the virtual volume. client = self._login() try: volume_info = client.getVolumeByName(target_vol_name) except hpexceptions.HTTPNotFound: err = (_("Virtual volume '%s' doesn't exist on array.") % target_vol_name) LOG.error(err) raise exception.InvalidInput(reason=err) finally: self._logout(client) # Generate the new volume information based on the new ID. new_vol_name = 'volume-' + volume['id'] volume_type = None if volume['volume_type_id']: try: volume_type = self._get_volume_type(volume['volume_type_id']) except Exception: reason = (_("Volume type ID '%s' is invalid.") % volume['volume_type_id']) raise exception.ManageExistingVolumeTypeMismatch(reason=reason) new_vals = {"name": new_vol_name} client = self._login() try: # Update the existing volume with the new name. client.modifyVolume(volume_info['id'], new_vals) finally: self._logout(client) LOG.info(_LI("Virtual volume '%(ref)s' renamed to '%(new)s'."), { 'ref': existing_ref['source-name'], 'new': new_vol_name }) display_name = None if volume['display_name']: display_name = volume['display_name'] if volume_type: LOG.info( _LI("Virtual volume %(disp)s '%(new)s' is " "being retyped."), { 'disp': display_name, 'new': new_vol_name }) try: self.retype(None, volume, volume_type, volume_type['extra_specs'], volume['host']) LOG.info( _LI("Virtual volume %(disp)s successfully retyped to " "%(new_type)s."), { 'disp': display_name, 'new_type': volume_type.get('name') }) except Exception: with excutils.save_and_reraise_exception(): LOG.warning( _LW("Failed to manage virtual volume %(disp)s " "due to error during retype."), {'disp': display_name}) # Try to undo the rename and clear the new comment. client = self._login() try: client.modifyVolume(volume_info['id'], {'name': target_vol_name}) finally: self._logout(client) updates = {'display_name': display_name} LOG.info( _LI("Virtual volume %(disp)s '%(new)s' is " "now being managed."), { 'disp': display_name, 'new': new_vol_name }) # Return display name to update the name displayed in the GUI and # any model updates from retype. return updates