コード例 #1
0
    def delete_flow(flow_id, flow, correlation_id):
        try:
            flow_path = flow['flowpath']['path']
            logger.info('Flow path remove: %s', flow_path)

            # TODO: Remove Flow should be moved down .. opposite order of create.
            #       (I'd do it now, but I'm troubleshooting something else)
            flow_utils.remove_flow(flow, flow_path)

            logger.info('Flow was removed: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            message_utils.send_delete_commands(flow_path, flow_id,
                                               correlation_id,
                                               int(flow['cookie']))

            logger.info('Flow rules removed: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            payload = {'payload': flow, 'clazz': MT_FLOW_RESPONSE}
            message_utils.send_info_message(payload, correlation_id)

        except Exception as e:
            logger.exception('Can not delete flow: %s', e.message)
            message_utils.send_error_message(correlation_id,
                                             "DELETION_FAILURE", e.message,
                                             flow_id)
            raise

        return True
コード例 #2
0
    def update_flow(flow_id, flow, correlation_id, tx):
        try:
            old_flow = flow_utils.get_old_flow(flow)

            #
            # Start the transaction to govern the create/delete
            #
            logger.info('Flow rules were built: correlation_id=%s, flow_id=%s', correlation_id, flow_id)
            rules = flow_utils.build_rules(flow)
            # TODO: add tx to store_flow
            flow_utils.store_flow(flow, tx)
            logger.info('Flow was stored: correlation_id=%s, flow_id=%s', correlation_id, flow_id)
            message_utils.send_install_commands(rules, correlation_id)

            MessageItem.delete_flow(old_flow['flowid'], old_flow, correlation_id, tx)

            payload = {'payload': flow, 'clazz': MT_FLOW_RESPONSE}
            message_utils.send_info_message(payload, correlation_id)

        except Exception as e:
            logger.exception('Can not update flow: %s', e.message)
            message_utils.send_error_message(
                correlation_id, "UPDATE_FAILURE", e.message, flow_id)
            raise

        return True
コード例 #3
0
    def create_flow(flow_id, flow, correlation_id):
        try:
            rules = flow_utils.build_rules(flow)

            logger.info('Flow rules were built: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            flow_utils.store_flow(flow)

            logger.info('Flow was stored: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            message_utils.send_install_commands(rules, correlation_id)

            logger.info('Flow rules installed: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            payload = {'payload': flow, 'clazz': MT_FLOW_RESPONSE}
            message_utils.send_info_message(payload, correlation_id)

        except Exception as e:
            logger.exception('Can not create flow: %s', flow_id)
            message_utils.send_error_message(correlation_id,
                                             "CREATION_FAILURE", e.message,
                                             flow_id)
            raise

        return True
コード例 #4
0
    def flow_operation(self):
        correlation_id = self.correlation_id
        timestamp = self.timestamp
        payload = self.payload

        operation = payload['operation']
        flows = payload['payload']
        forward = flows['forward']
        reverse = flows['reverse']
        flow_id = forward['flowid']

        logger.info(
            'Flow %s request processing: '
            'timestamp=%s, correlation_id=%s, payload=%s', operation,
            timestamp, correlation_id, payload)

        if operation == "CREATE" or operation == "PUSH":
            propagate = operation == "CREATE"
            # TODO: leverage transaction for creating both flows
            self.create_flow(flow_id, forward, correlation_id, propagate)
            self.create_flow(flow_id, reverse, correlation_id, propagate)

        elif operation == "DELETE" or operation == "UNPUSH":
            tx = graph.begin()
            propagate = operation == "DELETE"
            MessageItem.delete_flow(flow_id, forward, correlation_id, tx,
                                    propagate)
            MessageItem.delete_flow(flow_id, reverse, correlation_id, tx,
                                    propagate)
            if propagate:
                message_utils.send_info_message(
                    {
                        'payload': forward,
                        'clazz': MT_FLOW_RESPONSE
                    }, correlation_id)
                message_utils.send_info_message(
                    {
                        'payload': reverse,
                        'clazz': MT_FLOW_RESPONSE
                    }, correlation_id)
            tx.commit()

        elif operation == "UPDATE":
            tx = graph.begin()
            MessageItem.update_flow(flow_id, forward, correlation_id, tx)
            MessageItem.update_flow(flow_id, reverse, correlation_id, tx)
            tx.commit()
        else:
            logger.warn(
                'Flow operation is not supported: '
                'operation=%s, timestamp=%s, correlation_id=%s,', operation,
                timestamp, correlation_id)

        logger.info(
            'Flow %s request processed: '
            'timestamp=%s, correlation_id=%s, payload=%s', operation,
            timestamp, correlation_id, payload)

        return True
コード例 #5
0
    def create_flow(flow_id, flow, correlation_id, tx, propagate=True, from_nb=False):
        """
        :param propagate: If true, send to switch
        :param from_nb: If true, send response to NORTHBOUND API; otherwise to FLOW_TOPOLOGY
        :return:
        """

        try:
            rules = flow_utils.build_rules(flow)

            logger.info('Flow rules were built: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            flow_utils.store_flow(flow, tx)

            logger.info('Flow was stored: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            if propagate:
                message_utils.send_install_commands(rules, correlation_id)
                logger.info('Flow rules INSTALLED: correlation_id=%s, flow_id=%s', correlation_id, flow_id)

            if not from_nb:
                message_utils.send_info_message({'payload': flow, 'clazz': MT_FLOW_RESPONSE}, correlation_id)
            else:
                # The request is sent from Northbound .. send response back
                logger.info('Flow rules NOT PROPAGATED: correlation_id=%s, flow_id=%s', correlation_id, flow_id)
                data = {"payload":{"flowid": flow_id,"status": "UP"},
                        "clazz": message_utils.MT_INFO_FLOW_STATUS}
                message_utils.send_to_topic(
                    payload=data,
                    correlation_id=correlation_id,
                    message_type=message_utils.MT_INFO,
                    destination="NORTHBOUND",
                    topic=config.KAFKA_NORTHBOUND_TOPIC
                )

        except Exception as e:
            logger.exception('Can not create flow: %s', flow_id)
            if not from_nb:
                # Propagate is the normal scenario, so send response back to FLOW
                message_utils.send_error_message(correlation_id, "CREATION_FAILURE", e.message, flow_id)
            else:
                # This means we tried a PUSH, send response back to NORTHBOUND
                message_utils.send_error_message(correlation_id, "PUSH_FAILURE", e.message, flow_id,
                    destination="NORTHBOUND", topic=config.KAFKA_NORTHBOUND_TOPIC)
            raise

        return True
コード例 #6
0
    def update_flow(flow_id, flow, correlation_id):
        try:
            old_flow = flow_utils.get_old_flow(flow)

            old_flow_path = json.loads(old_flow['flowpath'])['path']

            logger.info('Flow path remove: %s', old_flow_path)

            flow_utils.remove_flow(old_flow, old_flow_path)

            logger.info('Flow was removed: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            rules = flow_utils.build_rules(flow)

            logger.info('Flow rules were built: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            flow_utils.store_flow(flow)

            logger.info('Flow was stored: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            message_utils.send_install_commands(rules, correlation_id)

            logger.info('Flow rules installed: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            message_utils.send_delete_commands(old_flow_path,
                                               old_flow['flowid'],
                                               correlation_id,
                                               int(old_flow['cookie']))

            logger.info('Flow rules removed: correlation_id=%s, flow_id=%s',
                        correlation_id, flow_id)

            payload = {'payload': flow, 'clazz': MT_FLOW_RESPONSE}
            message_utils.send_info_message(payload, correlation_id)

        except Exception as e:
            logger.exception('Can not update flow: %s', e.message)
            message_utils.send_error_message(correlation_id, "UPDATE_FAILURE",
                                             e.message, flow_id)
            raise

        return True
コード例 #7
0
    def flow_operation(self):
        correlation_id = self.correlation_id
        timestamp = self.timestamp
        payload = self.payload

        operation = payload['operation']
        flows = payload['payload']
        forward = flows['forward']
        reverse = flows['reverse']
        flow_id = forward['flowid']

        if self.not_allow_flow_operation():
            logger.info('Flow %s request is not allow: '
                    'timestamp=%s, correlation_id=%s, payload=%s',
                    operation, timestamp, correlation_id, payload)

            # TODO: We really should use the reply-to field, at least in NB, so that we know to send the response.
            op = payload['operation'].upper()
            if op == "PUSH" or op == "PUSH_PROPAGATE" or op == "UNPUSH" or op == "UNPUSH_PROPAGATE":
                message_utils.send_error_message(
                    correlation_id, 'REQUEST_INVALID', op+"-FAILURE - NOT ALLOWED RIGHT NOW - Toggle the feature to allow this behavior", "",
                    destination="NORTHBOUND", topic=config.KAFKA_NORTHBOUND_TOPIC)

            return True

        logger.info('Flow %s request processing: '
                    'timestamp=%s, correlation_id=%s, payload=%s',
                    operation, timestamp, correlation_id, payload)

        tx = None
        # flow_sem.acquire(timeout=10)  # wait 10 seconds .. then proceed .. possibly causing some issue.
        neo4j_update_lock.acquire()
        try:
            OP = operation.upper()
            if OP == "CREATE" or OP == "PUSH" or OP == "PUSH_PROPAGATE":
                propagate = (OP == "CREATE" or OP == "PUSH_PROPAGATE")
                from_nb = (OP == "PUSH" or OP == "PUSH_PROPAGATE")
                tx = graph.begin()
                self.create_flow(flow_id, forward, correlation_id, tx, propagate, from_nb)
                self.create_flow(flow_id, reverse, correlation_id, tx, propagate, from_nb)
                tx.commit()
                tx = None

            elif OP == "DELETE" or OP == "UNPUSH" or OP == "UNPUSH_PROPAGATE":
                tx = graph.begin()
                propagate = (OP == "DELETE" or OP == "UNPUSH_PROPAGATE")
                from_nb = (OP == "UNPUSH" or OP == "UNPUSH_PROPAGATE")
                MessageItem.delete_flow(flow_id, forward, correlation_id, tx, propagate, from_nb)
                MessageItem.delete_flow(flow_id, reverse, correlation_id, tx, propagate, from_nb)
                if not from_nb:
                    message_utils.send_info_message({'payload': forward, 'clazz': MT_FLOW_RESPONSE}, correlation_id)
                    message_utils.send_info_message({'payload': reverse, 'clazz': MT_FLOW_RESPONSE}, correlation_id)
                tx.commit()
                tx = None

            elif OP == "UPDATE":
                tx = graph.begin()
                MessageItem.update_flow(flow_id, forward, correlation_id, tx)
                MessageItem.update_flow(flow_id, reverse, correlation_id, tx)
                tx.commit()
                tx = None

            else:
                logger.warn('Flow operation is not supported: '
                            'operation=%s, timestamp=%s, correlation_id=%s,',
                            operation, timestamp, correlation_id)
        except Exception:
            if tx is not None:
                tx.rollback()
            # flow_sem.release()
            raise

        finally:
            #flow_sem.release()
            neo4j_update_lock.release()

        logger.info('Flow %s request processed: '
                    'timestamp=%s, correlation_id=%s, payload=%s',
                    operation, timestamp, correlation_id, payload)

        return True
コード例 #8
0
    def flow_operation(self):
        correlation_id = self.correlation_id
        timestamp = self.timestamp
        payload = self.payload

        operation = payload['operation']
        flows = payload['payload']
        forward = flows['forward']
        reverse = flows['reverse']
        flow_id = forward['flowid']

        logger.info(
            'Flow %s request processing: '
            'timestamp=%s, correlation_id=%s, payload=%s', operation,
            timestamp, correlation_id, payload)

        tx = None
        # flow_sem.acquire(timeout=10)  # wait 10 seconds .. then proceed .. possibly causing some issue.
        neo4j_update_lock.acquire()
        try:
            OP = operation.upper()
            if OP == "CREATE" or OP == "PUSH" or OP == "PUSH_PROPAGATE":
                propagate = (OP == "CREATE" or OP == "PUSH_PROPAGATE")
                from_nb = (OP == "PUSH" or OP == "PUSH_PROPAGATE")
                tx = graph.begin()
                self.create_flow(flow_id, forward, correlation_id, tx,
                                 propagate, from_nb)
                self.create_flow(flow_id, reverse, correlation_id, tx,
                                 propagate, from_nb)
                tx.commit()
                tx = None

            elif OP == "DELETE" or OP == "UNPUSH" or OP == "UNPUSH_PROPAGATE":
                tx = graph.begin()
                propagate = (OP == "DELETE" or OP == "UNPUSH_PROPAGATE")
                from_nb = (OP == "UNPUSH" or OP == "UNPUSH_PROPAGATE")
                MessageItem.delete_flow(flow_id, forward, correlation_id, tx,
                                        propagate, from_nb)
                MessageItem.delete_flow(flow_id, reverse, correlation_id, tx,
                                        propagate, from_nb)
                if not from_nb:
                    message_utils.send_info_message(
                        {
                            'payload': forward,
                            'clazz': MT_FLOW_RESPONSE
                        }, correlation_id)
                    message_utils.send_info_message(
                        {
                            'payload': reverse,
                            'clazz': MT_FLOW_RESPONSE
                        }, correlation_id)
                tx.commit()
                tx = None

            elif OP == "UPDATE":
                tx = graph.begin()
                MessageItem.update_flow(flow_id, forward, correlation_id, tx)
                MessageItem.update_flow(flow_id, reverse, correlation_id, tx)
                tx.commit()
                tx = None

            else:
                logger.warn(
                    'Flow operation is not supported: '
                    'operation=%s, timestamp=%s, correlation_id=%s,',
                    operation, timestamp, correlation_id)
        except Exception:
            if tx is not None:
                tx.rollback()
            # flow_sem.release()
            raise

        finally:
            #flow_sem.release()
            neo4j_update_lock.release()

        logger.info(
            'Flow %s request processed: '
            'timestamp=%s, correlation_id=%s, payload=%s', operation,
            timestamp, correlation_id, payload)

        return True