Skip to content

Commit 72d7ce8

Browse files
ofirZeliglebauce
authored andcommitted
Add injection to python rest api (#1508)
* Added support in the restAPI for injections - including creation, deletion, list * Fixed allinone
1 parent 7de7b5e commit 72d7ce8

File tree

4 files changed

+173
-4
lines changed

4 files changed

+173
-4
lines changed

cmd/allinone/allinone.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ var AllInOneCmd = &cobra.Command{
132132
os.Exit(1)
133133
}
134134

135-
os.Setenv("SKYDIVE_ANALYZERS", config.GetString("analyzer.listen"))
135+
os.Setenv("SKYDIVE_ANALYZERS", fmt.Sprintf("%s:%d", addr, svcAddr.Port))
136136
os.Setenv("SKYDIVE_LOGGING_FILE_PATH", logFile+"-agent"+extension)
137-
137+
138138
agentAttr := &os.ProcAttr{
139139
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
140140
Env: os.Environ(),
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#
2+
# Copyright (C) 2019 Red Hat, Inc.
3+
#
4+
# Licensed to the Apache Software Foundation (ASF) under one
5+
# or more contributor license agreements. See the NOTICE file
6+
# distributed with this work for additional information
7+
# regarding copyright ownership. The ASF licenses this file
8+
# to you under the Apache License, Version 2.0 (the
9+
# "License"); you may not use this file except in compliance
10+
# with the License. You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing,
15+
# software distributed under the License is distributed on an
16+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17+
# KIND, either express or implied. See the License for the
18+
# specific language governing permissions and limitations
19+
# under the License.
20+
#
21+
22+
23+
class PacketInjection(object):
24+
"""
25+
Definition of a Skydive packet injection.
26+
"""
27+
28+
def __init__(self, uuid="", src="", dst="", srcip="", dstip="", srcmac="",
29+
dstmac="", srcport="", dstport="", type="", payload="",
30+
trackingid="", icmpid="", count="", interval="",
31+
increment="", starttime=""):
32+
self.uuid = uuid
33+
self.src = src
34+
self.dst = dst
35+
self.srcip = srcip
36+
self.dstip = dstip
37+
self.srcmac = srcmac
38+
self.dstmac = dstmac
39+
self.srcport = srcport
40+
self.dstport = dstport
41+
self.type = type
42+
self.payload = payload
43+
self.trackingid = trackingid
44+
self.icmpid = icmpid
45+
self.count = count
46+
self.interval = interval
47+
self.increment = increment
48+
self.starttime = starttime
49+
50+
def repr_json(self):
51+
obj = {}
52+
53+
if self.uuid:
54+
obj["UUID"] = self.uuid
55+
if self.src:
56+
obj["Src"] = self.src
57+
if self.dst:
58+
obj["Dst"] = self.dst
59+
if self.srcip:
60+
obj["SrcIP"] = self.srcip
61+
if self.dstip:
62+
obj["DstIP"] = self.dstip
63+
if self.srcmac:
64+
obj["SrcMAC"] = self.srcmac
65+
if self.dstmac:
66+
obj["DstMAC"] = self.dstmac
67+
if self.srcport:
68+
obj["SrcPort"] = self.srcport
69+
if self.dstport:
70+
obj["DstPort"] = self.dstport
71+
if self.type:
72+
obj["Type"] = self.type
73+
if self.payload:
74+
obj["Payload"] = self.payload
75+
if self.trackingid:
76+
obj["TrackingID"] = self.trackingid
77+
if self.icmpid:
78+
obj["ICMPID"] = self.icmpid
79+
if self.count:
80+
obj["Count"] = self.count
81+
if self.interval:
82+
obj["Interval"] = self.interval
83+
if self.increment:
84+
obj["Increment"] = self.increment
85+
return obj
86+
87+
@classmethod
88+
def from_object(self, obj):
89+
return self(uuid=obj.get("UUID"),
90+
src=obj.get("Src"),
91+
dst=obj.get("Dst"),
92+
srcip=obj.get("SrcIP"),
93+
dstip=obj.get("DstIP"),
94+
srcmac=obj.get("SrcMAC"),
95+
dstmac=obj.get("DstMAC"),
96+
srcport=obj.get("SrcPort"),
97+
dstport=obj.get("DstPort"),
98+
type=obj.get("Type"),
99+
payload=obj.get("Payload"),
100+
trackingid=obj.get("TrackingID"),
101+
icmpid=obj.get("ICMPID"),
102+
count=obj.get("Count"),
103+
interval=obj.get("Interval"),
104+
increment=obj.get("Increment"))

contrib/python/api/skydive/rest/client.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@
3131
from skydive.rules import NodeRule, EdgeRule
3232
from skydive.alerts import Alert
3333
from skydive.captures import Capture
34+
from skydive.packet_injector import PacketInjection
3435

3536

3637
class BadRequest(Exception):
3738
pass
3839

3940

4041
class RESTClient:
42+
INJECTION_PATH = "/api/injectpacket"
43+
4144
def __init__(self, endpoint, scheme="http",
4245
username="", password="", cookies={},
4346
insecure=False, debug=0):
@@ -205,3 +208,37 @@ def edgerule_list(self):
205208
def edgerule_delete(self, rule_id):
206209
path = "/api/edgerule/%s" % rule_id
207210
self.request(path, method="DELETE")
211+
212+
def injection_create(self, src_query="", dst_query="", type="icmp4",
213+
payload="", interval=1000, src_ip="",
214+
dst_ip="", src_mac="", dst_mac="",
215+
count=1, icmp_id=0, src_port=0, dst_port=0,
216+
increment=False):
217+
218+
data = json.dumps({
219+
"Src": src_query,
220+
"Dst": dst_query,
221+
"SrcPort": src_port,
222+
"DstPort": dst_port,
223+
"SrcIP": src_ip,
224+
"DstIP": dst_ip,
225+
"SrcMAC": src_mac,
226+
"DstMAC": dst_mac,
227+
"Type": type,
228+
"Count": count,
229+
"ICMPID": icmp_id,
230+
"Interval": interval,
231+
"Payload": payload,
232+
"Increment": increment
233+
})
234+
235+
r = self.request(self.INJECTION_PATH, method="POST", data=data)
236+
return PacketInjection.from_object(r)
237+
238+
def injection_delete(self, injection_id):
239+
path = self.INJECTION_PATH+"/"+injection_id
240+
return self.request(path, method="DELETE")
241+
242+
def injection_list(self):
243+
objs = self.request(self.INJECTION_PATH)
244+
return [PacketInjection.from_object(o) for o in objs.values()]

contrib/python/api/tests/tests.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,35 @@ def test_topology_rules(self):
240240
break
241241

242242
self.assertTrue(found, "created edgerule not found")
243-
243+
restclient.edgerule_delete(edgerule1.uuid)
244244
restclient.noderule_delete(noderule1.uuid)
245245
restclient.noderule_delete(noderule2.uuid)
246-
restclient.edgerule_delete(edgerule1.uuid)
246+
247+
def test_injections(self):
248+
restclient = RESTClient("localhost:8082",
249+
scheme=self.schemeHTTP,
250+
username=self.username,
251+
password=self.password,
252+
insecure=True)
253+
254+
nodes = restclient.lookup("G.V().Has('Name', 'eth0')")
255+
256+
testnode = nodes[0]["Metadata"]["TID"]
257+
258+
query = "G.V().Has('TID', '" + testnode + "')"
259+
num_injections_before = len(restclient.injection_list())
260+
261+
injection_response = restclient.injection_create(query, query,
262+
count=1000)
263+
264+
num_injections_after = len(restclient.injection_list())
265+
266+
self.assertEqual(num_injections_after, num_injections_before + 1,
267+
"injection creation didn't succeed")
268+
269+
restclient.injection_delete(injection_response.uuid)
270+
271+
num_injections_after_deletion = len(restclient.injection_list())
272+
273+
self.assertEqual(num_injections_after_deletion, num_injections_before,
274+
"injection deletion didn't succeed")

0 commit comments

Comments
 (0)