Skip to content

Commit 0cf73f6

Browse files
committed
IPFIX HTTP exporter: provide an option to add custom header fields to the HTTP push requests
1 parent 64cd404 commit 0cf73f6

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

scripts/automation/trex_control_plane/interactive/trex/emu/emu_plugins/emu_plugin_ipfix.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ def ipfix_push(self, line):
516516
parsing_opts.IPFIX_HTTP_REPEATS_WAIT_TIME,
517517
parsing_opts.IPFIX_HTTP_SITES_PER_TENANT,
518518
parsing_opts.IPFIX_HTTP_DEVICES_PER_SITE,
519+
parsing_opts.IPFIX_HTTP_HEADER_FIELDS_JSON_FILE,
519520
parsing_opts.IPFIX_UDP_PACKETS_WAIT_TIME,
520521
)
521522
opts = parser.parse_args(line.split())
@@ -524,6 +525,15 @@ def ipfix_push(self, line):
524525
if exporter_params is None:
525526
raise TRexError("Failed to create ipfix exporter")
526527

528+
header_fields_json = None
529+
530+
if opts.header_fields_json_file:
531+
try:
532+
with open(opts.header_fields_json_file, 'r') as file:
533+
header_fields_json = file.read()
534+
except FileNotFoundError:
535+
raise TRexError("Header fields JSON file doesn't exist")
536+
527537
exporter_params.set_export_from_dir(True)
528538
if exporter_params.get_type() == "http":
529539
exporter_params.set_repeats_num(opts.http_repeats_num)
@@ -532,6 +542,7 @@ def ipfix_push(self, line):
532542
dir_scans_num = opts.dir_scans_num,
533543
files_wait_time = opts.files_wait_time,
534544
files_wait_time_speedup = opts.files_wait_time_speedup)
545+
exporter_params.set_header_fields(header_fields_json)
535546

536547
if exporter_params.get_type() == "udp":
537548
exporter_params.set_export_from_dir_params(dir = opts.dir,

scripts/automation/trex_control_plane/interactive/trex/emu/trex_emu_ipfix_profile.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,17 @@ def _create_file_obj(self, dst_url):
154154
return obj
155155

156156
def _create_http_obj(self, dst_url):
157-
re_pattern = r"^/api/ipfixfilecollector/([%\w-]+)/([%\w-]+)/([%\w-]+)/post_file$"
157+
re_pattern = r"([/\w]+)/([%\w-]+)/([%\w-]+)/([%\w-]+)/post_file$"
158158
match = re.search(re_pattern, dst_url.path)
159159
if not match:
160160
return None
161161

162-
tenant_id = match.groups()[0]
163-
site_id = match.groups()[1]
164-
device_id = match.groups()[2]
162+
dst_url_path = match.groups()[0]
163+
tenant_id = match.groups()[1]
164+
site_id = match.groups()[2]
165+
device_id = match.groups()[3]
165166

166-
obj = IpfixHttpExporterParams(dst_url.scheme, dst_url.hostname, dst_url.port, tenant_id, site_id, device_id)
167+
obj = IpfixHttpExporterParams(dst_url.scheme, dst_url.hostname, dst_url.port, tenant_id, site_id, device_id, dst_url_path)
167168
return obj
168169

169170

@@ -279,13 +280,14 @@ def set_compress(self, compress):
279280

280281

281282
class IpfixHttpExporterParams(IpfixFileExporterParams):
282-
def __init__(self, scheme, dst_ip_addr, dst_port, tenant_id, site_id, device_id):
283+
def __init__(self, scheme, dst_ip_addr, dst_port, tenant_id, site_id, device_id, dst_url_path):
283284
super(IpfixHttpExporterParams, self).__init__(None, None)
284285
self._dst_ip_addr = dst_ip_addr
285286
self._dst_port = dst_port # urlparse can return dst_port None
286287
self._tenant_id = tenant_id
287288
self._site_id = site_id
288289
self._device_id = device_id
290+
self._dst_url_path = dst_url_path
289291
self._max_posts = None
290292
self._tls_cert_file = None
291293
self._tls_key_file = None
@@ -295,6 +297,7 @@ def __init__(self, scheme, dst_ip_addr, dst_port, tenant_id, site_id, device_id)
295297
self._repeats_wait_time = None
296298
self._export_from_dir = None
297299
self._export_from_dir_params = None
300+
self._header_fields = None
298301
if scheme not in ["http", "https"]:
299302
raise ValueError("invalid scheme {}, scheme should be http/s".format(scheme))
300303
self._type = scheme
@@ -313,16 +316,22 @@ def get_json(self):
313316
add_to_json_if_not_none(exporter_params, "repeats_wait_time", self._repeats_wait_time)
314317
add_to_json_if_not_none(exporter_params, "export_from_dir", self._export_from_dir)
315318
add_to_json_if_not_none(exporter_params, "export_from_dir_params", self._export_from_dir_params)
319+
add_to_json_if_not_none(exporter_params, "header_fields", self._header_fields)
316320

317321
return None if len(exporter_params) == 0 else exporter_params
318322

319323
def get_dst_url(self):
320-
if self._dst_port is None:
321-
return "{0}://{1}/api/ipfixfilecollector/{2}/{3}/{4}/post_file".format(
322-
self._type, self._dst_ip_addr, self._tenant_id, self._site_id, self._device_id)
324+
dst_url_path = "/api/ipfixfilecollector"
325+
if self._dst_url_path:
326+
dst_url_path = self._dst_url_path
327+
328+
if not self._dst_port:
329+
return "{0}://{1}{2}/{3}/{4}/{5}/post_file".format(
330+
self._type, self._dst_ip_addr, dst_url_path, self._tenant_id, self._site_id, self._device_id)
323331
else:
324-
return "{0}://{1}:{2}/api/ipfixfilecollector/{3}/{4}/{5}/post_file".format(
325-
self._type, self._dst_ip_addr, self._dst_port, self._tenant_id, self._site_id, self._device_id)
332+
return "{0}://{1}:{2}{3}/{4}/{5}/{6}/post_file".format(
333+
self._type, self._dst_ip_addr, self._dst_port,
334+
dst_url_path, self._tenant_id, self._site_id, self._device_id)
326335

327336
def set_max_posts(self, max_posts):
328337
self._max_posts = max_posts
@@ -363,6 +372,15 @@ def set_export_from_dir_params(
363372

364373
self._export_from_dir_params = json
365374

375+
def set_header_fields(self, header_fields_json):
376+
# This function is used to add custom header fields to the post requests created by EMU.
377+
# The JSON should have the following format:
378+
# {
379+
# "header_1": "value 1",
380+
# "header_2": "value_2"
381+
# }
382+
if header_fields_json:
383+
self._header_fields = json.loads(header_fields_json)
366384

367385
###############################################################
368386
# Plugin

scripts/automation/trex_control_plane/interactive/trex/utils/parsing_opts.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,6 +1543,13 @@ class OPTIONS_DB_ARGS:
15431543
'dest': "http_devices_per_site",
15441544
'help': "Number of devices per site to be used in dst url"})
15451545

1546+
IPFIX_HTTP_HEADER_FIELDS_JSON_FILE = ArgumentPack(
1547+
['--header-fields-json-file'],
1548+
{'type': str,
1549+
'default': None,
1550+
'dest': "header_fields_json_file",
1551+
'help': "JSON file defining custom HTTP header fields to add to the post requests created by EMU"})
1552+
15461553
IPFIX_UDP_PACKETS_WAIT_TIME = ArgumentPack(
15471554
['--udp-packets-wait-time'],
15481555
{'type': str,

0 commit comments

Comments
 (0)