def unassign_floating_ip(self, floating_ip, fixed_ip): """Deletes SNAT and DNAT rules for given floating ip and fixed ip.""" if self._external_gw_info is None: raise v_exc.VRouterOperationError( ip_address=self.address, reason='External gateway not configured') cmd_list = [] # Check the cache for nat rules dict_key = self._get_floating_ip_key(floating_ip, fixed_ip) if dict_key in self._floating_ip_dict: # Get the NAT rules from the cache and delete them nat_rule = self._floating_ip_dict[dict_key] self._delete_snat_rule_cmd(cmd_list, nat_rule) self._delete_dnat_rule_cmd(cmd_list, nat_rule) # Delete the floating ip in external gateway interface gw_net = netaddr.IPNetwork(self._external_gw_info.get_ip_address()) self._delete_ethernet_ip_cmd( cmd_list, self._external_gw_info.get_ethernet_if_id(), '{0}/{1}'.format(floating_ip, gw_net.prefixlen)) else: raise v_exc.VRouterOperationError( ip_address=self.address, reason='NAT rule not found for floating ip {0}'.format( floating_ip)) self.exec_cmd_batch(cmd_list) if dict_key in self._floating_ip_dict: self._floating_ip_dict.pop(dict_key)
def _show_cmd(self, user_cmd): # TODO(asaprykin): Need to verify error handling op_cmd = '/rest/op/show/{0}'.format(user_cmd) response = self._rest_call("POST", op_cmd) self._check_response(response) op_url = response.headers['Location'] if op_url is None: raise v_exc.VRouterOperationError(ip_address=self.address, reason='REST API Op URL is None') op_url = "/" + op_url output = [] while True: response = self._rest_call('GET', op_url) if response.status_code == requests.codes.GONE: break if response.text: output.append(response.text) self._rest_call("DELETE", op_url) return ''.join(output)
def exec_cmd_batch(self, user_cmd_list): """Executes the given configuration command list. Commits and Saves the configuration changes to the startup config. """ response = self._rest_call("POST", "/rest/conf") self._check_response(response) config_url = response.headers['Location'] if config_url is None: raise v_exc.VRouterOperationError( ip_address=self.address, reason='REST API configuration URL is null') config_url = "/" + config_url for user_cmd in user_cmd_list: url = user_cmd.make_url(config_url) LOG.debug("Vyatta vRouter REST API: Config command %s", url) response = self._rest_call("PUT", url) self._check_response(response, config_url) response = self._rest_call("POST", config_url + "/commit") LOG.debug("Vyatta vRouter REST API: %s/commit", config_url) self._check_response(response, config_url) response = self._rest_call("POST", config_url + "/save") LOG.debug("Vyatta vRouter REST API: %s/save", config_url) self._check_response(response, config_url) response = self._rest_call("DELETE", config_url) self._check_response(response)
def assign_floating_ip(self, floating_ip, fixed_ip): """Creates SNAT and DNAT rules for given floating ip and fixed ip.""" if self._external_gw_info is None: raise v_exc.VRouterOperationError( ip_address=self.address, reason='External gateway not configured') cmd_list = [] ext_if_id = self._external_gw_info.get_ethernet_if_id() # Get the next NAT rule number and add the NAT rule nat_rule_num = self._get_next_nat_floating_ip_rule_num() self._add_snat_rule_cmd(cmd_list, nat_rule_num, ext_if_id, fixed_ip, floating_ip) self._add_dnat_rule_cmd(cmd_list, nat_rule_num, ext_if_id, floating_ip, fixed_ip) # Set the floating ip in external gateway interface gw_net = netaddr.IPNetwork(self._external_gw_info.get_ip_address()) self._set_ethernet_ip(cmd_list, self._external_gw_info.get_ethernet_if_id(), '{0}/{1}'.format(floating_ip, gw_net.prefixlen)) self.exec_cmd_batch(cmd_list) # Store SNAT and DNAT rule in cache dict_key = self._get_floating_ip_key(floating_ip, fixed_ip) self._floating_ip_dict[dict_key] = nat_rule_num
def _get_next_nat_subnet_ip_rule_num(self): """Returns the next NAT rule number for subnet ip.""" if self._nat_subnet_ip_rule_num >= self._MAX_NAT_SUBNET_IP_RULE_NUM: raise v_exc.VRouterOperationError( ip_address=self.address, reason='Max NAT Subnet IP rule count reached') self._nat_subnet_ip_rule_num += 1 return self._nat_subnet_ip_rule_num
def _get_next_nat_exclude_rule_num(self): """Returns the next NAT exclude rule number for VPN purposes""" if self._nat_exclude_rule_num >= self._MAX_NAT_EXCLUDE_RULE_NUM: raise v_exc.VRouterOperationError( ip_address=self.address, reason='Max NAT Exclude rule count reached') self._nat_exclude_rule_num += 1 return self._nat_exclude_rule_num
def _get_next_nat_floating_ip_rule_num(self): """Returns the next NAT rule number for floating ip.""" if (self._nat_floating_ip_rule_num >= self._MAX_NAT_FLOATING_IP_RULE_NUM): raise v_exc.VRouterOperationError( ip_address=self.address, reason='Max NAT Floating IP rule count reached') self._nat_floating_ip_rule_num += 1 return self._nat_floating_ip_rule_num
def _find_interface(self, mac_address): mac_address = mac_address.strip().lower() ifaces = self._get_interfaces() for iface in ifaces: if iface['mac_address'] == mac_address: return iface raise v_exc.VRouterOperationError( ip_address=self.address, reason='Ethernet interface with Mac-address {0} does not exist'. format(mac_address))
def _clear_gw_configuration(self, cmd_list): # If external gateway info was cached before # then clear the gateway router info if self._external_gw_info is not None: self._delete_external_gateway_if_cmd(cmd_list, self._external_gw_info) else: raise v_exc.VRouterOperationError( ip_address=self.address, reason='External gateway not already configured') # Execute the configuration commands self.exec_cmd_batch(cmd_list)
def _get_config_cmd(self, user_cmd): """Executes the given "get config" command.""" response = self._rest_call("POST", "/rest/conf") self._check_response(response) config_url = response.headers['Location'] if config_url is None: raise v_exc.VRouterOperationError( ip_address=self.address, reason='REST API Configuration URL is None') config_url = "/" + config_url config_cmd = '{0}/{1}/'.format(config_url, user_cmd) response = self._rest_call("GET", config_cmd) self._check_response(response) data = jsonutils.loads(response.text) self._rest_call("DELETE", config_url) return data
def _check_response(self, response, config_url=None, session=None): if session is None: session = requests if response.status_code not in (requests.codes.OK, requests.codes.CREATED): LOG.error( _LE('Vyatta vRouter REST API: Response Status : ' '%(status)s Reason: %(reason)s') % { 'status': response.status_code, 'reason': response.reason }) if config_url is not None: self._rest_call("DELETE", config_url, session=session) raise v_exc.VRouterOperationError(ip_address=self.address, reason=response.reason)
def _process_model(self): model = None show_output = self._show_cmd("version") LOG.debug('Vyatta vRouter REST API: Version output : %s', show_output) if show_output is not None: ma = re.compile(".+Description.+Brocade Vyatta\D+(\d+).+", re.DOTALL) result = ma.match(show_output) LOG.debug('Vyatta vRouter REST API: Result : %s', result) if result is not None: model_str = result.group(1) LOG.debug('Vyatta vRouter REST API: Result : %s', model_str) model = int(model_str) / 100 LOG.debug('Vyatta vRouter REST API: Result : %s', model) if model in (self._VROUTER_VSE_MODEL, self._VROUTER_VR_MODEL): self._vrouter_model = model LOG.debug('Vyatta vRouter REST API: Version : %s', self._vrouter_model) if self._vrouter_model is None: raise v_exc.VRouterOperationError( ip_address=self.address, reason='Unable to process vRouter model info: {0}'.format( model))