Example #1
0
def Trigger(tc):
    if tc.ignore == True:
        return api.types.status.SUCCESS

    if tc.error == True:
        return api.types.status.FAILURE

    tc.resp_tcpdump_erspan = None
    tc.resp_cleanup = None

    protoDir = api.GetTopologyDirectory() +\
               "/gen/telemetry/{}/{}".format('mirror', 'endpoint')
    api.Logger.info("Template Config files location: ", protoDir)

    policies = utils.GetTargetJsons('mirror', 'endpoint')
    for policy_json in policies:
        #
        # Get template-Mirror Config
        #
        api.Logger.info("Adding one config object for {}", format(policy_json))
        newObjects = agent_api.AddOneConfig(policy_json)
        if len(newObjects) == 0:
            api.Logger.error("Adding new objects to store failed")
            tc.error = True
            return api.types.status.FAILURE

        #
        # Modify template-Mirror Config to make sure that Naples-node
        # act as either source or destination
        #
        # Set up Collector in the remote node
        #
        if newObjects[0].kind == 'InterfaceMirrorSession':
            tc.ep_collector_objects = newObjects
            agent_api.RemoveConfigObjects(tc.ep_collector_objects)
        elif newObjects[0].kind == 'Endpoint':
            tc.endpoint_objects = newObjects
            agent_api.RemoveConfigObjects(tc.endpoint_objects)
            updateEndpointObjectTempl(tc, tc.endpoint_objects,
                                      tc.store_endpoint_objects[0])

    for i in range(0, len(policies)):
        #
        # Push Collector object
        #
        if i == 0:
            colObjects = tc.ep_collector_objects
            if tc.iterators.session == 'single':
                ret = eutils.generateEpCollectorConfig(tc, colObjects)
            else:
                ret = eutils.generateEpCollectorConfigForMultiMirrorSession(
                    tc, colObjects)
            if ret != api.types.status.SUCCESS:
                api.Logger.error("Unable to identify Collector Workload")
                tc.error = True
                return api.types.status.FAILURE

            api.Logger.info("Pushing collector objects")
            ret = agent_api.PushConfigObjects(colObjects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])
            if ret != api.types.status.SUCCESS:
                api.Logger.error("Unable to push collector objects")
                tc.error = True
                return api.types.status.FAILURE
            continue

        api.Logger.info("Generating Endpoint objects")
        cfg_api.PrintConfigsObjects(colObjects)
        #
        # Update Endpoint objects
        #
        epObjects = tc.endpoint_objects
        ret = eutils.generateEndpointConfig(tc, epObjects, colObjects)
        if ret != api.types.status.SUCCESS:
            agent_api.DeleteConfigObjects(tc.ep_collector_objects,
                                          [tc.naples.node_name],
                                          [tc.naples_device_name])
            api.Logger.error("Unable to identify Endpoints")
            tc.error = True
            return api.types.status.FAILURE

        api.Logger.info("Pushing Endpoint objects")
        ret = agent_api.UpdateConfigObjects(epObjects, [tc.naples.node_name],
                                            [tc.naples_device_name])
        if ret != api.types.status.SUCCESS:
            agent_api.DeleteConfigObjects(tc.ep_collector_objects,
                                          [tc.naples.node_name],
                                          [tc.naples_device_name])
            api.Logger.error("Unable to update endpoint objects")
            tc.error = True
            return api.types.status.FAILURE

        #
        # Establish Forwarding set up between Naples-peer and Collectors
        #
        eutils.establishForwardingSetup(tc)

        req_tcpdump_erspan = api.Trigger_CreateExecuteCommandsRequest(\
                             serial = True)
        for c in range(0, len(tc.ep_collector)):
            #
            # Set up TCPDUMP's on the collector
            #
            idx = tc.ep_collector_idx[c]
            if tc.ep_collector[c].IsNaples():
                ### TODO - run & revisit for windows case and fix any issues.
                if api.GetNodeOs(tc.naples.node_name) == "windows":
                    intfGuid = ionic_utils.winIntfGuid(
                        tc.ep_collector[c].node_name,
                        tc.ep_collector[c].interface)
                    intfVal = str(
                        ionic_utils.winTcpDumpIdx(tc.ep_collector[c].node_name,
                                                  intfGuid))
                    cmd = "sudo /mnt/c/Windows/System32/tcpdump.exe -c 1000 -XX -vv -i {} ip proto 47 and dst {} -U -w ep-mirror-{}.pcap"\
                          .format(intfVal, tc.collector_ip_address[idx], c)
                else:
                    intfVal = tc.ep_collector[c].interface
                    cmd = "tcpdump -c 1000 -XX -vv -nni {} ip proto gre and dst {}\
                           --immediate-mode -U -w ep-mirror-{}.pcap"\
                          .format(intfVal,
                              tc.collector_ip_address[idx], c)
            else:
                cmd = "tcpdump -p -c 1000 -XX -vv -nni {} ip proto gre\
                       and dst {} --immediate-mode -U -w ep-mirror-{}.pcap"\
                      .format(tc.ep_collector[c].interface,
                              tc.collector_ip_address[idx], c)
            eutils.add_command(req_tcpdump_erspan, tc.ep_collector[c], cmd,
                               True)

        resp_tcpdump_erspan = api.Trigger(req_tcpdump_erspan)
        for cmd in resp_tcpdump_erspan.commands:
            api.PrintCommandResults(cmd)

        #
        # Classic mode requires a delay to make sure that TCPDUMP background
        # process is fully up
        #
        if tc.classic_mode == True:
            time.sleep(2)

        #
        # Trigger packets for ERSPAN to take effect
        #
        tc.dest_port = '120'
        if api.GetNodeOs(tc.naples.node_name) == 'linux' or api.GetNodeOs(
                tc.naples.node_name) == 'windows':
            eutils.triggerTrafficInClassicModeLinux(tc)
        else:
            eutils.triggerTrafficInHostPinModeOrFreeBSD(tc)

        #
        # Dump sessions/flows/P4-tables for debug purposes
        #
        eutils.showSessionAndP4TablesForDebug(tc, tc.ep_collector,
                                              tc.ep_collector_idx)

        #
        # Terminate TCPDUMP background process
        #
        term_resp_tcpdump_erspan = api.Trigger_TerminateAllCommands(\
                                   resp_tcpdump_erspan)
        tc.resp_tcpdump_erspan = api.Trigger_AggregateCommandsResponse(\
                              resp_tcpdump_erspan, term_resp_tcpdump_erspan)
        if api.GetNodeOs(tc.naples.node_name) == "windows":
            req = api.Trigger_CreateExecuteCommandsRequest(serial=True)
            cmd = api.WINDOWS_POWERSHELL_CMD + " Stop-Process -Name 'tcpdump' -Force"
            api.Trigger_AddCommand(req,
                                   tc.naples.node_name,
                                   tc.naples.workload_name,
                                   cmd,
                                   background=False)
            resp = api.Trigger(req)

        # Delete the objects
        eutils.deGenerateEndpointConfig(tc, tc.endpoint_objects,
                                        tc.ep_collector_objects)
        agent_api.UpdateConfigObjects(tc.endpoint_objects,
                                      [tc.naples.node_name],
                                      [tc.naples_device_name])

        agent_api.DeleteConfigObjects(tc.ep_collector_objects,
                                      [tc.naples.node_name],
                                      [tc.naples_device_name])

        #
        # Make sure that Mirror-config has been removed
        #
        tc.resp_cleanup = eutils.showP4TablesForValidation(tc)

    return api.types.status.SUCCESS
