Full Code of selfuryon/netdev for AI

master 037abbd0ca65 cached
86 files
183.3 KB
42.4k tokens
270 symbols
1 requests
Download .txt
Showing preview only (203K chars total). Download the full file or copy to clipboard to get everything.
Repository: selfuryon/netdev
Branch: master
Commit: 037abbd0ca65
Files: 86
Total size: 183.3 KB

Directory structure:
gitextract_r978uqi3/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── ask_question.md
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .readthedocs.yml
├── CONTRIBUTING.rst
├── LICENSE
├── README.rst
├── docs/
│   ├── api.rst
│   ├── conf.py
│   ├── examples.rst
│   ├── index.rst
│   └── overview.rst
├── examples/
│   ├── alcatel_aos.py
│   ├── arista_eos.py
│   ├── aruba_aos_6.py
│   ├── aruba_aos_8.py
│   ├── cisco_asa.py
│   ├── cisco_ios.py
│   ├── cisco_iosxr.py
│   ├── cisco_nxos.py
│   ├── cisco_sg3xx.py
│   ├── fujitsu_switch.py
│   ├── hp_comware.py
│   ├── hp_comware_limited.py
│   ├── juniper_junos.py
│   ├── mikrotik_routeros.py
│   └── terminal.py
├── netdev/
│   ├── __init__.py
│   ├── dispatcher.py
│   ├── exceptions.py
│   ├── logger.py
│   ├── vendors/
│   │   ├── __init__.py
│   │   ├── alcatel/
│   │   │   ├── __init__.py
│   │   │   └── alcatel_aos.py
│   │   ├── arista/
│   │   │   ├── __init__.py
│   │   │   └── arista_eos.py
│   │   ├── aruba/
│   │   │   ├── __init__.py
│   │   │   ├── aruba_aos_6.py
│   │   │   └── aruba_aos_8.py
│   │   ├── base.py
│   │   ├── cisco/
│   │   │   ├── __init__.py
│   │   │   ├── cisco_asa.py
│   │   │   ├── cisco_ios.py
│   │   │   ├── cisco_iosxr.py
│   │   │   ├── cisco_nxos.py
│   │   │   └── cisco_sg3xx.py
│   │   ├── comware_like.py
│   │   ├── fujitsu/
│   │   │   ├── __init__.py
│   │   │   └── fujitsu_switch.py
│   │   ├── hp/
│   │   │   ├── __init__.py
│   │   │   ├── hp_comware.py
│   │   │   └── hp_comware_limited.py
│   │   ├── huawei/
│   │   │   ├── __init__.py
│   │   │   └── huawei.py
│   │   ├── infotecs/
│   │   │   ├── HW1000.py
│   │   │   └── __init__.py
│   │   ├── ios_like.py
│   │   ├── juniper/
│   │   │   ├── __init__.py
│   │   │   └── juniper_junos.py
│   │   ├── junos_like.py
│   │   ├── mikrotik/
│   │   │   ├── __init__.py
│   │   │   └── mikrotik_routeros.py
│   │   ├── terminal/
│   │   │   ├── __init__.py
│   │   │   └── terminal.py
│   │   └── ubiquiti/
│   │       ├── __init__.py
│   │       └── ubiquity_edge.py
│   └── version.py
├── pyproject.toml
└── tests/
    ├── test_arista_eos.py
    ├── test_aruba_aos_6.py
    ├── test_aruba_aos_8.py
    ├── test_cisco_asa.py
    ├── test_cisco_ios.py
    ├── test_cisco_iossg3xx.py
    ├── test_cisco_iosxr.py
    ├── test_cisco_nxos.py
    ├── test_fujitsu_switch.py
    ├── test_hp_comware.py
    ├── test_hp_comware_limited.py
    ├── test_huawei.py
    ├── test_hw1000.py
    ├── test_juniper_junos.py
    ├── test_mikrotik_routeros.py
    └── test_terminal.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/ask_question.md
================================================
---
name: Ask Question
about: Ask all information you want
---

**Question**

All what you want to know


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Report a bug in Netdev library
---

**Describe the bug**

A clear and concise description of what the bug is.

**General Information**

 - OS [e.g. Windows 10]
 - Netdev version [e.g. 0.9.0]
 - Device OS [e.g. Cisco IOS XE 3.4.6]

**Debug information**

I usually need a debug information for understanding what exactly happened. You can get it by using this code:

```python
import netdev
import logging

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)
```

**Additional context**

Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature Request
about: Feature Request in Netdev library
---

**Proposed functionality**


**Use case**


**Additional context**

Add any other context about the problem here.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
**Description**

Full description of purpose and all changes


================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Distribution / packaging
.Python
venv/
dist/
*.egg-info/
poetry.lock

