Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #3

Merged
merged 2 commits into from
May 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions aionet/connections/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async def read(self):
""" read from buffer """
raise NotImplementedError("Connection must implement read method ")

async def read_until_pattern(self, pattern, re_flags=0):
async def read_until_pattern(self, pattern, re_flags=0, read_for=0):
"""Read channel until pattern detected. Return ALL data available"""

if pattern is None:
Expand All @@ -69,8 +69,10 @@ async def read_until_pattern(self, pattern, re_flags=0):

fut = self.read()
try:
output += await asyncio.wait_for(fut, self._timeout)
output += await asyncio.wait_for(fut, read_for or self._timeout)
except asyncio.TimeoutError:
if read_for:
return output
raise TimeoutError(self._host)

for exp in pattern:
Expand All @@ -82,11 +84,11 @@ async def read_until_pattern(self, pattern, re_flags=0):
)
return output

async def read_until_prompt(self):
async def read_until_prompt(self, read_for=0):
""" read util prompt """
return await self.read_until_pattern(self._base_pattern)
return await self.read_until_pattern(self._base_pattern, read_for=read_for)

async def read_until_prompt_or_pattern(self, pattern, re_flags=0):
async def read_until_prompt_or_pattern(self, pattern, re_flags=0, read_for=0):
""" read util prompt or pattern """

logger.info("Host {}: Reading until prompt or pattern".format(self._host))
Expand All @@ -97,4 +99,4 @@ async def read_until_prompt_or_pattern(self, pattern, re_flags=0):
pattern = [self._base_prompt] + pattern
else:
raise ValueError("pattern must be string or list of strings")
return await self.read_until_pattern(pattern=pattern, re_flags=re_flags)
return await self.read_until_pattern(pattern=pattern, re_flags=re_flags, read_for=read_for)
6 changes: 3 additions & 3 deletions aionet/connections/ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import asyncio
import asyncssh
from aionet.constants import TERM_LEN, TERM_WID, TERM_TYPE
from aionet.exceptions import AionetAuthenticationError
from aionet.exceptions import AionetAuthenticationError, AionetTimeoutError
from aionet.connections.base import BaseConnection


