Skip to content

Commit b4abdd1

Browse files
committed
Workflow : Nto1CheckConnectivity
1 parent df7297d commit b4abdd1

File tree

3 files changed

+141
-3
lines changed

3 files changed

+141
-3
lines changed

Diff for: js/api.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,8 @@ export function REGEX(param: any): Predicate {
671671
return new Predicate("REGEX", param)
672672
}
673673

674-
export function WITHIN(...params: any[]): Predicate {
675-
return new Predicate("WITHIN", ...params)
674+
export function Within(...params: any[]): Predicate {
675+
return new Predicate("Within", ...params)
676676
}
677677

678678
export function WITHOUT(...params: any[]): Predicate {

Diff for: js/browser.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ window.GTE = apiLib.GTE
2626
window.LTE = apiLib.LTE
2727
window.IPV4RANGE = apiLib.IPV4RANGE
2828
window.REGEX = apiLib.REGEX
29-
window.WITHIN = apiLib.WITHIN
29+
window.Within = apiLib.Within
3030
window.WITHOUT = apiLib.WITHOUT
3131
window.INSIDE = apiLib.INSIDE
3232
window.OUTSIDE = apiLib.OUTSIDE

Diff for: statics/workflows/Nto1-check-connectivity.yaml

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
UUID: "18349e06-37d4-43c0-5882-d1aa4bf66133"
3+
Name: "Nto1CheckConnectivity"
4+
Title: "Test connectivity between N source to 1 Destination"
5+
Abstract: "This workflow aims to test the connectivity between N source to 1 Destination. It returns the status of the connection, true (with Flows) or false."
6+
Description: >
7+
# How to use:
8+
1. Enter the Gremlin Query for Source Nodes and Select the Destination Nodes to check the Connectivity between them
9+
2. Hit the 'Execute' button to run the workflow
10+
3. Result will be shown as status true or false along with flows between those interfaces.
11+
# How It Works:
12+
1. It will start capture on all Nodes from Source to Destination and injects 5 ICMP-Pkts from Source to Destination
13+
2. After 1 sec it will check for flows having the same capture-id created by this workflow
14+
3. If flows are there and the BA-Packtes in flow-metric > 0, then return 'Connectivity = ture' else 'Connectivity = false', along with this it also returns the flows
15+
4. For more information about Skydive workflows please follow - 'skydive.network/blog/introduction-to-workflows.html'
16+
Parameters:
17+
- Name: srcQuery
18+
Description: Gremlin Expression for Source-Nodes
19+
Type: string
20+
- Name: dstNode
21+
Description: Select Destination node
22+
Type: node
23+
- Name: Analysis
24+
Description: Analysis for Disconnectivity
25+
Type: boolean
26+
Source: |
27+
function Nto1CheckConnectivity(srcQuery, to, analyze) {
28+
var result = {}
29+
try {
30+
sources = client.gremlin.query(srcQuery);
31+
dstNode = client.gremlin.G().V().Has('TID', to).result();
32+
dstNodeIP = (dstNode[0].Metadata.IPV4[0]).split("/");
33+
datNodeIP = dstNodeIP[0]
34+
var id = Math.floor(25000 + (Math.random() * 10000));
35+
var maxID = id + sources.length;
36+
37+
var getInfo = function(sources) {
38+
var srcIP = [];
39+
var srcTID = "";
40+
41+
for (var i = 0; i != sources.length; i++) {
42+
srcTID += "'" + sources[i].Metadata.TID + "', ";
43+
if (sources[i].Metadata.IPV4) {
44+
ip = (sources[i].Metadata.IPV4[0]).split("/");
45+
srcIP[i] = ip[0]
46+
}
47+
}
48+
srcTID = srcTID.slice(0, -2);
49+
var info = {"srcTID" : srcTID, "srcIP" : srcIP};
50+
return info
51+
}
52+
53+
var capture = new Capture();
54+
if (analyze) {
55+
capture.GremlinQuery = srcQuery + ".ShortestPathTo(Metadata('TID', '" + to + "'), Metadata('RelationType', 'layer2'))";
56+
} else {
57+
capture.GremlinQuery = srcQuery;
58+
}
59+
var bpf = "icmp and (src " + datNodeIP + " or dst " + datNodeIP + ") and (icmp[4:2]>=" + id + " and icmp[4:2]<" + maxID + ")";
60+
capture.BPFFilter = "(" + bpf + ") " + "or (vlan and " + bpf + ")";
61+
62+
var packetInjection = new PacketInjection();
63+
packetInjection.Src = srcQuery
64+
packetInjection.Dst = "G.V().Has('TID', '" + to + "')";
65+
packetInjection.Type = "icmp4"
66+
packetInjection.ICMPID = id;
67+
packetInjection.Count = 5
68+
packetInjection.Mode = 0
69+
70+
capture = client.captures.create(capture)
71+
sleep(1000)
72+
client.packetInjections.create(packetInjection)
73+
sleep(1000)
74+
75+
var srcInfo = getInfo(sources)
76+
var srcIP = srcInfo["srcIP"];
77+
var srcTID = srcInfo["srcTID"];
78+
var srcFlow = client.gremlin.query("G.Flows().Has('CaptureID', '" + capture.UUID + "', 'NodeTID', Within(" + srcTID + "), 'Metric.ABPackets', GT(0), 'Metric.BAPackets', GT(0))");
79+
80+
var analysis = function(captureID, ip, src, dst) {
81+
var flowCaptured = client.gremlin.G().Flows().Has('CaptureID', captureID, 'Network.A', ip).result();
82+
var pathNodes = client.gremlin.G().V().Has('TID', src).ShortestPathTo(Metadata('TID', dst), Metadata('RelationType', 'layer2')).result();
83+
pathNodes = pathNodes[0];
84+
var flows = [];
85+
var noFlows = [];
86+
for (var i = 0; i != pathNodes.length; i++) {
87+
var found = false;
88+
for (var j = 0; j != flowCaptured.length; j++) {
89+
if (flowCaptured[j].NodeTID == pathNodes[i].Metadata.TID) {
90+
found = true;
91+
flows.push(flowCaptured[j]);
92+
break;
93+
}
94+
}
95+
if (!found && pathNodes[i].Metadata.Type != "ovsport") {
96+
noFlows.push(pathNodes[i]);
97+
}
98+
}
99+
100+
if (flows.length == 0) {
101+
flows[0] = "No Flows Found";
102+
}
103+
if (noFlows.length == 0) {
104+
noFlows[0] = "No Flows Found";
105+
}
106+
107+
var analysis = {"Flows" : flows, "NotReachedNodes" : noFlows}
108+
return analysis
109+
}
110+
111+
var flows = {};
112+
for (var i = 0; i != srcIP.length; i++) {
113+
var found = false;
114+
for (var j = 0; j != srcFlow.length; j++) {
115+
if (srcIP[i] == srcFlow[j].Network.A) {
116+
found = true;
117+
flows[sources[i].Metadata.TID] = {"Connectivity" : true, "Flow" : srcFlow[j]}
118+
break;
119+
}
120+
}
121+
if (!found) {
122+
if (analyze) {
123+
var flowCaptured = analysis(capture.UUID, srcIP[i], sources[i].Metadata.TID, to)
124+
flows[sources[i].Metadata.TID] = {"Connectivity" : false, "Analysis" : flowCaptured}
125+
} else {
126+
flows[sources[i].Metadata.TID] = {"Connectivity" : false}
127+
}
128+
}
129+
}
130+
131+
result["Connectivity"] = flows
132+
} catch (e) {
133+
console.log(e)
134+
result["Error"] = JSON.stringify(e)
135+
}
136+
if (capture && capture.UUID) client.captures.delete(capture.UUID)
137+
return result
138+
}

0 commit comments

Comments
 (0)