def _get_resource_by_name_or_id(self, name_or_id, resource): all_results = self.client.list(resource)['results'] matched_results = [] for rs in all_results: if rs.get('id') == name_or_id: # Matched by id - must be unique return name_or_id if rs.get('display_name') == name_or_id: # Matched by name - add to the list to verify it is unique matched_results.append(rs) if len(matched_results) == 0: err_msg = (_("Could not find %(resource)s %(name)s") % { 'name': name_or_id, 'resource': resource }) raise nsxlib_exceptions.ManagerError(details=err_msg) elif len(matched_results) > 1: err_msg = (_("Found multiple %(resource)s named %(name)s") % { 'name': name_or_id, 'resource': resource }) raise nsxlib_exceptions.ManagerError(details=err_msg) return matched_results[0].get('id')
def get_by_lswitch_id(self, logical_switch_id): resource = '?logical_switch_id=%s' % logical_switch_id router_ports = self.client.url_get(self.get_path(resource)) result_count = int(router_ports.get('result_count', "0")) if result_count >= 2: raise exceptions.ManagerError( details=_("Can't support more than one logical router ports " "on same logical switch %s ") % logical_switch_id) elif result_count == 1: return router_ports['results'][0] else: err_msg = (_("Logical router link port not found on logical " "switch %s") % logical_switch_id) raise exceptions.ResourceNotFound( manager=self.client.nsx_api_managers, operation=err_msg)
def search_by_tags(self, tags, resource_type=None, cursor=None, page_size=None): """Return the list of resources searched based on tags. Currently the query only supports AND boolean operator. :param tags: List of dictionaries containing tags. Each NSX tag dictionary is of the form: {'scope': <scope_key>, 'tag': <tag_value>} :param resource_type: Optional string parameter to limit the scope of the search to the given ResourceType. :param cursor: Opaque cursor to be used for getting next page of records (supplied by current result page). :param page_size: Maximum number of results to return in this page. """ if not tags: reason = _("Missing required argument 'tags'") raise exceptions.NsxSearchInvalidQuery(reason=reason) # Query will return nothing if the same scope is repeated. query_tags = self._build_query(tags) query = 'resource_type:%s' % resource_type if resource_type else None if query: query += " AND %s" % query_tags else: query = query_tags url = self._add_pagination_parameters("search?query=%s" % query, cursor, page_size) # Retry the search on case of error @utils.retry_upon_exception(exceptions.NsxSearchError, max_attempts=self.client.max_attempts) def do_search(url): return self.client.url_get(url) return do_search(url)
def _get_cert_from_file(self, filename): with open(filename, 'r') as f: cert_pem = f.read() if not cert_pem: raise nsxlib_exceptions.CertificateError( msg=_("Failed to read certificate from %s") % filename) # validate correct crypto try: cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem) except crypto.Error: raise nsxlib_exceptions.CertificateError( msg=_("Failed to import client certificate")) return cert
def update_lb_rule(self, virtual_server_id, lb_rule_name, actions=None, match_conditions=None, match_strategy=None, phase=None, position=-1, tenant=constants.POLICY_INFRA_TENANT): lb_rule = lb_defs.LBRuleDef( actions, match_conditions, lb_rule_name, match_strategy, phase) lbvs_def = self.entry_def( virtual_server_id=virtual_server_id, tenant=tenant) body = self.policy_api.get(lbvs_def) lb_rules = body.get('rules', []) # Remove existing rule try: rule_index = next(lb_rules.index(r) for r in lb_rules if r.get('display_name') == lb_rule_name) except Exception: err_msg = (_("No resource in rules matched for values: " "%(values)s") % {'values': lb_rule_name}) raise nsxlib_exc.ResourceNotFound( manager=self, operation=err_msg) if position < 0: position = rule_index del(lb_rules[rule_index]) # Insert new rule lb_rules = self._add_rule_in_position(body, lb_rule, position) return self._update_helper( virtual_server_id, rules=lb_rules, vs_data=body, tenant=tenant)
def update(self, ep_id, name=None, description=None, ip_address=None, username=None, password=None, thumbprint=None, edge_cluster_id=None, transport_zone_id=None, tenant=policy_constants.POLICY_INFRA_TENANT): """Update the enforcement point. username & password must be defined """ if not username or password is None: # username/password must be provided err_msg = (_("Cannot update an enforcement point without " "username and password")) raise exceptions.ManagerError(details=err_msg) # Get the original body because ip & thumbprint are mandatory body = self.get(ep_id) ep_def = policy_defs.EnforcementPointDef(ep_id=ep_id, tenant=tenant) ep_def.update_attributes_in_body(body=body, name=name, description=description, ip_address=ip_address, username=username, password=password, edge_cluster_id=edge_cluster_id, transport_zone_id=transport_zone_id, thumbprint=thumbprint) # update the backend return self.policy_api.create_or_update(ep_def)
class NsxLibException(Exception): """Base NsxLib Exception. To correctly use this class, inherit from it and define a 'message' property. That message will get printf'd with the keyword arguments provided to the constructor. """ message = _("An unknown exception occurred.") def __init__(self, **kwargs): try: super(NsxLibException, self).__init__(self.message % kwargs) self.msg = self.message % kwargs except Exception: with excutils.save_and_reraise_exception() as ctxt: if not self.use_fatal_exceptions(): ctxt.reraise = False # at least get the core message out if something happened super(NsxLibException, self).__init__(self.message) if six.PY2: def __unicode__(self): return unicode(self.msg) if six.PY2 else self.msg # noqa def __str__(self): return self.msg def use_fatal_exceptions(self): return False
def _validate_resource_type_length(resource_type): # Add in a validation to ensure that we catch this at build time if len(resource_type) > MAX_RESOURCE_TYPE_LEN: raise nsxlib_exceptions.NsxLibInvalidInput( error_message=(_('Resource type cannot exceed %(max_len)s ' 'characters: %(resource_type)s') % {'max_len': MAX_RESOURCE_TYPE_LEN, 'resource_type': resource_type}))
def validate_cert_params(key_size, valid_for_days, signature_alg, subject): """Validate parameters for certificate""" expected_key_sizes = (2048, 4096) if key_size not in expected_key_sizes: raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid key size %(value)d' '(must be one of %(list)s)') % { 'value': key_size, 'list': expected_key_sizes }) expected_signature_algs = ('sha256') if signature_alg not in expected_signature_algs: raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid signature algorithm %(value)s' '(must be one of %(list)s)') % { 'value': signature_alg, 'list': expected_signature_algs }) if (CERT_SUBJECT_COUNTRY in subject and (len(subject[CERT_SUBJECT_COUNTRY]) != 2)): raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid country %s: ' 'must be exactly 2 characters') % subject[CERT_SUBJECT_COUNTRY]) # values defined in rfc5280 max_len_constraints = { CERT_SUBJECT_STATE: 128, CERT_SUBJECT_ORG: 64, CERT_SUBJECT_UNIT: 64, CERT_SUBJECT_HOST: 64 } for field, max_len in max_len_constraints.items(): if field in subject and (len(subject[field]) > max_len): raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid %(field)s [%(value)s]: ' 'must not exceed %(max)d characters') % { 'field': field, 'value': subject[field], 'max': max_len })
def list(self, domain_id=None, tenant=policy_constants.POLICY_INFRA_TENANT): if not domain_id: # domain_id must be provided err_msg = (_("Cannot list deployment maps without a domain")) raise exceptions.ManagerError(details=err_msg) map_def = policy_defs.DeploymentMapDef(domain_id=domain_id, tenant=tenant) return self.policy_api.list(map_def)['results']
def check_manager_status_v2(client, manager_url): """MP healthcheck for Version 2.4 and above""" # Try to get the status silently and with no retries status = client.get('reverse-proxy/node/health', silent=True, with_retries=False) if (not status or not status.get('healthy', False)): msg = _("Manager is not in working state: %s") % status LOG.warning(msg) raise exceptions.ResourceNotFound( manager=manager_url, operation=msg)
def check_manager_status_v1(client, manager_url): """MP healthcheck for Version 2.3 and below""" # Try to get the cluster status silently and with no retries status = client.get('operational/application/status', silent=True, with_retries=False) if (not status or status.get('application_status') != 'WORKING'): msg = _("Manager is not in working state: %s") % status LOG.warning(msg) raise exceptions.ResourceNotFound( manager=manager_url, operation=msg)
def delete(self, map_id, domain_id=None, tenant=policy_constants.POLICY_INFRA_TENANT): if not domain_id: # domain_id must be provided err_msg = (_("Cannot delete deployment maps without a domain")) raise exceptions.ManagerError(details=err_msg) map_def = policy_defs.DeploymentMapDef( map_id=map_id, domain_id=domain_id, tenant=tenant) self.policy_api.delete(map_def)
def get_rate_limit(self): if (self.nsxlib and not self.nsxlib.feature_supported( nsx_constants.FEATURE_RATE_LIMIT)): msg = (_("Rate limit is not supported by NSX version %s") % self.nsxlib.get_version()) raise exceptions.ManagerError(details=msg) properties = self.get_properties() return properties.get('service_properties', {}).get('client_api_rate_limit')
def get_id_by_resource_and_tag(self, resource_type, scope, tag, alert_not_found=False, alert_multiple=False): """Search a resource type by 1 scope&tag. Return the id of the result only if it is single. """ query_tags = [{ 'scope': utils.escape_tag_data(scope), 'tag': utils.escape_tag_data(tag) }] query_result = self.search_by_tags(tags=query_tags, resource_type=resource_type) if not query_result['result_count']: if alert_not_found: msg = _("No %(type)s found for tag '%(scope)s:%(tag)s'") % { 'type': resource_type, 'scope': scope, 'tag': tag } LOG.warning(msg) raise exceptions.ResourceNotFound( manager=self.nsxlib_config.nsx_api_managers, operation=msg) elif query_result['result_count'] == 1: return query_result['results'][0]['id'] else: # multiple results if alert_multiple: msg = _("Multiple %(type)s found for tag '%(scope)s:" "%(tag)s'") % { 'type': resource_type, 'scope': scope, 'tag': tag } LOG.warning(msg) raise exceptions.ManagerError( manager=self.nsxlib_config.nsx_api_managers, operation=msg, details='')
def get_rate_limit(self): if (self.nsxlib and not self.nsxlib.feature_supported( nsx_constants.FEATURE_RATE_LIMIT)): msg = (_("Rate limit is not supported by NSX version %s") % self.nsxlib.get_version()) raise exceptions.ManagerError(details=msg) properties = self.get_properties() return properties.get('service_properties', {}).get( 'client_api_rate_limit')
def validate_cert_params(key_size, valid_for_days, signature_alg, subject): """Validate parameters for certificate""" expected_key_sizes = (2048, 4096) if key_size not in expected_key_sizes: raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid key size %(value)d' '(must be one of %(list)s)') % {'value': key_size, 'list': expected_key_sizes}) expected_signature_algs = ('sha256') if signature_alg not in expected_signature_algs: raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid signature algorithm %(value)s' '(must be one of %(list)s)') % {'value': signature_alg, 'list': expected_signature_algs}) if (CERT_SUBJECT_COUNTRY in subject and (len(subject[CERT_SUBJECT_COUNTRY]) != 2)): raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid country %s: ' 'must be exactly 2 characters') % subject[CERT_SUBJECT_COUNTRY]) # values defined in rfc5280 max_len_constraints = {CERT_SUBJECT_STATE: 128, CERT_SUBJECT_ORG: 64, CERT_SUBJECT_UNIT: 64, CERT_SUBJECT_HOST: 64} for field, max_len in max_len_constraints.items(): if field in subject and (len(subject[field]) > max_len): raise nsxlib_exceptions.NsxLibInvalidInput( error_message=_('Invalid %(field)s [%(value)s]: ' 'must not exceed %(max)d characters') % {'field': field, 'value': subject[field], 'max': max_len})
class ManagerError(NsxLibException): message = _("Unexpected error from backend manager (%(manager)s) " "for %(operation)s%(details)s") def __init__(self, **kwargs): details = kwargs.get('details', '') kwargs['details'] = ': %s' % details if details else '' super(ManagerError, self).__init__(**kwargs) try: self.msg = self.message % kwargs except KeyError: self.msg = details self.error_code = kwargs.get('error_code')
def _get_resource_by_name_or_id(self, name_or_id, resource): all_results = self.client.list(resource)['results'] matched_results = [] for rs in all_results: if rs.get('id') == name_or_id: # Matched by id - must be unique return name_or_id if rs.get('display_name') == name_or_id: # Matched by name - add to the list to verify it is unique matched_results.append(rs) if len(matched_results) == 0: err_msg = (_("Could not find %(resource)s %(name)s") % {'name': name_or_id, 'resource': resource}) raise nsxlib_exceptions.ManagerError(details=err_msg) elif len(matched_results) > 1: err_msg = (_("Found multiple %(resource)s named %(name)s") % {'name': name_or_id, 'resource': resource}) raise nsxlib_exceptions.ManagerError(details=err_msg) return matched_results[0].get('id')
def _build_tag_query(self, tag): # Validate that the correct keys are used if set(tag.keys()) - set(('scope', 'tag')): reason = _("Only 'scope' and 'tag' keys are supported") raise exceptions.NsxSearchInvalidQuery(reason=reason) _scope = tag.get('scope') _tag = tag.get('tag') if _scope and _tag: return 'tags.scope:%s AND tags.tag:%s' % (_scope, _tag) elif _scope: return 'tags.scope:%s' % _scope else: return 'tags.tag:%s' % _tag
def get_id_by_resource_and_tag(self, resource_type, scope, tag, alert_not_found=False, alert_multiple=False): """Search a resource type by 1 scope&tag. Return the id of the result only if it is single. """ query_tags = [{'scope': utils.escape_tag_data(scope), 'tag': utils.escape_tag_data(tag)}] query_result = self.search_by_tags( tags=query_tags, resource_type=resource_type) if not query_result['result_count']: if alert_not_found: msg = _("No %(type)s found for tag '%(scope)s:%(tag)s'") % { 'type': resource_type, 'scope': scope, 'tag': tag} LOG.warning(msg) raise exceptions.ResourceNotFound( manager=self.nsxlib_config.nsx_api_managers, operation=msg) elif query_result['result_count'] == 1: return query_result['results'][0]['id'] else: # multiple results if alert_multiple: msg = _("Multiple %(type)s found for tag '%(scope)s:" "%(tag)s'") % { 'type': resource_type, 'scope': scope, 'tag': tag} LOG.warning(msg) raise exceptions.ManagerError( manager=self.nsxlib_config.nsx_api_managers, operation=msg, details='')
def validate_tier0(self, tier0_groups_dict, tier0_uuid): err_msg = None if not tier0_uuid: err_msg = _("validate_tier0 should be called with tier0 uuid") raise exceptions.NsxLibInvalidInput(error_message=err_msg) try: lrouter = self._router_client.get(tier0_uuid) except exceptions.ResourceNotFound: err_msg = (_("Tier0 router %s not found at the backend. Either a " "valid UUID must be specified or a default tier0 " "router UUID must be configured in nsx.ini") % tier0_uuid) else: edge_cluster_uuid = lrouter.get('edge_cluster_id') if not edge_cluster_uuid: err_msg = _("Failed to get edge cluster uuid from tier0 " "router %s at the backend") % lrouter else: edge_cluster = self.nsxlib.edge_cluster.get(edge_cluster_uuid) member_index_list = [member['member_index'] for member in edge_cluster['members']] if len(member_index_list) < MIN_EDGE_NODE_NUM: err_msg = _("%(act_num)s edge members found in " "edge_cluster %(cluster_id)s, however we " "require at least %(exp_num)s edge nodes " "in edge cluster for use") % { 'act_num': len(member_index_list), 'exp_num': MIN_EDGE_NODE_NUM, 'cluster_id': edge_cluster_uuid} if err_msg: raise exceptions.NsxLibInvalidInput(error_message=err_msg) else: tier0_groups_dict[tier0_uuid] = { 'edge_cluster_uuid': edge_cluster_uuid, 'member_index_list': member_index_list}
def validate_tier0(self, tier0_groups_dict, tier0_uuid): err_msg = None try: lrouter = self._router_client.get(tier0_uuid) except exceptions.ResourceNotFound: err_msg = (_("Tier0 router %s not found at the backend. Either a " "valid UUID must be specified or a default tier0 " "router UUID must be configured in nsx.ini") % tier0_uuid) else: edge_cluster_uuid = lrouter.get('edge_cluster_id') if not edge_cluster_uuid: err_msg = _("Failed to get edge cluster uuid from tier0 " "router %s at the backend") % lrouter else: edge_cluster = self.nsxlib.edge_cluster.get(edge_cluster_uuid) member_index_list = [ member['member_index'] for member in edge_cluster['members'] ] if len(member_index_list) < MIN_EDGE_NODE_NUM: err_msg = _("%(act_num)s edge members found in " "edge_cluster %(cluster_id)s, however we " "require at least %(exp_num)s edge nodes " "in edge cluster for use") % { 'act_num': len(member_index_list), 'exp_num': MIN_EDGE_NODE_NUM, 'cluster_id': edge_cluster_uuid } if err_msg: raise exceptions.NsxLibInvalidInput(error_message=err_msg) else: tier0_groups_dict[tier0_uuid] = { 'edge_cluster_uuid': edge_cluster_uuid, 'member_index_list': member_index_list }
def add_nsgroup(self, nsgroup_id): for group in self._suggest_nested_group(nsgroup_id): try: LOG.debug("Adding NSGroup %s to nested group %s", nsgroup_id, group) self.nsxlib_nsgroup.add_members(group, consts.NSGROUP, [nsgroup_id]) break except exceptions.NSGroupIsFull: LOG.debug( "Nested group %(group_id)s is full, trying the " "next group..", {'group_id': group}) else: raise exceptions.ManagerError( details=_("Reached the maximum supported amount of " "security groups."))
def _delete_resource_by_values(self, resource, skip_not_found=True, strict_mode=True, **kwargs): """Delete resource objects matching the values in kwargs If skip_not_found is True - do not raise an exception if no object was found. If strict_mode is True - warnings will be issued if 0 or >1 objects where deleted. """ resources_list = self.client.list(resource) matched_num = 0 for res in resources_list['results']: if utils.dict_match(kwargs, res): LOG.debug("Deleting %s from resource %s", res, resource) delete_resource = resource + "/" + str(res['id']) self.client.delete(delete_resource) matched_num = matched_num + 1 if matched_num == 0: if skip_not_found: if strict_mode: LOG.warning( "No resource in %(res)s matched for values: " "%(values)s", { 'res': resource, 'values': kwargs }) else: err_msg = (_("No resource in %(res)s matched for values: " "%(values)s") % { 'res': resource, 'values': kwargs }) raise exceptions.ResourceNotFound( manager=self.client.nsx_api_managers, operation=err_msg) elif matched_num > 1 and strict_mode: LOG.warning( "%(num)s resources in %(res)s matched for values: " "%(values)s", { 'num': matched_num, 'res': resource, 'values': kwargs })
def validate_connection(self, cluster_api, endpoint, conn): client = nsx_client.NSX3Client( conn, url_prefix=endpoint.provider.url, url_path_base=cluster_api.nsxlib_config.url_base, default_headers=conn.default_headers) keepalive_section = cluster_api.nsxlib_config.keepalive_section result = client.get(keepalive_section, silent=True) # If keeplive section returns a list, it is assumed to be non-empty if not result or result.get('result_count', 1) <= 0: msg = _("No %(section)s found " "for '%(url)s'") % { 'section': keepalive_section, 'url': endpoint.provider.url } LOG.warning(msg) raise exceptions.ResourceNotFound(manager=endpoint.provider.url, operation=msg)
def _rest_call(self, url, method='GET', body=None, headers=None, silent=False, expected_results=None, **kwargs): request_headers = headers.copy() if headers else {} request_headers.update(self._default_headers) if utils.INJECT_HEADERS_CALLBACK: inject_headers = utils.INJECT_HEADERS_CALLBACK() request_headers.update(inject_headers) request_url = self._build_url(url) do_request = getattr(self._conn, method.lower()) if not silent: LOG.debug("REST call: %s %s. Headers: %s. Body: %s", method, request_url, request_headers, self._mask_password(body)) ts = time.time() result = do_request(request_url, data=body, headers=request_headers) te = time.time() if not silent: LOG.debug("REST call: %s %s. Response: %s. Took %2.4f", method, request_url, result.json() if result.content else '', te - ts) if not expected_results: expected_results = RESTClient._VERB_RESP_CODES[method.lower()] self._validate_result(result, expected_results, _("%(verb)s %(url)s") % { 'verb': method, 'url': request_url }, silent=silent) return result
def create_or_overwrite(self, name, ep_id=None, description=None, ip_address=None, username=None, password=None, thumbprint=None, edge_cluster_id=None, transport_zone_id=None, tenant=policy_constants.POLICY_INFRA_TENANT): if not ip_address or not username or password is None: err_msg = (_("Cannot create an enforcement point without " "ip_address, username and password")) raise exceptions.ManagerError(details=err_msg) ep_id = self._init_obj_uuid(ep_id) ep_def = policy_defs.EnforcementPointDef( ep_id=ep_id, name=name, description=description, ip_address=ip_address, username=username, password=password, thumbprint=thumbprint, edge_cluster_id=edge_cluster_id, transport_zone_id=transport_zone_id, tenant=tenant) return self.policy_api.create_or_update(ep_def)
def update_rate_limit(self, value): """update the NSX rate limit. default value is 40. 0 means no limit""" if (self.nsxlib and not self.nsxlib.feature_supported( nsx_constants.FEATURE_RATE_LIMIT)): msg = (_("Rate limit is not supported by NSX version %s") % self.nsxlib.get_version()) raise exceptions.ManagerError(details=msg) properties = self.get_properties() if 'service_properties' in properties: properties['service_properties']['client_api_rate_limit'] = int( value) # update the value using a PUT command, which is expected to return 202 expected_results = [requests.codes.accepted] self.client.update(self.uri_segment, properties, expected_results=expected_results) # restart the http service using POST, which is expected to return 202 restart_url = self.uri_segment + '?action=restart' self.client.create(restart_url, expected_results=expected_results)
def update_rate_limit(self, value): """update the NSX rate limit. default value is 40. 0 means no limit""" if (self.nsxlib and not self.nsxlib.feature_supported( nsx_constants.FEATURE_RATE_LIMIT)): msg = (_("Rate limit is not supported by NSX version %s") % self.nsxlib.get_version()) raise exceptions.ManagerError(details=msg) properties = self.get_properties() if 'service_properties' in properties: properties['service_properties'][ 'client_api_rate_limit'] = int(value) # update the value using a PUT command, which is expected to return 202 expected_results = [requests.codes.accepted] self.client.update(self.uri_segment, properties, expected_results=expected_results) # restart the http service using POST, which is expected to return 202 restart_url = self.uri_segment + '?action=restart' self.client.create(restart_url, expected_results=expected_results)
def update_lb_rule(self, virtual_server_id, lb_rule_name, actions=None, match_conditions=None, match_strategy=None, phase=None, position=-1, tenant=constants.POLICY_INFRA_TENANT): lb_rule = lb_defs.LBRuleDef(actions, match_conditions, lb_rule_name, match_strategy, phase) lbvs_def = self.entry_def(virtual_server_id=virtual_server_id, tenant=tenant) body = self.policy_api.get(lbvs_def) lb_rules = body.get('rules', []) # Remove existing rule try: rule_index = next( lb_rules.index(r) for r in lb_rules if r.get('display_name') == lb_rule_name) except Exception: err_msg = (_("No resource in rules matched for values: " "%(values)s") % { 'values': lb_rule_name }) raise nsxlib_exc.ResourceNotFound(manager=self, operation=err_msg) if position < 0: position = rule_index del (lb_rules[rule_index]) # Insert new rule lb_rules = self._add_rule_in_position(body, lb_rule, position) return self._update_helper(virtual_server_id, rules=lb_rules, vs_data=body, tenant=tenant)
def _rest_call(self, url, method='GET', body=None, headers=None, silent=False, expected_results=None, **kwargs): request_headers = headers.copy() if headers else {} request_headers.update(self._default_headers) if utils.INJECT_HEADERS_CALLBACK: inject_headers = utils.INJECT_HEADERS_CALLBACK() request_headers.update(inject_headers) request_url = self._build_url(url) do_request = getattr(self._conn, method.lower()) if not silent: LOG.debug("REST call: %s %s. Headers: %s. Body: %s", method, request_url, request_headers, self._mask_password(body)) ts = time.time() result = do_request( request_url, data=body, headers=request_headers) te = time.time() if not silent: LOG.debug("REST call: %s %s. Response: %s. Took %2.4f", method, request_url, result.json() if result.content else '', te - ts) if not expected_results: expected_results = RESTClient._VERB_RESP_CODES[method.lower()] self._validate_result( result, expected_results, _("%(verb)s %(url)s") % {'verb': method, 'url': request_url}, silent=silent) return result
def search_resource_by_attributes(self, resource_type, cursor=None, page_size=None, **attributes): """Search resources of a given type matching specific attributes. It is optional to specify attributes. If multiple attributes are specified they are ANDed together to form the search query. :param resource_type: String parameter specifying the desired resource_type :param cursor: Opaque cursor to be used for getting next page of records (supplied by current result page). :param page_size: Maximum number of results to return in this page. :param **attributes: an optional set of keyword arguments specifying filters for the search query. Wildcards will not be interpeted. :returns: a list of resources of the requested type matching specified filters. """ if not resource_type: raise exceptions.NsxSearchInvalidQuery( reason=_("Resource type was not specified")) attributes_query = " AND ".join(['%s:%s' % (k, v) for (k, v) in attributes.items()]) query = 'resource_type:%s' % resource_type + ( " AND %s" % attributes_query if attributes_query else "") url = self._add_pagination_parameters("search?query=%s" % query, cursor, page_size) # Retry the search on case of error @utils.retry_upon_exception(exceptions.NsxIndexingInProgress, max_attempts=self.client.max_attempts) def do_search(url): return self.client.url_get(url) return do_search(url)
def delete(self, uuid): """Not supported""" msg = _("Delete is not supported for %s") % self.uri_segment raise exceptions.ManagerError(details=msg)
def find_by_display_name(self, display_name): """Not supported""" msg = _("Find is not supported for %s") % self.uri_segment raise exceptions.ManagerError(details=msg)
def list(self): """Not supported""" msg = _("List is not supported for %s") % self.uri_segment raise exceptions.ManagerError(details=msg)
class BackendResourceNotFound(ResourceNotFound): message = _("%(details)s On backend (%(manager)s) with Operation: " "%(operation)s")
class InvalidInput(ManagerError): message = _("%(operation)s failed: Invalid input %(arg_val)s " "for %(arg_name)s")