Expand All @@ -14,7 +14,7 @@ def __init__(self,
username=u"",
password=u"",
port=22,
timeout=15,
timeout=30,
loop=None,
known_hosts=None,
local_addr=None,
Expand Down Expand Up @@ -81,7 +81,7 @@ async def connect(self):
except asyncssh.DisconnectError as e:
raise AionetAuthenticationError(self._host, e.code, e.reason)
except asyncio.TimeoutError:
raise TimeoutError(self._host)
raise AionetTimeoutError('timeout while connecting to %r' % self._host)

await self._start_session()

Expand Down
37 changes: 26 additions & 11 deletions aionet/vendors/devices/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class BaseDevice(object):

def __init__(
self,
host=u"",
ip=u"",
username=u"",
password=u"",
port=None,
Expand All @@ -43,7 +43,7 @@ def __init__(
"""
Initialize base class for asynchronous working with network devices

:param host: device hostname or ip address for connection
:param ip: ip address for connection
:param username: username for logging to device
:param password: user password for logging to device
:param port: port number. Default is 22 for ssh and 23 for telnet
Expand Down Expand Up @@ -121,8 +121,8 @@ def __init__(
:type compression_algs: list[str]
:type signature_algs: list[str]
"""
if host:
self.host = host
if ip:
self.host = ip
else:
raise ValueError("Host must be set")

Expand Down Expand Up @@ -246,7 +246,7 @@ async def _disable_paging(self):
""" disable terminal pagination """
self._logger.info(
"Disabling Pagination, command = %r" % type(self)._disable_paging_command)
await self._send_command_expect(type(self)._disable_paging_command)
await self.send_command_expect(type(self)._disable_paging_command)

async def _set_base_prompt(self):
"""
Expand Down Expand Up @@ -294,6 +294,21 @@ async def _find_prompt(self):
self._logger.debug("Found Prompt: %s" % repr(prompt))
return prompt

async def send_command_timing(self,
command_string,
read_for_seconds=2):
"""
send command and keep reading for the specified time in wait or until_prompt
:param command_string: command
:type command_string: str
:param read_for_seconds: seconds of reading
:type read_for_seconds: int
:return: command output
"""

output = await self.send_command_expect(command_string, read_for=read_for_seconds)
return output

async def send_command(
self,
command_string,
Expand Down Expand Up @@ -323,7 +338,7 @@ async def send_command(
"Send command: %s" % repr(command_string)
)

output = await self._send_command_expect(command_string, pattern, re_flags)
output = await self.send_command_expect(command_string, pattern, re_flags)

# Some platforms have ansi_escape codes
if self._ansi_escape_codes:
Expand Down Expand Up @@ -393,18 +408,18 @@ def _normalize_cmd(command):

async def send_new_line(self, pattern='', dont_read=False):
""" Sending new line """
return await self._send_command_expect('\n', pattern=pattern, dont_read=dont_read)
return await self.send_command_expect('\n', pattern=pattern, dont_read=dont_read)

async def _send_command_expect(self, command, pattern='', re_flags=0, dont_read=False):
async def send_command_expect(self, command, pattern='', re_flags=0, dont_read=False, read_for=0):
""" Send a single line of command and readuntil prompte"""
self._conn.send(self._normalize_cmd(command))
if dont_read:
return ''
if pattern:
output = await self._conn.read_until_prompt_or_pattern(pattern, re_flags)
output = await self._conn.read_until_prompt_or_pattern(pattern, re_flags, read_for=read_for)

else:
output = await self._conn.read_until_prompt()
output = await self._conn.read_until_prompt(read_for=read_for)

return output

Expand All @@ -426,7 +441,7 @@ async def send_config_set(self, config_commands=None):
self._logger.debug("Config commands: %s" % config_commands)
output = ""
for cmd in config_commands:
output += await self._send_command_expect(cmd)
output += await self.send_command_expect(cmd)

if self._ansi_escape_codes:
output = self._strip_ansi_escape_codes(output)
Expand Down
2 changes: 1 addition & 1 deletion aionet/vendors/devices/base_junos.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ async def send_config_set(
if commit_comment:
commit = type(self)._commit_comment_command.format(commit_comment)

output += await self._send_command_expect(commit)
output += await self.send_command_expect(commit)

if exit_config_mode:
output += await self.config_mode.exit()
Expand Down
2 changes: 1 addition & 1 deletion aionet/vendors/devices/cisco/cisco_asa.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async def _session_preparation(self):
async def _check_multiple_mode(self):
"""Check mode multiple. If mode is multiple we adding info about contexts"""
self._logger.info("Checking multiple mode")
out = await self._send_command_expect("show mode")
out = await self.send_command_expect("show mode")
if "multiple" in out:
self._multiple_mode = True

Expand Down
10 changes: 5 additions & 5 deletions aionet/vendors/devices/cisco/cisco_iosxr.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,18 @@ async def send_config_set(
if commit_comment:
commit = type(self)._commit_comment_command.format(commit_comment)

output += await self._send_command_expect(
output += await self.send_command_expect(
commit,
pattern=r"Do you wish to proceed with this commit anyway\?"
)
if "Failed to commit" in output:
show_config_failed = type(self)._show_config_failed
reason = await self._send_command_expect(show_config_failed)
reason = await self.send_command_expect(show_config_failed)
raise AionetCommitError(self.host, reason)
if "One or more commits have occurred" in output:
show_commit_changes = type(self)._show_commit_changes
await self._send_command_expect('no')
reason = await self._send_command_expect(show_commit_changes)
await self.send_command_expect('no')
reason = await self.send_command_expect(show_commit_changes)
raise AionetCommitError(self.host, reason)

if exit_config_mode:
Expand All @@ -86,5 +86,5 @@ async def send_config_set(
async def _cleanup(self):
""" Any needed cleanup before closing connection """
abort = type(self)._abort_command
await self._send_command_expect(abort)
await self.send_command_expect(abort)
self._logger.info("Cleanup session")
2 changes: 1 addition & 1 deletion aionet/vendors/devices/mikrotik/mikrotik_routeros.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async def _set_base_prompt(self):
async def _find_prompt(self):
"""Finds the current network device prompt, last line only."""
self._logger.info("Finding prompt")
prompt = await self._send_command_expect("\r")
prompt = await self.send_command_expect("\r")
prompt = prompt.strip()
if self._ansi_escape_codes:
prompt = self._strip_ansi_escape_codes(prompt)
Expand Down
2 changes: 1 addition & 1 deletion aionet/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
aionet Version information
"""

__version__ = "0.0.2"
__version__ = "0.0.3"
__author__ = "ali aqrabawi"
__author_email__ = "[email protected]"
__url__ = "http:https://aionet.readthedocs.io/"