Passed
Pull Request — master (#47)
by Vinicius
08:26 queued 02:22
created

build.main.Main.get_results()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 2
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
"""Main module of amlight/sdntrace Kytos Network Application.
2
3
An OpenFlow Data Path Trace.
4
5
The AmLight SDNTrace is a Kytos Network Application allows users to trace a
6
path directly from the data plane. Originally written for Ryu
7
(github.com/amlight/sdntrace).
8
9
Steps:
10
    1 - User requests a trace using a specific flow characteristic,
11
        for example VLAN = 1000 and Dest IP address = 2.2.2.2
12
    2 - REST module inserts trace request in a queue provided by the
13
        TraceManager
14
    3 - The TraceManager runs the Tracer, basically sending PacketOuts
15
        and waiting for PacketIn until reaching a timeout
16
    4 - After Timeout, result is provided back to REST that provides it
17
        back to user
18
Dependencies:
19
    * - amlight/coloring Napp will color all switches
20
21
At this moment, OpenFlow 1.3 is supported.
22
"""
23
24
25
from napps.amlight.sdntrace import settings
26
from napps.amlight.sdntrace.backends.of_parser import process_packet_in
27
from napps.amlight.sdntrace.shared.switches import Switches
28
from napps.amlight.sdntrace.tracing.trace_manager import TraceManager
29
30
from kytos.core import KytosNApp, rest
31
from kytos.core.helpers import listen_to
32
from kytos.core.rest_api import JSONResponse, Request, get_json_or_400
33
34
35
class Main(KytosNApp):
36
    """Main class of amlight/sdntrace NApp.
37
38
    REST methods:
39
        /sdntrace/trace ['PUT'] - request a trace
40
        /sdntrace/trace ['GET'] - list of previous trace requests and results
41
        /sdntrace/trace/<trace_id> - get the results of trace requested
42
        /sdntrace/stats - Show the number of requests received and active
43
        /sdntrace/settings - list the settings
44
    """
45
46
    def setup(self):
47
        """Default Kytos/Napps setup call."""
48
49
        # Create list of switches
50
        self.switches = Switches(
51
            self.controller.switches
52
        )  # noqa: E501  pylint: disable=attribute-defined-outside-init
53
54
        # Instantiate TraceManager
55
        self.tracing = TraceManager(self.controller)  # pylint: disable=W0201
56
57
    def execute(self):
58
        """Kytos Napp execute method"""
59
60
    def shutdown(self):
61
        """Execute when your napp is unloaded.
62
63
        If you have some cleanup procedure, insert it here.
64
        """
65
        self.tracing.stop_traces()
66
67
    @listen_to("kytos/of_core.v0x04.messages.in.ofpt_packet_in")
68
    def handle_packet_in(self, event):
69
        """Receives OpenFlow PacketIn msgs and search from trace packets.
70
        If process_packet_in returns 0,0,0, it means it is not a probe
71
        packet. Otherwise, store the msg for later use by Tracers.
72
73
        Args:
74
            event (KycoPacketIn): Received Event
75
        """
76
        ethernet, in_port, switch = process_packet_in(event)
77
        if not isinstance(ethernet, int):
78
            self.tracing.queue_probe_packet(event, ethernet, in_port, switch)
79
80
    @rest("/trace", methods=["PUT"])
81
    def run_trace(self, request: Request) -> JSONResponse:
82
        """Submit a trace request."""
83
        body = get_json_or_400(request, self.controller.loop)
84
        return JSONResponse(self.tracing.rest_new_trace(body))
85
86
    @rest("/trace", methods=["GET"])
87
    def get_results(self, _request: Request) -> JSONResponse:
88
        """List all traces performed so far."""
89
        return JSONResponse(self.tracing.rest_list_results())
90
91
    @rest("/trace/{trace_id}", methods=["GET"])
92
    def get_result(self, request: Request) -> JSONResponse:
93
        """List All Traces performed since the Napp loaded."""
94
        trace_id = request.path_params["trace_id"]
95
        return JSONResponse(self.tracing.rest_get_result(trace_id))
96
97
    @rest("/stats", methods=["GET"])
98
    def get_stats(self, _request: Request) -> JSONResponse:
99
        """Get statistics."""
100
        return JSONResponse(self.tracing.rest_list_stats())
101
102
    @staticmethod
103
    @rest("/settings", methods=["GET"])
104
    def list_settings(_request: Request) -> JSONResponse:
105
        """List the SDNTrace settings
106
107
        Return:
108
            SETTINGS in JSON format
109
        """
110
        settings_dict = {}
111
        settings_dict["color_field"] = settings.COLOR_FIELD
112
        settings_dict["color_value"] = settings.COLOR_VALUE
113
        settings_dict["trace_interval"] = settings.TRACE_INTERVAL
114
        settings_dict["parallel_traces"] = settings.PARALLEL_TRACES
115
        return JSONResponse(settings_dict)
116