def setUp(self): self.tmpdir = tempfile.mkdtemp() self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml') self.table = FakeOFTable(self.NUM_TABLES) dp = self.update_config(self.CONFIG) self.valve = valve_factory(dp)(dp, 'test_valve') # establish connection to datapath ofmsgs = self.valve.datapath_connect(self.DP_ID, range(1, self.NUM_PORTS + 1)) self.table.apply_ofmsgs(ofmsgs) # learn some mac addresses self.rcv_packet(1, 0x100, { 'eth_src': self.P1_V100_MAC, 'eth_dst': self.UNKNOWN_MAC }) self.rcv_packet(2, 0x200, { 'eth_src': self.P2_V200_MAC, 'eth_dst': self.P3_V200_MAC, 'vid': 0x200 }) self.rcv_packet(3, 0x200, { 'eth_src': self.P3_V200_MAC, 'eth_dst': self.P2_V200_MAC, 'vid': 0x200 })
def setUp(self): self.tmpdir = tempfile.mkdtemp() self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml') self.table = FakeOFTable(self.NUM_TABLES) dp = self.update_config(self.CONFIG) self.valve = valve_factory(dp)(dp, 'test_valve') # establish connection to datapath ofmsgs = self.valve.datapath_connect( self.DP_ID, range(1, self.NUM_PORTS + 1) ) self.table.apply_ofmsgs(ofmsgs) # learn some mac addresses self.rcv_packet(1, 0x100, { 'eth_src': self.P1_V100_MAC, 'eth_dst': self.UNKNOWN_MAC }) self.rcv_packet(2, 0x200, { 'eth_src': self.P2_V200_MAC, 'eth_dst': self.P3_V200_MAC, 'vid': 0x200 }) self.rcv_packet(3, 0x200, { 'eth_src': self.P3_V200_MAC, 'eth_dst': self.P2_V200_MAC, 'vid': 0x200 })
def check_config(conf_files, debug_level, check_output_file): """Return True and successful config dict, if all config can be parsed.""" logname = os.devnull logger = logging.getLogger('%s.config' % logname) logger_handler = logging.StreamHandler(stream=sys.stderr) logger.addHandler(logger_handler) logger.propagate = 0 logger.setLevel(debug_level) check_output = [] for conf_file in conf_files: check_result = False try: _, dps = dp_parser(conf_file, logname) if dps is not None: dps_conf = [(valve.valve_factory(dp), dp.to_conf()) for dp in dps] check_output.extend([conf for _, conf in dps_conf]) check_result = True continue except InvalidConfigError as config_err: check_output = [config_err] break pprint.pprint(check_output, stream=check_output_file) return check_result
def check_config(conf_files, debug_level, check_output_file): """Return True and successful config dict, if all config can be parsed.""" logname = os.devnull logger = logging.getLogger('%s.config' % logname) logger_handler = logging.StreamHandler(stream=sys.stderr) logger.addHandler(logger_handler) logger.propagate = 0 logger.setLevel(debug_level) check_output = '' check_result = False for conf_file in conf_files: try: _, dps = dp_parser(conf_file, logname) for dp in dps: valve_dp = valve.valve_factory(dp) if valve_dp is None: check_result = False break check_output = dp.to_conf() check_result = True except InvalidConfigError as config_err: check_output = config_err check_output_file.write(str(check_output)) return check_result
def check_config(conf_files, debug_level, check_output_file): """Return True and successful config dict, if all config can be parsed.""" logname = os.devnull logger = logging.getLogger('%s.config' % logname) logger_handler = logging.StreamHandler(stream=sys.stderr) logger.addHandler(logger_handler) logger.propagate = 0 logger.setLevel(debug_level) check_output = [] if conf_files: for conf_file in conf_files: check_result = False try: _, dps = dp_parser(conf_file, logname) if dps is not None: dps_conf = [(valve.valve_factory(dp), dp.to_conf()) for dp in dps] check_output.extend([conf for _, conf in dps_conf]) check_result = True continue except InvalidConfigError as config_err: check_output = [config_err] break else: check_result = False check_output = ['no files specified'] pprint.pprint(check_output, stream=check_output_file) return check_result
def __init__(self, *args, **kwargs): super(Faucet, self).__init__(*args, **kwargs) # There doesnt seem to be a sensible method of getting command line # options into ryu apps. Instead I am using the environment variable # FAUCET_CONFIG to allow this to be set, if it is not set it will # default to valve.yaml sysprefix = get_sys_prefix() self.config_file = os.getenv('FAUCET_CONFIG', sysprefix + '/etc/ryu/faucet/faucet.yaml') self.logfile = os.getenv('FAUCET_LOG', sysprefix + '/var/log/ryu/faucet/faucet.log') self.exc_logfile = os.getenv( 'FAUCET_EXCEPTION_LOG', sysprefix + '/var/log/ryu/faucet/faucet_exception.log') # Set the signal handler for reloading config file signal.signal(signal.SIGHUP, self.signal_handler) # Create dpset object for querying Ryu's DPSet application self.dpset = kwargs['dpset'] # Setup logging self.logger = get_logger(self.logname, self.logfile, logging.DEBUG, 0) # Set up separate logging for exceptions self.exc_logger = get_logger(self.exc_logname, self.exc_logfile, logging.DEBUG, 1) # TODO: metrics instance can be passed to Valves also, # for DP specific instrumentation. self.metrics = FaucetMetrics() prom_port = int(os.getenv('FAUCET_PROMETHEUS_PORT', '9244')) start_http_server(prom_port) # Set up a valve object for each datapath self.valves = {} self.config_hashes, valve_dps = dp_parser(self.config_file, self.logname) for valve_dp in valve_dps: # pylint: disable=no-member valve_cl = valve_factory(valve_dp) if valve_cl is None: self.logger.error('Hardware type not supported for DP: %s', valve_dp.name) else: valve = valve_cl(valve_dp, self.logname) self.valves[valve_dp.dp_id] = valve valve.update_config_metrics(self.metrics) self.gateway_resolve_request_thread = hub.spawn( self.gateway_resolve_request) self.host_expire_request_thread = hub.spawn(self.host_expire_request) self.dp_bgp_speakers = {} self._reset_bgp() # Register to API api = kwargs['faucet_api'] api._register(self) self.send_event_to_observers(EventFaucetAPIRegistered())
def setUp(self): self.tmpdir = tempfile.mkdtemp() self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml') self.table = FakeOFTable(7) with open(self.config_file, 'w') as f: f.write(self.CONFIG) _, dps = dp_parser(self.config_file, 'test_valve') self.valve = valve_factory(dps[0])(dps[0], 'test_valve') # establish connection to datapath ofmsgs = self.valve.datapath_connect( self.DP_ID, range(1, self.NUM_PORTS + 1) ) self.table.apply_ofmsgs(ofmsgs) # learn some mac addresses self.rcv_packet(1, 100, { 'eth_src': self.P1_V100_MAC, 'eth_dst': self.UNKNOWN_MAC }) self.rcv_packet(2, 200, { 'eth_src': self.P2_V200_MAC, 'eth_dst': self.P3_V200_MAC, 'vid': 200 }) self.rcv_packet(3, 200, { 'eth_src': self.P3_V200_MAC, 'eth_dst': self.P2_V200_MAC, 'vid': 200 })
def new_valve(self, new_dp): valve_cl = valve_factory(new_dp) if valve_cl is not None: return valve_cl(new_dp, self.logname, self.metrics, self.notifier) self.logger.error('%s hardware %s must be one of %s', new_dp.name, new_dp.hardware, sorted(list(SUPPORTED_HARDWARE.keys()))) return None
def _apply_configs_new(self, dp_id, new_dp): self.logger.info('Add new datapath %s', dpid_log(dp_id)) valve_cl = valve_factory(new_dp) if valve_cl is not None: return valve_cl(new_dp, self.logname, self.notifier) self.logger.error('%s hardware %s must be one of %s', new_dp.name, new_dp.hardware, sorted(list(SUPPORTED_HARDWARE.keys()))) return None
def new_valve(self, new_dp): valve_cl = valve_factory(new_dp) if valve_cl is not None: return valve_cl(new_dp, self.logname, self.metrics, self.notifier, self.dot1x) self.logger.error( '%s hardware %s must be one of %s', new_dp.name, new_dp.hardware, sorted(list(SUPPORTED_HARDWARE.keys()))) return None
def setup_valve(self, config): self.tmpdir = tempfile.mkdtemp() self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml') self.table = FakeOFTable(self.NUM_TABLES) self.faucet_event_sock = None self.logger = None self.metrics = None self.notifier = faucet_experimental_event.FaucetExperimentalEventNotifier( self.faucet_event_sock, self.metrics, self.logger) dp = self.update_config(config) self.valve = valve_factory(dp)(dp, 'test_valve', self.notifier)
def _load_configs(self, new_config_file): self.config_file = new_config_file self.config_hashes, new_dps = dp_parser(new_config_file, self.logname) if new_dps is None: self.logger.error('new config bad - rejecting') return deleted_valve_dpids = (set(list(self.valves.keys())) - set([valve.dp_id for valve in new_dps])) for new_dp in new_dps: dp_id = new_dp.dp_id if dp_id in self.valves: valve = self.valves[dp_id] cold_start, flowmods = valve.reload_config(new_dp) # pylint: disable=no-member if flowmods: self._send_flow_msgs(new_dp.dp_id, flowmods) if cold_start: self.metrics.faucet_config_reload_cold.labels( dp_id=hex(dp_id)).inc() else: self.metrics.faucet_config_reload_warm.labels( dp_id=hex(dp_id)).inc() else: # pylint: disable=no-member valve_cl = valve_factory(new_dp) if valve_cl is None: self.logger.error('%s hardware %s must be one of %s', new_dp.name, new_dp.hardware, sorted(list(SUPPORTED_HARDWARE.keys()))) continue else: valve = valve_cl(new_dp, self.logname) self.valves[dp_id] = valve self.logger.info('Add new datapath %s', dpid_log(dp_id)) self.metrics.reset_dpid(dp_id) valve.update_config_metrics(self.metrics) for deleted_valve_dpid in deleted_valve_dpids: self.logger.info('Deleting de-configured %s', dpid_log(deleted_valve_dpid)) del self.valves[deleted_valve_dpid] ryu_dp = self.dpset.get(deleted_valve_dpid) if ryu_dp is not None: ryu_dp.close() self._bgp.reset(self.valves, self.metrics)
def _validate_faucet_config(self, config_dir): logname = os.devnull try: root_config = os.path.join(config_dir, self.default_config) _, _, dps, top_confs = dp_parser(root_config, logname) dps_conf = None valve_cls = None acls_conf = None if dps is not None: dps_conf = {dp.name: dp for dp in dps} valve_cls = [valve.valve_factory(dp) for dp in dps] acls_conf = top_confs.get('acls', {}) if dps_conf: if not valve_cls: raise InvalidConfigError('no valid DPs defined') else: dps_conf = {} return (dps_conf, acls_conf) except InvalidConfigError as err: raise _ServerError(f'Invalid config: {err}') # pylint: disable=raise-missing-from
def check_config(conf_files): logname = '/dev/null' logger = logging.getLogger('%s.config' % logname) logger_handler = logging.StreamHandler(stream=sys.stderr) logger.addHandler(logger_handler) logger.propagate = 0 logger.setLevel(logging.DEBUG) for conf_file in conf_files: parse_result = dp_parser(conf_file, logname) if parse_result is None: return False else: _, dps = parse_result for dp in dps: valve_dp = valve.valve_factory(dp) if valve_dp is None: return False print((dp.to_conf())) return True
def setup_valve(self, config): """Set up test DP with config.""" self.tmpdir = tempfile.mkdtemp() self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml') self.faucet_event_sock = os.path.join(self.tmpdir, 'event.sock') self.logfile = os.path.join(self.tmpdir, 'faucet.log') self.table = FakeOFTable(self.NUM_TABLES) self.logger = valve_util.get_logger('faucet', self.logfile, logging.DEBUG, 0) self.registry = CollectorRegistry() # TODO: verify Prometheus variables self.metrics = faucet_metrics.FaucetMetrics(reg=self.registry) # pylint: disable=unexpected-keyword-arg # TODO: verify events self.notifier = faucet_experimental_event.FaucetExperimentalEventNotifier( self.faucet_event_sock, self.metrics, self.logger) self.notifier.start() dp = self.update_config(config, self.DP) self.valve = valve_factory(dp)(dp, 'test_valve', self.notifier) self.valve.update_config_metrics(self.metrics) self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.connect(self.faucet_event_sock)
def setup_valve(self, config): self.tmpdir = tempfile.mkdtemp() self.config_file = os.path.join(self.tmpdir, 'valve_unit.yaml') self.table = FakeOFTable(self.NUM_TABLES) dp = self.update_config(config) self.valve = valve_factory(dp)(dp, 'test_valve')