Skip to content

Commit b5e5699

Browse files
committed
Merge branch 'develop' for 0.20.1
2 parents ff91ba2 + 4badde2 commit b5e5699

File tree

13 files changed

+184
-63
lines changed

13 files changed

+184
-63
lines changed

build/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ prettytable==3.3.0 ; python_full_version > "3.8.1" and python_version < "3.10"
8686
prometheus-client==0.14.1 ; python_full_version > "3.8.1" and python_version < "3.10"
8787
prompt-toolkit==3.0.29 ; python_full_version > "3.8.1" and python_version < "3.10"
8888
protobuf==3.20.3 ; python_full_version > "3.8.1" and python_version < "3.10"
89+
psutil==5.9.4 ; python_full_version > "3.8.1" and python_version < "3.10"
8990
ptyprocess==0.7.0 ; python_full_version > "3.8.1" and python_version < "3.10" and os_name != "nt" or python_full_version > "3.8.1" and python_version < "3.10" and sys_platform != "win32"
9091
py==1.11.0 ; python_full_version > "3.8.1" and python_version < "3.10" and implementation_name == "pypy"
9192
pyarrow==10.0.1 ; python_full_version > "3.8.1" and python_version < "3.10"

docs/release-notes.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Release Notes
22

3+
## 0.20.1 (Feb 22, 2023)
4+
5+
This is a bugfix release. The main changes in this release including the bug fixes are:
6+
7+
* Memory leak caused by one of the libraries we use has been eliminated by working around the leak in our code.
8+
* EOS interfaces that were in err-disabled or unconnected state were incorrectly marked as being admin down as well. Now, the admin state is shown correctly.
9+
* Displaying the processor and memory of the device on which the poller is running. This is displayed during the poller startup. A warning message is also printed if the server specifications are not optimal for running SuzieQ. This optimality is based on assumptions about the network such as devices, the amount of state per device etc. Individual user experience maybe different.
10+
* Reduced the number of outstanding commands per device to be always 1 for IOS/IOSXE. This is to avoid the outputs getting mixed up accidentally. This is a rare event, but nevertheless we want to eliminate it.
11+
312
## 0.20.0 (Feb 2, 2023)
413

514
This is largely a major bug fix release, fixing many parser issues, documentation updates. The main major addition is support for Junos EVO platforms. Among the major bug fixes are:

poetry.lock

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "suzieq"
3-
version = "0.20.0"
3+
version = "0.20.1"
44
description = "A framework and application for network observability"
55
readme = 'README.md'
66
repository = 'https://github.com/netenglabs/suzieq'
@@ -49,6 +49,7 @@ ciscoconfparse = "^1.6.21"
4949
notebook = "6.4.12"
5050
urllib3 = "^1.26.12"
5151
packaging = "^21.3"
52+
psutil = "^5.9.4"
5253

5354
[tool.poetry.dev-dependencies]
5455
pylint = "*"

suzieq/poller/sq_poller.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
from suzieq.shared.exceptions import InventorySourceError, PollingError, \
1616
SqPollerConfError
1717
from suzieq.shared.utils import (poller_log_params, init_logger,
18-
load_sq_config, print_version)
18+
load_sq_config, print_version,
19+
log_suzieq_info)
1920
from suzieq.poller.controller.utils.inventory_utils import read_inventory
2021

2122

@@ -45,6 +46,8 @@ async def start_controller(user_args: argparse.Namespace, config_data: Dict):
4546
read_inventory(user_args.inventory)
4647
print('Inventory syntax check passed')
4748
return
49+
50+
log_suzieq_info('Poller Controller', logger, show_more=True)
4851
controller = Controller(user_args, config_data)
4952
controller.init()
5053
await controller.run()

suzieq/poller/worker/nodes/node.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,10 +528,14 @@ def _set_devtype(self, devtype: str, version_str: str) -> None:
528528
elif self.devtype == "eos":
529529
self.__class__ = EosNode
530530
elif self.devtype == "iosxe":
531+
# Since we need to create one single interactive session with
532+
# ios and iosxe, we cannot concurrently issue commands
533+
self.batch_size = 1
531534
self.__class__ = IosXENode
532535
elif self.devtype == "iosxr":
533536
self.__class__ = IosXRNode
534537
elif self.devtype == "ios":
538+
self.batch_size = 1
535539
self.__class__ = IOSNode
536540
elif self.devtype.startswith("junos"):
537541
self.__class__ = JunosNode

