def validate_and_sync_switch_rules(self): switch_id = self.payload['switch_id'] diff = flow_utils.validate_switch_rules(switch_id, self.payload['flows']) logger.debug('Switch rules validation result: %s', diff) sync_actions = flow_utils.build_commands_to_sync_rules(switch_id, diff["missing_rules"]) commands = sync_actions["commands"] if commands: logger.info('Install commands for switch %s are to be sent: %s', switch_id, commands) message_utils.send_force_install_commands(switch_id, commands, self.correlation_id) return True
def sync_switch_rules(self): switch_id = self.payload['switch_id'] rules_to_sync = self.payload['rules'] logger.debug('Switch rules synchronization for rules: %s', rules_to_sync) sync_actions = flow_utils.build_commands_to_sync_rules(switch_id, rules_to_sync) commands = sync_actions["commands"] if commands: logger.info('Install commands for switch %s are to be sent: %s', switch_id, commands) message_utils.send_force_install_commands(switch_id, commands, self.correlation_id) message_utils.send_sync_rules_response(sync_actions["installed_rules"], self.correlation_id) return True
def sync_switch_rules(self): switch_id = self.payload['switch_id'] rules_to_sync = self.payload['rules'] logger.debug('Switch rules synchronization for rules: %s', rules_to_sync) commands, installed_rules = flow_utils.build_commands_to_sync_rules( switch_id, rules_to_sync) if commands: indent = ' ' * 4 logger.info('Install commands for switch %s are to be sent:\n%s%s', switch_id, indent, (',\n' + indent).join(str(x) for x in commands)) message_utils.send_force_install_commands(switch_id, commands, self.correlation_id) message_utils.send_sync_rules_response( installed_rules, self.correlation_id) return True
def validate_switch(self, dumped_rules=None): switch_id = self.payload['switch_id'] query = "MATCH p = (sw:switch)-[segment:flow_segment]-() " \ "WHERE sw.name='{}' " \ "RETURN segment" result = graph.run(query.format(switch_id)).data() if dumped_rules: cookies = [x['cookie'] for x in dumped_rules['flows']] else: cookies = [x['cookie'] for x in self.payload['flows']] commands = [] # define three types of rules with cookies missed_rules = set() excess_rules = set() proper_rules = set() # group flow_segments by parent cookie, it is helpful for building # transit switch rules segment_pairs = collections.defaultdict(list) for relationship in result: flow_segment = relationship['segment'] segment_pairs[flow_segment['parent_cookie']].append(flow_segment) # check whether the switch has all necessary cookies for pair in segment_pairs.values(): cookie = pair[0]['parent_cookie'] cookie_hex = flow_utils.cookie_to_hex(cookie) if pair[0]['parent_cookie'] not in cookies: logger.warn('Rule %s is not found on switch %s', cookie_hex, switch_id) commands.extend( MessageItem.command_from_segment(pair, switch_id)) missed_rules.add(cookie_hex) else: proper_rules.add(cookie_hex) # check whether the switch has one-switch flows. # since one-switch flows don't have flow_segments we have to validate # such flows separately query = "MATCH (sw:switch)-[r:flow]->(sw:switch) " \ "WHERE sw.name='{}' RETURN r" result = graph.run(query.format(switch_id)).data() for item in result: flow = flow_utils.hydrate_flow(item) cookie_hex = flow_utils.cookie_to_hex(flow['cookie']) if flow['cookie'] not in cookies: logger.warn("Found missed one-switch flow %s for switch %s", cookie_hex, switch_id) missed_rules.add(cookie_hex) output_action = flow_utils.choose_output_action( flow['src_vlan'], flow['dst_vlan']) commands.append( message_utils.build_one_switch_flow_from_db( switch_id, flow, output_action)) else: proper_rules.add(cookie_hex) # check whether the switch has redundant rules for flow in self.payload['flows']: hex_cookie = flow_utils.cookie_to_hex(flow['cookie']) if hex_cookie not in proper_rules and \ hex_cookie not in flow_utils.ignored_rules: logger.error('Rule %s is obsolete for the switch %s', hex_cookie, switch_id) excess_rules.add(hex_cookie) message_utils.send_force_install_commands(switch_id, commands, self.correlation_id) if dumped_rules: message_utils.send_sync_rules_response(missed_rules, excess_rules, proper_rules, self.correlation_id) return True