def handle_flow_topology_sync(self): payload = { 'switches': [], 'isls': [], 'flows': flow_utils.get_flows(), 'clazz': MT_NETWORK} message_utils.send_to_topic( payload, self.correlation_id, message_utils.MT_INFO, destination="WFM_FLOW_LCM", topic=config.KAFKA_FLOW_TOPIC)
def get_feature_toggle_state(self): payload = message_utils.make_features_status_response() for feature, status in features_status.items(): transport_key = features_status_app_to_transport_map[feature] setattr(payload, transport_key, status) message_utils.send_to_topic(payload, self.correlation_id, message_type=message_utils.MT_INFO, destination="NORTHBOUND", topic=config.KAFKA_NORTHBOUND_TOPIC) return True
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
def delete_flow(flow_id, flow, correlation_id, parent_tx=None, propagate=True, from_nb=False): """ Simple algorithm - delete the stuff in the DB, send delete commands, send a response. Complexity - each segment in the path may have a separate cookie, so that information needs to be gathered. NB: Each switch in the flow should get a delete command. # TODO: eliminate flowpath as part of delete_flow request; rely on flow_id only # TODO: Add state to flow .. ie "DELETING", as part of refactoring project to add state - eg: flow_utils.update_state(flow, DELETING, parent_tx) :param parent_tx: If there is a larger transaction to use, then use it. :return: True, unless an exception is raised. """ try: # All flows .. single switch or multi .. will start with deleting based on the src and flow cookie; then # we'll have a delete per segment based on the destination. Consequently, the "single switch flow" is # automatically addressed using this algorithm. flow_cookie = int(flow['cookie']) transit_vlan = int(flow['transit_vlan']) current_node = {'switch_id': flow['src_switch'], 'flow_id': flow_id, 'cookie': flow_cookie, 'meter_id': flow['meter_id'], 'in_port': flow['src_port'], 'in_vlan': flow['src_vlan']} nodes = [current_node] segments = flow_utils.fetch_flow_segments(flow_id, flow_cookie) for segment in segments: current_node['out_port'] = segment['src_port'] # every segment should have a cookie field, based on merge_segment; but just in case.. segment_cookie = segment.get('cookie', flow_cookie) current_node = {'switch_id': segment['dst_switch'], 'flow_id': flow_id, 'cookie': segment_cookie, 'meter_id': None, 'in_port': segment['dst_port'], 'in_vlan': transit_vlan, 'out_port': segment['dst_port']} nodes.append(current_node) current_node['out_port'] = flow['dst_port'] if propagate: logger.info('Flow rules remove start: correlation_id=%s, flow_id=%s, path=%s', correlation_id, flow_id, nodes) message_utils.send_delete_commands(nodes, correlation_id) logger.info('Flow rules removed end : correlation_id=%s, flow_id=%s', correlation_id, flow_id) if from_nb: # The request is sent from Northbound .. send response back logger.info('Flow rules from NB: correlation_id=%s, flow_id=%s', correlation_id, flow_id) data = {"payload":{"flowid": flow_id,"status": "DOWN"}, "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 ) flow_utils.remove_flow(flow, parent_tx) logger.info('Flow was removed: correlation_id=%s, flow_id=%s', correlation_id, flow_id) except Exception as e: logger.exception('Can not delete flow: %s', e.message) if not from_nb: # Propagate is the normal scenario, so send response back to FLOW message_utils.send_error_message(correlation_id, "DELETION_FAILURE", e.message, flow_id) else: # This means we tried a UNPUSH, send response back to NORTHBOUND message_utils.send_error_message( correlation_id, "UNPUSH_FAILURE", e.message, flow_id, destination="NORTHBOUND", topic=config.KAFKA_NORTHBOUND_TOPIC) raise return True