def create_importmap(type, action, name, value, route_family=None): if action != 'drop': raise RuntimeConfigError( 'Unknown action. For now we only support "drop" action.') if type not in ('prefix_match', 'rt_match'): raise RuntimeConfigError( 'Unknown type. We support only "prefix_match" and "rt_match".') if type == 'prefix_match': return _create_prefix_match_importmap(name, value, route_family) elif type == 'rt_match': return _create_rt_match_importmap(name, value)
def add_vrf_conf(self, vrf_conf): if vrf_conf.rd_rf_id in self._vrfs_by_rd_rf.keys(): raise RuntimeConfigError( desc='VrfConf with rd_rf %s already exists' % str(vrf_conf.rd_rf_id) ) if vrf_conf.id in self._vrfs_by_id: raise RuntimeConfigError( desc='VrfConf with id %s already exists' % str(vrf_conf.id) ) self._vrfs_by_rd_rf[vrf_conf.rd_rf_id] = vrf_conf self._vrfs_by_id[vrf_conf.id] = vrf_conf self._notify_listeners(VrfsConf.ADD_VRF_CONF_EVT, vrf_conf)
def _create_prefix_match_importmap(name, value, route_family): core_service = CORE_MANAGER.get_core_service() importmap_manager = core_service.importmap_manager try: if route_family == 'ipv4': importmap_manager.create_vpnv4_nlri_import_map(name, value) elif route_family == 'ipv6': importmap_manager.create_vpnv6_nlri_import_map(name, value) else: raise RuntimeConfigError( 'Unknown address family %s. it should be ipv4 or ipv6' % route_family) except ImportMapAlreadyExistsError: raise RuntimeConfigError('Map with this name already exists') return True
def wrapped_fun(**kwargs): """Wraps a function to do validation before calling actual func. Wraps a function to take key-value args. only. Checks if: 1) all required argument of wrapped function are provided 2) no extra/un-known arguments are passed 3) checks if validator for required arguments is available 4) validates required arguments 5) if validator for optional arguments is registered, validates optional arguments. Raises exception if no validator can be found for required args. """ # Check if we are missing arguments. if not kwargs and len(self._req_args) > 0: raise MissingRequiredConf(desc='Missing all required ' 'attributes.') # Check if we have unknown arguments. given_args = set(kwargs.keys()) unknown_attrs = given_args - set(self._all_args) if unknown_attrs: raise RuntimeConfigError(desc=('Unknown attributes %r' % unknown_attrs)) # Check if required arguments are missing missing_req_args = set(self._req_args) - given_args if missing_req_args: conf_name = ', '.join(missing_req_args) raise MissingRequiredConf(conf_name=conf_name) # # Prepare to call wrapped function. # # Collect required arguments in the order asked and validate it. req_values = [] for req_arg in self._req_args: req_value = kwargs.get(req_arg) # Validate required value. validator = get_validator(req_arg) if not validator: raise ValueError('No validator registered for function=%s' ' and arg=%s' % (func, req_arg)) validator(req_value) req_values.append(req_value) # Collect optional arguments. opt_items = {} for opt_arg, opt_value in kwargs.items(): if opt_arg in self._opt_args: # Validate optional value. # Note: If no validator registered for optional value, # skips validation. validator = get_validator(opt_arg) if validator: validator(opt_value) opt_items[opt_arg] = opt_value # Call actual function return func(*req_values, **opt_items)
def _create_rt_match_importmap(name, value): core_service = CORE_MANAGER.get_core_service() importmap_manager = core_service.importmap_manager try: importmap_manager.create_rt_import_map(name, value) except ImportMapAlreadyExistsError: raise RuntimeConfigError('Map with this name already exists') return True
def remove_neighbor_conf(self, neigh_ip_address): neigh_conf = self._neighbors.pop(neigh_ip_address, None) if not neigh_conf: raise RuntimeConfigError(desc='Tried to remove a neighbor that ' 'does not exists') else: self._notify_listeners(NeighborsConf.REMOVE_NEIGH_CONF_EVT, neigh_conf) return neigh_conf
def get_vrf_conf(self, route_dist, vrf_rf, vrf_id=None): if route_dist is None and vrf_id is None: raise RuntimeConfigError(desc='To get VRF supply route_dist ' 'or vrf_id.') if route_dist is not None and vrf_id is not None: vrf1 = self._vrfs_by_id.get(vrf_id) rd_rf_id = VrfConf.create_rd_rf_id(route_dist, vrf_rf) vrf2 = self._vrfs_by_rd_rf.get(rd_rf_id) if vrf1 is not vrf2: raise RuntimeConfigError(desc='Given VRF ID (%s) and RD (%s)' ' are not of same VRF.' % (vrf_id, route_dist)) vrf = vrf1 elif route_dist is not None: rd_rf_id = VrfConf.create_rd_rf_id(route_dist, vrf_rf) vrf = self._vrfs_by_rd_rf.get(rd_rf_id) else: vrf = self._vrfs_by_id.get(vrf_id) return vrf
def stop(**kwargs): """Stops current context is one is active. Raises RuntimeConfigError if runtime is not active or initialized yet. """ if not CORE_MANAGER.started: raise RuntimeConfigError('No runtime is active. Call start to create ' 'a runtime') CORE_MANAGER.stop() return True
def add_neighbor_conf(self, neigh_conf): # Check if we already know this neighbor if neigh_conf.ip_address in self._neighbors.keys(): message = 'Neighbor with given ip address already exists' raise RuntimeConfigError(desc=message) # Add this neighbor to known configured neighbors and generate update # event self._neighbors[neigh_conf.ip_address] = neigh_conf self._notify_listeners(NeighborsConf.ADD_NEIGH_CONF_EVT, neigh_conf)
def _get_neighbor_conf(neigh_ip_address): """Returns neighbor configuration for given neighbor ip address. Raises exception if no neighbor with `neigh_ip_address` exists. """ neigh_conf = \ CORE_MANAGER.neighbors_conf.get_neighbor_conf(neigh_ip_address) if not neigh_conf: raise RuntimeConfigError(desc='No Neighbor configuration with IP' ' address %s' % neigh_ip_address) assert isinstance(neigh_conf, NeighborConf) return neigh_conf
def reset_neighbor(ip_address): neighs_conf = CORE_MANAGER.neighbors_conf neigh_conf = neighs_conf.get_neighbor_conf(ip_address) # Check if we have neighbor with given IP. if not neigh_conf: raise RuntimeConfigError('No neighbor configuration found for given' ' IP: %s' % ip_address) # If neighbor is enabled, we disable it. if neigh_conf.enabled: # Disable neighbor to close existing session. neigh_conf.enabled = False # Enable neighbor after NEIGHBOR_RESET_WAIT_TIME # this API works asynchronously # it's recommended to check it really reset neighbor later def up(): neigh_conf.enabled = True hub.spawn_after(NEIGHBOR_RESET_WAIT_TIME, up) else: raise RuntimeConfigError('Neighbor %s is not enabled, hence cannot' ' reset.' % ip_address) return True
def start(**kwargs): """Starts new context using provided configuration. Raises RuntimeConfigError if a context is already active. """ if CORE_MANAGER.started: raise RuntimeConfigError('Current context has to be stopped to start ' 'a new context.') try: waiter = kwargs.pop('waiter') except KeyError: waiter = hub.Event() common_config = CommonConf(**kwargs) hub.spawn(CORE_MANAGER.start, *[], **{ 'common_conf': common_config, 'waiter': waiter }) return True
def remove_vrf_conf(self, route_dist=None, vrf_id=None, vrf_rf=None): """Removes any matching `VrfConf` for given `route_dist` or `vrf_id` Parameters: - `route_dist`: (str) route distinguisher of a configured VRF - `vrf_id`: (str) vrf ID - `vrf_rf`: (str) route family of the VRF configuration If only `route_dist` is given, removes `VrfConf`s for all supported address families for this `route_dist`. If `vrf_rf` is given, than only removes `VrfConf` for that specific route family. If only `vrf_id` is given, matching `VrfConf` will be removed. """ if route_dist is None and vrf_id is None: raise RuntimeConfigError(desc='To delete supply route_dist or id.') # By default we remove all VRFs for given Id or RD vrf_rfs = SUPPORTED_VRF_RF # If asked to delete specific route family vrf conf. if vrf_rf: vrf_rfs = vrf_rf # For all vrf route family asked to be deleted, we collect all deleted # VrfConfs removed_vrf_confs = [] for route_family in vrf_rfs: if route_dist is not None: rd_rf_id = VrfConf.create_rd_rf_id(route_dist, route_family) vrf_conf = self._vrfs_by_rd_rf.pop(rd_rf_id, None) if vrf_conf: self._vrfs_by_id.pop(vrf_conf.id, None) removed_vrf_confs.append(vrf_conf) else: vrf_conf = self._vrfs_by_id.pop(vrf_id, None) if vrf_conf: self._vrfs_by_rd_rf.pop(vrf_conf.rd_rd_id, None) removed_vrf_confs.append(vrf_conf) # We do not raise any exception if we cannot find asked VRF. for vrf_conf in removed_vrf_confs: self._notify_listeners(VrfsConf.REMOVE_VRF_CONF_EVT, vrf_conf) return removed_vrf_confs
def set_neighbor_attribute_map(neigh_ip_address, at_maps, route_dist=None, route_family=VRF_RF_IPV4): """set attribute_maps to the neighbor.""" core = CORE_MANAGER.get_core_service() peer = core.peer_manager.get_by_addr(neigh_ip_address) at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT at_maps_dict = {} if route_dist is not None: vrf_conf =\ CORE_MANAGER.vrfs_conf.get_vrf_conf(route_dist, route_family) if vrf_conf: at_maps_key = ':'.join([route_dist, route_family]) else: raise RuntimeConfigError(desc='No VrfConf with rd %s' % route_dist) at_maps_dict[const.ATTR_MAPS_LABEL_KEY] = at_maps_key at_maps_dict[const.ATTR_MAPS_VALUE] = at_maps peer.attribute_maps = at_maps_dict return True
def get_vrf(route_dist, route_family=VRF_RF_IPV4): vrf_conf = CORE_MANAGER.vrfs_conf.get_vrf_conf(route_dist, vrf_rf=route_family) if not vrf_conf: raise RuntimeConfigError(desc='No VrfConf with vpn id %s' % route_dist) return vrf_conf.settings