def get_qos_opts(self, opts): qos = {} if not strutils.bool_from_string(opts.get('qos')): return for key, value in opts.items(): if (key in constants.OPTS_QOS_VALUE) and value is not None: if (key.upper() != 'IOTYPE') and (int(value) <= 0): err_msg = (_('QoS config is wrong. %(key)s' ' must be set greater than 0.') % { 'key': key }) raise exception.InvalidInput(reason=err_msg) elif ((key.upper() == 'IOTYPE') and (value not in ['0', '1', '2'])): raise exception.InvalidInput( reason=(_('Illegal value specified for IOTYPE: ' 'set to either 0, 1, or 2.'))) else: qos[key.upper()] = value return qos
def test_do_setup_vpe_failed(self): mock_login = self.mock_object(as13000_nas.RestAPIExecutor, 'logins', mock.Mock()) side_effect = exception.InvalidInput(reason='fake_exception') mock_vpe = self.mock_object(self.driver, '_validate_pools_exist', mock.Mock(side_effect=side_effect)) self.assertRaises(exception.InvalidInput, self.driver.do_setup, self._ctxt) mock_login.assert_called_once() mock_vpe.assert_called_once()
def get_backend_driver(self): filename = self.configuration.manila_huawei_conf_file try: tree = ET.parse(filename) root = tree.getroot() except Exception as err: message = (_('Read Huawei config file(%(filename)s)' ' for Manila error: %(err)s') % {'filename': filename, 'err': err}) LOG.error(message) raise exception.InvalidInput(reason=message) product = root.findtext('Storage/Product') backend_driver = HUAWEI_UNIFIED_DRIVER_REGISTRY.get(product) if backend_driver is None: raise exception.InvalidInput( reason=_('Product %s is not supported. Product ' 'must be set to V3.') % product) return backend_driver
def do_call(self, url, data=None, method=None, calltimeout=constants.SOCKET_TIMEOUT): """Send requests to server. Send HTTPS call, get response in JSON. Convert response into Python Object and return it. """ if self.url: url = self.url + url if "xx/sessions" not in url: LOG.debug( 'Request URL: %(url)s\n' 'Call Method: %(method)s\n' 'Request Data: %(data)s\n', { 'url': url, 'method': method, 'data': data }) opener = urlreq.build_opener(urlreq.HTTPCookieProcessor(self.cookie)) urlreq.install_opener(opener) result = None try: req = urlreq.Request(url, data, self.headers) if method: req.get_method = lambda: method res_temp = urlreq.urlopen(req, timeout=calltimeout) res = res_temp.read().decode("utf-8") LOG.debug('Response Data: %(res)s.', {'res': res}) except Exception as err: LOG.error( _LE('\nBad response from server: %(url)s.' ' Error: %(err)s'), { 'url': url, 'err': err }) res = '{"error":{"code":%s,' \ '"description":"Connect server error"}}' \ % constants.ERROR_CONNECT_TO_SERVER try: result = jsonutils.loads(res) except Exception as err: err_msg = (_('JSON transfer error: %s.') % err) LOG.error(err_msg) raise exception.InvalidInput(reason=err_msg) return result
def test_share_manage_invalid_input(self): body = get_fake_manage_body() self._setup_manage_mocks() error = mock.Mock( side_effect=exception.InvalidInput(message="", reason="fake")) self.mock_object(share_api.API, 'manage', mock.Mock(side_effect=error)) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, self.request, body) self.mock_policy_check.assert_called_once_with(self.context, self.resource_name, 'manage')
def _get_share_url_type(self, share_proto): share_url_type = None if share_proto == 'NFS': share_url_type = "NFSHARE" elif share_proto == 'CIFS': share_url_type = "CIFSHARE" else: raise exception.InvalidInput( reason=(_('Invalid NAS protocol supplied: %s.') % share_proto)) return share_url_type
def remove_access(self, access_id, share_proto, vstore_id=None): if share_proto == 'NFS': url = "/NFS_SHARE_AUTH_CLIENT/%s" % access_id elif share_proto == 'CIFS': url = "/CIFS_SHARE_AUTH_CLIENT/%s" % access_id else: msg = _('Invalid NAS protocol %s.') % share_proto raise exception.InvalidInput(reason=msg) data = {'vstoreId': vstore_id} if vstore_id else None result = self.call(url, "DELETE", data) _assert_result(result, 'Delete access %s error.', access_id)
def get_configured_ip_versions(self): if self.configured_ip_version is None: try: self.configured_ip_version = [] for ip in self.configuration.lvm_share_export_ips: self.configured_ip_version.append( ipaddress.ip_address(six.text_type(ip)).version) except Exception: message = (_("Invalid 'lvm_share_export_ips' option supplied " "%s.") % self.configuration.lvm_share_export_ips) raise exception.InvalidInput(reason=message) return self.configured_ip_version
def _allow_access_rest(self, share_id, access_to, share_proto, access_level, share_type_id): """Allow access to the share.""" if share_proto == 'NFS': self._allow_nfs_access_rest(share_id, access_to, access_level, share_type_id) elif share_proto == 'CIFS': self._allow_cifs_access_rest(share_id, access_to, access_level) else: raise exception.InvalidInput( reason=(_('Invalid NAS protocol supplied: %s.') % share_proto))
def get_qos_opts(self, opts): qos = {} if not strutils.bool_from_string(opts.get('qos')): return for key, value in opts.items(): if (key in constants.OPTS_QOS_VALUE) and value is not None: if (key.upper() != 'IOTYPE') and (int(value) <= 0): err_msg = (_('QoS config is wrong. %(key)s' ' must be set greater than 0.') % { 'key': key }) raise exception.InvalidInput(reason=err_msg) elif ((key.upper() == 'IOTYPE') and (value not in ['0', '1', '2'])): raise exception.InvalidInput( reason=(_('Illegal value specified for IOTYPE: ' 'set to either 0, 1, or 2.'))) else: qos[key.upper()] = value if len(qos) <= 1 or 'IOTYPE' not in qos: msg = (_('QoS config is incomplete. Please set more. ' 'QoS policy: %(qos_policy)s.') % { 'qos_policy': qos }) raise exception.InvalidInput(reason=msg) lowerlimit = constants.QOS_LOWER_LIMIT upperlimit = constants.QOS_UPPER_LIMIT if (set(lowerlimit).intersection(set(qos)) and set(upperlimit).intersection(set(qos))): msg = (_('QoS policy conflict, both protection policy and ' 'restriction policy are set. ' 'QoS policy: %(qos_policy)s ') % { 'qos_policy': qos }) raise exception.InvalidInput(reason=msg) return qos
def __init__(self, *args, **kwargs): """Do initialization.""" LOG.debug("Enter into init function of Huawei Driver.") super(HuaweiNasDriver, self).__init__((True, False), *args, **kwargs) if not self.configuration: raise exception.InvalidInput( reason=_("Huawei driver configuration missing.")) self.configuration.append_config_values(huawei_opts) kwargs.pop('configuration') self.plugin = importutils.import_object(self.get_backend_driver(), self.configuration, **kwargs)
def get_all_snapshots(self, context, search_opts=None, sort_key='share_id', sort_dir='desc'): policy.check_policy(context, 'share', 'get_all_snapshots') search_opts = search_opts or {} LOG.debug("Searching for snapshots by: %s", six.text_type(search_opts)) # Read and remove key 'all_tenants' if was provided all_tenants = search_opts.pop('all_tenants', None) string_args = {'sort_key': sort_key, 'sort_dir': sort_dir} string_args.update(search_opts) for k, v in string_args.items(): if not (isinstance(v, six.string_types) and v): msg = _("Wrong '%(k)s' filter provided: " "'%(v)s'.") % { 'k': k, 'v': string_args[k] } raise exception.InvalidInput(reason=msg) if (context.is_admin and all_tenants): snapshots = self.db.share_snapshot_get_all(context, filters=search_opts, sort_key=sort_key, sort_dir=sort_dir) else: snapshots = self.db.share_snapshot_get_all_by_project( context, context.project_id, filters=search_opts, sort_key=sort_key, sort_dir=sort_dir) # Remove key 'usage' if provided search_opts.pop('usage', None) if search_opts: results = [] not_found = object() for snapshot in snapshots: for opt, value in six.iteritems(search_opts): if snapshot.get(opt, not_found) != value: break else: results.append(snapshot) snapshots = results return snapshots
def check_for_setup_error(self): # Ensure vserver is specified in configuration. if not self._vserver: msg = _('Vserver must be specified in the configuration ' 'when the driver is not managing share servers.') raise exception.InvalidInput(reason=msg) # Ensure vserver exists. if not self._client.vserver_exists(self._vserver): raise exception.VserverNotFound(vserver=self._vserver) # If we have vserver credentials, ensure the vserver they connect # to matches the vserver specified in the configuration. if not self._have_cluster_creds: if self._vserver not in self._client.list_vservers(): msg = _('Vserver specified in the configuration does not ' 'match supplied credentials.') raise exception.InvalidInput(reason=msg) # Ensure one or more aggregates are available to the vserver. if not self._find_matching_aggregates(): msg = _('No aggregates are available to Vserver %s for ' 'provisioning shares. Ensure that one or more aggregates ' 'are assigned to the Vserver and that the configuration ' 'option netapp_aggregate_name_search_pattern is set ' 'correctly.') % self._vserver raise exception.NetAppException(msg) msg = ('Using Vserver %(vserver)s for backend %(backend)s with ' '%(creds)s credentials.') msg_args = {'vserver': self._vserver, 'backend': self._backend_name} msg_args['creds'] = ('cluster' if self._have_cluster_creds else 'Vserver') LOG.info(msg % msg_args) super(NetAppCmodeSingleSVMFileStorageLibrary, self).\ check_for_setup_error()
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)
def update_share(self, share_id, share_proto, params, vstore_id=None): if share_proto == 'NFS': url = "/NFSHARE/%s" % share_id elif share_proto == 'CIFS': url = "/CIFSHARE/%s" % share_id else: msg = _('Invalid NAS protocol %s.') % share_proto raise exception.InvalidInput(reason=msg) data = params if vstore_id: data['vstoreId'] = vstore_id result = self.call(url, "PUT", data) _assert_result(result, 'Update share %s error.', share_id)
def _read_xml(self): """Open xml file and parse the content.""" filename = self.configuration.manila_huawei_conf_file try: tree = ET.parse(filename) root = tree.getroot() except Exception as err: message = (_('Read Huawei config file(%(filename)s)' ' for Manila error: %(err)s') % {'filename': filename, 'err': err}) LOG.error(message) raise exception.InvalidInput(reason=message) return root
def _get_share_access_count(self, share_id, share_proto, vstore_id=None): if share_proto == 'NFS': url = "/NFS_SHARE_AUTH_CLIENT" elif share_proto == 'CIFS': url = "/CIFS_SHARE_AUTH_CLIENT" else: msg = _('Invalid NAS protocol %s.') % share_proto raise exception.InvalidInput(reason=msg) url += "/count?filter=PARENTID::%s" % share_id data = {'vstoreId': vstore_id} if vstore_id else None result = self.call(url, "GET", data) _assert_result(result, 'Get access count of share %s error.', share_id) return int(result['data']['COUNT'])
def delete_share(self, share_id, share_proto, vstore_id=None): if share_proto == 'NFS': url = "/NFSHARE/%s" % share_id elif share_proto == 'CIFS': url = "/CIFSHARE/%s" % share_id else: msg = _('Invalid NAS protocol %s.') % share_proto raise exception.InvalidInput(reason=msg) data = {'vstoreId': vstore_id} if vstore_id else None result = self.call(url, "DELETE", data) if _error_code(result) == constants.SHARE_NOT_EXIST: LOG.warning('Share %s to delete not exist.', share_id) return _assert_result(result, 'Delete share %s error.', share_id)
def _get_share_name_by_export_location(self, export_location, share_proto): export_location_split = None share_name = None share_ip = None if export_location: if share_proto == 'NFS': export_location_split = export_location.split(':/') if len(export_location_split) == 2: share_name = export_location_split[1] share_ip = export_location_split[0] elif share_proto == 'CIFS': export_location_split = export_location.split('\\') if (len(export_location_split) == 4 and export_location_split[0] == "" and export_location_split[1] == ""): share_ip = export_location_split[2] share_name = export_location_split[3] if share_name is None: raise exception.InvalidInput( reason=(_('No share with export location %s could be found.') % export_location)) root = self._read_xml() target_ip = root.findtext('Storage/LogicalPortIP') if target_ip: if share_ip != target_ip.strip(): raise exception.InvalidInput( reason=(_('The share IP %s is not configured.') % share_ip)) else: raise exception.InvalidInput( reason=(_('The config parameter LogicalPortIP is not set.'))) return share_name
def _validate_access_type(protocol, access_type): if access_type not in ('ip', 'user'): msg = (_("Invalid access type. Expected 'ip' or 'user'. " "Actual '%s'.") % access_type) LOG.error(msg) raise exception.InvalidInput(msg) if protocol == 'nfs' and access_type != 'ip': msg = (_("Invalid NFS access type. HPE 3PAR NFS supports 'ip'. " "Actual '%s'.") % access_type) LOG.error(msg) raise exception.HPE3ParInvalid(msg) return protocol
def _get_location_path(self, share_name, share_proto, ip, vol_id): if share_proto == 'NFS': vol = self.api_executor.get_specific_volinfo(vol_id) vol_mount_path = vol.find('vol_mount_path').text location = '%s:%s' % (ip, vol_mount_path) else: msg = _('Invalid NAS protocol: %s') % share_proto raise exception.InvalidInput(reason=msg) export_location = { 'path': location, 'is_admin_only': False, } return export_location
def get_controller_opts(self, opts): if strutils.bool_from_string(opts['huawei_controller']): if not opts['controllername']: opts['controllerid'] = None raise exception.InvalidInput( reason=_('Controller name is None, please set ' 'huawei_controller:controllername in key.')) else: controller_name = opts['controllername'] controller_id = self.helper.get_controller_by_name(controller_name) opts['controllerid'] = controller_id else: opts['controllerid'] = None return opts
def _get_vserver(self, share_server=None): if share_server is not None: msg = _('Share server must not be passed to the driver ' 'when the driver is not managing share servers.') raise exception.InvalidParameterValue(err=msg) if not self._vserver: msg = _('Vserver not specified in configuration.') raise exception.InvalidInput(reason=msg) if not self._client.vserver_exists(self._vserver): raise exception.VserverNotFound(vserver=self._vserver) vserver_client = self._get_api_client(self._vserver) return self._vserver, vserver_client
def _get_share_access_by_range(self, share_id, share_proto, range, vstore_id=None): if share_proto == 'NFS': url = "/NFS_SHARE_AUTH_CLIENT" elif share_proto == 'CIFS': url = "/CIFS_SHARE_AUTH_CLIENT" else: msg = _('Invalid NAS protocol %s.') % share_proto raise exception.InvalidInput(reason=msg) url += "?filter=PARENTID::%s" % share_id url += "&range=[%s-%s]" % range data = {'vstoreId': vstore_id} if vstore_id else None result = self.call(url, "GET", data) _assert_result(result, 'Get accesses of share %s error.', share_id) return result.get('data', [])
def _get_export_options(self, share): """Set various export attributes for share.""" metadata = share.get('share_metadata') options = None for item in metadata: if item['key'] == 'export_options': options = item['value'] else: msg = (_('Unknown metadata key %s.') % item['key']) LOG.error(msg) raise exception.InvalidInput(reason=msg) if not options: options = self.configuration.knfs_export_options return options
def is_all_tenants(search_opts): """Checks to see if the all_tenants flag is in search_opts :param dict search_opts: The search options for a request :returns: boolean indicating if all_tenants are being requested or not """ all_tenants = search_opts.get('all_tenants') if all_tenants: try: all_tenants = strutils.bool_from_string(all_tenants, True) except ValueError as err: raise exception.InvalidInput(six.text_type(err)) else: # The empty string is considered enabling all_tenants all_tenants = 'all_tenants' in search_opts return all_tenants
def allow_access(self, share_id, access_to, share_proto, access_level, share_type_id=None, vstore_id=None): if share_proto == 'NFS': self._allow_nfs_access(share_id, access_to, access_level, share_type_id, vstore_id) elif share_proto == 'CIFS': self._allow_cifs_access(share_id, access_to, access_level, vstore_id) else: msg = self._invalid_nas_protocol(share_proto) raise exception.InvalidInput(reason=msg)
def invoke_api(na_server, api_name, api_family='cm', query=None, des_result=None, additional_elems=None, is_iter=False, records=0, tag=None, timeout=0, tunnel=None): """Invokes any given API call to a NetApp server. :param na_server: na_server instance :param api_name: API name string :param api_family: cm or 7m :param query: API query as dict :param des_result: desired result as dict :param additional_elems: dict other than query and des_result :param is_iter: is iterator API :param records: limit for records, 0 for infinite :param timeout: timeout seconds :param tunnel: tunnel entity, vserver or vfiler name """ record_step = 50 if not (na_server or isinstance(na_server, NaServer)): msg = _("Requires an NaServer instance.") raise exception.InvalidInput(reason=msg) server = copy.copy(na_server) if api_family == 'cm': server.set_vserver(tunnel) else: server.set_vfiler(tunnel) if timeout > 0: server.set_timeout(timeout) iter_records = 0 cond = True while cond: na_element = create_api_request( api_name, query, des_result, additional_elems, is_iter, record_step, tag) result = server.invoke_successfully(na_element, True) if is_iter: if records > 0: iter_records = iter_records + record_step if iter_records >= records: cond = False tag_el = result.get_child_by_name('next-tag') tag = tag_el.get_content() if tag_el else None if not tag: cond = False else: cond = False yield result
def change_access(self, access_id, share_proto, access_level, vstore_id=None): if share_proto == 'NFS': url = "/NFS_SHARE_AUTH_CLIENT/%s" % access_id access = {"ACCESSVAL": access_level} elif share_proto == 'CIFS': url = "/CIFS_SHARE_AUTH_CLIENT/" + access_id access = {"PERMISSION": access_level} else: msg = _('Invalid NAS protocol %s.') % share_proto raise exception.InvalidInput(reason=msg) if vstore_id: access['vstoreId'] = vstore_id result = self.call(url, "PUT", access) _assert_result(result, 'Change access %s level to %s error.', access_id, access_level)
def append_sc(addr_list, sc_type): for addr in addr_list: address_mask = addr.strip().split('/', 1) address = address_mask[0] ls = [{"allow": True, "etype": "network", "entity": address}] if len(address_mask) == 2: try: mask = int(address_mask[1]) if mask != 32: ls[0]['mask'] = mask except Exception: raise exception.InvalidInput( reason=_('<{}> is not a valid access parameter' ).format(addr)) new_sc = {"securityModes": ["sys"]} new_sc[sc_type] = ls security_contexts.append(new_sc)