예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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