Skip to content

Commit 5ea489e

Browse files
committed
Node: change how we look for prompt with IOS devices
Signed-off-by: Dinesh Dutt <[email protected]>
1 parent 4badde2 commit 5ea489e

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

suzieq/poller/worker/nodes/node.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import TypeVar, Dict, Callable, List
1+
from typing import TypeVar, Dict, Callable, List, Optional
22
from abc import abstractmethod
33
from collections import defaultdict
44
import time
@@ -119,7 +119,7 @@ async def initialize(self, **kwargs) -> TNode:
119119
self._conn_lock = asyncio.Lock()
120120
self._last_exception = None
121121
self._exception_timestamp = None
122-
self._current_exception = None
122+
self._current_exception: Optional[Exception] = None
123123
self.api_key = None
124124
self._fetching_dev_data = False # If we are fetching the dev data
125125
self._stdin = self._stdout = self._long_proc = None
@@ -141,7 +141,7 @@ async def initialize(self, **kwargs) -> TNode:
141141
self.ssh_config_file = kwargs.get("ssh_config_file", None)
142142
self.enable_password = kwargs.get('enable_password')
143143

144-
passphrase = kwargs.get("passphrase", None)
144+
passphrase: str = kwargs.get("passphrase", None)
145145
jump_host = kwargs.get("jump_host", "")
146146
if jump_host:
147147
jump_result = urlparse(jump_host)
@@ -230,7 +230,7 @@ def last_exception(self) -> Exception:
230230
return self._last_exception
231231

232232
@property
233-
def current_exception(self) -> Exception:
233+
def current_exception(self) -> Optional[Exception]:
234234
'''The current exception faced on this device'''
235235
return self._current_exception
236236

@@ -1665,7 +1665,7 @@ def _extract_nos_version(self, data) -> None:
16651665

16661666
class IosXENode(Node):
16671667
'''IOS-XE Node-sepcific telemetry gather implementation'''
1668-
WAITFOR = r'.*[>#]\s*$' # devtype specific termination sequence
1668+
IOS_DEFAULT_PROMPT = ('>', '#') # devtype specific termination sequence
16691669

16701670
async def _rest_connect(self):
16711671
raise NotImplementedError(
@@ -1678,6 +1678,7 @@ async def _rest_gather(self, service_callback, cmd_list, cb_token,
16781678

16791679
async def _fetch_init_dev_data_devtype(self, reconnect: bool):
16801680
"""Fill in the boot time of the node by executing certain cmds"""
1681+
self.prompt = self.IOS_DEFAULT_PROMPT
16811682
await self._exec_cmd(self._parse_init_dev_data,
16821683
["show version"], None, 'text',
16831684
reconnect=reconnect)
@@ -1701,6 +1702,8 @@ async def _ssh_connect(self):
17011702
output = await self.wait_for_prompt()
17021703
if output.strip().endswith('>'):
17031704
if await self._handle_privilege_escalation() == -1:
1705+
self.logger.error(f'{self.address}:{self.port}: '
1706+
'Privilege escalation failed')
17041707
await self._close_connection()
17051708
self._conn = None
17061709
self._stdin = None
@@ -1719,7 +1722,7 @@ async def _ssh_connect(self):
17191722

17201723
# Set the terminal length to 0 to avoid paging
17211724
self._stdin.write('terminal length 0\n')
1722-
output = await self._stdout.readuntil(self.WAITFOR)
1725+
output = await self._stdout.readuntil(self.prompt)
17231726

17241727
async def _handle_privilege_escalation(self) -> int:
17251728
'''Escalata privilege if necessary
@@ -1729,7 +1732,13 @@ async def _handle_privilege_escalation(self) -> int:
17291732
self.logger.info(
17301733
f'Privilege escalation required for {self.hostname}')
17311734
self._stdin.write('enable\n')
1732-
output = await self.wait_for_prompt(r'Password:\s*')
1735+
output = await self.wait_for_prompt(('Password:', '%'))
1736+
if '%' in output:
1737+
self.logger.error('Privilege escalation failed, Aborting')
1738+
self.current_exception = PollingError(
1739+
'Privilege Escalation Failed')
1740+
return -1
1741+
17331742
if self.enable_password:
17341743
self._stdin.write(self.enable_password + '\n')
17351744
else:
@@ -1739,8 +1748,8 @@ async def _handle_privilege_escalation(self) -> int:
17391748
if (output in ['suzieq timeout', 'Password:'] or
17401749
output.strip().endswith('>')):
17411750
self.logger.error(
1742-
f'Privilege escalation failed for {self.hostname}'
1743-
', Aborting connection')
1751+
f'{self.address}:{self.port} Privilege escalation failed, '
1752+
'Aborting connection')
17441753
return -1
17451754

17461755
self.logger.info(f'Privilege escalation succeeded for {self.hostname}')
@@ -1762,7 +1771,7 @@ async def wait_for_prompt(self, prompt: str = None,
17621771
the output data or 'timeout'
17631772
"""
17641773
if prompt is None:
1765-
prompt = self.WAITFOR
1774+
prompt = self.prompt
17661775
coro = self._stdout.readuntil(prompt)
17671776
try:
17681777
output = await asyncio.wait_for(coro, timeout=timeout)
@@ -1772,6 +1781,8 @@ async def wait_for_prompt(self, prompt: str = None,
17721781
self.logger.error(f'{self.address}.{self.port} '
17731782
'Timed out waiting for expected prompt')
17741783
# Return something that won't ever be in real output
1784+
await self._close_connection()
1785+
self.prompt = self.IOS_DEFAULT_PROMPT
17751786
return 'suzieq timeout'
17761787

17771788
async def _parse_init_dev_data_devtype(self, output, cb_token) -> None:
@@ -1786,6 +1797,9 @@ async def _parse_init_dev_data_devtype(self, output, cb_token) -> None:
17861797
hostupstr = re.search(r'(\S+)\s+uptime is (.*)\n', data)
17871798
if hostupstr:
17881799
self._set_hostname(hostupstr.group(1))
1800+
self.prompt = tuple(f'{self.hostname}{x}'
1801+
for x in self.IOS_DEFAULT_PROMPT)
1802+
17891803
timestr = hostupstr.group(2)
17901804
self.bootupTimestamp = parse_relative_timestamp(
17911805
timestr, output[0]['cmd_timestamp'] / 1000)
@@ -1832,7 +1846,7 @@ async def _ssh_gather(self, service_callback, cmd_list, cb_token, oformat,
18321846

18331847
cmd_timestamp = time.time()
18341848
self._stdin.write(cmd + '\n')
1835-
output = await self.wait_for_prompt()
1849+
output = await self.wait_for_prompt(timeout=timeout)
18361850
if 'Invalid input detected' in output:
18371851
status = -1
18381852
elif 'suzieq timeout' in output:

0 commit comments

Comments
 (0)