Example #2
0
def Trigger(tc):
    if tc.ignore == True:
        return api.types.status.SUCCESS

    if tc.error == True:
        return api.types.status.FAILURE

    protoDir1 = api.GetTopologyDirectory() +\
                "/gen/telemetry/{}/{}".format('mirror', 'lif')
    api.Logger.info("Template Config files location: ", protoDir1)
    protoDir2 = api.GetTopologyDirectory() +\
                "/gen/telemetry/{}/{}".format('mirror', tc.iterators.proto)
    api.Logger.info("Template Config files location: ", protoDir2)
    protoDir3 = api.GetTopologyDirectory() +\
                "/gen/telemetry/{}/{}".format('flowmon', tc.iterators.proto)
    api.Logger.info("Template Config files location: ", protoDir3)

    result = api.types.status.SUCCESS

    count = 0
    MirrorPolicies = utils.GetTargetJsons('mirror', tc.iterators.proto)
    FlowMonPolicies = utils.GetTargetJsons('flowmon', tc.iterators.proto)
    LifPolicies = utils.GetTargetJsons('mirror', 'lif')
    flowmon_policy_idx = 0
    ret_count = 0
    for mirror_json in MirrorPolicies:
        #
        # Get template-Mirror Config
        #
        newMirrorObjects = agent_api.AddOneConfig(mirror_json)
        if len(newMirrorObjects) == 0:
            api.Logger.error("Adding new Mirror objects to store failed")
            tc.error = True
            return api.types.status.FAILURE
        agent_api.RemoveConfigObjects(newMirrorObjects)

        #
        # Ignore Multi-collector template config's, since Expanded-Telemetry
        # testbundle dynamically creates such config's
        #
        if len(newMirrorObjects[0].spec.collectors) > 1:
            continue

        idx = 0
        for flowmon_json in FlowMonPolicies:
            if idx < flowmon_policy_idx:
                idx += 1
                continue

            #
            # Get template-FlowMon Config
            #
            newFlowMonObjects = agent_api.AddOneConfig(flowmon_json)
            if len(newFlowMonObjects) == 0:
                api.Logger.error("Adding new FlowMon objects to store failed")
                tc.error = True
                return api.types.status.FAILURE
            agent_api.RemoveConfigObjects(newFlowMonObjects)

            #
            # Ignore Multi-collector template config's, since Expanded-Telemetry
            # testbundle dynamically creates such config's
            #
            if len(newFlowMonObjects[0].spec.exports) > 1:
                flowmon_policy_idx += 1
                idx += 1
                continue

            #
            # Modify template-Mirror / template-FlowMon Config to make sure
            # that Naples-node # act as either source or destination
            #
            # Set up Collector in the remote node
            #
            eutils.generateMirrorConfig(tc, mirror_json, newMirrorObjects)
            eutils.generateFlowMonConfig(tc, flowmon_json, newFlowMonObjects)

            ret_count = 0
            for i in range(0, len(tc.mirror_verif)):
                #
                # If Execution-Optimization is enabled, no need to run the
                # test for the same protocol more than once
                #
                if i > 0 and tc.mirror_verif[i]['protocol'] ==\
                             tc.mirror_verif[i-1]['protocol']:
                    continue

                #
                # Flow-ERSPAN for TCP-traffic is not tested (yet) in
                # Classic-mode until applicable pkt-trigger tools are
                # identified
                #
                if tc.classic_mode == True and\
                   tc.mirror_verif[i]['protocol'] == 'tcp':
                    continue

                for policy_json in LifPolicies:
                    #
                    # Get template-Mirror Config
                    #
                    newObjects = agent_api.AddOneConfig(policy_json)
                    if len(newObjects) == 0:
                        api.Logger.error("Adding new objects to store failed")
                        tc.error = True
                        return api.types.status.FAILURE

                    #
                    # Modify template-Mirror Config to make sure that
                    # Naples-node act as either source or destination
                    #
                    # Set up Collector in the remote node
                    #
                    if newObjects[0].kind == 'InterfaceMirrorSession':
                        tc.lif_collector_objects = newObjects
                        agent_api.RemoveConfigObjects(tc.lif_collector_objects)
                    elif newObjects[0].kind == 'Interface':
                        tc.interface_objects = newObjects
                        agent_api.RemoveConfigObjects(tc.interface_objects)

                #
                # Push Collector Config to Naples
                #
                colObjects = tc.lif_collector_objects
                ret = eutils.generateLifCollectorConfig(tc, colObjects)
                if ret != api.types.status.SUCCESS:
                    api.Logger.error("Unable to identify Collector Workload")
                    tc.error = True
                    return api.types.status.FAILURE

                ret = agent_api.PushConfigObjects(colObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                if ret != api.types.status.SUCCESS:
                    api.Logger.error("Unable to push collector objects")
                    tc.error = True
                    return api.types.status.FAILURE

                #
                # Push Mirror / FlowMon Config to Naples
                #
                ret = agent_api.PushConfigObjects(newMirrorObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                if ret != api.types.status.SUCCESS:
                    agent_api.DeleteConfigObjects(tc.lif_collector_objects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    api.Logger.error("Unable to push mirror objects")
                    tc.error = True
                    return api.types.status.FAILURE

                ret = agent_api.PushConfigObjects(newFlowMonObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                if ret != api.types.status.SUCCESS:
                    agent_api.DeleteConfigObjects(tc.lif_collector_objects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    agent_api.DeleteConfigObjects(newMirrorObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    api.Logger.error("Unable to push flowmon objects")
                    tc.error = True
                    return api.types.status.FAILURE

                #
                # Update Interface objects
                #
                ifObjects = tc.interface_objects
                ret = eutils.generateLifInterfaceConfig(
                    tc, ifObjects, tc.lif_collector_objects)
                if ret != api.types.status.SUCCESS:
                    agent_api.DeleteConfigObjects(tc.lif_collector_objects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    agent_api.DeleteConfigObjects(newMirrorObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    agent_api.DeleteConfigObjects(newFlowMonObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    api.Logger.error(
                        "Unable to identify Uplink/LIF Interfaces")
                    tc.error = True
                    return api.types.status.FAILURE

                ret = agent_api.UpdateConfigObjects(ifObjects,
                                                    [tc.naples.node_name],
                                                    [tc.naples_device_name])
                if ret != api.types.status.SUCCESS:
                    agent_api.DeleteConfigObjects(tc.lif_collector_objects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    agent_api.DeleteConfigObjects(newMirrorObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    agent_api.DeleteConfigObjects(newFlowMonObjects,
                                                  [tc.naples.node_name],
                                                  [tc.naples_device_name])
                    api.Logger.error("Unable to update interface objects")
                    tc.error = True
                    return api.types.status.FAILURE

                #
                # Establish Forwarding set up between Naples-peer and
                # Collectors
                #
                eutils.establishForwardingSetup(tc)

                #
                # Give a little time for flows clean-up to happen so that
                # stale IPFIX records don't show up
                #
                if tc.classic_mode == True:
                    time.sleep(1)

                if tc.collection == 'distinct':
                    req_tcpdump_flow_erspan = \
                    api.Trigger_CreateExecuteCommandsRequest(serial = True)
                    for c in range(0, len(tc.flow_collector)):
                        #
                        # Set up TCPDUMP's on the collector
                        #
                        idx = tc.flow_collector_idx[c]
                        if tc.flow_collector[c].IsNaples():
                            cmd = "tcpdump -c 600 -XX -vv -nni {} ip proto\
                            gre and dst {} --immediate-mode -U\
                            -w flow-mirror-{}.pcap"\
                            .format(tc.flow_collector[c].interface,
                                    tc.collector_ip_address[idx], c)
                        else:
                            cmd = "tcpdump -p -c 600 -XX -vv -nni {} ip\
                            proto gre and dst {} --immediate-mode -U\
                            -w flow-mirror-{}.pcap"\
                            .format(tc.flow_collector[c].interface,
                                    tc.collector_ip_address[idx], c)
                        eutils.add_command(req_tcpdump_flow_erspan,
                                           tc.flow_collector[c], cmd, True)

                    resp_tcpdump_flow_erspan = api.Trigger(\
                                               req_tcpdump_flow_erspan)
                    for cmd in resp_tcpdump_flow_erspan.commands:
                        api.PrintCommandResults(cmd)

                    #
                    # Classic mode requires a delay to make sure that TCPDUMP
                    # background process is fully up
                    #
                    if tc.classic_mode == True:
                        time.sleep(1)

                req_tcpdump_lif_erspan = \
                api.Trigger_CreateExecuteCommandsRequest(serial = True)
                req_tcpdump_flowmon = api.Trigger_CreateExecuteCommandsRequest(\
                                      serial = True)
                for c in range(0, len(tc.lif_collector)):
                    #
                    # Set up TCPDUMP's on the collector
                    #
                    idx = tc.lif_collector_idx[c]
                    if tc.lif_collector[c].IsNaples():
                        cmd = "tcpdump -c 1000 -XX -vv -nni {} ip proto gre\
                              and dst {} --immediate-mode -U\
                              -w lif-mirror-{}.pcap"\
                              .format(tc.lif_collector[c].interface,
                                      tc.collector_ip_address[idx], c)
                    else:
                        cmd = "tcpdump -p -c 1000 -XX -vv -nni {} ip proto\
                              gre and dst {} --immediate-mode -U\
                              -w lif-mirror-{}.pcap"\
                              .format(tc.lif_collector[c].interface,
                                      tc.collector_ip_address[idx], c)
                    eutils.add_command(req_tcpdump_lif_erspan,
                                       tc.lif_collector[c], cmd, True)

                for c in range(0, len(tc.flowmon_collector)):
                    #
                    # Set up TCPDUMP's on the collector
                    #
                    idx = tc.flowmon_collector_idx[c]
                    if tc.flowmon_collector[c].IsNaples():
                        cmd = "tcpdump -c 600 -XX -vv -nni {} udp and\
                               dst port {} and dst {} --immediate-mode\
                               -U -w flowmon-{}.pcap"\
                        .format(tc.flowmon_collector[c].interface,
                        tc.export_port[c], tc.collector_ip_address[idx], c)
                    else:
                        cmd = "tcpdump -p -c 600 -XX -vv -nni {} udp\
                               and dst port {} and dst {}\
                               --immediate-mode -U -w flowmon-{}.pcap"\
                        .format(tc.flowmon_collector[c].interface,
                        tc.export_port[c], tc.collector_ip_address[idx], c)
                    eutils.add_command(req_tcpdump_flowmon,
                                       tc.flowmon_collector[c], cmd, True)

                resp_tcpdump_lif_erspan = api.Trigger(\
                                          req_tcpdump_lif_erspan)
                for cmd in resp_tcpdump_lif_erspan.commands:
                    api.PrintCommandResults(cmd)

                #
                # Classic mode requires a delay to make sure that TCPDUMP
                # background process is fully up
                #
                if tc.classic_mode == True:
                    time.sleep(2)

                resp_tcpdump_flowmon = api.Trigger(req_tcpdump_flowmon)
                for cmd in resp_tcpdump_flowmon.commands:
                    api.PrintCommandResults(cmd)

                #
                # Classic mode requires a delay to make sure that TCPDUMP
                # background process is fully up
                #
                if tc.classic_mode == True:
                    time.sleep(2)

                #
                # Trigger packets for ERSPAN / FLOWMON to take effect
                #
                tc.protocol = tc.mirror_verif[i]['protocol']
                tc.dest_port = utils.GetDestPort(tc.mirror_verif[i]['port'])

                protocol = tc.protocol
                tc.protocol = 'all'
                if api.GetNodeOs(tc.naples.node_name) == 'linux':
                    eutils.triggerTrafficInClassicModeLinux(tc)
                else:
                    eutils.triggerTrafficInHostPinModeOrFreeBSD(tc)
                tc.protocol = protocol

                #
                # Dump sessions/flows/P4-tables for debug purposes
                #
                eutils.showSessionAndP4TablesForDebug(tc, tc.lif_collector,
                                                      tc.lif_collector_idx)

                #
                # Terminate TCPDUMP background process
                #
                term_resp_tcpdump_lif_erspan = \
                api.Trigger_TerminateAllCommands(resp_tcpdump_lif_erspan)
                tc.resp_tcpdump_lif_erspan = \
                api.Trigger_AggregateCommandsResponse(\
                resp_tcpdump_lif_erspan, term_resp_tcpdump_lif_erspan)

                if tc.collection == 'distinct':
                    term_resp_tcpdump_flow_erspan = \
                    api.Trigger_TerminateAllCommands(resp_tcpdump_flow_erspan)
                    tc.resp_tcpdump_flow_erspan = \
                    api.Trigger_AggregateCommandsResponse(\
                    resp_tcpdump_flow_erspan, term_resp_tcpdump_flow_erspan)

                term_resp_tcpdump_flowmon = api.Trigger_TerminateAllCommands(\
                                            resp_tcpdump_flowmon)
                tc.resp_tcpdump_flowmon = \
                api.Trigger_AggregateCommandsResponse(resp_tcpdump_flowmon,
                                                      term_resp_tcpdump_flowmon)

                # Delete the objects
                eutils.deGenerateLifInterfaceConfig(tc, tc.interface_objects,
                                                    tc.lif_collector_objects)
                agent_api.UpdateConfigObjects(tc.interface_objects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])
                agent_api.DeleteConfigObjects(tc.lif_collector_objects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])
                agent_api.DeleteConfigObjects(newMirrorObjects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])
                agent_api.DeleteConfigObjects(newFlowMonObjects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])

                #
                # Make sure that Mirror-config has been removed
                #
                tc.resp_cleanup = eutils.showP4TablesForValidation(tc)

                #
                # Validate ERSPAN packets reception
                #
                tc.tcp_erspan_pkts_expected = \
                               NUMBER_OF_TCP_ERSPAN_PACKETS_PER_SESSION
                tc.udp_erspan_pkts_expected = (tc.udp_count << 1)
                tc.icmp_erspan_pkts_expected = (tc.udp_count << 1)+\
                                               (tc.icmp_count << 1)

                if tc.iterators.direction != 'both':
                    tc.tcp_erspan_pkts_expected >>= 1
                    tc.udp_erspan_pkts_expected >>= 1
                    tc.icmp_erspan_pkts_expected >>= 1

                if tc.dupcheck == 'disable':
                    tc.tcp_erspan_pkts_expected = \
                    (tc.tcp_erspan_pkts_expected+1) << 1
                    tc.udp_erspan_pkts_expected <<= 1
                    tc.icmp_erspan_pkts_expected <<= 1

                #
                # Adjust Expected-pkt-counts taking into account Flow-ERSPAN
                # Config's
                #
                if tc.collection == 'unified':
                    if (tc.protocol == 'tcp' or tc.iterators.proto == 'mixed')\
                        and tc.iterators.direction != 'both':
                        tc.tcp_erspan_pkts_expected <<= 1
                    if (tc.protocol == 'udp' or tc.iterators.proto == 'mixed')\
                        and tc.iterators.direction != 'both':
                        tc.udp_erspan_pkts_expected <<= 1
                    if tc.protocol == 'icmp' or tc.iterators.proto == 'mixed':
                        if tc.iterators.direction != 'both':
                            tc.icmp_erspan_pkts_expected <<= 1
                        #if tc.iterators.direction != 'egress':
                        #    tc.icmp_erspan_pkts_expected += 1

                protocol = tc.protocol
                tc.protocol = 'all'
                tc.feature = 'lif-erspan'
                tc.resp_tcpdump_erspan = tc.resp_tcpdump_lif_erspan
                res_1 = eutils.validateErspanPackets(tc, tc.lif_collector,
                                                     tc.lif_collector_idx)

                if tc.collection == 'distinct':
                    tc.tcp_erspan_pkts_expected = 0
                    tc.udp_erspan_pkts_expected = 0
                    tc.icmp_erspan_pkts_expected = 0
                    tc.protocol = protocol
                    if tc.protocol == 'tcp' or tc.iterators.proto == 'mixed':
                        tc.tcp_erspan_pkts_expected = \
                               NUMBER_OF_TCP_ERSPAN_PACKETS_PER_SESSION
                    if tc.protocol == 'udp' or tc.iterators.proto == 'mixed':
                        tc.udp_erspan_pkts_expected = (tc.udp_count << 1)
                    if tc.protocol == 'icmp' or tc.iterators.proto == 'mixed':
                        tc.icmp_erspan_pkts_expected = (tc.udp_count << 1)+\
                                                       (tc.icmp_count << 1)

                    tc.protocol = 'all'
                    tc.feature = 'flow-erspan'
                    tc.resp_tcpdump_erspan = tc.resp_tcpdump_flow_erspan
                    res_f = eutils.validateErspanPackets(
                        tc, tc.flow_collector, tc.flow_collector_idx)
                    if res_f == api.types.status.FAILURE:
                        result = api.types.status.FAILURE

                #
                # Validate IPFIX packets reception
                #
                tc.feature = 'flowmon'
                res_2 = eutils.validateIpFixPackets(tc)
                tc.protocol = protocol

                #
                # Validate Config-cleanup
                #
                res_3 = eutils.validateConfigCleanup(tc)

                if res_1 == api.types.status.FAILURE or\
                   res_2 == api.types.status.FAILURE or\
                   res_3 == api.types.status.FAILURE:
                    result = api.types.status.FAILURE

                if result == api.types.status.FAILURE:
                    break

                ret_count += 1

            flowmon_policy_idx += 1
            break

        if result == api.types.status.FAILURE:
            break

        count += ret_count

    tc.SetTestCount(count)
    return result
Example #3
0
def Trigger(tc):
    if tc.ignore == True:
        return api.types.status.SUCCESS

    if tc.error == True:
        return api.types.status.FAILURE

    protoDir = api.GetTopologyDirectory() +\
               "/gen/telemetry/{}/{}".format('mirror', tc.iterators.proto)
    api.Logger.info("Template Config files location: ", protoDir)

    result = api.types.status.SUCCESS

    count = 0
    policies = utils.GetTargetJsons('mirror', tc.iterators.proto)
    for policy_json in policies:
        #
        # Get template-Mirror Config
        #
        newObjects = agent_api.AddOneConfig(policy_json)
        if len(newObjects) == 0:
            api.Logger.error("Adding new objects to store failed")
            tc.error = True
            return api.types.status.FAILURE
        agent_api.RemoveConfigObjects(newObjects)

        #
        # Ignore Multi-collector template config's, since Expanded-Telemetry
        # testbundle dynamically creates such config's
        #
        if len(newObjects[0].spec.collectors) > 1:
            continue

        #
        # Modify template-Mirror Config to make sure that Naples-node
        # act as either source or destination
        #
        # Set up Collector in the remote node
        #
        eutils.generateMirrorConfig(tc, policy_json, newObjects)

        ret_count = 0
        for i in range(0, len(tc.mirror_verif)):
            #
            # If Execution-Optimization is enabled, no need to run the test
            # for the same protocol more than once
            #
            if i > 0 and tc.mirror_verif[i]['protocol'] ==\
                         tc.mirror_verif[i-1]['protocol']:
                continue

            #
            # Flow-ERSPAN for TCP-traffic is not tested (yet) in
            # Classic-mode until applicable pkt-trigger tools are identified
            #
            if tc.classic_mode == True and\
               tc.mirror_verif[i]['protocol'] == 'tcp':
                continue

            #
            # Push Mirror Config to Naples
            #
            ret = agent_api.PushConfigObjects(newObjects,
                                              [tc.naples.node_name],
                                              [tc.naples_device_name])
            if ret != api.types.status.SUCCESS:
                api.Logger.error("Unable to push mirror objects")
                tc.error = True
                return api.types.status.FAILURE

            #
            # Establish Forwarding set up between Naples-peer and Collectors
            #
            eutils.establishForwardingSetup(tc)

            req_tcpdump_erspan = api.Trigger_CreateExecuteCommandsRequest(\
                                 serial = True)
            for c in range(0, len(tc.flow_collector)):
                #
                # Set up TCPDUMP's on the collector
                #
                idx = tc.flow_collector_idx[c]
                if tc.flow_collector[c].IsNaples():
                    cmd = "tcpdump -c 600 -XX -vv -nni {} ip proto gre and\
                           dst {} --immediate-mode -U -w flow-mirror-{}.pcap"\
                          .format(tc.flow_collector[c].interface,
                                  tc.collector_ip_address[idx], c)
                else:
                    cmd = "tcpdump -p -c 600 -XX -vv -nni {} ip proto gre and\
                           dst {} --immediate-mode -U -w flow-mirror-{}.pcap"\
                          .format(tc.flow_collector[c].interface,
                                  tc.collector_ip_address[idx], c)
                eutils.add_command(req_tcpdump_erspan, tc.flow_collector[c],
                                   cmd, True)

            resp_tcpdump_erspan = api.Trigger(req_tcpdump_erspan)
            for cmd in resp_tcpdump_erspan.commands:
                api.PrintCommandResults(cmd)

            #
            # Classic mode requires a delay to make sure that TCPDUMP background
            # process is fully up
            #
            if tc.classic_mode == True:
                time.sleep(2)

            #
            # Trigger packets for ERSPAN to take effect
            #
            tc.protocol = tc.mirror_verif[i]['protocol']
            tc.dest_port = utils.GetDestPort(tc.mirror_verif[i]['port'])
            if api.GetNodeOs(tc.naples.node_name) == 'linux':
                eutils.triggerTrafficInClassicModeLinux(tc)
            else:
                eutils.triggerTrafficInHostPinModeOrFreeBSD(tc)

            #
            # Dump sessions/flows/P4-tables for debug purposes
            #
            eutils.showSessionAndP4TablesForDebug(tc, tc.flow_collector,
                                                  tc.flow_collector_idx)

            #
            # Terminate TCPDUMP background process
            #
            term_resp_tcpdump_erspan = api.Trigger_TerminateAllCommands(\
                                       resp_tcpdump_erspan)
            tc.resp_tcpdump_erspan = api.Trigger_AggregateCommandsResponse(\
                              resp_tcpdump_erspan, term_resp_tcpdump_erspan)

            # Delete the objects
            agent_api.DeleteConfigObjects(newObjects, [tc.naples.node_name],
                                          [tc.naples_device_name])

            #
            # Make sure that Mirror-config has been removed
            #
            tc.resp_cleanup = eutils.showP4TablesForValidation(tc)

            #
            # Validate ERSPAN packets reception
            #
            tc.tcp_erspan_pkts_expected = \
                               NUMBER_OF_TCP_ERSPAN_PACKETS_PER_SESSION
            tc.udp_erspan_pkts_expected = (tc.udp_count << 1)
            tc.icmp_erspan_pkts_expected = (tc.icmp_count << 1)

            if tc.protocol == 'udp' and tc.iterators.proto == 'mixed':
                tc.protocol = 'udp-mixed'
                tc.icmp_erspan_pkts_expected = tc.udp_erspan_pkts_expected

            res_1 = eutils.validateErspanPackets(tc, tc.flow_collector,
                                                 tc.flow_collector_idx)

            #
            # Validate Config-cleanup
            #
            res_2 = eutils.validateConfigCleanup(tc)

            if res_1 == api.types.status.FAILURE or\
               res_2 == api.types.status.FAILURE:
                result = api.types.status.FAILURE

            if result == api.types.status.FAILURE:
                break

            ret_count += 1

        if result == api.types.status.FAILURE:
            break

        count += ret_count

    tc.SetTestCount(count)

    return result