suzieq/poller/worker/services/bgp.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
from datetime import datetime
33
from copy import deepcopy
44

5-
from dateparser import parse
65
import numpy as np
76

87
from suzieq.poller.worker.services.service import Service
98
from suzieq.shared.utils import (get_timestamp_from_cisco_time,
109
get_timestamp_from_junos_time,
11-
convert_asndot_to_asn)
10+
convert_asndot_to_asn,
11+
parse_relative_timestamp)
1212

1313

1414
# pylint: disable=too-many-statements
@@ -46,11 +46,8 @@ def _clean_eos_data(self, processed_data, raw_data):
4646
entry['keepaliveTime'] = entry['configKeepalive']
4747
continue
4848

49-
estdTime = parse(
50-
entry.get('estdTime', ''),
51-
settings={'RELATIVE_BASE':
52-
datetime.fromtimestamp(
53-
(raw_data[0]['timestamp'])/1000), })
49+
estdTime = parse_relative_timestamp(
50+
entry.get('estdTime', ''), raw_data[0]['timestamp'], ms=True)
5451

5552
if 'EVPN' in entry.get('afi', []):
5653
afidx = entry['afi'].index('EVPN')
@@ -81,7 +78,7 @@ def _clean_eos_data(self, processed_data, raw_data):
8178
new_entry['rrclient'] = True
8279
else:
8380
new_entry['rrclient'] = False
84-
new_entry['estdTime'] = int(estdTime.timestamp()*1000)
81+
new_entry['estdTime'] = estdTime
8582
if entry['pfxBestRx']:
8683
# Depending on the moodiness of the output, this field
8784
# may not be present. So, ignore it.
@@ -448,13 +445,10 @@ def _clean_iosxr_data(self, processed_data, raw_data):
448445
entry['afi'] = entry['afi'].lower()
449446
if entry.get('safi', ''):
450447
entry['safi'] = entry['safi'].lower()
451-
estdTime = parse(
452-
entry.get('estdTime', ''),
453-
settings={'RELATIVE_BASE':
454-
datetime.fromtimestamp(
455-
(raw_data[0]['timestamp'])/1000), })
448+
estdTime = parse_relative_timestamp(
449+
entry.get('estdTime', ''), raw_data[0]['timestamp'], ms=True)
456450
if estdTime:
457-
entry['estdTime'] = int(estdTime.timestamp()*1000)
451+
entry['estdTime'] = estdTime
458452
entry['routerId'] = vrf_rtrid.get(entry['vrf'], '')
459453
if entry.get('rrclient', '') == '':
460454
entry['rrclient'] = 'False'

suzieq/poller/worker/services/interfaces.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
from datetime import datetime
33
from collections import defaultdict
44
from json import loads
5-
from dateparser import parse
65
import numpy as np
76

87
from suzieq.poller.worker.services.service import Service
98
from suzieq.shared.utils import (get_timestamp_from_junos_time,
10-
expand_ios_ifname, expand_nxos_ifname)
11-
from suzieq.shared.utils import convert_macaddr_format_to_colon
9+
expand_ios_ifname, expand_nxos_ifname,
10+
convert_macaddr_format_to_colon,
11+
parse_relative_timestamp)
1212
from suzieq.shared.utils import MISSING_SPEED, NO_SPEED, MISSING_SPEED_IF_TYPES
1313

1414

@@ -151,11 +151,9 @@ def _clean_eos_data(self, processed_data, _):
151151
adm_state = entry.get('adminState', 'down')
152152
if adm_state == 'notconnect':
153153
entry['reason'] = 'notconnect'
154-
entry['adminState'] = 'down'
155154
entry['state'] = 'notConnected'
156155
elif adm_state == 'errdisabled':
157156
entry['reason'] = 'errdisabled'
158-
entry['adminState'] = 'down'
159157
entry['state'] = 'errDisabled'
160158
elif adm_state == 'connected':
161159
entry['adminState'] = 'up'
@@ -590,14 +588,10 @@ def fix_nxos_speed(entry):
590588
if any(x in lastChange for x in 'dwmy'):
591589
lastChange = f'{lastChange} hours ago'
592590

