def _allocate_ip(*args, **kwargs): nsx_pool = self.nsx_pools[args[0]] if kwargs.get('ip_addr'): ip_addr = netaddr.IPAddress(kwargs['ip_addr']) # verify that this ip was not yet allocated if ip_addr in nsx_pool['allocated']: raise nsx_lib_exc.ManagerError( manager='dummy', operation='allocate', details='IP already allocated', error_code=error.ERR_CODE_IPAM_IP_ALLOCATED) # skip ip validation for this mock. nsx_pool['allocated'].append(ip_addr) return {'allocation_id': str(ip_addr)} # get an unused ip from the pool ranges = nsx_pool['pool']['subnets'][0]['allocation_ranges'] for ip_range in ranges: r = netaddr.IPRange(ip_range['start'], ip_range['end']) for ip_addr in r: if ip_addr not in nsx_pool['allocated']: nsx_pool['allocated'].append(ip_addr) return {'allocation_id': str(ip_addr)} # no IP was found raise nsx_lib_exc.ManagerError( manager='dummy', operation='allocate', details='All IPs in the pool are allocated', error_code=error.ERR_CODE_IPAM_POOL_EXHAUSTED)
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 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)
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 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 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_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 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 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 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 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 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)
def create_or_overwrite(self, name, domain_id, map_id=None, description=None, precedence=0, category=policy_constants.CATEGORY_DEFAULT, sequence_number=None, service_ids=None, action=policy_constants.ACTION_ALLOW, source_groups=None, dest_groups=None, tenant=policy_constants.POLICY_INFRA_TENANT): """Create CommunicationMap & Entry. source_groups/dest_groups should be a list of group ids belonging to the domain. NOTE: In multi-connection environment, it is recommended to execute this call under lock to prevent race condition where two entries end up with same sequence number. """ # Validate and convert inputs if not service_ids: # service-ids must be provided err_msg = (_("Cannot create a communication map %(name)s without " "services") % {'name': name}) raise exceptions.ManagerError(details=err_msg) if map_id: # get the next available sequence number last_sequence = self._get_last_seq_num(domain_id, map_id, tenant=tenant) else: map_id = self._init_obj_uuid(map_id) last_sequence = -1 if not sequence_number: if last_sequence < 0: sequence_number = 1 else: sequence_number = last_sequence + 1 # Build the communication entry. Since we currently support only one # it will have the same id as its parent entry_def = policy_defs.CommunicationMapEntryDef( domain_id=domain_id, map_id=map_id, entry_id=map_id, name=name, description=description, sequence_number=sequence_number, source_groups=source_groups, dest_groups=dest_groups, service_ids=service_ids, action=action, tenant=tenant) map_def = policy_defs.CommunicationMapDef( domain_id=domain_id, map_id=map_id, tenant=tenant, name=name, description=description, precedence=precedence, category=category) if last_sequence < 0: # if communication map is absent, we need to create it return self.policy_api.create_with_parent(map_def, entry_def) # TODO(asarfaty) combine both calls together self.policy_api.create_or_update(map_def) self.policy_api.create_or_update(entry_def) return self.get(domain_id, map_id, tenant=tenant)