# Unit tests
tests/*.log
*.yaml

# Docs
/docs/_build
/docs/[Mm]ake*

# Others
.idea/
.vscode/


================================================
FILE: .readthedocs.yml
================================================
---
version: 2

python:
  version: 3.7
  install:
      - method: pip
        path: .
        extra_requirements:
            - docs



================================================
FILE: CONTRIBUTING.rst
================================================
Contributing to Netdev
======================

You're welcome to contribute to this project.

Asking questions
----------------

You can always ask me any question about this project in:

* `twitter (@selfuryon) <https://twitter.com/selfuryon>`_
* telegram (@selfuryon)
* selfuryon@gmail.com

You can also use the `issue tracker <https://github.com/selfuryon/netdev/issues>`_ for asking.

Reporting bugs
--------------

For reporting bugs, you need to use the `issue tracker <https://github.com/selfuryon/netdev/issues>`_.
Before creating a new issue, please check the currently open issues to see
if your problem has already been reported.

Requesting feature enhancements
-------------------------------

The `issue tracker <https://github.com/selfuryon/netdev/issues>`_
should also be used to post feature enhancement requests.

Contributing code
-----------------

I haven't any restrictions about contributing code. I can create PR with any fixes and features
and you don't need to do anything else for it except PR. All PRs will be reviewed.

You should also know, that code is distributed by
using `3-clause BSD license <https://opensource.org/licenses/BSD-3-Clause>`_.

Branches
--------
I have two main branches:

* The master branch always has a latest stable version
  of the code. All commits on this branch are Releases.

* The develop branch is the main branch for implementing and testing new features and fixing bugs.
  If you have a heavy feature you can create a separate branch for that. All PR is merged only to develop branch

================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2019 Sergey Yakovlev

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: README.rst
================================================
THIS PROJECT IS UNMAINTAINED
****************************
I'm not interested in this project anymore, sorry. 
I don't work as an network engineer anymore so I haven't any special goals to improve and maintain it.

Netdev
******

Asynchronous multi-vendor library for interacting with network devices

Inspired by netmiko

Requires:
---------
* asyncio
* AsyncSSH
* Python >=3.5
* pyYAML
  
 
Supports:
---------
* Cisco IOS 
* Cisco IOS XE
* Cisco IOS XR
* Cisco ASA
* Cisco NX-OS
* Cisco SG3XX
* HP Comware (like V1910 too)
* Fujitsu Blade Switches
* Mikrotik RouterOS
* Arista EOS
* Juniper JunOS
* Aruba AOS 6.X
* Aruba AOS 8.X
* Terminal
* Alcatel AOS

Examples:
---------
Example of interacting with Cisco IOS devices:

.. code-block:: python

    import asyncio
    import netdev

    async def task(param):
        async with netdev.create(**param) as ios:
            # Testing sending simple command
            out = await ios.send_command("show ver")
            print(out)
            # Testing sending configuration set
            commands = ["line console 0", "exit"]
            out = await ios.send_config_set(commands)
            print(out)
            # Testing sending simple command with long output
            out = await ios.send_command("show run")
            print(out)
            # Testing interactive dialog
            out = await ios.send_command("conf", pattern=r'\[terminal\]\?', strip_command=False)
            out += await ios.send_command("term", strip_command=False)
            out += await ios.send_command("exit", strip_command=False, strip_prompt=False)
            print(out)


    async def run():
        dev1 = { 'username' : 'user',
                 'password' : 'pass',
                 'device_type': 'cisco_ios',
                 'host': 'ip address',
        }
        dev2 = { 'username' : 'user',
                 'password' : 'pass',
                 'device_type': 'cisco_ios',
                 'host': 'ip address',
        }
        devices = [dev1, dev2]
        tasks = [task(dev) for dev in devices]
        await asyncio.wait(tasks)


    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())




================================================
FILE: docs/api.rst
================================================
.. module:: netdev

.. _API:

API Documentation
*****************

Overview
========

You should use separate class for each device vendor.
For this purpose are used Factory method :func:`create`. You should specify device_type in params
for taking right class


Factory method
==============

.. autofunction:: create

.. module:: netdev.vendors

Classes
=======

Base classes
------------
These classes are abstract and used as parent by other classes:

BaseDevice
~~~~~~~~~~

.. autoclass:: BaseDevice
   :members:
   :special-members: __init__

IOSLikeDevice
~~~~~~~~~~~~~

.. autoclass:: IOSLikeDevice
   :members:
   :inherited-members:

ComwareLikeDevice
~~~~~~~~~~~~~~~~~

.. autoclass:: ComwareLikeDevice
   :members:
   :inherited-members:


JunOSLikeDevice
~~~~~~~~~~~~~~~

.. autoclass:: JunOSLikeDevice
   :members:
   :inherited-members:

End classes
-----------
These classes are using for particular connection to end devices

CiscoIOS
~~~~~~~~

.. autoclass:: CiscoIOS
   :members:
   :inherited-members:

CiscoIOSXR
~~~~~~~~~~

.. autoclass:: CiscoIOSXR
   :members:
   :inherited-members:

CiscoASA
~~~~~~~~

.. autoclass:: CiscoASA
   :members:
   :inherited-members:

CiscoNXOS
~~~~~~~~~

.. autoclass:: CiscoNXOS
   :members:
   :inherited-members:

CiscoSG3XX
~~~~~~~~~

.. autoclass:: CiscoSG3XX
   :members:
   :inherited-members:

FujitsuSwitch
~~~~~~~~~~~~~

.. autoclass:: FujitsuSwitch
   :members:
   :inherited-members:

HPComware
~~~~~~~~~

.. autoclass:: HPComware
   :members:
   :inherited-members:

HPComwareLimited
~~~~~~~~~~~~~~~~

.. autoclass:: HPComwareLimited
   :members:
   :inherited-members:

MikrotikRouterOS
~~~~~~~~~~~~~~~~

.. autoclass:: MikrotikRouterOS
   :members:
   :inherited-members:

AristaEOS
~~~~~~~~~

.. autoclass:: AristaEOS
   :members:
   :inherited-members:

ArubaAOS6
~~~~~~~~~

.. autoclass:: ArubaAOS6
   :members:
   :inherited-members:

JuniperJunOS
~~~~~~~~~~~~

.. autoclass:: JuniperJunOS
   :members:
   :inherited-members:

Terminal
~~~~~~~~

.. autoclass:: Terminal
   :members:
   :inherited-members:

AlcatelAOS
~~~~~~~~

.. autoclass:: AlcatelAOS
   :members:
   :inherited-members:


================================================
FILE: docs/conf.py
================================================
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# netdev documentation build configuration file, created by
# sphinx-quickstart on Sun Jul 17 21:52:23 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import os
import sys

import sphinx_rtd_theme

html_theme = 'sphinx_rtd_theme'

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('..'))

from netdev import __version__, __author__

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', ]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'

# The encoding of source files.
# source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'netdev'
copyright = '2016, {}'.format(__author__)
author = __author__

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '.'.join(__version__.split('.')[:2])
# The full version, including alpha/beta/rc tags.
release = __version__

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['_build']

# The reST default role (used for this markup: `text`) to use for all
# documents.
# default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []

# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.



# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
# html_theme_options = {'display_version': True}

# Add any paths that contain custom themes here, relative to this directory.
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

# The name for this set of Sphinx documents.  If None, it defaults to
# "<project> v<release> documentation".
# html_title = None

# A shorter title for the navigation bar.  Default is the same as html_title.
# html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = None

# The name of an image file (within the static path) to use as favicon of the
# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
# html_favicon = None

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
# html_extra_path = []

# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
# html_last_updated_fmt = '%b %d, %Y'

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}

# Additional templates that should be rendered to pages, maps page names to
# template names.
# html_additional_pages = {}

# If false, no module index is generated.
# html_domain_indices = True

# If false, no index is generated.
# html_use_index = True

# If true, the index is split into individual pages for each letter.
# html_split_index = False

# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None

# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
#   'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
#   'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr'
# html_search_language = 'en'

# A dictionary with options for the search language support, empty by default.
# Now only 'ja' uses this config value
# html_search_options = {'type': 'default'}

# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
# html_search_scorer = 'scorer.js'

# Output file base name for HTML help builder.
htmlhelp_basename = 'netdevdoc'

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {}  # The paper size ('letterpaper' or 'a4paper').# 'papersize': 'letterpaper',

    # The font size ('10pt', '11pt' or '12pt').# 'pointsize': '10pt',

    # Additional stuff for the LaTeX preamble.# 'preamble': '',

    # Latex figure (float) alignment# 'figure_align': 'htbp',}}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).}
latex_documents = [(master_doc, 'netdev.tex', 'netdev Documentation', 'Yakovlev Sergey', 'manual'), ]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False

# If true, show page references after internal links.
# latex_show_pagerefs = False

# If true, show URL addresses after external links.
# latex_show_urls = False

# Documents to append as an appendix to all manuals.
# latex_appendices = []

# If false, no module index is generated.
# latex_domain_indices = True


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, 'netdev', 'netdev Documentation', [author], 1)]

# If true, show URL addresses after external links.
# man_show_urls = False


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [(
master_doc, 'netdev', 'netdev Documentation', author, 'netdev', 'One line description of project.', 'Miscellaneous'), ]

# Documents to append as an appendix to all manuals.
# texinfo_appendices = []

# If false, no module index is generated.
# texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
# texinfo_no_detailmenu = False


# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/': None}


================================================
FILE: docs/examples.rst
================================================
.. _Examples:

Examples
********

In examples are used configuration files.
config.yaml:

.. code-block:: text

   device_list: credentials.yaml

credentials.yaml

.. code-block:: text

   - device_type: cisco_asa
     host: 1.1.1.1
     password: ****
     username: ****
   - device_type: cisco_ios
     host: 2.2.2.2
     password: ****
     username: ****
   - device_type: fujitsu_switch
     host: 3.3.3.3
     password: ****
     username: ****
   - device_type: hp_comware
     host: 4.4.4.4
     password: ****
     username: ****
   - device_type: hp_comware_limited
     host: 5.5.5.5
     password: ****
     username: ****
     cmdline_password: '512900'
   - device_type: arista_eos
     host: 6.6.6.6
     password: ****
     username: ****
   - device_type: juniper_junos
     host: 7.7.7.7
     password: ****
     username: ****

ASA example
-----------
.. literalinclude:: ../examples/cisco_asa.py

NX-OS example
-------------
.. literalinclude:: ../examples/cisco_nxos.py

IOS example
-----------
.. literalinclude:: ../examples/cisco_ios.py

IOS XR example
--------------
.. literalinclude:: ../examples/cisco_iosxr.py

IOS SG3XX example
--------------
.. literalinclude:: ../examples/cisco_sg3xx.py

Fujitsu example
---------------
.. literalinclude:: ../examples/fujitsu_switch.py

Comware example
---------------
.. literalinclude:: ../examples/hp_comware.py

Comware Limited example
-----------------------
.. literalinclude:: ../examples/hp_comware_limited.py

Mikrotik RouterOS example
-------------------------
.. literalinclude:: ../examples/mikrotik_routeros.py

Arista EOS example
------------------
.. literalinclude:: ../examples/arista_eos.py

Aruba AOS 6.X example
---------------------
.. literalinclude:: ../examples/aruba_aos_6.py

Juniper JunOS example
---------------------
.. literalinclude:: ../examples/juniper_junos.py

Terminal example
----------------
.. literalinclude:: ../examples/terminal.py

Alcatel AOS example
----------------
.. literalinclude:: ../examples/alcatel_aos.py

================================================
FILE: docs/index.rst
================================================
.. toctree::
   :hidden:
   :maxdepth: -1

   overview
   api
   examples

.. include:: ../README.rst


================================================
FILE: docs/overview.rst
================================================
.. module:: netdev

.. _overview:

Library information
*******************

Overview
========
Netdev is asynchronous multi-vendor library for interacting with network devices. So you can create many
simultaneous connection to network devices for parallel executing commands.

For creating connection to network device you should use function :func:`create` like this:

.. code-block:: python

   async def working_with_netdev():
      dev = netdev.create(host='host', username='username', password='password', device_type='device_type')
      await dev.connect() # Connecting and preparing session for working
      output = await dev.send_command('command') # working with command in privilege/user mode
      print(output)
      output = await dev.send_config_set(['first_command','second_command'] #working with commands in config mode
      print(output)
      await dev.disconnect() #disconnecting from device

   loop = asyncio.get_event_loop()
   loop.run_until_complete(working_with_netdev())

or the same with using async context manager:

.. code-block:: python

   async def working_with_netdev():
      async with netdev.create(host='host', username='username', password='password', device_type='device_type') as dev:
          output = await dev.send_command('command') # working with command in privilege/user mode
          print(output)
          output = await dev.send_config_set(['first_command','second_command'] #working with commands in config mode
          print(output)

   loop = asyncio.get_event_loop()
   loop.run_until_complete(working_with_netdev())


Library structure
=================

.. module:: netdev.vendors

Library consist from several base classes and end classes which using for communication.
The main class is :class:`BaseDevice`. It provides some basic functionality regardless of device type.
Library also have three common child classes: :class:`IOSLikeDevice`, :class:`ComwareLikeDevice`
and :class:`JunOSLikeDevice`.

:class:`IOSLikeDevice` class provides basic methods for Cisco IOS like devices: devices which have user exec,
privilege exec and conf mode concepts.

:class:`ComwareLikeDevice` class provides basic methods for HP Comware like devices: these devices have only
exec view and system view concepts.

:class:`JunOSLikeDevice` class provides basic methods for Juniper JunOS like devices: they have operation mode and
configuration mode concepts with committing changes.

All other classes are the end classes which you can use for working with particular device:

* :class:`MikrotikRouterOS`
* :class:`CiscoIOS`
* :class:`CiscoIOSXR`
* :class:`CiscoASA`
* :class:`CiscoNXOS`
* :class:`CiscoSG3XX`
* :class:`FujitsuSwitch`
* :class:`HPComware`
* :class:`HPComwareLimited`
* :class:`AristaEOS`
* :class:`JuniperJunOS`
* :class:`AlcatelAOS`

The particular class selected by parameter *device_type* in :func:`create`

Logging
=======

For debugging purpose library has :data:`logger` object. You can use it like this:

.. code-block:: python

    import netdev

    netdev_logger = netdev.logger
    netdev_logger.setLevel(logging.INFO)
    netdev_logger.addHandler(logging.StreamHandler())

    #Your own code

Common public methods and properties
====================================

Base classes have several common public methods.

Managing flow
-------------
For working with network device firstly you need to connect to device and after working you need
to disconnect from device. For this purpose are used these methods:

- :func:`BaseDevice.connect`
- :func:`BaseDevice.disconnect`

Sending commands
----------------
Some devices using mode principle: exists exec mode and configuration mode. Exec mode are used for getting some
information from device, configuration mode are used for configuration device. For this purpose netdev
have 2 basic methods:

- :func:`BaseDevice.send_command`

This method is used for sending specific command to device in exec mode. Basically for getting some information
from device

- :func:`BaseDevice.send_config_set`

This method are used for sending command list to device in configuration mode. Command list is the list of all commands
which configure device.


Some others
-----------

- :attr:`BaseDevice.base_prompt`
- :attr:`CiscoASA.current_context`
- :attr:`CiscoASA.multiple_mode`


================================================
FILE: examples/alcatel_aos.py
================================================
#!/usr/bin/env python3

# Import Python library
import asyncio, netdev

# Coroutine used for the tasks
async def task(param):

    # Create an object for the devices and open SSH connections
    async with netdev.create(**param) as device:

        # Testing sending simple command
        
        # Command to send
        cmd = "show system"

        # Sending command
        output = await device.send_command(cmd)

        # Display the output
        print(output)

        # Display separator
        print("*" * 80)

        # Testing sending configuration set

        # Commands to send
        commands = ["vlan 3000", "no vlan 3001"]

        # Sending command
        output = await device.send_config_set(commands)

        # Display the output
        print(output)


# Main coroutine
async def main():

    # Parameters of the network device
    my_device = {   'username' : 'LOGIN',
                    'password' : 'PASSWORD',
                    'host': 'IP_ADDRESS',
                    'device_type': 'alcatel_aos',
    }

    # List of devices
    devices = [my_device]
    
    # List of tasks
    my_tasks = [task(dev) for dev in devices]
    
    # Starting the coroutine of the tasks
    await asyncio.wait(my_tasks)


# Main function call
if __name__ == '__main__':

    # Run the main coroutine
    asyncio.run(main())

    '''
    Result:
    ********************************************************************************
    System:
    Description:  Alcatel-Lucent Enterprise OS6860E-48 8.4.1.141.R03 GA, December 07, 2017.,
    Object ID:    1.3.6.1.4.1.6486.801.1.1.2.1.11.1.7,
    Up Time:      5 days 5 hours 3 minutes and 56 seconds,
    Contact:      Alcatel-Lucent, http://enterprise.alcatel-lucent.com,
    Name:         switch01,
    Location:     Somewhere nearby,
    Services:     78,
    Date & Time:  SAT AUG 29 2020 18:48:53 (CEST)
    Flash Space:
        Primary CMM:
        Available (bytes):  933896192,
        Comments         :  None

    ********************************************************************************
    vlan 3000

    switch01 ==> no vlan 3001

    switch01 ==>

    ********************************************************************************

    '''

================================================
FILE: examples/arista_eos.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as arista:
        # Testing sending simple command
        out = await arista.send_command('show run', strip_command=True)
        print(out)
        # Testing sending configuration set
        commands = ["vlan 1", "exit"]
        out = await arista.send_config_set(commands)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'arista_eos']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/aruba_aos_6.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as ios:
        # Testing sending simple command
        out = await ios.send_command("show ver")
        print(out)
        # Testing sending configuration set
        commands = ["interface loopback", "exit"]
        out = await ios.send_config_set(commands)
        print(out)
        # Testing sending simple command with long output
        out = await ios.send_command("show run")
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'aruba_aos_6']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/aruba_aos_8.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as ios:
        # Testing sending simple command
        out = await ios.send_command("show ver")
        print(out)
        # Testing sending configuration set
        commands = ["interface loopback", "exit"]
        out = await ios.send_config_set(commands)
        print(out)
        # Testing sending simple command with long output
        out = await ios.send_command("show run")
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'aruba_aos_8']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/cisco_asa.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as asa:
        # Testing sending simple command
        out = await asa.send_command('show run')
        print(out)
        # Testing interactive dialog
        out = await asa.send_command("copy r scp:", pattern=r'\[running-config\]\?', strip_command=False)
        out += await asa.send_command("\n", pattern=r'\[\]\?', strip_command=False)
        out += await asa.send_command("\n", strip_command=False)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'cisco_asa']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/cisco_ios.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as ios:
        # Testing sending simple command
        out = await ios.send_command("show ver")
        print(out)
        # Testing sending configuration set
        commands = ["line console 0", "exit"]
        out = await ios.send_config_set(commands)
        print(out)
        # Testing sending simple command with long output
        out = await ios.send_command("show run")
        print(out)
        # Testing interactive dialog
        out = await ios.send_command("conf", pattern=r'\[terminal\]\?', strip_command=False)
        out += await ios.send_command("term", strip_command=False)
        out += await ios.send_command("exit", strip_command=False, strip_prompt=False)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'cisco_ios']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/cisco_iosxr.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as iosxr:
        # Testing sending simple command
        out = await iosxr.send_command("show ver")
        print(out)
        # Testing sending simple command with long output
        out = await iosxr.send_command("show run")
        print(out)
        # Testing sending configuration set
        commands = ["interface loopback 0", "description TEST LOOPBACK"]
        out = await iosxr.send_config_set(commands, with_commit=True)
        print(out)
        # Testing failed commit
        commands = ["interface GigabitEthernet 0/0/0/0", "service-policy input 1"]
        out = await iosxr.send_config_set(commands, with_commit=False)
        print(out)
        try:
            commands = ["interface GigabitEthernet 0/0/0/0", "service-policy input 2"]
            await iosxr.send_config_set(commands)
        except netdev.CommitError:
            print("Commit Error")


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'cisco_ios_xr']
    await asyncio.gather(*tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/cisco_nxos.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as nxos:
        # Testing sending simple command
        out = await nxos.send_command('show run', strip_command=True)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'cisco_nxos']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/cisco_sg3xx.py
================================================
#!/usr/bin/env python3

# Import Python library
import asyncio, netdev

# Coroutine used for the tasks
async def task(param):

    # Create an object for the devices and open SSH connections
    async with netdev.create(**param) as ios:

        # Testing sending simple command
        
        # Command to send
        cmd = "show clock"

        # Sending command
        output = await ios.send_command(cmd)

        # Display the output
        print(output)

# Main coroutine
async def main():

    # Parameters of the network device
    my_device = {   'username' : 'LOGIN',
                    'password' : 'PASSWORD',
                    'host': 'IP_ADDRESS',
                    'device_type': 'cisco_sg3xx',
    }

    # List of devices
    devices = [my_device]
    
    # List of tasks
    my_tasks = [task(dev) for dev in devices]
    
    # Starting the coroutine of the tasks
    await asyncio.wait(my_tasks)


# Main function call
if __name__ == '__main__':

    # Run the main coroutine
    asyncio.run(main())

    '''
    Result:
    ********************************************************************************
    .14:07:35 J  Aug 28 2020
    Time source is sntp
    Time from Browser is disabled
    ********************************************************************************

    '''

================================================
FILE: examples/fujitsu_switch.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)

async def task(param):
    async with netdev.create(**param) as fuj:
        # Testing sending configuration set
        out = await fuj.send_config_set(['vlan database', 'exit'])
        print(out)
        # Testing sending simple command
        out = await fuj.send_command('show ver')
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'fujitsu_switch']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/hp_comware.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as hp:
        # Testing sending simple command
        out = await hp.send_command('display ver')
        print(out)
        # Testing sending configuration set
        commands = ["Vlan 1", "quit"]
        out = await hp.send_config_set(commands)
        print(out)
        # Testing sending simple command with long output
        out = await hp.send_command('display cur')
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'hp_comware']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/hp_comware_limited.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as hp:
        # Testing sending simple command
        out = await hp.send_command('display ver')
        print(out)
        # Testing sending configuration set
        commands = ["Vlan 1", "quit"]
        out = await hp.send_config_set(commands)
        print(out)
        # Testing sending simple command with long output
        out = await hp.send_command('display cur')
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'hp_comware_limited']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/juniper_junos.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as junos:
        # Testing sending simple command
        out = await junos.send_command("show version")
        print(out)
        # Testing sending configuration set
        commands = ["edit system", "edit login"]
        out = await junos.send_config_set(commands, with_commit=True)
        print(out)
        # Testing sending simple command with long output
        out = await junos.send_command("show config")
        print(out)
        # Testing interactive dialog
        commands = ["set system login message 123", "delete system login message 123"]
        out = await junos.send_config_set(commands, with_commit=False, exit_config_mode=False)
        out += await junos.send_command("exit", pattern=r'Exit with uncommitted changes\?', strip_command=False)
        out += await junos.send_command("no", strip_command=False)
        out += await junos.send_command("rollback 0", strip_command=False)
        out += await junos.send_command("exit configuration-mode", strip_command=False)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'juniper_junos']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/mikrotik_routeros.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as routeros:
        # Testing sending simple command
        commands = ['/ip address', 'print', '/']
        for cmd in commands:
            print(await routeros.send_command(cmd))

        # Testing sending configuration set
        out = await routeros.send_config_set(commands)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'mikrotik_routeros']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: examples/terminal.py
================================================
import asyncio
import logging

import yaml

import netdev

config_path = 'config.yaml'

logging.basicConfig(level=logging.INFO)
netdev.logger.setLevel(logging.DEBUG)


async def task(param):
    async with netdev.create(**param) as term:
        # Testing sending simple command
        out = await term.send_command('ls -al', strip_command=True)
        print(out)
        out = await term.send_command('pwd', strip_command=True)
        print(out)
        out = await term.send_command('echo test', strip_command=True)
        print(out)


async def run():
    config = yaml.safe_load(open(config_path, 'r'))
    devices = yaml.safe_load(open(config['device_list'], 'r'))
    tasks = [task(dev) for dev in devices if dev['device_type'] == 'terminal']
    await asyncio.wait(tasks)


loop = asyncio.get_event_loop()
loop.run_until_complete(run())


================================================
FILE: netdev/__init__.py
================================================
import netdev.vendors
from netdev.dispatcher import create, platforms
from netdev.exceptions import DisconnectError, TimeoutError, CommitError
from netdev.logger import logger
from netdev.version import __author__, __author_email__, __url__, __version__

__all__ = (
    "create",
    "platforms",
    "logger",
    "DisconnectError",
    "TimeoutError",
    "CommitError",
    "vendors",
)


================================================
FILE: netdev/dispatcher.py
================================================
"""
Factory function for creating netdev classes
"""
from netdev.vendors import AlcatelAOS
from netdev.vendors import AristaEOS
from netdev.vendors import ArubaAOS6, ArubaAOS8
from netdev.vendors import CiscoASA, CiscoIOS, CiscoIOSXR, CiscoNXOS, CiscoSG3XX
from netdev.vendors import FujitsuSwitch
from netdev.vendors import HPComware, HPComwareLimited
from netdev.vendors import JuniperJunOS
from netdev.vendors import MikrotikRouterOS
from netdev.vendors import Terminal
from netdev.vendors import UbiquityEdgeSwitch
from netdev.vendors import HW1000
from netdev.vendors import Huawei

# @formatter:off
# The keys of this dictionary are the supported device_types
CLASS_MAPPER = {
    "alcatel_aos": AlcatelAOS,
    "arista_eos": AristaEOS,
    "aruba_aos_6": ArubaAOS6,
    "aruba_aos_8": ArubaAOS8,
    "cisco_asa": CiscoASA,
    "cisco_ios": CiscoIOS,
    "cisco_ios_xe": CiscoIOS,
    "cisco_ios_xr": CiscoIOSXR,
    "cisco_nxos": CiscoNXOS,
    "cisco_sg3xx": CiscoSG3XX,
    "fujitsu_switch": FujitsuSwitch,
    "hp_comware": HPComware,
    "hp_comware_limited": HPComwareLimited,
    "juniper_junos": JuniperJunOS,
    "mikrotik_routeros": MikrotikRouterOS,
    "ubiquity_edge": UbiquityEdgeSwitch,
    "terminal": Terminal,
    "hw1000": HW1000,
    "huawei": Huawei,
}

# @formatter:on

platforms = list(CLASS_MAPPER.keys())
platforms.sort()
platforms_str = u"\n".join(platforms)


def create(*args, **kwargs):
    """Factory function selects the proper class and creates object based on device_type"""
    if kwargs["device_type"] not in platforms:
        raise ValueError(
            "Unsupported device_type: "
            "currently supported platforms are: {0}".format(platforms_str)
        )
    connection_class = CLASS_MAPPER[kwargs["device_type"]]
    return connection_class(*args, **kwargs)


================================================
FILE: netdev/exceptions.py
================================================
class DisconnectError(Exception):
    """AsyncSSH Disconnect Error with ip address"""

    def __init__(self, ip_address, code, reason):
        self.ip_address = ip_address
        self.code = code
        self.reason = reason
        self.msg = "Host {} Disconnect Error: {}".format(ip_address, reason)
        super().__init__(self.msg)


class TimeoutError(Exception):
    """concurrent.futures._base.TimeoutError with ip address"""

    def __init__(self, ip_address):
        self.ip_address = ip_address
        self.msg = "Host {} Timeout Error".format(ip_address)
        super().__init__(self.msg)


class CommitError(Exception):
    """concurrent.futures._base.TimeoutError with ip address"""

    def __init__(self, ip_address, reason):
        self.ip_address = ip_address
        self.reason = reason
        self.msg = "Host {} Commit Error: {}".format(ip_address, reason)
        super().__init__(self.msg)


================================================
FILE: netdev/logger.py
================================================
"""
Logging configuration for netdev
"""
import logging

logger = logging.getLogger(__package__)
logger.setLevel(logging.WARNING)


================================================
FILE: netdev/vendors/__init__.py
================================================
from netdev.vendors.alcatel import AlcatelAOS
from netdev.vendors.arista import AristaEOS
from netdev.vendors.aruba import ArubaAOS8, ArubaAOS6
from netdev.vendors.base import BaseDevice
from netdev.vendors.cisco import CiscoNXOS, CiscoIOSXR, CiscoASA, CiscoIOS, CiscoSG3XX
from netdev.vendors.comware_like import ComwareLikeDevice
from netdev.vendors.fujitsu import FujitsuSwitch
from netdev.vendors.hp import HPComware, HPComwareLimited
from netdev.vendors.ios_like import IOSLikeDevice
from netdev.vendors.juniper import JuniperJunOS
from netdev.vendors.junos_like import JunOSLikeDevice
from netdev.vendors.mikrotik import MikrotikRouterOS
from netdev.vendors.terminal import Terminal
from netdev.vendors.ubiquiti import UbiquityEdgeSwitch
from netdev.vendors.infotecs import HW1000
from netdev.vendors.huawei import Huawei

__all__ = (
    "CiscoASA",
    "CiscoIOS",
    "CiscoIOSXR",
    "CiscoNXOS",
    "CiscoSG3XX",
    "HPComware",
    "HPComwareLimited",
    "FujitsuSwitch",
    "MikrotikRouterOS",
    "JuniperJunOS",
    "JunOSLikeDevice",
    "AristaEOS",
    "ArubaAOS6",
    "ArubaAOS8",
    "BaseDevice",
    "IOSLikeDevice",
    "ComwareLikeDevice",
    "Terminal",
    "arista",
    "aruba",
    "cisco",
    "fujitsu",
    "hp",
    "juniper",
    "mikrotik",
    "UbiquityEdgeSwitch",
    "HW1000",
    "AlcatelAOS",
    "Huawei",
)


================================================
FILE: netdev/vendors/alcatel/__init__.py
================================================
from .alcatel_aos import AlcatelAOS

__all__ = ["AlcatelAOS"]


================================================
FILE: netdev/vendors/alcatel/alcatel_aos.py
================================================
from netdev.vendors.base import BaseDevice
from netdev.logger import logger
import asyncio
import re

class AlcatelAOS(BaseDevice):
    """Class for working with Alcatel AOS"""


    async def _read_until_prompt_or_pattern(self, pattern="", re_flags=0):
        """Read until either self.base_pattern or pattern is detected. Return ALL data available"""
        output = ""
        logger.info("Host {}: Reading until prompt or pattern".format(self._host))
        if not pattern:
            pattern = self._base_pattern
        base_prompt_pattern = self._base_pattern
        while True:
            fut = self._stdout.read(self._MAX_BUFFER)
            try:
                output += await asyncio.wait_for(fut, self._timeout)
            except asyncio.TimeoutError:
                raise TimeoutError(self._host)
            if re.search("\n" + pattern, output, flags=re_flags) or re.search(
                "\n" + base_prompt_pattern, output, flags=re_flags
            ):
                logger.debug(
                    "Host {}: Reading pattern '{}' or '{}' was found: {}".format(
                        self._host, pattern, base_prompt_pattern, repr(output)
                    )
                )
                return output



================================================
FILE: netdev/vendors/arista/__init__.py
================================================
from .arista_eos import AristaEOS

__all__ = ["AristaEOS"]


================================================
FILE: netdev/vendors/arista/arista_eos.py
================================================
from netdev.vendors.ios_like import IOSLikeDevice


class AristaEOS(IOSLikeDevice):
    """Class for working with Arista EOS"""

    pass


================================================
FILE: netdev/vendors/aruba/__init__.py
================================================
from .aruba_aos_6 import ArubaAOS6
from .aruba_aos_8 import ArubaAOS8

__all__ = ["ArubaAOS6", "ArubaAOS8"]


================================================
FILE: netdev/vendors/aruba/aruba_aos_6.py
================================================
"""Subclass specific to Aruba AOS 6.x"""

import re

from netdev.logger import logger
from netdev.vendors.ios_like import IOSLikeDevice


class ArubaAOS6(IOSLikeDevice):
    """Class for working with Aruba OS 6.X"""

    _disable_paging_command = "no paging"
    """Command for disabling paging"""

    _config_exit = "end"
    """Command for existing from configuration mode to privilege exec"""

    _config_check = ") (config"
    """Checking string in prompt. If it's exist im prompt - we are in configuration mode"""

    _pattern = r"\({prompt}.*?\) (\(.*?\))?\s?[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    async def _set_base_prompt(self):
        """
        Setting two important vars:

            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. It's platform specific parameter

        For Aruba AOS 6 devices base_pattern is "(prompt) (\(.*?\))?\s?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()

        # Strip off trailing terminator
        self._base_prompt = prompt[1:-3]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt, delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt


================================================
FILE: netdev/vendors/aruba/aruba_aos_8.py
================================================
"""Subclass specific to Aruba AOS 8.x"""

import re

from netdev.logger import logger
from netdev.vendors.ios_like import IOSLikeDevice


class ArubaAOS8(IOSLikeDevice):
    """Class for working with Aruba OS 8.X"""

    _disable_paging_command = "no paging"
    """Command for disabling paging"""

    _config_exit = "end"
    """Command for existing from configuration mode to privilege exec"""

    _config_check = "] (config"
    """Checking string in prompt. If it's exist im prompt - we are in configuration mode"""

    _pattern = r"\({prompt}.*?\) [*^]?\[.*?\] (\(.*?\))?\s?[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    async def _set_base_prompt(self):
        """
        Setting two important vars:

            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. It's platform specific parameter

        For Aruba AOS 8 devices base_pattern is "(prompt) [node] (\(.*?\))?\s?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        prompt = prompt.split(")")[0]
        # Strip off trailing terminator
        self._base_prompt = prompt[1:]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt, delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt


================================================
FILE: netdev/vendors/base.py
================================================
"""
Base Class for using in connection to network devices

Connections Method are based upon AsyncSSH and should be running in asyncio loop
"""

import asyncio
import re

import asyncssh

from netdev.exceptions import TimeoutError, DisconnectError
from netdev.logger import logger


class BaseDevice(object):
    """
    Base Abstract Class for working with network devices
    """

    def __init__(
        self,
        host=u"",
        username=u"",
        password=u"",
        port=22,
        device_type=u"",
        timeout=15,
        loop=None,
        known_hosts=None,
        local_addr=None,
        client_keys=None,
        passphrase=None,
        tunnel=None,
        pattern=None,
        agent_forwarding=False,
        agent_path=(),
        client_version=u"netdev",
        family=0,
        kex_algs=(),
        encryption_algs=(),
        mac_algs=(),
        compression_algs=(),
        signature_algs=(),
        server_host_key_algs=None,
    ):
        """
        Initialize base class for asynchronous working with network devices

        :param host: device hostname or ip address for connection
        :param username: username for logging to device
        :param password: user password for logging to device
        :param port: ssh port for connection. Default is 22
        :param device_type: network device type
        :param timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param passphrase: password for encrypted client keys
        :param tunnel: An existing SSH connection that this new connection should be tunneled over
        :param pattern: pattern for searching the end of device prompt.
                Example: r"{hostname}.*?(\(.*?\))?[{delimeters}]"
        :param agent_forwarding: Allow or not allow agent forward for server
        :param agent_path:
            The path of a UNIX domain socket to use to contact an ssh-agent
            process which will perform the operations needed for client
            public key authentication. If this is not specified and the environment
            variable `SSH_AUTH_SOCK` is set, its value will be used as the path.
            If `client_keys` is specified or this argument is explicitly set to `None`,
            an ssh-agent will not be used.
        :param client_version: version which advertised to ssh server
        :param family:
           The address family to use when creating the socket. By default,
           the address family is automatically selected based on the host.
        :param kex_algs:
            A list of allowed key exchange algorithms in the SSH handshake,
            taken from `key exchange algorithms
            <https://asyncssh.readthedocs.io/en/latest/api.html#kexalgs>`_
        :param encryption_algs:
            A list of encryption algorithms to use during the SSH handshake,
            taken from `encryption algorithms
            <https://asyncssh.readthedocs.io/en/latest/api.html#encryptionalgs>`_
        :param mac_algs:
            A list of MAC algorithms to use during the SSH handshake, taken
            from `MAC algorithms <https://asyncssh.readthedocs.io/en/latest/api.html#macalgs>`_
        :param compression_algs:
            A list of compression algorithms to use during the SSH handshake,
            taken from `compression algorithms
            <https://asyncssh.readthedocs.io/en/latest/api.html#compressionalgs>`_, or
            `None` to disable compression
        :param signature_algs:
            A list of public key signature algorithms to use during the SSH
            handshake, taken from `signature algorithms
            <https://asyncssh.readthedocs.io/en/latest/api.html#signaturealgs>`_
        :param server_host_key_algs:
            A list of server host key algorithms to allow during the SSH handshake,
            taken from server host key algorithms.
            https://asyncssh.readthedocs.io/en/latest/api.html#publickeyalgs
        

        :type host: str
        :type username: str
        :type password: str
        :type port: int
        :type device_type: str
        :type timeout: int
        :type known_hosts:
            *see* `SpecifyingKnownHosts
            <https://asyncssh.readthedocs.io/en/latest/api.html#specifyingknownhosts>`_
        :type loop: :class:`AbstractEventLoop <asyncio.AbstractEventLoop>`
        :type pattern: str
        :type tunnel: :class:`BaseDevice <netdev.vendors.BaseDevice>`
        :type family:
            :class:`socket.AF_UNSPEC` or :class:`socket.AF_INET` or :class:`socket.AF_INET6`
        :type local_addr: tuple(str, int)
        :type client_keys:
            *see* `SpecifyingPrivateKeys
            <https://asyncssh.readthedocs.io/en/latest/api.html#specifyingprivatekeys>`_
        :type passphrase: str
        :type agent_path: str
        :type agent_forwarding: bool
        :type client_version: str
        :type kex_algs: list[str]
        :type encryption_algs: list[str]
        :type mac_algs: list[str]
        :type compression_algs: list[str]
        :type signature_algs: list[str]
        :type server_host_key_algs: list[str]
        """
        if host:
            self._host = host
        else:
            raise ValueError("Host must be set")
        self._port = int(port)
        self._device_type = device_type
        self._timeout = timeout
        if loop is None:
            self._loop = asyncio.get_event_loop()
        else:
            self._loop = loop

        """Convert needed connect params to a dictionary for simplicity"""
        self._connect_params_dict = {
            "host": self._host,
            "port": self._port,
            "username": username,
            "password": password,
            "known_hosts": known_hosts,
            "local_addr": local_addr,
            "client_keys": client_keys,
            "passphrase": passphrase,
            "tunnel": tunnel,
            "agent_forwarding": agent_forwarding,
            "family": family,
            "agent_path": agent_path,
            "client_version": client_version,
            "kex_algs": kex_algs,
            "encryption_algs": encryption_algs,
            "mac_algs": mac_algs,
            "compression_algs": compression_algs,
            "signature_algs": signature_algs,
        }

        if pattern is not None:
            self._pattern = pattern
            
        """
        A list of server host key algorithms to use instead of the default of 
        those present in known_hosts when performing the SSH handshake. This should only be set,
        when the user sets it.
        """
        if server_host_key_algs is not None:
            self._connect_params_dict['server_host_key_algs'] = server_host_key_algs

        # Filling internal vars
        self._stdin = self._stdout = self._stderr = self._conn = None
        self._base_prompt = self._base_pattern = ""
        self._MAX_BUFFER = 65535
        self._ansi_escape_codes = False

    _delimiter_list = [">", "#"]
    """All this characters will stop reading from buffer. It mean the end of device prompt"""

    _pattern = r"{prompt}.*?(\(.*?\))?[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    _disable_paging_command = "terminal length 0"
    """Command for disabling paging"""

    @property
    def base_prompt(self):
        """Returning base prompt for this network device"""
        return self._base_prompt

    async def __aenter__(self):
        """Async Context Manager"""
        await self.connect()
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """Async Context Manager"""
        await self.disconnect()

    async def connect(self):
        """
        Basic asynchronous connection method

        It connects to device and makes some preparation steps for working.
        Usual using 3 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for finding and setting device prompt
        * _disable_paging() for non interactive output in commands
        """
        logger.info("Host {}: Trying to connect to the device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        await self._disable_paging()
        logger.info("Host {}: Has connected to the device".format(self._host))

    async def _establish_connection(self):
        """Establishing SSH connection to the network device"""
        logger.info(
            "Host {}: Establishing connection to port {}".format(self._host, self._port)
        )
        output = ""
        # initiate SSH connection
        fut = asyncssh.connect(**self._connect_params_dict)
        try:
            self._conn = await asyncio.wait_for(fut, self._timeout)
        except asyncssh.DisconnectError as e:
            raise DisconnectError(self._host, e.code, e.reason)
        except asyncio.TimeoutError:
            raise TimeoutError(self._host)
        self._stdin, self._stdout, self._stderr = await self._conn.open_session(
            term_type="Dumb", term_size=(200, 24)
        )
        logger.info("Host {}: Connection is established".format(self._host))
        # Flush unnecessary data
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        output = await self._read_until_pattern(delimiters)
        logger.debug(
            "Host {}: Establish Connection Output: {}".format(self._host, repr(output))
        )
        return output

    async def _set_base_prompt(self):
        """
        Setting two important vars:

            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. It's platform specific parameter

        For Cisco devices base_pattern is "prompt(\(.*?\))?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()

        # Strip off trailing terminator
        self._base_prompt = prompt[:-1]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt, delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

    async def _disable_paging(self):
        """Disable paging method"""
        logger.info("Host {}: Trying to disable paging".format(self._host))
        command = type(self)._disable_paging_command
        command = self._normalize_cmd(command)
        logger.debug(
            "Host {}: Disable paging command: {}".format(self._host, repr(command))
        )
        self._stdin.write(command)
        output = await self._read_until_prompt()
        logger.debug(
            "Host {}: Disable paging output: {}".format(self._host, repr(output))
        )
        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)
        return output

    async def _find_prompt(self):
        """Finds the current network device prompt, last line only"""
        logger.info("Host {}: Finding prompt".format(self._host))
        self._stdin.write(self._normalize_cmd("\n"))
        prompt = ""
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        prompt = await self._read_until_pattern(delimiters)
        prompt = prompt.strip()
        if self._ansi_escape_codes:
            prompt = self._strip_ansi_escape_codes(prompt)
        if not prompt:
            raise ValueError(
                "Host {}: Unable to find prompt: {}".format(self._host, repr(prompt))
            )
        logger.debug("Host {}: Found Prompt: {}".format(self._host, repr(prompt)))
        return prompt

    async def send_command(
        self,
        command_string,
        pattern="",
        re_flags=0,
        strip_command=True,
        strip_prompt=True,
    ):
        """
        Sending command to device (support interactive commands with pattern)

        :param str command_string: command for executing basically in privilege mode
        :param str pattern: pattern for waiting in output (for interactive commands)
        :param re.flags re_flags: re flags for pattern
        :param bool strip_command: True or False for stripping command from output
        :param bool strip_prompt: True or False for stripping ending device prompt
        :return: The output of the command
        """
        logger.info("Host {}: Sending command".format(self._host))
        output = ""
        command_string = self._normalize_cmd(command_string)
        logger.debug(
            "Host {}: Send command: {}".format(self._host, repr(command_string))
        )
        self._stdin.write(command_string)
        output = await self._read_until_prompt_or_pattern(pattern, re_flags)

        # Some platforms have ansi_escape codes
        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)
        output = self._normalize_linefeeds(output)
        if strip_prompt:
            output = self._strip_prompt(output)
        if strip_command:
            output = self._strip_command(command_string, output)

        logger.debug(
            "Host {}: Send command output: {}".format(self._host, repr(output))
        )
        return output

    def _strip_prompt(self, a_string):
        """Strip the trailing router prompt from the output"""
        logger.info("Host {}: Stripping prompt".format(self._host))
        response_list = a_string.split("\n")
        last_line = response_list[-1]
        if self._base_prompt in last_line:
            return "\n".join(response_list[:-1])
        else:
            return a_string

    async def _read_until_prompt(self):
        """Read channel until self.base_pattern detected. Return ALL data available"""
        return await self._read_until_pattern(self._base_pattern)

    async def _read_until_pattern(self, pattern="", re_flags=0):
        """Read channel until pattern detected. Return ALL data available"""
        output = ""
        logger.info("Host {}: Reading until pattern".format(self._host))
        if not pattern:
            pattern = self._base_pattern
        logger.debug("Host {}: Reading pattern: {}".format(self._host, pattern))
        while True:
            fut = self._stdout.read(self._MAX_BUFFER)
            try:
                output += await asyncio.wait_for(fut, self._timeout)
            except asyncio.TimeoutError:
                raise TimeoutError(self._host)
            if re.search(pattern, output, flags=re_flags):
                logger.debug(
                    "Host {}: Reading pattern '{}' was found: {}".format(
                        self._host, pattern, repr(output)
                    )
                )
                return output

    async def _read_until_prompt_or_pattern(self, pattern="", re_flags=0):
        """Read until either self.base_pattern or pattern is detected. Return ALL data available"""
        output = ""
        logger.info("Host {}: Reading until prompt or pattern".format(self._host))
        if not pattern:
            pattern = self._base_pattern
        base_prompt_pattern = self._base_pattern
        while True:
            fut = self._stdout.read(self._MAX_BUFFER)
            try:
                output += await asyncio.wait_for(fut, self._timeout)
            except asyncio.TimeoutError:
                raise TimeoutError(self._host)
            if re.search(pattern, output, flags=re_flags) or re.search(
                base_prompt_pattern, output, flags=re_flags
            ):
                logger.debug(
                    "Host {}: Reading pattern '{}' or '{}' was found: {}".format(
                        self._host, pattern, base_prompt_pattern, repr(output)
                    )
                )
                return output

    @staticmethod
    def _strip_backspaces(output):
        """Strip any backspace characters out of the output"""
        backspace_char = "\x08"
        return output.replace(backspace_char, "")

    @staticmethod
    def _strip_command(command_string, output):
        """
        Strip command_string from output string

        Cisco IOS adds backspaces into output for long commands (i.e. for commands that line wrap)
        """
        logger.info("Stripping command")
        backspace_char = "\x08"

        # Check for line wrap (remove backspaces)
        if backspace_char in output:
            output = output.replace(backspace_char, "")
            output_lines = output.split("\n")
            new_output = output_lines[1:]
            return "\n".join(new_output)
        else:
            command_length = len(command_string)
            return output[command_length:]

    @staticmethod
    def _normalize_linefeeds(a_string):
        """Convert '\r\r\n','\r\n', '\n\r' to '\n"""
        newline = re.compile(r"(\r\r\n|\r\n|\n\r)")
        return newline.sub("\n", a_string)

    @staticmethod
    def _normalize_cmd(command):
        """Normalize CLI commands to have a single trailing newline"""
        command = command.rstrip("\n")
        command += "\n"
        return command

    async def send_config_set(self, config_commands=None):
        """
        Sending configuration commands to device

        The commands will be executed one after the other.

        :param list config_commands: iterable string list with commands for applying to network device
        :return: The output of this commands
        """
        logger.info("Host {}: Sending configuration settings".format(self._host))
        if config_commands is None:
            return ""
        if not hasattr(config_commands, "__iter__"):
            raise ValueError(
                "Host {}: Invalid argument passed into send_config_set".format(
                    self._host
                )
            )

        # Send config commands
        logger.debug("Host {}: Config commands: {}".format(self._host, config_commands))
        output = ""
        for cmd in config_commands:
            self._stdin.write(self._normalize_cmd(cmd))
            output += await self._read_until_prompt()

        if self._ansi_escape_codes:
            output = self._strip_ansi_escape_codes(output)

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output

    @staticmethod
    def _strip_ansi_escape_codes(string_buffer):
        """
        Remove some ANSI ESC codes from the output

        http://en.wikipedia.org/wiki/ANSI_escape_code

        Note: this does not capture ALL possible ANSI Escape Codes only the ones
        I have encountered

        Current codes that are filtered:
        ESC = '\x1b' or chr(27)
        ESC = is the escape character [^ in hex ('\x1b')
        ESC[24;27H   Position cursor
        ESC[?25h     Show the cursor
        ESC[E        Next line (HP does ESC-E)
        ESC[K        Erase line. Clear from cursor to end of screen
        ESC[2K       Erase line
        ESC[1;24r    Enable scrolling from start to row end
        ESC7         Save cursor position
        ESC[r        Scroll all screen
        ESC8         Restore cursor position
        ESC[nA       Move cursor up to n cells
        ESC[nB       Move cursor down to n cells

        require:
            HP ProCurve
            F5 LTM's
            Mikrotik
        """
        logger.info("Stripping ansi escape codes")
        logger.debug("Unstripped output: {}".format(repr(string_buffer)))

        code_save_cursor = chr(27) + r"7"
        code_scroll_screen = chr(27) + r"\[r"
        code_restore_cursor = chr(27) + r"8"
        code_cursor_up = chr(27) + r"\[\d+A"
        code_cursor_down = chr(27) + r"\[\d+B"

        code_position_cursor = chr(27) + r"\[\d+;\d+H"
        code_show_cursor = chr(27) + r"\[\?25h"
        code_next_line = chr(27) + r"E"
        code_erase_line_from_cursor = chr(27) + r"\[K"
        code_erase_line = chr(27) + r"\[2K"
        code_enable_scroll = chr(27) + r"\[\d+;\d+r"

        code_set = [
            code_save_cursor,
            code_scroll_screen,
            code_restore_cursor,
            code_cursor_up,
            code_cursor_down,
            code_position_cursor,
            code_show_cursor,
            code_erase_line,
            code_erase_line_from_cursor,
            code_enable_scroll,
        ]

        output = string_buffer
        for ansi_esc_code in code_set:
            output = re.sub(ansi_esc_code, "", output)

        # CODE_NEXT_LINE must substitute with '\n'
        output = re.sub(code_next_line, "\n", output)

        logger.debug("Stripped output: {}".format(repr(output)))

        return output

    async def _cleanup(self):
        """ Any needed cleanup before closing connection """
        logger.info("Host {}: Cleanup session".format(self._host))
        pass

    async def disconnect(self):
        """ Gracefully close the SSH connection """
        logger.info("Host {}: Disconnecting".format(self._host))
        await self._cleanup()
        self._conn.close()
        await self._conn.wait_closed()


================================================
FILE: netdev/vendors/cisco/__init__.py
================================================
from .cisco_asa import CiscoASA
from .cisco_ios import CiscoIOS
from .cisco_iosxr import CiscoIOSXR
from .cisco_nxos import CiscoNXOS
from .cisco_sg3xx import CiscoSG3XX

__all__ = ["CiscoIOS", "CiscoIOSXR", "CiscoASA", "CiscoNXOS", "CiscoSG3XX"]


================================================
FILE: netdev/vendors/cisco/cisco_asa.py
================================================
"""Subclass specific to Cisco ASA"""

import re

from netdev.logger import logger
from netdev.vendors.ios_like import IOSLikeDevice


class CiscoASA(IOSLikeDevice):
    """Class for working with Cisco ASA"""

    def __init__(self, *args, **kwargs):
        """
        Initialize class for asynchronous working with network devices

        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param str secret: secret password for privilege mode
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        """
        super().__init__(*args, **kwargs)
        self._multiple_mode = False

    _disable_paging_command = "terminal pager 0"

    @property
    def multiple_mode(self):
        """ Returning Bool True if ASA in multiple mode"""
        return self._multiple_mode

    async def connect(self):
        """
        Async Connection method

        Using 5 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for finding and setting device prompt
        * _enable() for getting privilege exec mode
        * _disable_paging() for non interact output in commands
        *  _check_multiple_mode() for checking multiple mode in ASA
        """
        logger.info("Host {}: trying to connect to the device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        await self.enable_mode()
        await self._disable_paging()
        await self._check_multiple_mode()
        logger.info("Host {}: Has connected to the device".format(self._host))

    async def _set_base_prompt(self):
        """
        Setting two important vars for ASA
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For ASA devices base_pattern is "prompt([\/\w]+)?(\(.*?\))?[#|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Cut off prompt from "prompt/context/other" if it exists
        # If not we get all prompt
        prompt = prompt[:-1].split("/")
        prompt = prompt[0]
        self._base_prompt = prompt
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt, delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

    async def _check_multiple_mode(self):
        """Check mode multiple. If mode is multiple we adding info about contexts"""
        logger.info("Host {}:Checking multiple mode".format(self._host))
        out = await self.send_command("show mode")
        if "multiple" in out:
            self._multiple_mode = True

        logger.debug(
            "Host {}: Multiple mode: {}".format(self._host, self._multiple_mode)
        )


================================================
FILE: netdev/vendors/cisco/cisco_ios.py
================================================
from netdev.vendors.ios_like import IOSLikeDevice


class CiscoIOS(IOSLikeDevice):
    """Class for working with Cisco IOS/IOS XE"""

    pass


================================================
FILE: netdev/vendors/cisco/cisco_iosxr.py
================================================
from netdev.exceptions import CommitError
from netdev.logger import logger
from netdev.vendors.ios_like import IOSLikeDevice


class CiscoIOSXR(IOSLikeDevice):
    """Class for working with Cisco IOS XR"""

    _commit_command = "commit"
    """Command for committing changes"""

    _commit_comment_command = "commit comment {}"
    """Command for committing changes with comment"""

    _abort_command = "abort"
    """Command for aborting all changes and exit to privilege mode"""

    _show_config_failed = "show configuration failed"
    """Command for showing the reason of failed commit"""

    _show_commit_changes = "show configuration commit changes"
    """Command for showing the other commit which have occurred during our session"""

    async def send_config_set(
        self,
        config_commands=None,
        with_commit=True,
        commit_comment="",
        exit_config_mode=True,
    ):
        """
        Sending configuration commands to device
        By default automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool with_commit: if true it commit all changes after applying all config_commands
        :param string commit_comment: message for configuration commit
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of these commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self.config_mode()
        output += await super(IOSLikeDevice, self).send_config_set(
            config_commands=config_commands
        )
        if with_commit:
            commit = type(self)._commit_command
            if commit_comment:
                commit = type(self)._commit_comment_command.format(commit_comment)

            self._stdin.write(self._normalize_cmd(commit))
            output += await self._read_until_prompt_or_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(
                    self._normalize_cmd(show_config_failed)
                )
                raise CommitError(self._host, reason)
            if "One or more commits have occurred" in output:
                show_commit_changes = type(self)._show_commit_changes
                self._stdin.write(self._normalize_cmd("no"))
                reason = await self.send_command(
                    self._normalize_cmd(show_commit_changes)
                )
                raise CommitError(self._host, reason)

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output

    async def exit_config_mode(self):
        """Exit from configuration mode"""
        logger.info("Host {}: Exiting from configuration mode".format(self._host))
        output = ""
        exit_config = type(self)._config_exit
        if await self.check_config_mode():
            self._stdin.write(self._normalize_cmd(exit_config))
            output = await self._read_until_prompt_or_pattern(
                r"Uncommitted changes found"
            )
            if "Uncommitted changes found" in output:
                self._stdin.write(self._normalize_cmd("no"))
                output += await self._read_until_prompt()
            if await self.check_config_mode():
                raise ValueError("Failed to exit from configuration mode")
        return output

    async def _cleanup(self):
        """ Any needed cleanup before closing connection """
        abort = type(self)._abort_command
        abort = self._normalize_cmd(abort)
        self._stdin.write(abort)
        logger.info("Host {}: Cleanup session".format(self._host))


================================================
FILE: netdev/vendors/cisco/cisco_nxos.py
================================================
import re

from netdev.vendors.ios_like import IOSLikeDevice


class CiscoNXOS(IOSLikeDevice):
    """Class for working with Cisco Nexus/NX-OS"""

    @staticmethod
    def _normalize_linefeeds(a_string):
        """
        Convert '\r\n' or '\r\r\n' to '\n, and remove extra '\r's in the text
        """
        newline = re.compile(r"(\r\r\n|\r\n)")

        return newline.sub("\n", a_string).replace("\r", "")


================================================
FILE: netdev/vendors/cisco/cisco_sg3xx.py
================================================
"""Subclass specific to Cisco SG3XX"""

from netdev.vendors.ios_like import IOSLikeDevice

class CiscoSG3XX(IOSLikeDevice):
    """Class for working with Cisco SG3XX"""

    def __init__(self, *args, **kwargs):
        """
        Initialize class for asynchronous working with network devices

        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param str secret: secret password for privilege mode
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        """
        super().__init__(*args, **kwargs)
        self._ansi_escape_codes = True

    _disable_paging_command = "terminal datadump"




================================================
FILE: netdev/vendors/comware_like.py
================================================
"""
ComwareLikeDevice Class is abstract class for using in HP Comware like devices

Connection Method are based upon AsyncSSH and should be running in asyncio loop
"""

import re

from netdev.logger import logger
from netdev.vendors.base import BaseDevice


class ComwareLikeDevice(BaseDevice):
    """
    This Class for working with hp comware like devices

    HP Comware like devices having several concepts:

    * user exec or user view. This mode is using for getting information from device
    * system view. This mode is using for configuration system
    """

    _delimiter_list = [">", "]"]
    """All this characters will stop reading from buffer. It mean the end of device prompt"""

    _delimiter_left_list = ["<", "["]
    """Begging prompt characters. Prompt must contain it"""

    _pattern = r"[{delimiter_left}]{prompt}[\-\w]*[{delimiter_right}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    _disable_paging_command = "screen-length disable"
    """Command for disabling paging"""

    _system_view_enter = "system-view"
    """Command for entering to system view"""

    _system_view_exit = "return"
    """Command for existing from system view to user view"""

    _system_view_check = "]"
    """Checking string in prompt. If it's exist im prompt - we are in system view"""

    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Comware devices base_pattern is "[\]|>]prompt(\-\w+)?[\]|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Strip off trailing terminator
        self._base_prompt = prompt[1:-1]
        delimiter_right = map(re.escape, type(self)._delimiter_list)
        delimiter_right = r"|".join(delimiter_right)
        delimiter_left = map(re.escape, type(self)._delimiter_left_list)
        delimiter_left = r"|".join(delimiter_left)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(
            delimiter_left=delimiter_left,
            prompt=base_prompt,
            delimiter_right=delimiter_right,
        )
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

    async def _check_system_view(self):
        """Check if we are in system view. Return boolean"""
        logger.info("Host {}: Checking system view".format(self._host))
        check_string = type(self)._system_view_check
        self._stdin.write(self._normalize_cmd("\n"))
        output = await self._read_until_prompt()
        return check_string in output

    async def _system_view(self):
        """Enter to system view"""
        logger.info("Host {}: Entering to system view".format(self._host))
        output = ""
        system_view_enter = type(self)._system_view_enter
        if not await self._check_system_view():
            self._stdin.write(self._normalize_cmd(system_view_enter))
            output += await self._read_until_prompt()
            if not await self._check_system_view():
                raise ValueError("Failed to enter to system view")
        return output

    async def _exit_system_view(self):
        """Exit from system view"""
        logger.info("Host {}: Exiting from system view".format(self._host))
        output = ""
        system_view_exit = type(self)._system_view_exit
        if await self._check_system_view():
            self._stdin.write(self._normalize_cmd(system_view_exit))
            output += await self._read_until_prompt()
            if await self._check_system_view():
                raise ValueError("Failed to exit from system view")
        return output

    async def send_config_set(self, config_commands=None, exit_system_view=False):
        """
        Sending configuration commands to device
        Automatically exits/enters system-view.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool exit_system_view: If true it will quit from system view automatically
        :return: The output of this commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self._system_view()
        output += await super().send_config_set(config_commands=config_commands)

        if exit_system_view:
            output += await self._exit_system_view()

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output


================================================
FILE: netdev/vendors/fujitsu/__init__.py
================================================
from .fujitsu_switch import FujitsuSwitch

__all__ = ["FujitsuSwitch"]


================================================
FILE: netdev/vendors/fujitsu/fujitsu_switch.py
================================================
"""Subclass specific to Fujitsu Blade Switch"""

import re

from netdev.logger import logger
from netdev.vendors.ios_like import IOSLikeDevice


class FujitsuSwitch(IOSLikeDevice):
    """Class for working with Fujitsu Blade switch"""

    _pattern = r"\({prompt}.*?\) (\(.*?\))?[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    _disable_paging_command = "no pager"
    """Command for disabling paging"""

    _config_enter = "conf"
    """Command for entering to configuration mode"""

    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Fujitsu devices base_pattern is "(prompt) (\(.*?\))?[>|#]"
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Strip off trailing terminator
        self._base_prompt = prompt[1:-3]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt, delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

    @staticmethod
    def _normalize_linefeeds(a_string):
        """
        Convert '\r\r\n','\r\n', '\n\r' to '\n and remove extra '\n\n' in the text
        """
        newline = re.compile(r"(\r\r\n|\r\n|\n\r)")
        return newline.sub("\n", a_string).replace("\n\n", "\n")


================================================
FILE: netdev/vendors/hp/__init__.py
================================================
from .hp_comware import HPComware
from .hp_comware_limited import HPComwareLimited

__all__ = ["HPComware", "HPComwareLimited"]


================================================
FILE: netdev/vendors/hp/hp_comware.py
================================================
from netdev.vendors.comware_like import ComwareLikeDevice


class HPComware(ComwareLikeDevice):
    """Class for working with HP Comware"""

    pass


================================================
FILE: netdev/vendors/hp/hp_comware_limited.py
================================================
from netdev.logger import logger
from netdev.vendors.comware_like import ComwareLikeDevice


class HPComwareLimited(ComwareLikeDevice):
    """Class for working with HP Comware Limited like 1910 and 1920 models"""

    def __init__(self, cmdline_password=u"", *args, **kwargs):
        """
        Initialize  class for asynchronous working with network devices

        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param str cmdline_password: password for entering to _cmd_line
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        """
        super().__init__(*args, **kwargs)
        self._cmdline_password = cmdline_password

    _cmdline_mode_enter_command = "_cmdline-mode on"
    """Command for entering to cmdline model"""

    _cmdline_mode_check = "Invalid password"
    """Checking string for wrong password in trying of entering to cmdline mode"""

    async def connect(self):
        """
        Basic asynchronous connection method

        It connects to device and makes some preparation steps for working.
        Usual using 4 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for finding and setting device prompt
        * _cmdline_mode_enter() for entering hidden full functional mode
        * _disable_paging() for non interact output in commands
        """
        logger.info("Host {}: Trying to connect to the device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        await self._cmdline_mode_enter()
        await self._disable_paging()
        logger.info("Host {}: Has connected to the device".format(self._host))

    async def _cmdline_mode_enter(self):
        """Entering to cmdline-mode"""
        logger.info("Host {}: Entering to cmdline mode".format(self._host))
        output = ""
        cmdline_mode_enter = type(self)._cmdline_mode_enter_command
        check_error_string = type(self)._cmdline_mode_check

        output = await self.send_command(cmdline_mode_enter, pattern="\[Y\/N\]")
        output += await self.send_command("Y", pattern="password\:")
        output += await self.send_command(self._cmdline_password)

        logger.debug(
            "Host {}: cmdline mode output: {}".format(self._host, repr(output))
        )
        logger.info("Host {}: Checking cmdline mode".format(self._host))
        if check_error_string in output:
            raise ValueError("Failed to enter to cmdline mode")

        return output


================================================
FILE: netdev/vendors/huawei/__init__.py
================================================
from .huawei import Huawei

__all__ = ["Huawei"]

================================================
FILE: netdev/vendors/huawei/huawei.py
================================================
from netdev.vendors.comware_like import ComwareLikeDevice
import re
from netdev.logger import logger

class Huawei(ComwareLikeDevice):
    """Class for working with Huawei"""

    _disable_paging_command = "screen-length 0 temporary"
    """Command for disabling paging"""

    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Comware devices base_pattern is "[\]|>]prompt(\-\w+)?[\]|>]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Strip off any leading HRP_. characters for USGv5 HA
        prompt = re.sub(r"^HRP_.", "", prompt, flags=re.M)
        # Strip off trailing terminator
        self._base_prompt = prompt[1:-1]
        delimiter_right = map(re.escape, type(self)._delimiter_list)
        delimiter_right = r"|".join(delimiter_right)
        delimiter_left = map(re.escape, type(self)._delimiter_left_list)
        delimiter_left = r"|".join(delimiter_left)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(
            delimiter_left=delimiter_left,
            prompt=base_prompt,
            delimiter_right=delimiter_right,
        )
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

================================================
FILE: netdev/vendors/infotecs/HW1000.py
================================================
"""
HW1000 is a class for working with Vipnet HW1000 crypto gateways
"""
import re
from netdev.logger import logger
from netdev.vendors.base import BaseDevice

class HW1000(BaseDevice):
    """
    Class for working with Vipnet HW1000
    
    HW1000 devices have three administration modes:
    *user exec or unprivileged exec. This mode allows you perform basic tests and get system information.
    *privilege exec. This mode allows all EXEC mode commands available on the system. HW100 supports
        only one active privilege session. Use preempt_privilege=True to close current privilege session
    *shell. This mode exits standart device shell and enters Linux shell 
    """
    def __init__(self, secret=u'',preempt_privilege=False, *args, **kwargs):
        """
        Initialize class for asynchronous working with network devices
        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param str secret: secret password for privilege mode
        :param bool preempt_privilege: close current privilige session (if exists). Default is False
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        """
        self._secret = secret
        self._preempt_privilege = preempt_privilege

        super().__init__(*args, **kwargs)

    _priv_enter = 'enable'
    """Command for entering to privilege exec"""

    _priv_exit = 'exit'
    """Command for existing from privilege exec to user exec"""

    _priv_check = '#'
    """Checking string in prompt. If it's exist im prompt - we are in privilege exec"""

    _priv_confirm_message = "Are you sure you want to force termination of the specified session"
    """Confirmation message for privilege preemtion""" 

    _shell_enter = "admin esc"
    """Command for entering Linux shell"""
    
    _shell_exit = "exit"
    """Command for exiting Linux shell"""

    _shell_check = "sh"
    """Checking string in prompt. If it's exist im prompt - we are in Linux shell"""

    _shell_enter_message = "Are you sure you want to exit to the Linux system shell?"
    """Confirmation message for entering Linux shell"""

    async def connect(self):
        """
        Basic asynchronous connection method for HW1000 devices

        It connects to device and makes some preparation steps for working.
        Usual using 3 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for finding and setting device prompt
        * _enable() for getting privilege exec mode
        """
        logger.info("Host {}: Trying to connect to the device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        await self.enable_mode()
        logger.info("Host {}: Has connected to the device".format(self._host))

    async def check_enable_mode(self):
        """Check if we are in privilege exec. Return boolean"""
        logger.info('Host {}: Checking privilege exec'.format(self._host))
        check_string = type(self)._priv_check
        self._stdin.write(self._normalize_cmd('\n'))
        output = await self._read_until_prompt()
        return check_string in output

    async def enable_mode(self, pattern='password', re_flags=re.IGNORECASE):
        """Enter to privilege exec"""
        logger.info('Host {}: Entering to privilege exec'.format(self._host))
        output = ""
        enable_command = type(self)._priv_enter
        if not await self.check_enable_mode():
            self._stdin.write(self._normalize_cmd(enable_command))
            output += await self._read_until_prompt_or_pattern(
                pattern=pattern, re_flags=re_flags)
            if re.search(pattern, output, re_flags):
                self._stdin.write(self._normalize_cmd(self._secret))
                output += await self._read_until_prompt_or_pattern(
                    pattern=type(self)._priv_confirm_message,re_flags=re_flags)
                if re.search(type(self)._priv_confirm_message,output,re_flags):
                    if self._preempt_privilege:
                        self._stdin.write(self._normalize_cmd("Yes"))
                    else:
                        raise ValueError("Failed to enter privilege exec:"
                        "there is already a active administration session."
                        "Use preempt_privilege=True")
            if not await self.check_enable_mode():
                raise ValueError("Failed to enter to privilege exec")
        return output

    async def exit_enable_mode(self):
        """Exit from privilege exec"""
        logger.info('Host {}: Exiting from privilege exec'.format(self._host))
        output = ""
        exit_enable = type(self)._priv_exit
        if await self.check_enable_mode():
            self._stdin.write(self._normalize_cmd(exit_enable))
            output += await self._read_until_prompt()
            if await self.check_enable_mode():
                raise ValueError("Failed to exit from privilege exec")
        return output

    async def check_shell_mode(self):
        """Checks if device in shell mode or not"""
        logger.info('Host {}: Checking shell mode'.format(self._host))
        check_string = type(self)._shell_check
        self._stdin.write(self._normalize_cmd('\n'))
        output = await self._read_until_pattern(r'[\>|\#]')
        logger.info(output)
        return check_string in output
    
    async def enter_shell_mode(self,re_flags=re.IGNORECASE):
        """ Enter into shell mode"""
        logger.info('Host {}: Entering to shell mode'.format(self._host))
        output = ''
        shell_command = type(self)._shell_enter
        if not await self.check_shell_mode():
            self._stdin.write(self._normalize_cmd(shell_command))
            output += await self._read_until_pattern(
                pattern=type(self)._shell_enter_message,re_flags=re_flags)
            self._stdin.write(self._normalize_cmd("Yes"))
            output += await self._read_until_pattern('password:', re_flags=re_flags)
            self._stdin.write(self._normalize_cmd(self._secret))
            output += await self._read_until_pattern(r'[\>|\#]')
            await self._set_base_prompt() # base promt differs in shell mode
            if not await self.check_shell_mode():
                raise ValueError('Failed to enter to shell mode')
        return output
    
    async def exit_shell_mode(self):
        """Exit from shell mode"""
        logger.info('Host {}: Exiting from shell mode'.format(self._host))
        output = ''
        exit_shell = type(self)._shell_exit
        if await self.check_shell_mode():
            self._stdin.write(self._normalize_cmd(exit_shell))
            output = await self._read_until_pattern(r'[\>|\#]')
            if await self.check_shell_mode():
                raise ValueError("Failed to exit from shell mode")
            await self._set_base_prompt() # base promt differs in shell mode
        return output
    
    async def _cleanup(self):
        """ Any needed cleanup before closing connection """
        logger.info("Host {}: Cleanup session".format(self._host))
        await self.exit_shell_mode()
        await self.exit_enable_mode()
        

================================================
FILE: netdev/vendors/infotecs/__init__.py
================================================
from .HW1000 import HW1000

__all__ = ['HW1000']


================================================
FILE: netdev/vendors/ios_like.py
================================================
"""
IOSLikeDevice Class is abstract class for using in Cisco IOS like devices

Connection Method are based upon AsyncSSH and should be running in asyncio loop
"""

import re

from netdev.logger import logger
from netdev.vendors.base import BaseDevice


class IOSLikeDevice(BaseDevice):
    """
    This Class is abstract class for working with Cisco IOS like devices

    Cisco IOS like devices having several concepts:

    * user exec or unprivileged exec. This mode allows you perform basic tests and get system information.
    * privilege exec. This mode allows the use of all EXEC mode commands available on the system
    * configuration mode or config mode. This mode are used for configuration whole system.
    """

    def __init__(self, secret=u"", *args, **kwargs):
        """
        Initialize class for asynchronous working with network devices

        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param str secret: secret password for privilege mode
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        """
        super().__init__(*args, **kwargs)
        self._secret = secret

    _priv_enter = "enable"
    """Command for entering to privilege exec"""

    _priv_exit = "disable"
    """Command for existing from privilege exec to user exec"""

    _priv_check = "#"
    """Checking string in prompt. If it's exist im prompt - we are in privilege exec"""

    _config_enter = "conf t"
    """Command for entering to configuration mode"""

    _config_exit = "end"
    """Command for existing from configuration mode to privilege exec"""

    _config_check = ")#"
    """Checking string in prompt. If it's exist im prompt - we are in configuration mode"""

    async def connect(self):
        """
        Basic asynchronous connection method for Cisco IOS like devices

        It connects to device and makes some preparation steps for working.
        Usual using 4 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for finding and setting device prompt
        * _enable() for getting privilege exec mode
        * _disable_paging() for non interact output in commands
        """
        logger.info("Host {}: Trying to connect to the device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        await self.enable_mode()
        await self._disable_paging()
        logger.info("Host {}: Has connected to the device".format(self._host))

    async def check_enable_mode(self):
        """Check if we are in privilege exec. Return boolean"""
        logger.info("Host {}: Checking privilege exec".format(self._host))
        check_string = type(self)._priv_check
        self._stdin.write(self._normalize_cmd("\n"))
        output = await self._read_until_prompt()
        return check_string in output

    async def enable_mode(self, pattern="password", re_flags=re.IGNORECASE):
        """Enter to privilege exec"""
        logger.info("Host {}: Entering to privilege exec".format(self._host))
        output = ""
        enable_command = type(self)._priv_enter
        if not await self.check_enable_mode():
            self._stdin.write(self._normalize_cmd(enable_command))
            output += await self._read_until_prompt_or_pattern(
                pattern=pattern, re_flags=re_flags
            )
            if re.search(pattern, output, re_flags):
                self._stdin.write(self._normalize_cmd(self._secret))
                output += await self._read_until_prompt()
            if not await self.check_enable_mode():
                raise ValueError("Failed to enter to privilege exec")
        return output

    async def exit_enable_mode(self):
        """Exit from privilege exec"""
        logger.info("Host {}: Exiting from privilege exec".format(self._host))
        output = ""
        exit_enable = type(self)._priv_exit
        if await self.check_enable_mode():
            self._stdin.write(self._normalize_cmd(exit_enable))
            output += await self._read_until_prompt()
            if await self.check_enable_mode():
                raise ValueError("Failed to exit from privilege exec")
        return output

    async def check_config_mode(self):
        """Checks if the device is in configuration mode or not"""
        logger.info("Host {}: Checking configuration mode".format(self._host))
        check_string = type(self)._config_check
        self._stdin.write(self._normalize_cmd("\n"))
        output = await self._read_until_prompt()
        return check_string in output

    async def config_mode(self):
        """Enter into config_mode"""
        logger.info("Host {}: Entering to configuration mode".format(self._host))
        output = ""
        config_command = type(self)._config_enter
        if not await self.check_config_mode():
            self._stdin.write(self._normalize_cmd(config_command))
            output = await self._read_until_prompt()
            if not await self.check_config_mode():
                raise ValueError("Failed to enter to configuration mode")
        return output

    async def exit_config_mode(self):
        """Exit from configuration mode"""
        logger.info("Host {}: Exiting from configuration mode".format(self._host))
        output = ""
        exit_config = type(self)._config_exit
        if await self.check_config_mode():
            self._stdin.write(self._normalize_cmd(exit_config))
            output = await self._read_until_prompt()
            if await self.check_config_mode():
                raise ValueError("Failed to exit from configuration mode")
        return output

    async def send_config_set(self, config_commands=None, exit_config_mode=True):
        """
        Sending configuration commands to Cisco IOS like devices
        Automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in conf mode
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of this commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self.config_mode()
        output += await super().send_config_set(config_commands=config_commands)

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output

    async def _cleanup(self):
        """ Any needed cleanup before closing connection """
        logger.info("Host {}: Cleanup session".format(self._host))
        await self.exit_config_mode()


================================================
FILE: netdev/vendors/juniper/__init__.py
================================================
from .juniper_junos import JuniperJunOS

__all__ = ["JuniperJunOS"]


================================================
FILE: netdev/vendors/juniper/juniper_junos.py
================================================
from netdev.logger import logger
from netdev.vendors.junos_like import JunOSLikeDevice


class JuniperJunOS(JunOSLikeDevice):
    """Class for working with Juniper JunOS"""

    _cli_check = ">"
    """Checking string for shell mode"""

    _cli_command = "cli"
    """Command for entering to cli mode"""

    async def connect(self):
        """
        Juniper JunOS asynchronous connection method

        It connects to device and makes some preparation steps for working:

        * _establish_connection() for connecting to device
        * cli_mode() for checking shell mode. If we are in shell - we automatically enter to cli
        * _set_base_prompt() for finding and setting device prompt
        * _disable_paging() for non interact output in commands
        """
        logger.info("Host {}: Trying to connect to the device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        await self.cli_mode()
        await self._disable_paging()
        logger.info("Host {}: Entering to cmdline mode".format(self._host))

    async def check_cli_mode(self):
        """Check if we are in cli mode. Return boolean"""
        logger.info("Host {}: Checking shell mode".format(self._host))
        cli_check = type(self)._cli_check
        self._stdin.write(self._normalize_cmd("\n"))
        output = await self._read_until_prompt()
        return cli_check in output

    async def cli_mode(self):
        """Enter to cli mode"""
        logger.info("Host {}: Entering to cli mode".format(self._host))
        output = ""
        cli_command = type(self)._cli_command
        if not await self.check_cli_mode():
            self._stdin.write(self._normalize_cmd(cli_command))
            output += await self._read_until_prompt()
            if not await self.check_cli_mode():
                raise ValueError("Failed to enter to cli mode")
        return output


================================================
FILE: netdev/vendors/junos_like.py
================================================
"""
JunOSLikeDevice Class is abstract class for using in Juniper JunOS like devices

Connection Method are based upon AsyncSSH and should be running in asyncio loop
"""

import re

from netdev.logger import logger
from netdev.vendors.base import BaseDevice


class JunOSLikeDevice(BaseDevice):
    """
    JunOSLikeDevice Class for working with Juniper JunOS like devices

    Juniper JunOS like devices having several concepts:

    * shell mode (csh). This is csh shell for FreeBSD. This mode is not covered by this Class.
    * cli mode (specific shell). The entire configuration is usual configured in this shell:

      * operation mode. This mode is using for getting information from device
      * configuration mode. This mode is using for configuration system
    """

    _delimiter_list = ["%", ">", "#"]
    """All this characters will stop reading from buffer. It mean the end of device prompt"""

    _pattern = r"\w+(\@[\-\w]*)?[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    _disable_paging_command = "set cli screen-length 0"
    """Command for disabling paging"""

    _config_enter = "configure"
    """Command for entering to configuration mode"""

    _config_exit = "exit configuration-mode"
    """Command for existing from configuration mode to privilege exec"""

    _config_check = "#"
    """Checking string in prompt. If it's exist im prompt - we are in configuration mode"""

    _commit_command = "commit"
    """Command for committing changes"""

    _commit_comment_command = "commit comment {}"
    """Command for committing changes with comment"""

    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually username or hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For JunOS devices base_pattern is "user(@[hostname])?[>|#]
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        prompt = prompt[:-1]
        # Strip off trailing terminator
        if "@" in prompt:
            prompt = prompt.split("@")[1]
        self._base_prompt = prompt
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

    async def check_config_mode(self):
        """Check if are in configuration mode. Return boolean"""
        logger.info("Host {}: Checking configuration mode".format(self._host))
        check_string = type(self)._config_check
        self._stdin.write(self._normalize_cmd("\n"))
        output = await self._read_until_prompt()
        return check_string in output

    async def config_mode(self):
        """Enter to configuration mode"""
        logger.info("Host {}: Entering to configuration mode".format(self._host))
        output = ""
        config_enter = type(self)._config_enter
        if not await self.check_config_mode():
            self._stdin.write(self._normalize_cmd(config_enter))
            output += await self._read_until_prompt()
            if not await self.check_config_mode():
                raise ValueError("Failed to enter to configuration mode")
        return output

    async def exit_config_mode(self):
        """Exit from configuration mode"""
        logger.info("Host {}: Exiting from configuration mode".format(self._host))
        output = ""
        config_exit = type(self)._config_exit
        if await self.check_config_mode():
            self._stdin.write(self._normalize_cmd(config_exit))
            output += await self._read_until_prompt()
            if await self.check_config_mode():
                raise ValueError("Failed to exit from configuration mode")
        return output

    async def send_config_set(
        self,
        config_commands=None,
        with_commit=True,
        commit_comment="",
        exit_config_mode=True,
    ):
        """
        Sending configuration commands to device
        By default automatically exits/enters configuration mode.

        :param list config_commands: iterable string list with commands for applying to network devices in system view
        :param bool with_commit: if true it commit all changes after applying all config_commands
        :param string commit_comment: message for configuration commit
        :param bool exit_config_mode: If true it will quit from configuration mode automatically
        :return: The output of these commands
        """

        if config_commands is None:
            return ""

        # Send config commands
        output = await self.config_mode()
        output += await super().send_config_set(config_commands=config_commands)
        if with_commit:
            commit = type(self)._commit_command
            if commit_comment:
                commit = type(self)._commit_comment_command.format(commit_comment)

            self._stdin.write(self._normalize_cmd(commit))
            output += await self._read_until_prompt()

        if exit_config_mode:
            output += await self.exit_config_mode()

        output = self._normalize_linefeeds(output)
        logger.debug(
            "Host {}: Config commands output: {}".format(self._host, repr(output))
        )
        return output


================================================
FILE: netdev/vendors/mikrotik/__init__.py
================================================
from .mikrotik_routeros import MikrotikRouterOS

__all__ = ["MikrotikRouterOS"]


================================================
FILE: netdev/vendors/mikrotik/mikrotik_routeros.py
================================================
import asyncssh
import asyncio

from netdev.exceptions import DisconnectError, TimeoutError
from netdev.logger import logger
from netdev.vendors.base import BaseDevice


class MikrotikRouterOS(BaseDevice):
    """Class for working with Mikrotik RouterOS"""

    def __init__(self, *args, **kwargs):
        """
        Initialize class for asynchronous working with network devices
        Invoke init with some special params (base_pattern and username)

        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object

        Mikrotik duplicate prompt in connection, so we should use pattern like
        prompt .* prompt.
        For disabling colors in CLI output we should user this username = username+c
        '+c' disables colors
        '+t' disable auto term capabilities detection
        '+200w' set terminal width to 200 rows
        """
        super().__init__(*args, **kwargs)
        self._base_pattern = r"\[.*?\] \>.*\[.*?\] \>"
        self._connect_params_dict["username"] += "+ct200w"
        self._ansi_escape_codes = True

    _pattern = r"\[.*?\] (\/.*?)?\>"

    async def connect(self):
        """
        Async Connection method

        RouterOS using 2 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for finding and setting device prompt
        """
        logger.info("Host {}: Connecting to device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        logger.info("Host {}: Connected to device".format(self._host))

    async def _establish_connection(self):
        """Establish SSH connection to the network device"""
        logger.info(
            "Host {}: Establishing connection to port {}".format(self._host, self._port)
        )
        output = ""
        # initiate SSH connection
        fut = asyncssh.connect(**self._connect_params_dict)
        try:
            self._conn = await asyncio.wait_for(fut, self._timeout)
        except asyncssh.DisconnectError as e:
            raise DisconnectError(self._host, e.code, e.reason)
        except asyncio.TimeoutError:
            raise TimeoutError(self._host)
        self._stdin, self._stdout, self._stderr = await self._conn.open_session(
            term_type="Dumb"
        )
        logger.info("Host {}: Connection is established".format(self._host))
        # Flush unnecessary data
        output = await self._read_until_prompt()
        logger.debug(
            "Host {}: Establish Connection Output: {}".format(self._host, repr(output))
        )
        return output

    async def _set_base_prompt(self):
        """
        Setting two important vars
        * base_prompt - textual prompt in CLI (usually hostname)
        * base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Mikrotik devices base_pattern is "r"\[.*?\] (\/.*?)?\>"
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        self._base_pattern = type(self)._pattern
        prompt = await self._find_prompt()
        user = ""
        # Strip off trailing terminator
        prompt = prompt[1:-3]
        if "@" in prompt:
            prompt = prompt.split("@")[1]
        self._base_prompt = prompt
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt

    async def _find_prompt(self):
        """Finds the current network device prompt, last line only."""
        logger.info("Host {}: Finding prompt".format(self._host))
        self._stdin.write("\r")
        prompt = ""
        prompt = await self._read_until_prompt()
        prompt = prompt.strip()
        if self._ansi_escape_codes:
            prompt = self._strip_ansi_escape_codes(prompt)
        if not prompt:
            raise ValueError("Unable to find prompt: {0}".format(prompt))
        logger.debug("Host {}: Prompt: {}".format(self._host, prompt))
        return prompt

    @staticmethod
    def _normalize_cmd(command):
        """Specific trailing newline for Mikrotik"""
        command = command.rstrip("\n")
        command += "\r"
        return command


================================================
FILE: netdev/vendors/terminal/__init__.py
================================================
from .terminal import Terminal

__all__ = ["Terminal"]


================================================
FILE: netdev/vendors/terminal/terminal.py
================================================
import re

from netdev.logger import logger
from netdev.vendors.base import BaseDevice


class Terminal(BaseDevice):
    """Class for working with General Terminal"""

    def __init__(self, delimeter_list=None, *args, **kwargs):
        """
        Initialize class for asynchronous working with network devices
        Invoke init with some special params (base_pattern and username)

        :param str host: device hostname or ip address for connection
        :param str username: username for logging to device
        :param str password: user password for logging to device
        :param int port: ssh port for connection. Default is 22
        :param str device_type: network device type
        :param known_hosts: file with known hosts. Default is None (no policy). With () it will use default file
        :param delimeter_list: list with delimeters
        :param str local_addr: local address for binding source of tcp connection
        :param client_keys: path for client keys. Default in None. With () it will use default file in OS
        :param str passphrase: password for encrypted client keys
        :param float timeout: timeout in second for getting information from channel
        :param loop: asyncio loop object
        """
        super().__init__(*args, **kwargs)
        if delimeter_list is not None:
            self._delimiter_list = delimeter_list

    _delimiter_list = ["$", "#"]
    """All this characters will stop reading from buffer. It mean the end of device prompt"""

    _pattern = r"[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    async def connect(self):
        """
        Async Connection method

        General Terminal using 2 functions:

        * _establish_connection() for connecting to device
        * _set_base_prompt() for setting base pattern without setting base prompt
        """
        logger.info("Host {}: Connecting to device".format(self._host))
        await self._establish_connection()
        await self._set_base_prompt()
        logger.info("Host {}: Connected to device".format(self._host))

    async def _set_base_prompt(self):
        """Setting base pattern"""
        logger.info("Host {}: Setting base prompt".format(self._host))
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(delimiters=delimiters)
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt


================================================
FILE: netdev/vendors/ubiquiti/__init__.py
================================================
from .ubiquity_edge import UbiquityEdgeSwitch

__all__ = ["UbiquityEdgeSwitch"]


================================================
FILE: netdev/vendors/ubiquiti/ubiquity_edge.py
================================================
"""Subclass specific to Ubiquity Edge Switch"""
import re

from netdev.logger import logger
from netdev.vendors.ios_like import IOSLikeDevice


class UbiquityEdgeSwitch(IOSLikeDevice):
    """Class for working with Ubiquity Edge Switches"""

    _pattern = r"\({prompt}.*?\) (\(.*?\))?[{delimiters}]"
    """Pattern for using in reading buffer. When it found processing ends"""

    _config_enter = "configure"
    """Command for entering to configuration mode"""

    async def _set_base_prompt(self):
        """
        Setting two important vars
            base_prompt - textual prompt in CLI (usually hostname)
            base_pattern - regexp for finding the end of command. IT's platform specific parameter

        For Ubiquity devices base_pattern is "(prompt) (\(.*?\))?[>|#]"
        """
        logger.info("Host {}: Setting base prompt".format(self._host))
        prompt = await self._find_prompt()
        # Strip off trailing terminator
        self._base_prompt = prompt[1:-3]
        delimiters = map(re.escape, type(self)._delimiter_list)
        delimiters = r"|".join(delimiters)
        base_prompt = re.escape(self._base_prompt[:12])
        pattern = type(self)._pattern
        self._base_pattern = pattern.format(prompt=base_prompt, delimiters=delimiters)
        logger.debug("Host {}: Base Prompt: {}".format(self._host, self._base_prompt))
        logger.debug("Host {}: Base Pattern: {}".format(self._host, self._base_pattern))
        return self._base_prompt


================================================
FILE: netdev/version.py
================================================
""" Netdev Version information
"""

__version__ = "0.9.3"
__author__ = "Yakovlev Sergey"
__author_email__ = "selfuryon@gmail.com"
__url__ = "http://netdev.readthedocs.io/"


================================================
FILE: pyproject.toml
================================================
[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"

[tool.poetry]
name = "netdev"
version = "0.9.3"
description = "Asynchronous multi-vendor library for interacting with network devices"
authors = ["Sergey Yakovlev <selfuryon@gmail.com>"]
license = "Apache-2.0"
readme = "README.rst"
homepage = "https://netdev.readthedocs.io"
documentation = "https://netdev.readthedocs.io"
repository = "https://github.com/selfuryon/netdev"
keywords = ['netdev','network', 'netmiko', 'asyncio']
classifiers = [
        "Development Status :: 4 - Beta",
        "Framework :: AsyncIO",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Intended Audience :: Developers",
        "Intended Audience :: System Administrators",
        "Intended Audience :: Telecommunications Industry",
        "Topic :: System :: Networking",
        "Topic :: System :: Systems Administration",
]

[tool.poetry.dependencies]
python = "^3.6"
PyYAML = "^5.1"
asyncssh = "^1.15"
sphinx = { version = "^2.0", optional = true}
sphinx_rtd_theme = { version = "^0.4", optional = true}

[tool.poetry.dev-dependencies]
PyYAML = "^5.1"
asyncssh = "^1.16"
black = {version = "^19.3b0",allows-prereleases = true}
pytest = "^4.0"
pylint = "^2.3"
sphinx = "^2.0"
sphinx_rtd_theme = "^0.4"

[tool.poetry.extras]
docs = ["sphinx", "sphinx_rtd_theme"]



================================================
FILE: tests/test_arista_eos.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestArista(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'arista_eos']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as arista:
                    out = await arista.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as arista:
                    commands = ["dir", "show ver", "show run"]
                    for cmd in commands:
                        out = await arista.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as arista:
                    commands = ["vlan 1", "exit"]
                    out = await arista.send_config_set(commands)
                    self.assertIn("vlan 1", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as arista:
                    out = await arista.send_command('sh run | i hostname')
                    self.assertIn(arista.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as arista:
                        await arista.send_command('sh run | i hostname')

        self.loop.run_until_complete(task())

    def test_interactive_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as arista:
                    out = await arista.send_command("erase startup", pattern=r'\[confirm\]', strip_command=False)
                    out += await arista.send_command("no", strip_command=False)
                    out += await arista.send_command("show startup", strip_command=False)
                    self.assertIn('Startup-config last modified', out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_aruba_aos_6.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestAOS6(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'aruba_aos_6']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    out = await aos.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    commands = ["dir", "show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await aos.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    commands = ["interface loopback", "exit"]
                    out = await aos.send_config_set(commands)
                    self.assertIn("interface loopback", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    out = await aos.send_command('sh run | i hostname')
                    self.assertIn(aos.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as aos:
                        await aos.send_command('sh run | i hostname')

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_aruba_aos_8.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestAOS8(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'aruba_aos_8']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    out = await aos.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    commands = ["dir", "show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await aos.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    commands = ["interface loopback", "exit"]
                    out = await aos.send_config_set(commands)
                    self.assertIn("loopback", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as aos:
                    out = await aos.send_command('sh run | i hostname')
                    self.assertIn(aos.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as aos:
                        await aos.send_command('sh run | i hostname')

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_cisco_asa.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestASA(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'cisco_asa']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as asa:
                    out = await asa.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as asa:
                        await asa.send_command('show run | i hostname')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as asa:
                    commands = ["show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await asa.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as asa:
                    commands = ["interface Management0/0", "exit"]
                    out = await asa.send_config_set(commands)
                    self.assertIn("interface Management0/0", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_interactive_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as asa:
                    out = await asa.send_command("copy r scp:", pattern=r'\[running-config\]\?', strip_command=False)
                    out += await asa.send_command("\n", pattern=r'\[\]\?', strip_command=False)
                    out += await asa.send_command("\n", strip_command=False)
                    self.assertIn('%Error', out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_cisco_ios.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestIOS(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'cisco_ios']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as ios:
                        await ios.send_command('show run | i hostname')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    commands = ["dir", "show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await ios.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    commands = ["line con 0", "exit"]
                    out = await ios.send_config_set(commands)
                    self.assertIn("line con 0", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command('sh run | i hostname')
                    self.assertIn(ios.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_interactive_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command("conf", pattern=r'\[terminal\]\?', strip_command=False)
                    out += await ios.send_command("term", strip_command=False)
                    out += await ios.send_command("exit", strip_command=False)
                    self.assertIn('Enter configuration commands', out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_cisco_iossg3xx.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestIOSSG3XX(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'cisco_sg3xx']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as ios:
                        await ios.send_command('show run | i hostname')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    commands = ["dir", "show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await ios.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    commands = ["line con", "exit"]
                    out = await ios.send_config_set(commands)
                    self.assertIn("line con", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command('sh run | i hostname')
                    self.assertIn(ios.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_interactive_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command("conf", pattern=r'\[terminal\]\?', strip_command=False)
                    out += await ios.send_command("term", strip_command=False)
                    out += await ios.send_command("exit", strip_command=False)
                    self.assertIn('Enter configuration commands', out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_cisco_iosxr.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestIOSXR(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'cisco_ios_xr']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as iosxr:
                    out = await iosxr.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as iosxr:
                        await iosxr.send_command('show run | i hostname')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as iosxr:
                    commands = ["dir", "show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await iosxr.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as iosxr:
                    commands = ["line con 0", "exit"]
                    out = await iosxr.send_config_set(commands)
                    self.assertIn("line con 0", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_interactive_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    out = await ios.send_command("conf", strip_command=False)
                    out += await ios.send_command("hostname test", strip_command=False)
                    out += await ios.send_command("exit", pattern=r'Uncommitted changes found', strip_command=False)
                    out += await ios.send_command("no", strip_command=False)
                    self.assertIn('commit them before exiting', out)

        self.loop.run_until_complete(task())

    def test_exit_without_commit(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as ios:
                    commands = ["interface GigabitEthernet 0/0/0/0", "service-policy input 1"]
                    out = await ios.send_config_set(commands, with_commit=False)
                    self.assertIn('Uncommitted changes found', out)

        self.loop.run_until_complete(task())

    def test_errors_in_commit(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.CommitError):
                    async with netdev.create(**dev) as ios:
                        commands = ["interface GigabitEthernet 0/0/0/0", "service-policy input 1"]
                        await ios.send_config_set(commands)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_cisco_nxos.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
netdev.logger.setLevel(logging.DEBUG)
config_path = 'config.yaml'


class TestNXOS(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'cisco_nxos']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as nxos:
                    out = await nxos.send_command('show run | i hostname')
                    self.assertIn("hostname", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as nxos:
                        await nxos.send_command('show run | i hostname')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as nxos:
                    commands = ["dir", "show ver", "show run", "show ssh key"]
                    for cmd in commands:
                        out = await nxos.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as nxos:
                    commands = ["line con", "exit"]
                    out = await nxos.send_config_set(commands)
                    self.assertIn("line con", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as nxos:
                    out = await nxos.send_command('sh run | i hostname')
                    self.assertIn(nxos.base_prompt, out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_fujitsu_switch.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestFujitsu(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'fujitsu_switch']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_run_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as fuj:
                    out = await fuj.send_command('show run | i snmp')
                    self.assertIn("snmp", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as fuj:
                        await fuj.send_command('show run | i snmp')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as fuj:
                    commands = ["dir", "show ver", "show run", "show ssh"]
                    for cmd in commands:
                        out = await fuj.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as fuj:
                    commands = ["vlan database", "exit"]
                    out = await fuj.send_config_set(commands)
                    self.assertIn("vlan database", out)
                    self.assertIn("exit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as fuj:
                    out = await fuj.send_command("sh run | i 'switch '")
                    self.assertIn(fuj.base_prompt, out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_hp_comware.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestComware(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'hp_comware']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_sysname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    out = await hp.send_command('display cur | i sysname')
                    self.assertIn("sysname", out)

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    commands = ["dir", "display ver", "display cur", "display ssh server status"]
                    for cmd in commands:
                        out = await hp.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    commands = ["vlan 1", "quit"]
                    out = await hp.send_config_set(commands)
                    self.assertIn("vlan 1", out)
                    self.assertIn("quit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    out = await hp.send_command('display cur | i sysname')
                    self.assertIn(hp.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as hp:
                        await hp.send_command('display cur | i sysname')

        self.loop.run_until_complete(task())

================================================
FILE: tests/test_hp_comware_limited.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestComwareLimited(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'hp_comware_limited']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_sysname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    out = await hp.send_command('display cur | i sysname')
                    self.assertIn("sysname", out)

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    commands = ["dir", "display ver", "display cur", "display ssh server status"]
                    for cmd in commands:
                        out = await hp.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    commands = ["vlan 1", "quit"]
                    out = await hp.send_config_set(commands)
                    self.assertIn("vlan 1", out)
                    self.assertIn("quit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hp:
                    out = await hp.send_command('display cur | i sysname')
                    self.assertIn(hp.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as hp:
                        await hp.send_command('display cur | i sysname')

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_huawei.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestHuawei(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'huawei']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_sysname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as huawei:
                    out = await huawei.send_command('display cur | i sysname')
                    self.assertIn("sysname", out)

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as huawei:
                    commands = ["dir", "display ver", "display cur"]
                    for cmd in commands:
                        out = await huawei.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as huawei:
                    commands = ["vlan 1", "quit"]
                    out = await huawei.send_config_set(commands)
                    self.assertIn("vlan 1", out)
                    self.assertIn("quit", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as huawei:
                    out = await huawei.send_command('display cur | i sysname')
                    self.assertIn(huawei.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as huawei:
                        await huawei.send_command('display cur | i sysname')

        self.loop.run_until_complete(task())

================================================
FILE: tests/test_hw1000.py
================================================
import asyncio
import logging
import unittest
import yaml
import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'

class TestHW1000(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.load(devs)
                params = [p for p in devices if p['device_type'] == 'hw1000']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_simple_command(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hw:
                    out = await hw.send_command("inet show snmp")
                    self.assertIn('SNMP',out)
        self.loop.run_until_complete(task())

    def test_long_command(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hw:
                    out = await hw.send_command("inet show interface")
                    out_len=(len(out.split('\n')))
                    self.assertGreater(out_len,10)
        self.loop.run_until_complete(task())

    def test_linux_mode(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hw:
                    out = await hw.enter_shell_mode()
                    out = await hw.send_command("id")
                    self.assertIn('uid=0(root)',out)
        self.loop.run_until_complete(task())

    def test_linux_mode_indepotence(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as hw:
                    out = await hw.enter_shell_mode()
                    out = await hw.enter_shell_mode()
                    out = await hw.send_command("id")
                    self.assertIn('uid=0(root)',out)
        self.loop.run_until_complete(task())


================================================
FILE: tests/test_juniper_junos.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestJunOS(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'juniper_junos']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_system_hostname(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as junos:
                    out = await junos.send_command('show configuration system host-name')
                    self.assertIn("host-name", out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as junos:
                        await junos.send_command('show configuration system host-name')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as junos:
                    commands = ["show ver", "show conf", "show chassis firmware"]
                    for cmd in commands:
                        out = await junos.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_config_set(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as junos:
                    commands = ["edit system", "edit login"]
                    out = await junos.send_config_set(commands, with_commit=False)
                    self.assertIn("edit system", out)
                    self.assertIn("edit login", out)

        self.loop.run_until_complete(task())

    def test_base_prompt(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as junos:
                    out = await junos.send_command('show configuration system host-name')
                    self.assertIn(junos.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_interactive_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as junos:
                    commands = ["set system login message 123", "delete system login message 123"]
                    out = await junos.send_config_set(commands, with_commit=False, exit_config_mode=False)
                    out += await junos.send_command("exit", pattern=r'Exit with uncommitted changes\?',
                                                    strip_command=False)
                    out += await junos.send_command("no", strip_command=False)
                    out += await junos.send_command("rollback 0", strip_command=False)
                    out += await junos.send_command("exit configuration-mode", strip_command=False)
                    self.assertIn('load complete', out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_mikrotik_routeros.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestRouterOS(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'mikrotik_routeros']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_system_identity(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as mik:
                    out = await mik.send_command('/system identity print')
                    self.assertIn(mik.base_prompt, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as mik:
                        await mik.send_command('/system identity print')

        self.loop.run_until_complete(task())

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as mik:
                    commands = ["/ip address print", "/system package print", " /user print"]
                    for cmd in commands:
                        out = await mik.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())


================================================
FILE: tests/test_terminal.py
================================================
import asyncio
import logging
import unittest

import yaml

import netdev

logging.basicConfig(filename='unittest.log', level=logging.DEBUG)
config_path = 'config.yaml'


class TestTerminal(unittest.TestCase):
    @staticmethod
    def load_credits():
        with open(config_path, 'r') as conf:
            config = yaml.safe_load(conf)
            with open(config['device_list'], 'r') as devs:
                devices = yaml.safe_load(devs)
                params = [p for p in devices if p['device_type'] == 'terminal']
                return params

    def setUp(self):
        self.loop = asyncio.new_event_loop()
        self.loop.set_debug(False)
        asyncio.set_event_loop(self.loop)
        self.devices = self.load_credits()
        self.assertFalse(len(self.devices) == 0)

    def test_show_several_commands(self):
        async def task():
            for dev in self.devices:
                async with netdev.create(**dev) as terminal:
                    commands = ["ls -al", "pwd", "echo test"]
                    for cmd in commands:
                        out = await terminal.send_command(cmd, strip_command=False)
                        self.assertIn(cmd, out)

        self.loop.run_until_complete(task())

    def test_timeout(self):
        async def task():
            for dev in self.devices:
                with self.assertRaises(netdev.TimeoutError):
                    async with netdev.create(**dev, timeout=0.1) as terminal:
                        out = await terminal.send_command("uname -a")

        self.loop.run_until_complete(task())
Download .txt
gitextract_r978uqi3/

├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── ask_question.md
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .readthedocs.yml
├── CONTRIBUTING.rst
├── LICENSE
├── README.rst
├── docs/
│   ├── api.rst
│   ├── conf.py
│   ├── examples.rst
│   ├── index.rst
│   └── overview.rst
├── examples/
│   ├── alcatel_aos.py
│   ├── arista_eos.py
│   ├── aruba_aos_6.py
│   ├── aruba_aos_8.py
│   ├── cisco_asa.py
│   ├── cisco_ios.py
│   ├── cisco_iosxr.py
│   ├── cisco_nxos.py
│   ├── cisco_sg3xx.py
│   ├── fujitsu_switch.py
│   ├── hp_comware.py
│   ├── hp_comware_limited.py
│   ├── juniper_junos.py
│   ├── mikrotik_routeros.py
│   └── terminal.py
├── netdev/
│   ├── __init__.py
│   ├── dispatcher.py
│   ├── exceptions.py
│   ├── logger.py
│   ├── vendors/
│   │   ├── __init__.py
│   │   ├── alcatel/
│   │   │   ├── __init__.py
│   │   │   └── alcatel_aos.py
│   │   ├── arista/
│   │   │   ├── __init__.py
│   │   │   └── arista_eos.py
│   │   ├── aruba/
│   │   │   ├── __init__.py
│   │   │   ├── aruba_aos_6.py
│   │   │   └── aruba_aos_8.py
│   │   ├── base.py
│   │   ├── cisco/
│   │   │   ├── __init__.py
│   │   │   ├── cisco_asa.py
│   │   │   ├── cisco_ios.py
│   │   │   ├── cisco_iosxr.py
│   │   │   ├── cisco_nxos.py
│   │   │   └── cisco_sg3xx.py
│   │   ├── comware_like.py
│   │   ├── fujitsu/
│   │   │   ├── __init__.py
│   │   │   └── fujitsu_switch.py
│   │   ├── hp/
│   │   │   ├── __init__.py
│   │   │   ├── hp_comware.py
│   │   │   └── hp_comware_limited.py
│   │   ├── huawei/
│   │   │   ├── __init__.py
│   │   │   └── huawei.py
│   │   ├── infotecs/
│   │   │   ├── HW1000.py
│   │   │   └── __init__.py
│   │   ├── ios_like.py
│   │   ├── juniper/
│   │   │   ├── __init__.py
│   │   │   └── juniper_junos.py
│   │   ├── junos_like.py
│   │   ├── mikrotik/
│   │   │   ├── __init__.py
│   │   │   └── mikrotik_routeros.py
│   │   ├── terminal/
│   │   │   ├── __init__.py
│   │   │   └── terminal.py
│   │   └── ubiquiti/
│   │       ├── __init__.py
│   │       └── ubiquity_edge.py
│   └── version.py
├── pyproject.toml
└── tests/
    ├── test_arista_eos.py
    ├── test_aruba_aos_6.py
    ├── test_aruba_aos_8.py
    ├── test_cisco_asa.py
    ├── test_cisco_ios.py
    ├── test_cisco_iossg3xx.py
    ├── test_cisco_iosxr.py
    ├── test_cisco_nxos.py
    ├── test_fujitsu_switch.py
    ├── test_hp_comware.py
    ├── test_hp_comware_limited.py
    ├── test_huawei.py
    ├── test_hw1000.py
    ├── test_juniper_junos.py
    ├── test_mikrotik_routeros.py
    └── test_terminal.py
Download .txt
SYMBOL INDEX (270 symbols across 55 files)

FILE: examples/alcatel_aos.py
  function task (line 7) | async def task(param):
  function main (line 39) | async def main():

FILE: examples/arista_eos.py
  function task (line 14) | async def task(param):
  function run (line 25) | async def run():

FILE: examples/aruba_aos_6.py
  function task (line 14) | async def task(param):
  function run (line 28) | async def run():

FILE: examples/aruba_aos_8.py
  function task (line 14) | async def task(param):
  function run (line 28) | async def run():

FILE: examples/cisco_asa.py
  function task (line 14) | async def task(param):
  function run (line 26) | async def run():

FILE: examples/cisco_ios.py
  function task (line 14) | async def task(param):
  function run (line 33) | async def run():

FILE: examples/cisco_iosxr.py
  function task (line 14) | async def task(param):
  function run (line 37) | async def run():

FILE: examples/cisco_nxos.py
  function task (line 14) | async def task(param):
  function run (line 21) | async def run():

FILE: examples/cisco_sg3xx.py
  function task (line 7) | async def task(param):
  function main (line 24) | async def main():

FILE: examples/fujitsu_switch.py
  function task (line 13) | async def task(param):
  function run (line 23) | async def run():

FILE: examples/hp_comware.py
  function task (line 14) | async def task(param):
  function run (line 28) | async def run():

FILE: examples/hp_comware_limited.py
  function task (line 14) | async def task(param):
  function run (line 28) | async def run():

FILE: examples/juniper_junos.py
  function task (line 14) | async def task(param):
  function run (line 36) | async def run():

FILE: examples/mikrotik_routeros.py
  function task (line 14) | async def task(param):
  function run (line 26) | async def run():

FILE: examples/terminal.py
  function task (line 14) | async def task(param):
  function run (line 25) | async def run():

FILE: netdev/dispatcher.py
  function create (line 48) | def create(*args, **kwargs):

FILE: netdev/exceptions.py
  class DisconnectError (line 1) | class DisconnectError(Exception):
    method __init__ (line 4) | def __init__(self, ip_address, code, reason):
  class TimeoutError (line 12) | class TimeoutError(Exception):
    method __init__ (line 15) | def __init__(self, ip_address):
  class CommitError (line 21) | class CommitError(Exception):
    method __init__ (line 24) | def __init__(self, ip_address, reason):

FILE: netdev/vendors/alcatel/alcatel_aos.py
  class AlcatelAOS (line 6) | class AlcatelAOS(BaseDevice):
    method _read_until_prompt_or_pattern (line 10) | async def _read_until_prompt_or_pattern(self, pattern="", re_flags=0):

FILE: netdev/vendors/arista/arista_eos.py
  class AristaEOS (line 4) | class AristaEOS(IOSLikeDevice):

FILE: netdev/vendors/aruba/aruba_aos_6.py
  class ArubaAOS6 (line 9) | class ArubaAOS6(IOSLikeDevice):
    method _set_base_prompt (line 24) | async def _set_base_prompt(self):

FILE: netdev/vendors/aruba/aruba_aos_8.py
  class ArubaAOS8 (line 9) | class ArubaAOS8(IOSLikeDevice):
    method _set_base_prompt (line 24) | async def _set_base_prompt(self):

FILE: netdev/vendors/base.py
  class BaseDevice (line 16) | class BaseDevice(object):
    method __init__ (line 21) | def __init__(
    method base_prompt (line 192) | def base_prompt(self):
    method __aenter__ (line 196) | async def __aenter__(self):
    method __aexit__ (line 201) | async def __aexit__(self, exc_type, exc_val, exc_tb):
    method connect (line 205) | async def connect(self):
    method _establish_connection (line 222) | async def _establish_connection(self):
    method _set_base_prompt (line 249) | async def _set_base_prompt(self):
    method _disable_paging (line 272) | async def _disable_paging(self):
    method _find_prompt (line 289) | async def _find_prompt(self):
    method send_command (line 307) | async def send_command(
    method _strip_prompt (line 348) | def _strip_prompt(self, a_string):
    method _read_until_prompt (line 358) | async def _read_until_prompt(self):
    method _read_until_pattern (line 362) | async def _read_until_pattern(self, pattern="", re_flags=0):
    method _read_until_prompt_or_pattern (line 383) | async def _read_until_prompt_or_pattern(self, pattern="", re_flags=0):
    method _strip_backspaces (line 407) | def _strip_backspaces(output):
    method _strip_command (line 413) | def _strip_command(command_string, output):
    method _normalize_linefeeds (line 433) | def _normalize_linefeeds(a_string):
    method _normalize_cmd (line 439) | def _normalize_cmd(command):
    method send_config_set (line 445) | async def send_config_set(self, config_commands=None):
    method _strip_ansi_escape_codes (line 481) | def _strip_ansi_escape_codes(string_buffer):
    method _cleanup (line 550) | async def _cleanup(self):
    method disconnect (line 555) | async def disconnect(self):

FILE: netdev/vendors/cisco/cisco_asa.py
  class CiscoASA (line 9) | class CiscoASA(IOSLikeDevice):
    method __init__ (line 12) | def __init__(self, *args, **kwargs):
    method multiple_mode (line 35) | def multiple_mode(self):
    method connect (line 39) | async def connect(self):
    method _set_base_prompt (line 59) | async def _set_base_prompt(self):
    method _check_multiple_mode (line 83) | async def _check_multiple_mode(self):

FILE: netdev/vendors/cisco/cisco_ios.py
  class CiscoIOS (line 4) | class CiscoIOS(IOSLikeDevice):

FILE: netdev/vendors/cisco/cisco_iosxr.py
  class CiscoIOSXR (line 6) | class CiscoIOSXR(IOSLikeDevice):
    method send_config_set (line 24) | async def send_config_set(
    method exit_config_mode (line 82) | async def exit_config_mode(self):
    method _cleanup (line 99) | async def _cleanup(self):

FILE: netdev/vendors/cisco/cisco_nxos.py
  class CiscoNXOS (line 6) | class CiscoNXOS(IOSLikeDevice):
    method _normalize_linefeeds (line 10) | def _normalize_linefeeds(a_string):

FILE: netdev/vendors/cisco/cisco_sg3xx.py
  class CiscoSG3XX (line 5) | class CiscoSG3XX(IOSLikeDevice):
    method __init__ (line 8) | def __init__(self, *args, **kwargs):

FILE: netdev/vendors/comware_like.py
  class ComwareLikeDevice (line 13) | class ComwareLikeDevice(BaseDevice):
    method _set_base_prompt (line 44) | async def _set_base_prompt(self):
    method _check_system_view (line 71) | async def _check_system_view(self):
    method _system_view (line 79) | async def _system_view(self):
    method _exit_system_view (line 91) | async def _exit_system_view(self):
    method send_config_set (line 103) | async def send_config_set(self, config_commands=None, exit_system_view...

FILE: netdev/vendors/fujitsu/fujitsu_switch.py
  class FujitsuSwitch (line 9) | class FujitsuSwitch(IOSLikeDevice):
    method _set_base_prompt (line 21) | async def _set_base_prompt(self):
    method _normalize_linefeeds (line 43) | def _normalize_linefeeds(a_string):

FILE: netdev/vendors/hp/hp_comware.py
  class HPComware (line 4) | class HPComware(ComwareLikeDevice):

FILE: netdev/vendors/hp/hp_comware_limited.py
  class HPComwareLimited (line 5) | class HPComwareLimited(ComwareLikeDevice):
    method __init__ (line 8) | def __init__(self, cmdline_password=u"", *args, **kwargs):
    method connect (line 34) | async def connect(self):
    method _cmdline_mode_enter (line 53) | async def _cmdline_mode_enter(self):

FILE: netdev/vendors/huawei/huawei.py
  class Huawei (line 5) | class Huawei(ComwareLikeDevice):
    method _set_base_prompt (line 11) | async def _set_base_prompt(self):

FILE: netdev/vendors/infotecs/HW1000.py
  class HW1000 (line 8) | class HW1000(BaseDevice):
    method __init__ (line 18) | def __init__(self, secret=u'',preempt_privilege=False, *args, **kwargs):
    method connect (line 64) | async def connect(self):
    method check_enable_mode (line 81) | async def check_enable_mode(self):
    method enable_mode (line 89) | async def enable_mode(self, pattern='password', re_flags=re.IGNORECASE):
    method exit_enable_mode (line 113) | async def exit_enable_mode(self):
    method check_shell_mode (line 125) | async def check_shell_mode(self):
    method enter_shell_mode (line 134) | async def enter_shell_mode(self,re_flags=re.IGNORECASE):
    method exit_shell_mode (line 152) | async def exit_shell_mode(self):
    method _cleanup (line 165) | async def _cleanup(self):

FILE: netdev/vendors/ios_like.py
  class IOSLikeDevice (line 13) | class IOSLikeDevice(BaseDevice):
    method __init__ (line 24) | def __init__(self, secret=u"", *args, **kwargs):
    method connect (line 62) | async def connect(self):
    method check_enable_mode (line 81) | async def check_enable_mode(self):
    method enable_mode (line 89) | async def enable_mode(self, pattern="password", re_flags=re.IGNORECASE):
    method exit_enable_mode (line 106) | async def exit_enable_mode(self):
    method check_config_mode (line 118) | async def check_config_mode(self):
    method config_mode (line 126) | async def config_mode(self):
    method exit_config_mode (line 138) | async def exit_config_mode(self):
    method send_config_set (line 150) | async def send_config_set(self, config_commands=None, exit_config_mode...
    method _cleanup (line 176) | async def _cleanup(self):

FILE: netdev/vendors/juniper/juniper_junos.py
  class JuniperJunOS (line 5) | class JuniperJunOS(JunOSLikeDevice):
    method connect (line 14) | async def connect(self):
    method check_cli_mode (line 32) | async def check_cli_mode(self):
    method cli_mode (line 40) | async def cli_mode(self):

FILE: netdev/vendors/junos_like.py
  class JunOSLikeDevice (line 13) | class JunOSLikeDevice(BaseDevice):
    method _set_base_prompt (line 50) | async def _set_base_prompt(self):
    method check_config_mode (line 74) | async def check_config_mode(self):
    method config_mode (line 82) | async def config_mode(self):
    method exit_config_mode (line 94) | async def exit_config_mode(self):
    method send_config_set (line 106) | async def send_config_set(

FILE: netdev/vendors/mikrotik/mikrotik_routeros.py
  class MikrotikRouterOS (line 9) | class MikrotikRouterOS(BaseDevice):
    method __init__ (line 12) | def __init__(self, *args, **kwargs):
    method connect (line 43) | async def connect(self):
    method _establish_connection (line 57) | async def _establish_connection(self):
    method _set_base_prompt (line 82) | async def _set_base_prompt(self):
    method _find_prompt (line 103) | async def _find_prompt(self):
    method _normalize_cmd (line 118) | def _normalize_cmd(command):

FILE: netdev/vendors/terminal/terminal.py
  class Terminal (line 7) | class Terminal(BaseDevice):
    method __init__ (line 10) | def __init__(self, delimeter_list=None, *args, **kwargs):
    method connect (line 38) | async def connect(self):
    method _set_base_prompt (line 52) | async def _set_base_prompt(self):

FILE: netdev/vendors/ubiquiti/ubiquity_edge.py
  class UbiquityEdgeSwitch (line 8) | class UbiquityEdgeSwitch(IOSLikeDevice):
    method _set_base_prompt (line 17) | async def _set_base_prompt(self):

FILE: tests/test_arista_eos.py
  class TestArista (line 13) | class TestArista(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_show_several_commands (line 39) | def test_show_several_commands(self):
    method test_config_set (line 50) | def test_config_set(self):
    method test_base_prompt (line 61) | def test_base_prompt(self):
    method test_timeout (line 70) | def test_timeout(self):
    method test_interactive_commands (line 79) | def test_interactive_commands(self):

FILE: tests/test_aruba_aos_6.py
  class TestAOS6 (line 13) | class TestAOS6(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_show_several_commands (line 39) | def test_show_several_commands(self):
    method test_config_set (line 50) | def test_config_set(self):
    method test_base_prompt (line 61) | def test_base_prompt(self):
    method test_timeout (line 70) | def test_timeout(self):

FILE: tests/test_aruba_aos_8.py
  class TestAOS8 (line 13) | class TestAOS8(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_show_several_commands (line 39) | def test_show_several_commands(self):
    method test_config_set (line 50) | def test_config_set(self):
    method test_base_prompt (line 61) | def test_base_prompt(self):
    method test_timeout (line 70) | def test_timeout(self):

FILE: tests/test_cisco_asa.py
  class TestASA (line 13) | class TestASA(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):
    method test_config_set (line 59) | def test_config_set(self):
    method test_interactive_commands (line 70) | def test_interactive_commands(self):

FILE: tests/test_cisco_ios.py
  class TestIOS (line 13) | class TestIOS(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):
    method test_config_set (line 59) | def test_config_set(self):
    method test_base_prompt (line 70) | def test_base_prompt(self):
    method test_interactive_commands (line 79) | def test_interactive_commands(self):

FILE: tests/test_cisco_iossg3xx.py
  class TestIOSSG3XX (line 13) | class TestIOSSG3XX(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):
    method test_config_set (line 59) | def test_config_set(self):
    method test_base_prompt (line 70) | def test_base_prompt(self):
    method test_interactive_commands (line 79) | def test_interactive_commands(self):

FILE: tests/test_cisco_iosxr.py
  class TestIOSXR (line 13) | class TestIOSXR(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):
    method test_config_set (line 59) | def test_config_set(self):
    method test_interactive_commands (line 70) | def test_interactive_commands(self):
    method test_exit_without_commit (line 82) | def test_exit_without_commit(self):
    method test_errors_in_commit (line 92) | def test_errors_in_commit(self):

FILE: tests/test_cisco_nxos.py
  class TestNXOS (line 14) | class TestNXOS(unittest.TestCase):
    method load_credits (line 16) | def load_credits():
    method setUp (line 24) | def setUp(self):
    method test_show_run_hostname (line 31) | def test_show_run_hostname(self):
    method test_timeout (line 40) | def test_timeout(self):
    method test_show_several_commands (line 49) | def test_show_several_commands(self):
    method test_config_set (line 60) | def test_config_set(self):
    method test_base_prompt (line 71) | def test_base_prompt(self):

FILE: tests/test_fujitsu_switch.py
  class TestFujitsu (line 13) | class TestFujitsu(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_run_hostname (line 30) | def test_show_run_hostname(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):
    method test_config_set (line 59) | def test_config_set(self):
    method test_base_prompt (line 70) | def test_base_prompt(self):

FILE: tests/test_hp_comware.py
  class TestComware (line 13) | class TestComware(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_sysname (line 30) | def test_show_sysname(self):
    method test_show_several_commands (line 39) | def test_show_several_commands(self):
    method test_config_set (line 50) | def test_config_set(self):
    method test_base_prompt (line 61) | def test_base_prompt(self):
    method test_timeout (line 70) | def test_timeout(self):

FILE: tests/test_hp_comware_limited.py
  class TestComwareLimited (line 13) | class TestComwareLimited(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_sysname (line 30) | def test_show_sysname(self):
    method test_show_several_commands (line 39) | def test_show_several_commands(self):
    method test_config_set (line 50) | def test_config_set(self):
    method test_base_prompt (line 61) | def test_base_prompt(self):
    method test_timeout (line 70) | def test_timeout(self):

FILE: tests/test_huawei.py
  class TestHuawei (line 13) | class TestHuawei(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_sysname (line 30) | def test_show_sysname(self):
    method test_show_several_commands (line 39) | def test_show_several_commands(self):
    method test_config_set (line 50) | def test_config_set(self):
    method test_base_prompt (line 61) | def test_base_prompt(self):
    method test_timeout (line 70) | def test_timeout(self):

FILE: tests/test_hw1000.py
  class TestHW1000 (line 10) | class TestHW1000(unittest.TestCase):
    method load_credits (line 12) | def load_credits():
    method setUp (line 20) | def setUp(self):
    method test_simple_command (line 27) | def test_simple_command(self):
    method test_long_command (line 35) | def test_long_command(self):
    method test_linux_mode (line 44) | def test_linux_mode(self):
    method test_linux_mode_indepotence (line 53) | def test_linux_mode_indepotence(self):

FILE: tests/test_juniper_junos.py
  class TestJunOS (line 13) | class TestJunOS(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_system_hostname (line 30) | def test_show_system_hostname(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):
    method test_config_set (line 59) | def test_config_set(self):
    method test_base_prompt (line 70) | def test_base_prompt(self):
    method test_interactive_commands (line 79) | def test_interactive_commands(self):

FILE: tests/test_mikrotik_routeros.py
  class TestRouterOS (line 13) | class TestRouterOS(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_system_identity (line 30) | def test_show_system_identity(self):
    method test_timeout (line 39) | def test_timeout(self):
    method test_show_several_commands (line 48) | def test_show_several_commands(self):

FILE: tests/test_terminal.py
  class TestTerminal (line 13) | class TestTerminal(unittest.TestCase):
    method load_credits (line 15) | def load_credits():
    method setUp (line 23) | def setUp(self):
    method test_show_several_commands (line 30) | def test_show_several_commands(self):
    method test_timeout (line 41) | def test_timeout(self):
Condensed preview — 86 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (205K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/ask_question.md",
    "chars": 112,
    "preview": "---\r\nname: Ask Question\r\nabout: Ask all information you want\r\n---\r\n\r\n**Question**\r\n\r\nAll what you want to know\r\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 617,
    "preview": "---\r\nname: Bug Report\r\nabout: Report a bug in Netdev library\r\n---\r\n\r\n**Describe the bug**\r\n\r\nA clear and concise descrip"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 200,
    "preview": "---\r\nname: Feature Request\r\nabout: Feature Request in Netdev library\r\n---\r\n\r\n**Proposed functionality**\r\n\r\n\r\n**Use case*"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 64,
    "preview": "**Description**\r\n\r\nFull description of purpose and all changes\r\n"
  },
  {
    "path": ".gitignore",
    "chars": 264,
    "preview": "# Byte-compiled / optimized / DLL files\r\n__pycache__/\r\n*.py[cod]\r\n*$py.class\r\n\r\n# Distribution / packaging\r\n.Python\r\nven"
  },
  {
    "path": ".readthedocs.yml",
    "chars": 145,
    "preview": "---\r\nversion: 2\r\n\r\npython:\r\n  version: 3.7\r\n  install:\r\n      - method: pip\r\n        path: .\r\n        extra_requirements"
  },
  {
    "path": "CONTRIBUTING.rst",
    "chars": 1592,
    "preview": "Contributing to Netdev\r\n======================\r\n\r\nYou're welcome to contribute to this project.\r\n\r\nAsking questions\r\n---"
  },
  {
    "path": "LICENSE",
    "chars": 11345,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.rst",
    "chars": 2171,
    "preview": "THIS PROJECT IS UNMAINTAINED\n****************************\nI'm not interested in this project anymore, sorry. \nI don't wo"
  },
  {
    "path": "docs/api.rst",
    "chars": 2323,
    "preview": ".. module:: netdev\r\n\r\n.. _API:\r\n\r\nAPI Documentation\r\n*****************\r\n\r\nOverview\r\n========\r\n\r\nYou should use separate "
  },
  {
    "path": "docs/conf.py",
    "chars": 9851,
    "preview": "#!/usr/bin/env python3\r\n# -*- coding: utf-8 -*-\r\n#\r\n# netdev documentation build configuration file, created by\r\n# sphin"
  },
  {
    "path": "docs/examples.rst",
    "chars": 2126,
    "preview": ".. _Examples:\r\n\r\nExamples\r\n********\r\n\r\nIn examples are used configuration files.\r\nconfig.yaml:\r\n\r\n.. code-block:: text\r\n"
  },
  {
    "path": "docs/index.rst",
    "chars": 111,
    "preview": ".. toctree::\r\n   :hidden:\r\n   :maxdepth: -1\r\n\r\n   overview\r\n   api\r\n   examples\r\n\r\n.. include:: ../README.rst\r\n"
  },
  {
    "path": "docs/overview.rst",
    "chars": 4424,
    "preview": ".. module:: netdev\r\n\r\n.. _overview:\r\n\r\nLibrary information\r\n*******************\r\n\r\nOverview\r\n========\r\nNetdev is asynchr"
  },
  {
    "path": "examples/alcatel_aos.py",
    "chars": 2234,
    "preview": "#!/usr/bin/env python3\n\n# Import Python library\nimport asyncio, netdev\n\n# Coroutine used for the tasks\nasync def task(pa"
  },
  {
    "path": "examples/arista_eos.py",
    "chars": 869,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/aruba_aos_6.py",
    "chars": 982,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/aruba_aos_8.py",
    "chars": 982,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/cisco_asa.py",
    "chars": 1000,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/cisco_ios.py",
    "chars": 1284,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/cisco_iosxr.py",
    "chars": 1468,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/cisco_nxos.py",
    "chars": 707,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/cisco_sg3xx.py",
    "chars": 1316,
    "preview": "#!/usr/bin/env python3\n\n# Import Python library\nimport asyncio, netdev\n\n# Coroutine used for the tasks\nasync def task(pa"
  },
  {
    "path": "examples/fujitsu_switch.py",
    "chars": 820,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/hp_comware.py",
    "chars": 971,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/hp_comware_limited.py",
    "chars": 979,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/juniper_junos.py",
    "chars": 1605,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/mikrotik_routeros.py",
    "chars": 883,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "examples/terminal.py",
    "chars": 881,
    "preview": "import asyncio\r\nimport logging\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nconfig_path = 'config.yaml'\r\n\r\nlogging.basicConfig(lev"
  },
  {
    "path": "netdev/__init__.py",
    "chars": 406,
    "preview": "import netdev.vendors\r\nfrom netdev.dispatcher import create, platforms\r\nfrom netdev.exceptions import DisconnectError, T"
  },
  {
    "path": "netdev/dispatcher.py",
    "chars": 1872,
    "preview": "\"\"\"\r\nFactory function for creating netdev classes\r\n\"\"\"\r\nfrom netdev.vendors import AlcatelAOS\r\nfrom netdev.vendors impor"
  },
  {
    "path": "netdev/exceptions.py",
    "chars": 951,
    "preview": "class DisconnectError(Exception):\r\n    \"\"\"AsyncSSH Disconnect Error with ip address\"\"\"\r\n\r\n    def __init__(self, ip_addr"
  },
  {
    "path": "netdev/logger.py",
    "chars": 137,
    "preview": "\"\"\"\r\nLogging configuration for netdev\r\n\"\"\"\r\nimport logging\r\n\r\nlogger = logging.getLogger(__package__)\r\nlogger.setLevel(l"
  },
  {
    "path": "netdev/vendors/__init__.py",
    "chars": 1404,
    "preview": "from netdev.vendors.alcatel import AlcatelAOS\r\nfrom netdev.vendors.arista import AristaEOS\r\nfrom netdev.vendors.aruba im"
  },
  {
    "path": "netdev/vendors/alcatel/__init__.py",
    "chars": 62,
    "preview": "from .alcatel_aos import AlcatelAOS\n\n__all__ = [\"AlcatelAOS\"]\n"
  },
  {
    "path": "netdev/vendors/alcatel/alcatel_aos.py",
    "chars": 1242,
    "preview": "from netdev.vendors.base import BaseDevice\nfrom netdev.logger import logger\nimport asyncio\nimport re\n\nclass AlcatelAOS(B"
  },
  {
    "path": "netdev/vendors/arista/__init__.py",
    "chars": 62,
    "preview": "from .arista_eos import AristaEOS\r\n\r\n__all__ = [\"AristaEOS\"]\r\n"
  },
  {
    "path": "netdev/vendors/arista/arista_eos.py",
    "chars": 145,
    "preview": "from netdev.vendors.ios_like import IOSLikeDevice\r\n\r\n\r\nclass AristaEOS(IOSLikeDevice):\r\n    \"\"\"Class for working with Ar"
  },
  {
    "path": "netdev/vendors/aruba/__init__.py",
    "chars": 112,
    "preview": "from .aruba_aos_6 import ArubaAOS6\r\nfrom .aruba_aos_8 import ArubaAOS8\r\n\r\n__all__ = [\"ArubaAOS6\", \"ArubaAOS8\"]\r\n"
  },
  {
    "path": "netdev/vendors/aruba/aruba_aos_6.py",
    "chars": 1744,
    "preview": "\"\"\"Subclass specific to Aruba AOS 6.x\"\"\"\r\n\r\nimport re\r\n\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.ios_like "
  },
  {
    "path": "netdev/vendors/aruba/aruba_aos_8.py",
    "chars": 1799,
    "preview": "\"\"\"Subclass specific to Aruba AOS 8.x\"\"\"\r\n\r\nimport re\r\n\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.ios_like "
  },
  {
    "path": "netdev/vendors/base.py",
    "chars": 22444,
    "preview": "\"\"\"\r\nBase Class for using in connection to network devices\r\n\r\nConnections Method are based upon AsyncSSH and should be r"
  },
  {
    "path": "netdev/vendors/cisco/__init__.py",
    "chars": 254,
    "preview": "from .cisco_asa import CiscoASA\r\nfrom .cisco_ios import CiscoIOS\r\nfrom .cisco_iosxr import CiscoIOSXR\r\nfrom .cisco_nxos "
  },
  {
    "path": "netdev/vendors/cisco/cisco_asa.py",
    "chars": 3945,
    "preview": "\"\"\"Subclass specific to Cisco ASA\"\"\"\r\n\r\nimport re\r\n\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.ios_like impo"
  },
  {
    "path": "netdev/vendors/cisco/cisco_ios.py",
    "chars": 150,
    "preview": "from netdev.vendors.ios_like import IOSLikeDevice\r\n\r\n\r\nclass CiscoIOS(IOSLikeDevice):\r\n    \"\"\"Class for working with Cis"
  },
  {
    "path": "netdev/vendors/cisco/cisco_iosxr.py",
    "chars": 4232,
    "preview": "from netdev.exceptions import CommitError\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.ios_like import IOSLike"
  },
  {
    "path": "netdev/vendors/cisco/cisco_nxos.py",
    "chars": 432,
    "preview": "import re\r\n\r\nfrom netdev.vendors.ios_like import IOSLikeDevice\r\n\r\n\r\nclass CiscoNXOS(IOSLikeDevice):\r\n    \"\"\"Class for wo"
  },
  {
    "path": "netdev/vendors/cisco/cisco_sg3xx.py",
    "chars": 1307,
    "preview": "\"\"\"Subclass specific to Cisco SG3XX\"\"\"\n\nfrom netdev.vendors.ios_like import IOSLikeDevice\n\nclass CiscoSG3XX(IOSLikeDevic"
  },
  {
    "path": "netdev/vendors/comware_like.py",
    "chars": 5102,
    "preview": "\"\"\"\r\nComwareLikeDevice Class is abstract class for using in HP Comware like devices\r\n\r\nConnection Method are based upon "
  },
  {
    "path": "netdev/vendors/fujitsu/__init__.py",
    "chars": 74,
    "preview": "from .fujitsu_switch import FujitsuSwitch\r\n\r\n__all__ = [\"FujitsuSwitch\"]\r\n"
  },
  {
    "path": "netdev/vendors/fujitsu/fujitsu_switch.py",
    "chars": 1893,
    "preview": "\"\"\"Subclass specific to Fujitsu Blade Switch\"\"\"\r\n\r\nimport re\r\n\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.io"
  },
  {
    "path": "netdev/vendors/hp/__init__.py",
    "chars": 132,
    "preview": "from .hp_comware import HPComware\r\nfrom .hp_comware_limited import HPComwareLimited\r\n\r\n__all__ = [\"HPComware\", \"HPComwar"
  },
  {
    "path": "netdev/vendors/hp/hp_comware.py",
    "chars": 157,
    "preview": "from netdev.vendors.comware_like import ComwareLikeDevice\r\n\r\n\r\nclass HPComware(ComwareLikeDevice):\r\n    \"\"\"Class for wor"
  },
  {
    "path": "netdev/vendors/hp/hp_comware_limited.py",
    "chars": 3275,
    "preview": "from netdev.logger import logger\r\nfrom netdev.vendors.comware_like import ComwareLikeDevice\r\n\r\n\r\nclass HPComwareLimited("
  },
  {
    "path": "netdev/vendors/huawei/__init__.py",
    "chars": 48,
    "preview": "from .huawei import Huawei\n\n__all__ = [\"Huawei\"]"
  },
  {
    "path": "netdev/vendors/huawei/huawei.py",
    "chars": 1649,
    "preview": "from netdev.vendors.comware_like import ComwareLikeDevice\nimport re\nfrom netdev.logger import logger\n\nclass Huawei(Comwa"
  },
  {
    "path": "netdev/vendors/infotecs/HW1000.py",
    "chars": 8060,
    "preview": "\"\"\"\r\nHW1000 is a class for working with Vipnet HW1000 crypto gateways\r\n\"\"\"\r\nimport re\r\nfrom netdev.logger import logger\r"
  },
  {
    "path": "netdev/vendors/infotecs/__init__.py",
    "chars": 52,
    "preview": "from .HW1000 import HW1000\r\n\r\n__all__ = ['HW1000']\r\n"
  },
  {
    "path": "netdev/vendors/ios_like.py",
    "chars": 7694,
    "preview": "\"\"\"\r\nIOSLikeDevice Class is abstract class for using in Cisco IOS like devices\r\n\r\nConnection Method are based upon Async"
  },
  {
    "path": "netdev/vendors/juniper/__init__.py",
    "chars": 71,
    "preview": "from .juniper_junos import JuniperJunOS\r\n\r\n__all__ = [\"JuniperJunOS\"]\r\n"
  },
  {
    "path": "netdev/vendors/juniper/juniper_junos.py",
    "chars": 1976,
    "preview": "from netdev.logger import logger\r\nfrom netdev.vendors.junos_like import JunOSLikeDevice\r\n\r\n\r\nclass JuniperJunOS(JunOSLik"
  },
  {
    "path": "netdev/vendors/junos_like.py",
    "chars": 5855,
    "preview": "\"\"\"\r\nJunOSLikeDevice Class is abstract class for using in Juniper JunOS like devices\r\n\r\nConnection Method are based upon"
  },
  {
    "path": "netdev/vendors/mikrotik/__init__.py",
    "chars": 83,
    "preview": "from .mikrotik_routeros import MikrotikRouterOS\r\n\r\n__all__ = [\"MikrotikRouterOS\"]\r\n"
  },
  {
    "path": "netdev/vendors/mikrotik/mikrotik_routeros.py",
    "chars": 5126,
    "preview": "import asyncssh\r\nimport asyncio\r\n\r\nfrom netdev.exceptions import DisconnectError, TimeoutError\r\nfrom netdev.logger impor"
  },
  {
    "path": "netdev/vendors/terminal/__init__.py",
    "chars": 58,
    "preview": "from .terminal import Terminal\r\n\r\n__all__ = [\"Terminal\"]\r\n"
  },
  {
    "path": "netdev/vendors/terminal/terminal.py",
    "chars": 2661,
    "preview": "import re\r\n\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.base import BaseDevice\r\n\r\n\r\nclass Terminal(BaseDevice"
  },
  {
    "path": "netdev/vendors/ubiquiti/__init__.py",
    "chars": 83,
    "preview": "from .ubiquity_edge import UbiquityEdgeSwitch\r\n\r\n__all__ = [\"UbiquityEdgeSwitch\"]\r\n"
  },
  {
    "path": "netdev/vendors/ubiquiti/ubiquity_edge.py",
    "chars": 1529,
    "preview": "\"\"\"Subclass specific to Ubiquity Edge Switch\"\"\"\r\nimport re\r\n\r\nfrom netdev.logger import logger\r\nfrom netdev.vendors.ios_"
  },
  {
    "path": "netdev/version.py",
    "chars": 179,
    "preview": "\"\"\" Netdev Version information\r\n\"\"\"\r\n\r\n__version__ = \"0.9.3\"\r\n__author__ = \"Yakovlev Sergey\"\r\n__author_email__ = \"selfur"
  },
  {
    "path": "pyproject.toml",
    "chars": 1389,
    "preview": "[build-system]\nrequires = [\"poetry>=0.12\"]\nbuild-backend = \"poetry.masonry.api\"\n\n[tool.poetry]\nname = \"netdev\"\nversion ="
  },
  {
    "path": "tests/test_arista_eos.py",
    "chars": 3318,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_aruba_aos_6.py",
    "chars": 2744,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_aruba_aos_8.py",
    "chars": 2734,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_cisco_asa.py",
    "chars": 2969,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_cisco_ios.py",
    "chars": 3279,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_cisco_iossg3xx.py",
    "chars": 3194,
    "preview": "import asyncio\nimport logging\nimport unittest\n\nimport yaml\n\nimport netdev\n\nlogging.basicConfig(filename='unittest.log', "
  },
  {
    "path": "tests/test_cisco_iosxr.py",
    "chars": 3957,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_cisco_nxos.py",
    "chars": 2779,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_fujitsu_switch.py",
    "chars": 2731,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_hp_comware.py",
    "chars": 2736,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_hp_comware_limited.py",
    "chars": 2753,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_huawei.py",
    "chars": 2670,
    "preview": "import asyncio\nimport logging\nimport unittest\n\nimport yaml\n\nimport netdev\n\nlogging.basicConfig(filename='unittest.log', "
  },
  {
    "path": "tests/test_hw1000.py",
    "chars": 2294,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\nimport yaml\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittest.lo"
  },
  {
    "path": "tests/test_juniper_junos.py",
    "chars": 3772,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_mikrotik_routeros.py",
    "chars": 2010,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  },
  {
    "path": "tests/test_terminal.py",
    "chars": 1634,
    "preview": "import asyncio\r\nimport logging\r\nimport unittest\r\n\r\nimport yaml\r\n\r\nimport netdev\r\n\r\nlogging.basicConfig(filename='unittes"
  }
]

About this extraction

This page contains the full source code of the selfuryon/netdev GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 86 files (183.3 KB), approximately 42.4k tokens, and a symbol index with 270 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!