593-
lastChange = parse(
594-
lastChange,
595-
settings={'RELATIVE_BASE': datetime.fromtimestamp(
596-
(raw_data[0]['timestamp'])/1000),
597-
'TIMEZONE': 'UTC'})
591+
lastChange = parse_relative_timestamp(
592+
lastChange, raw_data[0]['timestamp'], ms=True)
598593
if lastChange:
599-
old_entry['statusChangeTimestamp'] = int(
600-
lastChange.timestamp() * 1000)
594+
old_entry['statusChangeTimestamp'] = lastChange
601595
else:
602596
old_entry['statusChangeTimestamp'] = 0
603597
old_entry['description'] = entry.get('description', '')
@@ -895,14 +889,12 @@ def _clean_iosxr_data(self, processed_data, raw_data):
895889
entry['interfaceMac'] = convert_macaddr_format_to_colon(
896890
entry.get('interfaceMac', '0000.0000.0000'))
897891

898-
lastChange = parse(
892+
lastChange = parse_relative_timestamp(
899893
entry.get('statusChangeTimestamp', ''),
900-
settings={'RELATIVE_BASE':
901-
datetime.fromtimestamp(
902-
(raw_data[0]['timestamp'])/1000), })
894+
raw_data[0]['timestamp'], ms=True)
895+
903896
if lastChange:
904-
entry['statusChangeTimestamp'] = int(lastChange.timestamp()
905-
* 1000)
897+
entry['statusChangeTimestamp'] = lastChange
906898
if 'ipAddressList' not in entry:
907899
entry['ipAddressList'] = []
908900
entry['ip6AddressList'] = []

suzieq/poller/worker/services/routes.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import re
2-
from datetime import datetime
3-
4-
from dateparser import parse
52
import numpy as np
63

74
from suzieq.poller.worker.services.service import Service
85
from suzieq.shared.utils import (expand_nxos_ifname,
96
get_timestamp_from_cisco_time,
10-
get_timestamp_from_junos_time)
7+
get_timestamp_from_junos_time,
8+
parse_relative_timestamp)
119

1210

1311
class RoutesService(Service):
@@ -289,11 +287,8 @@ def _clean_iosxr_data(self, processed_data, raw_data):
289287
lastchange = lastchange.split(':')
290288
lastchange = (f'{lastchange[0]} hour '
291289
f'{lastchange[1]}:{lastchange[2]} mins ago')
292-
lastchange = parse(
293-
lastchange,
294-
settings={'RELATIVE_BASE':
295-
datetime.fromtimestamp(
296-
(raw_data[0]['timestamp'])/1000), })
290+
lastchange = parse_relative_timestamp(
291+
lastchange, raw_data[0]['timestamp'], ms=True)
297292
if lastchange:
298293
entry['statusChangeTimestamp'] = lastchange.timestamp()*1000
299294
else:

suzieq/poller/worker/sq_worker.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
from typing import Dict
99

1010
import uvloop
11+
1112
from suzieq.poller.worker.worker import Worker
1213
from suzieq.poller.worker.writers.output_worker import OutputWorker
1314
from suzieq.shared.exceptions import InventorySourceError, SqPollerConfError
14-
from suzieq.shared.utils import init_logger, load_sq_config, poller_log_params
15+
from suzieq.shared.utils import (init_logger, load_sq_config, log_suzieq_info,
16+
poller_log_params)
1517

1618

1719
async def start_worker(userargs: argparse.Namespace, cfg: Dict):
@@ -29,6 +31,7 @@ async def start_worker(userargs: argparse.Namespace, cfg: Dict):
2931
logger = init_logger('suzieq.poller.worker', logfile,
3032
loglevel, logsize, log_stdout)
3133

34+
log_suzieq_info('Poller Worker', logger)
3235
worker = None
3336
try:
3437
worker = Worker(userargs, cfg)

0 commit comments

Comments
 (0)