Showing preview only (465K chars total). Download the full file or copy to clipboard to get everything.
Repository: etingof/pysmi
Branch: master
Commit: 58f2bf29cccf
Files: 134
Total size: 428.9 KB
Directory structure:
gitextract_1dgs2gwy/
├── .bandit.yml
├── .flake8.ini
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .travis.yml
├── CHANGES.rst
├── LICENSE.rst
├── MANIFEST.in
├── README.md
├── THANKS.txt
├── TODO.txt
├── devel-requirements.txt
├── docs/
│ ├── Makefile
│ ├── README.txt
│ └── source/
│ ├── .static/
│ │ └── css/
│ │ └── rtdimproved.css
│ ├── changelog.rst
│ ├── conf.py
│ ├── contents.rst
│ ├── documentation.rst
│ ├── download.rst
│ ├── examples/
│ │ ├── always-borrow-precompiled-pysnmp-files.rst
│ │ ├── borrow-precompiled-pysnmp-files-on-failure.rst
│ │ ├── compile-smistar-mibs-into-pysnmp-files-if-needed.rst
│ │ ├── compile-smiv2-mibs-from-text-into-pysnmp-code.rst
│ │ ├── download-and-compile-smistar-mibs-into-json.rst
│ │ └── download-and-compile-smistar-mibs-into-pysnmp-files.rst
│ ├── library-reference.rst
│ ├── license.rst
│ ├── mibcopy.rst
│ ├── mibdump.rst
│ └── pysmi/
│ ├── borrower/
│ │ ├── anyfile/
│ │ │ └── anyfileborrower.rst
│ │ └── pyfile/
│ │ └── pyfileborrower.rst
│ ├── codegen/
│ │ ├── jsondoc/
│ │ │ └── jsoncodegen.rst
│ │ ├── null/
│ │ │ └── nullcodegen.rst
│ │ └── pysnmp/
│ │ └── pysnmpcodegen.rst
│ ├── compiler/
│ │ ├── mibcompiler.rst
│ │ └── mibstatus.rst
│ ├── parser/
│ │ └── smi/
│ │ ├── dialect.rst
│ │ └── parserfactory.rst
│ ├── reader/
│ │ ├── callback/
│ │ │ └── callbackreader.rst
│ │ ├── ftpclient/
│ │ │ └── ftpreader.rst
│ │ ├── httpclient/
│ │ │ └── httpreader.rst
│ │ ├── localfile/
│ │ │ └── filereader.rst
│ │ └── zipreader/
│ │ └── zipreader.rst
│ ├── searcher/
│ │ ├── pyfile/
│ │ │ └── pyfilesearcher.rst
│ │ ├── pypackage/
│ │ │ └── pypackagesearcher.rst
│ │ └── stub/
│ │ └── stubsearcher.rst
│ └── writer/
│ ├── callback/
│ │ └── callbackwriter.rst
│ ├── localfile/
│ │ └── filewriter.rst
│ └── pyfile/
│ └── pyfilewriter.rst
├── examples/
│ ├── always-borrow-precompiled-pysnmp-files.py
│ ├── borrow-precompiled-pysnmp-files-on-failure.py
│ ├── compile-smistar-mibs-into-pysnmp-files-if-needed.py
│ ├── compile-smiv2-mibs-from-text-into-pysnmp-code.py
│ ├── download-and-compile-smistar-mibs-into-json.py
│ └── download-and-compile-smistar-mibs-into-pysnmp-files.py
├── pysmi/
│ ├── __init__.py
│ ├── borrower/
│ │ ├── __init__.py
│ │ ├── anyfile.py
│ │ ├── base.py
│ │ └── pyfile.py
│ ├── codegen/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── intermediate.py
│ │ ├── jfilters.py
│ │ ├── jsondoc.py
│ │ ├── null.py
│ │ ├── pysnmp.py
│ │ ├── symtable.py
│ │ └── templates/
│ │ ├── jsondoc/
│ │ │ └── base.j2
│ │ └── pysnmp/
│ │ ├── base.j2
│ │ ├── managed-objects-instances.j2
│ │ ├── mib-definitions.j2
│ │ └── mib-instrumentation/
│ │ ├── managed-objects-instances.j2
│ │ └── managed-objects.j2
│ ├── compat.py
│ ├── compiler.py
│ ├── debug.py
│ ├── error.py
│ ├── lexer/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ └── smi.py
│ ├── mibinfo.py
│ ├── parser/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── dialect.py
│ │ ├── null.py
│ │ ├── smi.py
│ │ ├── smiv1.py
│ │ ├── smiv1compat.py
│ │ └── smiv2.py
│ ├── reader/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── callback.py
│ │ ├── ftpclient.py
│ │ ├── httpclient.py
│ │ ├── localfile.py
│ │ ├── url.py
│ │ └── zipreader.py
│ ├── searcher/
│ │ ├── __init__.py
│ │ ├── anyfile.py
│ │ ├── base.py
│ │ ├── pyfile.py
│ │ ├── pypackage.py
│ │ └── stub.py
│ └── writer/
│ ├── __init__.py
│ ├── base.py
│ ├── callback.py
│ ├── localfile.py
│ └── pyfile.py
├── requirements.txt
├── scripts/
│ ├── mibcopy.py
│ └── mibdump.py
├── setup.cfg
├── setup.py
├── test-requirements.txt
├── tests/
│ ├── __init__.py
│ ├── __main__.py
│ ├── test_agentcapabilities_smiv2_pysnmp.py
│ ├── test_imports_smiv2_pysnmp.py
│ ├── test_modulecompliance_smiv2_pysnmp.py
│ ├── test_moduleidentity_smiv2_pysnmp.py
│ ├── test_notificationgroup_smiv2_pysnmp.py
│ ├── test_notificationtype_smiv2_pysnmp.py
│ ├── test_objectgroup_smiv2_pysnmp.py
│ ├── test_objectidentity_smiv2_pysnmp.py
│ ├── test_objecttype_smiv2_pysnmp.py
│ ├── test_smiv1_smiv2_pysnmp.py
│ ├── test_traptype_smiv2_pysnmp.py
│ ├── test_typedeclaration_smiv1_pysnmp.py
│ ├── test_typedeclaration_smiv2_pysnmp.py
│ ├── test_valuedeclaration_smiv2_pysnmp.py
│ └── test_zipreader.py
└── tox.ini
================================================
FILE CONTENTS
================================================
================================================
FILE: .bandit.yml
================================================
skips:
- B603 # Ignore warnings about calling subprocess.Popen without shell=True
- B607 # Ignore warnings about calling subprocess.Popen without a full path to executable
================================================
FILE: .flake8.ini
================================================
[flake8]
show-source = True
# E123, E125 seem invalid
ignore = E123,E125,D104,D100,D101,D102,D103,D106,D107,D412,W504
#enable-extensions=H106,H203,H204,H205,H210,H904
builtins = _
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
================================================
FILE: .github/FUNDING.yml
================================================
custom: http://snmplabs.com/sponsorship.html
================================================
FILE: .gitignore
================================================
# Python stuff
*.pyc
__pycache__
# vim swapfiles
*.sw?
# python packaging
MANIFEST
dist/
build/
*.egg-info/
# PyCharm stuff
.idea/
# Sphinx template
docs/source/.templates/layout.html
# Eclipse stuff
.project
.pydevproject
# Virtual envs
venv*
.coverage
.tox/
================================================
FILE: .travis.yml
================================================
language: python
cache: pip
matrix:
include:
- os: linux
dist: trusty
python: '2.6'
- os: linux
dist: trusty
python: '2.7'
# Jinja seems to be broken on py3.2
# - os: linux
# dist: trusty
# python: '3.2'
- os: linux
dist: trusty
python: '3.3'
- os: linux
dist: trusty
python: '3.4'
- os: linux
dist: trusty
python: '3.5'
- os: linux
dist: trusty
python: '3.6'
- os: linux
dist: xenial
python: '3.7'
- os: linux
dist: trusty
python: 'nightly'
- os: linux
dist: trusty
python: 'pypy'
- os: linux
dist: trusty
python: 'pypy3'
install:
- pip install codecov
- pip install -r requirements.txt -r devel-requirements.txt
- pip install -e .
script:
- PYTHONPATH=.:$PYTHONPATH python tests/__main__.py
after_success:
- PYTHONPATH=.:$PYTHONPATH coverage run --omit=*test* tests/__main__.py
- codecov
================================================
FILE: CHANGES.rst
================================================
Revision 0.4.0, XX-03-2020
--------------------------
- Introduced Jinja2 templates for code generation.
This change significantly refactors the way how code generation
works. Previously, pysmi code generator has been responsible for
producing a well-formed text document (e.g. JSON or pysnmp).
With this change, all code generations should be done through
Jinja2 templates by rendering them in the context of the parsed MIB
taking shape of the intermediate MIB representation which other parts
of pysmi provide.
- By way of moving pysnmp code generation to Jinja2 template, the
Python code layout of pysnmp modules improved dramatically - it
is just one little step from being PEP8-compliant.
- The template-based pysnmp code generator drops some backward
compatibility aids that keep Python MIB modules compatible with
older pysnmp versions. Perhaps in the followup patch we should
make the Python MIB module failing early and clearly on import
when it's old pysnmp importing it.
- Jinja does not seem to work well with Python < 2.6 and Python == 3.2.
Despite pysmi is trying to support those Python versions, it may
start to fail on them due to Jinja failures.
- Introduced SNMP agent code hooks generation template allowing
building a functional skeleton of the Python module from a
given ASN.1 MIB. The tapping points include SMI Managed Object
read/readnext/write/create and destroy work flows.
Revision 0.3.5, XX-03-2020
--------------------------
- Added tox runner with a handful of basic jobs
- Copyright notice extended to the year 2020
- Fixed MIB file load by URI on Windows
Revision 0.3.4, 14-04-2019
--------------------------
- Added `implied` key to JSON SNMP table index structure
- Rebased MIB importing code onto `importlib` because `imp` is long
deprecated
- Fixed Py file borrower to become functional
Revision 0.3.3, 29-12-2018
--------------------------
- Added mibcopy.py documentation
- Copyright notice bumped up to year 2019
Revision 0.3.2, 22-10-2018
--------------------------
- Bumped upper Python version to 3.7 and enabled pip cache
- Exit code indication of the command-line tools aligned with
sysexits.h to report more useful termination status
Revision 0.3.1, 10-06-2018
--------------------------
- Fixed pysnmp lower version in test-requirements.txt
- Fixed compiler crash when building comments at a platform which
has broken users/groups databases
Revision 0.3.0, 29-04-2018
--------------------------
- The `mibcopy` tool implemented to copy MIB modules from files with
potentially messed up names into a directory under canonical MIB
names picking up the latest MIB revision along the way.
- ZIP archive reader implemented to pull ASN.1 MIB files from .zip
archives pretty much in the same way as from plain directories
- HTTP/S proxy support added (through respecting `http_proxy` environment
variable) by switching from `httplib` to `urllib2` internally
- Copyright notice bumped up to year 2018
- Project site in the docs changes from SourceForge to snmplabs.com
- PRODUCT-RELEASE generation added to the JSON code generator
- Added special handling of BITS-like DEFVAL syntax for Integers
that occurs in buggy MIBs
- Fixed missing REVISIONS generations in MODULE-IDENTITY
Revision 0.2.2, 13-11-2017
--------------------------
- Library documentation refactored and updated
- Fixed malformed Python code being produced by pysnmp code generator
Revision 0.2.1, 11-11-2017
--------------------------
- Added MIB *status*, *product release* and *revision description* set
calls at pysnmp code generator
- Changed REVISION field format in JSON representation - it is now
a list of dicts each with *revision* timestamp and *description* text
- MIB REFERENCE fields are only exported if --with-mib-text is on
- Sphinx documentation theme changed to Alabaster
- Multiple fixes to pysnmp codegen not to produce function calls
with more than 255 parameters
Revision 0.1.4, 14-10-2017
--------------------------
- Fix to SMI lexer to treat tokens starting from a digit as belonging
to a lower-cased class. This fixes sub-OID parsing bug (specifically,
802dot3(10006))
- Fix to the mibdump.py local MIB path automatic injection in front
of existing --mib-sources
Revision 0.1.3, 19-05-2017
--------------------------
* INET-ADDRESS-MIB configured as pre-built at pysnmp codegen
* JSON codegen produces "nodetype" element for OBJECT-TYPE
* Fix to mibdump.py --destination-directory option
* Fix to pysnmp and JSON code generators to properly refer to MIB module
defining particular MIB object
Revision 0.1.2, 12-04-2017
--------------------------
* The @mib@ magic in reader's URL template made optional. If it is not present,
MIB module name is just appended to URL template
* Send User-Agent containing pysmi and Python versions as well as platform name.
* Fixed missing STATUS/DISPLAY-HINT/REFERENCE/etc fields generation at pysnmp
backend when running in the non-full-text mode
* Fixed broken `ordereddict` dependency on Python 2.6-
Revision 0.1.1, 30-03-2017
--------------------------
* Generate REFERENCE and STATUS fields at various SMI objects
* Generate DESCRIPTION field followed REVISION field at MODULE-IDENTITY objects
* Generate PRODUCT-RELEASE field at AGENT-CAPABILITIES objects
* Generated Python source aligned with PEP8
* MIB texts cleaned up by default, --keep-texts-layout preserves original formatting
* Fix to the `ordereddict` conditional dependency
* Missing test module recovered
* Failing tests fixed
Revision 0.1.0, 25-03-2017
--------------------------
* JSON code generating backend implemented
* Experimental JSON OID->MIB indices generation implemented
* Package structure flattened for easier use
* Minor refactoring to the test suite
* Source code statically analyzed, hardened and PEP8-ized
* Files closed explicitly to mute ResourceWarnings
* Fixed to Python 2.4 (and aged ply) compatibility
* Added a workaround to avoid generating pysnmp TextualConvention classes
inheriting from TextualConvention (when MIB defines a TEXTUAL-CONVENTION
based on another TEXTUAL-CONVENTION as SYNTAX)
* Author's e-mail changed, copyright extended to year 2017
Revision 0.0.7, 12-02-2016
--------------------------
* Crash on existing .py file handling fixed.
* Fix to __doc__ use in setup.py to make -O0 installation mode working.
* Fix to PyPackageSearcher not to fail on broken Python packages.
* Source code pep8'ed
* Copyright added to source files.
Revision 0.0.6, 01-10-2015
--------------------------
* Several typos fixed, source code linted again.
* Some dead code cleaned up.
Revision 0.0.5, 28-09-2015
--------------------------
* Wheel distribution format now supported.
* Handle the case of MIB symbols conflict with Python reserved words.
* Handle binary DEFVAL initializer for INTEGER's.
* Generate LAST-UPDATED at pysnmp code generator.
Revision 0.0.4, 01-07-2015
--------------------------
* Fix to MRO compliance for mixin classes generation at pysnmp backend
* Fix to repeated imports in generated code at pysnmp backend
* Fix to mibdump tool to properly handle the --generate-mib-texts option.
* Fix to Python compile() - optimize flag is valid only past Python 3.1
* Fix to SMIv1 INDEX clause code generation for pysnmp backend.
* Tighten file creation security at pysmi.writer.pyfile
Revision 0.0.3, 28-06-2015
--------------------------
* Two-pass compiler design allows for much accurate code generation.
* Sphinx-based documentation first introduced
Revision 0.0.0, 11-04-2015
--------------------------
* First public release, not fully operational yet
================================================
FILE: LICENSE.rst
================================================
Copyright (c) 2015-2020 Ilya Etingof <etingof@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: MANIFEST.in
================================================
include *.txt *.rst *.md
recursive-include tests *.py
recursive-include examples *.py
recursive-include docs *.txt *.rst *.svg *.py Makefile
================================================
FILE: README.md
================================================
SNMP MIB parser
---------------
[](https://pypi.org/project/pysmi/)
[](https://secure.travis-ci.org/etingof/pysmi)
[](https://codecov.io/github/etingof/pysmi)
[](https://raw.githubusercontent.com/etingof/pysmi/master/LICENSE.rst)
PySMI is a pure-Python implementation of
[SNMP SMI](https://en.wikipedia.org/wiki/Management_information_base) MIB parser.
This tool is designed to turn ASN.1 MIBs into various formats. As of this moment,
JSON and [pysnmp](https://github.com/etingof/pysnmp) modules can be generated
from ASN.1 MIBs.
Features
--------
* Understands SMIv1, SMIv2 and de-facto SMI dialects
* Turns MIBs into pysnmp classes and JSON documents
* Maintains an index of MIB objects over many MIB modules
* Automatically pulls ASN.1 MIBs from local directories, ZIP archives,
HTTP and FTP servers
* 100% Python, works with Python 2.4 up to Python 3.7
Rendered PySMI documentation can be found at [pysmi site](http://snmplabs.com/pysmi).
How to use PySMI
----------------
If you are using pysnmp, you might never notice pysmi presence - pysnmp
calls pysmi for MIB download and compilation behind the scenes (you can
still can do that manually by invoking *mibdump.py* tool).
To turn ASN.1 MIB into a JSON document, call *mibdump.py* tool like this:
```
$ mibdump.py --generate-mib-texts --destination-format json IF-MIB
Source MIB repositories: file:///usr/share/snmp/mibs, http://mibs.snmplabs.com/asn1/@mib@
Borrow missing/failed MIBs from: http://mibs.snmplabs.com/json/fulltexts/@mib@
Existing/compiled MIB locations:
Compiled MIBs destination directory: .
MIBs excluded from code generation: RFC-1212, RFC-1215, RFC1065-SMI, RFC1155-SMI,
RFC1158-MIB, RFC1213-MIB, SNMPv2-CONF, SNMPv2-SMI, SNMPv2-TC, SNMPv2-TM
MIBs to compile: IF-MIB
Destination format: json
Parser grammar cache directory: not used
Also compile all relevant MIBs: yes
Rebuild MIBs regardless of age: yes
Do not create/update MIBs: no
Byte-compile Python modules: no (optimization level no)
Ignore compilation errors: no
Generate OID->MIB index: no
Generate texts in MIBs: yes
Keep original texts layout: no
Try various filenames while searching for MIB module: yes
Created/updated MIBs: IANAifType-MIB, IF-MIB, SNMPv2-MIB
Pre-compiled MIBs borrowed:
Up to date MIBs: SNMPv2-CONF, SNMPv2-SMI, SNMPv2-TC
Missing source MIBs:
Ignored MIBs:
Failed MIBs:
```
JSON document build from
[IF-MIB module](http://mibs.snmplabs.com/asn1/IF-MIB)
would hold information such as:
```
{
"ifMIB": {
"name": "ifMIB",
"oid": "1.3.6.1.2.1.31",
"class": "moduleidentity",
"revisions": [
"2007-02-15 00:00",
"1996-02-28 21:55",
"1993-11-08 21:55"
]
},
...
"ifTestTable": {
"name": "ifTestTable",
"oid": "1.3.6.1.2.1.31.1.3",
"nodetype": "table",
"class": "objecttype",
"maxaccess": "not-accessible"
},
"ifTestEntry": {
"name": "ifTestEntry",
"oid": "1.3.6.1.2.1.31.1.3.1",
"nodetype": "row",
"class": "objecttype",
"maxaccess": "not-accessible",
"augmention": {
"name": "ifTestEntry",
"module": "IF-MIB",
"object": "ifEntry"
}
},
"ifTestId": {
"name": "ifTestId",
"oid": "1.3.6.1.2.1.31.1.3.1.1",
"nodetype": "column",
"class": "objecttype",
"syntax": {
"type": "TestAndIncr",
"class": "type"
},
"maxaccess": "read-write"
},
...
}
```
In general, converted MIBs capture all aspects of original (ASN.1) MIB contents
and layout. The snippet above is just a partial example, but here is the
complete [IF-MIB.json](http://mibs.snmplabs.com/json/fulltexts/IF-MIB.json)
file.
Besides one-to-one MIB conversion, PySMI library can produce JSON index to
facilitate fast MIB information lookup across large collection of MIB files.
For example, JSON index for
[IP-MIB.json](http://mibs.snmplabs.com/json/asn1/IP-MIB),
[TCP-MIB.json](http://mibs.snmplabs.com/json/asn1/TCP-MIB) and
[UDP-MIB.json](http://mibs.snmplabs.com/json/asn1/UDP-MIB)
modules would keep information like this:
```
{
"compliance": {
"1.3.6.1.2.1.48.2.1.1": [
"IP-MIB"
],
"1.3.6.1.2.1.49.2.1.1": [
"TCP-MIB"
],
"1.3.6.1.2.1.50.2.1.1": [
"UDP-MIB"
]
},
"identity": {
"1.3.6.1.2.1.48": [
"IP-MIB"
],
"1.3.6.1.2.1.49": [
"TCP-MIB"
],
"1.3.6.1.2.1.50": [
"UDP-MIB"
]
},
"oids": {
"1.3.6.1.2.1.4": [
"IP-MIB"
],
"1.3.6.1.2.1.5": [
"IP-MIB"
],
"1.3.6.1.2.1.6": [
"TCP-MIB"
],
"1.3.6.1.2.1.7": [
"UDP-MIB"
],
"1.3.6.1.2.1.49": [
"TCP-MIB"
],
"1.3.6.1.2.1.50": [
"UDP-MIB"
]
}
}
```
With this example, *compliance* and *identity* keys point to
*MODULE-COMPLIANCE* and *MODULE-IDENTITY* MIB objects, *oids*
list top-level OIDs branches defined in MIB modules. Full index
build over thousands of MIBs could be seen
[here](http://mibs.snmplabs.com/json/index.json).
The PySMI library can automatically fetch required MIBs from HTTP, FTP sites
or local directories. You could configure any MIB source available to you (including
[http://mibs.snmplabs.com/asn1/](http://mibs.snmplabs.com/asn1/)) for that purpose.
How to get PySMI
----------------
The pysmi package is distributed under terms and conditions of 2-clause
BSD [license](http://snmplabs.com/pysmi/license.html). Source code is freely
available as a GitHub [repo](https://github.com/etingof/pysmi).
You could `pip install pysmi` or download it from [PyPI](https://pypi.org/project/pysmi/).
If something does not work as expected,
[open an issue](https://github.com/etingof/pysmi/issues) at GitHub or
post your question [on Stack Overflow](http://stackoverflow.com/questions/ask).
Copyright (c) 2015-2020, [Ilya Etingof](mailto:etingof@gmail.com).
All rights reserved.
================================================
FILE: THANKS.txt
================================================
Lars Michelsen
Tanya Tereschenko
================================================
FILE: TODO.txt
================================================
* add more tests on edge cases
* generate reverse OID -> MIB index
* handle SMIv1 MAX clause in range constraint
* support MAX clause mapping it into type-specific value
* possibly split symbol table code generator onto imported modules and symbol
table code generators.
* support more common broken SMI constructs
* DEFVAL and AUGMENTS should not depend on the order of symbols in MIB
* make a collection of fixed MIBs (e.g. Huawei has lots of bad/broken MIBs)
* some MIBs use hex as DEFVAL for types other than OCTET STRING (additional AST processing phase will help)
* handle the case when the symbol and the enumaration value (which can be in DEFVAL) have the same name - llc2 in NETLINK-SPECIFIC-MIB (additional AST processing phase will help)
* check imports and try to add necessary ones if missed (like OBJECT-TYPE, MODULE-IDENTITY, etc)
* generate TextualConvention first or add additional AST processing phase
* implement a cache of available files at abstract reader path
* create a command-line tool for splitting MIBs stored in a single file
* create a MIB querying tool: get MIB module's OIDs, enterprise IDs,
canonical name(s); search MIB objects by regexp; build source .index
* implement xml/html/yaml codegeneration backend
* write a tool to fetch canonical MIB name from MIB file, rename MIB file, split merged MIBs onto individual files
* write a tool to turn IANA assigned numbers into JSON
* introduce cached MIBs invalidation feature -- may be useful when we screw up and produce bad MIBs
* json codegen:
- make schema configurable
- further simplify/review codegen code
- rebuild the docs
- conditionally require simplejson and ordereddict
- add tests
- is it a good idea to make writers also reading data?
- review symtable for unused pieces
- write a tool to split json index onto separate documents
- index NOTIFICATION-TYPE's
- add example script on index build
================================================
FILE: devel-requirements.txt
================================================
Sphinx <= 1.6; python_version < '2.7'
Sphinx > 1.6; python_version >= '2.7'
pysnmp < 5.0.0
================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build
# User-friendly check for sphinx-build
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
endif
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " xml to make Docutils-native XML files"
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
@echo " coverage to run coverage check of the documentation (if enabled)"
clean:
rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PySMI.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PySMI.qhc"
applehelp:
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
@echo
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
@echo "N.B. You won't be able to view it unless you put it in" \
"~/Library/Documentation/Help or install it in your application" \
"bundle."
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/PySMI"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PySMI"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
latexpdfja:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through platex and dvipdfmx..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
coverage:
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
@echo "Testing of coverage in the sources finished, look at the " \
"results in $(BUILDDIR)/coverage/python.txt."
xml:
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
@echo
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
================================================
FILE: docs/README.txt
================================================
You need Sphinx too build this documentation. Or you can read it in ASCII. ;)
Better run:
# pip sphinx
and once Sphinx is installed on your system, run:
$ make html
To build a copy of HTML'ed PySMI documentation.
================================================
FILE: docs/source/.static/css/rtdimproved.css
================================================
@import url("../pygments.css");
@import url("theme.css");
/* fix horizontal padding to accomodate adsense banners */
.wy-nav-content {
padding: 1.618em 2.236em;
height: 100%;
/* max-width: 800px; */
margin: auto;
}
================================================
FILE: docs/source/changelog.rst
================================================
Changelog
=========
.. include:: ../../CHANGES.rst
================================================
FILE: docs/source/conf.py
================================================
# -*- coding: utf-8 -*-
#
# PySMI documentation build configuration file, created by
# sphinx-quickstart on Sat Jun 27 23:15:54 2015.
#
# 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 sys
import os
import shlex
# 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('.'))
# -- 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.napoleon',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo'
]
# 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 = 'contents'
# General information about the project.
project = u'SNMP SMI compiler'
copyright = u'2015-2020, Ilya Etingof <etingof@gmail.com>'
author = u'Ilya Etingof <etingof@gmail.com>'
# 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 = '0.1'
# The full version, including alpha/beta/rc tags.
release = '0.1'
# 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 = []
# 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 = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'alabaster'
# 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 = { 'collapse_navigation': False }
html_theme_options = {
'logo': 'logo.svg',
'description': '<p align=left><i><b>Brewing free software for the greater good</i></b></p>',
'show_powered_by': False,
'github_user': 'etingof',
'github_repo': 'pysmi',
'fixed_sidebar': True,
}
html_sidebars = {
'**': [
'about.html',
'navigation.html',
'relations.html',
'searchbox.html',
'donate.html',
]
}
# 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 = '.static/favicon.ico'
# 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']
# Custom CSS theme
#html_style = 'css/rtdimproved.css'
# 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 = False
# If false, no index is generated.
html_use_index = False
# 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 = False
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
html_show_sphinx = False
# 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', 'hu', 'it', 'ja'
# 'nl', 'no', 'pt', 'ro', 'ru', '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 = 'PySMIdoc'
# -- 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, 'PySMI.tex', u'SNMP SMI compiler',
u'Ilya Etingof \\textless{}etingof@gmail.com\\textgreater{}', '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, 'pysmi', u'SNMP SMI compiler',
[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, 'PySMI', u'SNMP SMI compiler',
author, 'PySMI', '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}
# this merges constructor docstring with class docstring
autoclass_content = 'both'
# Napoleon settings
napoleon_google_docstring = True
napoleon_numpy_docstring = False
napoleon_include_private_with_doc = False
napoleon_include_special_with_doc = True
napoleon_use_admonition_for_examples = False
napoleon_use_admonition_for_notes = False
napoleon_use_admonition_for_references = False
napoleon_use_ivar = False
napoleon_use_param = False
napoleon_use_rtype = False
================================================
FILE: docs/source/contents.rst
================================================
SNMP SMI compiler
=================
.. toctree::
:maxdepth: 2
The PySMI library and tools are designed to parse, verify and transform
`SNMP SMI <https://en.wikipedia.org/wiki/Management_information_base>`_ MIB
modules from their original ASN.1 form into JSON or `pysnmp <http://snmplabs.com/pysnmp/>`_
representation.
Documentation
-------------
.. toctree::
:maxdepth: 2
/documentation
Source code & Changelog
-----------------------
Project source code is hosted at `GitHub <https://github.com/etingof/pysmi>`_.
Everyone is welcome to fork and contribute back!
We maintain the detailed :doc:`log of changes </changelog>` to our software.
Download & Install
------------------
.. toctree::
:maxdepth: 2
/download
Changes
-------
.. toctree::
:maxdepth: 1
/changelog
License
-------
The SNMP SMI library software is distributed under 2-clause BSD License.
.. toctree::
:maxdepth: 2
/license
MIB files archive
-----------------
The PySMI project maintains a `collection <http://mibs.snmplabs.com/asn1/>`_
of publicly available ASN.1 MIB files collected on the Internet. You are
welcome to use this MIBs archive however we can't guarantee any degree
of consistency or reliability when it comes to these MIB modules.
The *mibdump.py* tool as well as many other utilities based on PySMI
are programmed to use this MIB repository for automatic download and
dependency resolution.
You can always reconfigure PySMI to use some other remote MIB repository
instead or in addition to this one.
Contact
-------
In case of questions or troubles using SNMP SMI library, please open up an
`issue <https://github.com/etingof/pysmi/issues>`_ at GitHub or ask at
`Stack Overflow <http://stackoverflow.com/questions/tagged/pysmi>`_ .
================================================
FILE: docs/source/documentation.rst
================================================
PySMI documentation
===================
PySMI library is highly modular. The top-level component is called
*compiler* and it acts as main user-facing object. Most of other
components are plugged into the *compiler* object prior to its use.
Normally, user asks *compiler* to perform certain transformation of
named MIB module. Compiler will:
* Search its data sources for given MIB module (identified by name)
noting their last modification times.
* Search compiler-managed repositories of already converted MIB modules
for modules that are more recent than corresponding source MIB module.
* If freshly transformed MIB module is found, processing stops here.
* Otherwise compiler passes ASN.1 MIB module content to the *lexer*
component.
* Lexer returns a sequence of tokenized ASN.1 MIB contents. Compiler
then passes that sequence of tokens to the *parser* component.
* Parser runs LR algorithm on tokenized MIB thus transforming MIB
contents into Abstract Syntax Tree (AST) and also noting what other
MIB modules are referred to from the MIB being parsed.
* In case of parser failure, what is usually an indication of broken
ASN.1 MIB syntax, compiler may attempt to fetch pre-transformed MIB
contents from configured source. This process is called *borrowing*
in PySMI.
* In case of successful parser completion, compiler will pass produced
AST to *code generator* component.
* Code generator walks its input AST and performs actual data
transformation.
* The above steps may be repeated for each of the MIB modules referred
to as parser figures out. Once no more unresolved dependencies remain,
compiler will call its *writer* component to store all transformed MIB
modules.
The location of ASN.1 MIB modules and flavor of their syntax, as well as
desired transformation format, is determined by respective components
chosen and configured to compiler.
.. toctree::
:maxdepth: 2
/mibdump
/mibcopy
/library-reference
================================================
FILE: docs/source/download.rst
================================================
Download & Install
==================
The best way to obtain SNMP SMI library is by running `pip`:
.. code-block:: bash
$ virtualenv venv
$ source venv/bin/activate
$ pip install pysmi
Alternatively, you can download the latest release from
`GitHub <https://github.com/etingof/pysmi/releases>`_
or `PyPI <https://pypi.org/project/pysmi/>`_.
================================================
FILE: docs/source/examples/always-borrow-precompiled-pysnmp-files.rst
================================================
.. include:: /../../examples/always-borrow-precompiled-pysnmp-files.py
:start-after: """
:end-before: """#
.. literalinclude:: /../../examples/always-borrow-precompiled-pysnmp-files.py
:start-after: """#
:language: python
:download:`Download</../../examples/always-borrow-precompiled-pysnmp-files.py>` script.
================================================
FILE: docs/source/examples/borrow-precompiled-pysnmp-files-on-failure.rst
================================================
.. include:: /../../examples/borrow-precompiled-pysnmp-files-on-failure.py
:start-after: """
:end-before: """#
.. literalinclude:: /../../examples/borrow-precompiled-pysnmp-files-on-failure.py
:start-after: """#
:language: python
:download:`Download</../../examples/borrow-precompiled-pysnmp-files-on-failure.py>` script.
================================================
FILE: docs/source/examples/compile-smistar-mibs-into-pysnmp-files-if-needed.rst
================================================
.. include:: /../../examples/compile-smistar-mibs-into-pysnmp-files-if-needed.py
:start-after: """
:end-before: """#
.. literalinclude:: /../../examples/compile-smistar-mibs-into-pysnmp-files-if-needed.py
:start-after: """#
:language: python
:download:`Download</../../examples/compile-smistar-mibs-into-pysnmp-files-if-needed.py>` script.
================================================
FILE: docs/source/examples/compile-smiv2-mibs-from-text-into-pysnmp-code.rst
================================================
.. include:: /../../examples/compile-smiv2-mibs-from-text-into-pysnmp-code.py
:start-after: """
:end-before: """#
.. literalinclude:: /../../examples/compile-smiv2-mibs-from-text-into-pysnmp-code.py
:start-after: """#
:language: python
:download:`Download</../../examples/compile-smiv2-mibs-from-text-into-pysnmp-code.py>` script.
================================================
FILE: docs/source/examples/download-and-compile-smistar-mibs-into-json.rst
================================================
.. include:: /../../examples/download-and-compile-smistar-mibs-into-json.py
:start-after: """
:end-before: """#
.. literalinclude:: /../../examples/download-and-compile-smistar-mibs-into-json.py
:start-after: """#
:language: python
:download:`Download</../../examples/download-and-compile-smistar-mibs-into-json.py>` script.
================================================
FILE: docs/source/examples/download-and-compile-smistar-mibs-into-pysnmp-files.rst
================================================
.. include:: /../../examples/download-and-compile-smistar-mibs-into-pysnmp-files.py
:start-after: """
:end-before: """#
.. literalinclude:: /../../examples/download-and-compile-smistar-mibs-into-pysnmp-files.py
:start-after: """#
:language: python
:download:`Download</../../examples/download-and-compile-smistar-mibs-into-pysnmp-files.py>` script.
================================================
FILE: docs/source/library-reference.rst
================================================
PySMI library
=============
The *MibCompiler* object is the top-most interface to PySMI library features.
It holds together the otherwise isolated pieces of the compiler infrastructure
and manages the workflow of ASN.1 MIB transformation.
This example showcases some of its features:
.. code-block:: python
from pysmi.reader import HttpReader
from pysmi.searcher import StubSearcher
from pysmi.writer import CallbackWriter
from pysmi.parser import SmiStarParser
from pysmi.codegen import JsonCodeGen
from pysmi.compiler import MibCompiler
inputMibs = ['IF-MIB', 'IP-MIB']
httpSources = [('mibs.snmplabs.com', 80, '/asn1/@mib@')]
# store compiled MIBs by calling this function
def store_mibs(mibName, jsonDoc, cbCtx):
print('# MIB module %s' % mibName)
print(jsonDoc)
mibCompiler = MibCompiler(
SmiStarParser(), JsonCodeGen(), CallbackWriter(store_mibs)
)
# pull ASN.1 MIBs over HTTP
mibCompiler.addSources(*[HttpReader(*x) for x in httpSources])
# never recompile MIBs with ASN.1 MACROs
mibCompiler.addSearchers(StubSearcher(*JsonCodeGen.baseMibs))
status = mibCompiler.compile(*inputMibs)
print(status)
.. toctree::
:maxdepth: 2
/pysmi/compiler/mibcompiler
/pysmi/compiler/mibstatus
MIB sources
-----------
PySMI offers a handful of distinct transport mechanisms for fetching MIBs by
name from specific locations. In all cases MIB module name to file name match
may not be exact -- some name fuzzying can be performed to mitigate
possible changes to MIB file name.
.. toctree::
:maxdepth: 2
/pysmi/reader/localfile/filereader
/pysmi/reader/zipreader/zipreader
/pysmi/reader/httpclient/httpreader
/pysmi/reader/ftpclient/ftpreader
/pysmi/reader/callback/callbackreader
Conditional compilation
-----------------------
There are cases when MIB transformation may or must not be performed.
Such cases include:
* foundation MIBs containing manually implemented pieces or ASN.1 MACRO's
* obsolete MIBs fully reimplemented within modern MIBs
* already transformed MIBs
:ref:`MibCompiler <compiler.MibCompiler>` expects user to supply a
*searcher* object that would allow or skip MIB transformation for particular
name based on whatever reason it is aware of.
In general, *searcher* logic is specific to target format. At the time being,
only `pysnmp <http://snmplabs.com/pysnmp>`_ code generation backend requires
such filtering.
.. toctree::
:maxdepth: 2
/pysmi/searcher/pyfile/pyfilesearcher
/pysmi/searcher/pypackage/pypackagesearcher
/pysmi/searcher/stub/stubsearcher
Parser configuration
--------------------
MIBs may be written in one of the two major SMI language versions (v1 and v2).
Some MIBs may contain typical errors.
PySMI offers a way to customize the parser to consume either of the major SMI
grammars as well as to recover from well-known errors in MIB files.
.. toctree::
:maxdepth: 2
/pysmi/parser/smi/parserfactory
/pysmi/parser/smi/dialect
Code generators
---------------
Once ASN.1 MIB is parsed up, AST is passed to a code generator which turns
AST into desired representation of the MIB.
.. toctree::
:maxdepth: 2
/pysmi/codegen/jsondoc/jsoncodegen
/pysmi/codegen/pysnmp/pysnmpcodegen
/pysmi/codegen/null/nullcodegen
Borrow pre-compiled MIBs
------------------------
Some MIBs in circulation appear broken beyond automatic repair. To
handle such cases PySMI introduces the *MIB borrowing*
functionality. When :ref:`MibCompiler <compiler.MibCompiler>`
gives up compiling a MIB, it can try to go out and take a copy of
already transformed MIB to complete the request successfully.
.. toctree::
:maxdepth: 2
/pysmi/borrower/anyfile/anyfileborrower
/pysmi/borrower/pyfile/pyfileborrower
Write compiled MIBs
-------------------
Successfully transformed MIB modules' contents will be passed to *writer*
object given to :ref:`MibCompiler <compiler.MibCompiler>` on instantiation.
.. toctree::
:maxdepth: 2
/pysmi/writer/localfile/filewriter
/pysmi/writer/pyfile/pyfilewriter
/pysmi/writer/callback/callbackwriter
Examples
--------
The following examples focus on various feature of the PySMI library.
.. toctree::
:maxdepth: 2
/examples/download-and-compile-smistar-mibs-into-json.rst
/examples/download-and-compile-smistar-mibs-into-pysnmp-files.rst
/examples/compile-smistar-mibs-into-pysnmp-files-if-needed.rst
/examples/compile-smiv2-mibs-from-text-into-pysnmp-code.rst
/examples/borrow-precompiled-pysnmp-files-on-failure.rst
/examples/always-borrow-precompiled-pysnmp-files.rst
In case of any troubles or confusion, try enabling PySMI debugging
and watch the output:
.. code-block:: python
from pysmi import debug
debug.setLogger(debug.Debug('all'))
================================================
FILE: docs/source/license.rst
================================================
License
=======
.. include:: ../../LICENSE.rst
================================================
FILE: docs/source/mibcopy.rst
================================================
The *mibcopy* tool
==================
.. toctree::
:maxdepth: 2
The *mibcopy.py* tool attempts to normalize the file name of the MIB file.
It turned out that sometimes vendors name their MIBs in any possible way,
not necessarily after the canonical MIB name. This causes problems to the
MIB consumers as they may not be able to locate the MIB they need on the
file system.
The way how *mibcopy.py* works is that it tries to read the MIB from
the given file (or all files from a given directory or archive), parse
MIB's canonical name from the contents of the file. Based on that, the
tool tries to rename MIB file into the name which is the same as canonical
MIB name. If *mibcopy.py* encounters the same named file already present
on the file system, it reads it up to see its revision date. Then the
tool compares the revision dates of the colliding MIB files and either
overrides the offending file or drops the file being copied as outdated.
The ultimate goal is to end up with the latest versions of the MIB files
all named after their canonical names.
.. code-block:: bash
$ mibcopy.py --help
Synopsis:
SNMP SMI/MIB files copying tool. When given MIB file(s) or
directory(ies) on input and a destination directory, the tool
parses MIBs to figure out their canonical MIB module name and
the latest revision date, then copies MIB module on input
into the destination directory under its MIB module name
*if* there is no such file already or its revision date is
older.
Documentation:
http://snmplabs.com/pysmi
Usage: mibcopy.py [--help]
[--version]
[--verbose]
[--quiet]
[--debug=<all|borrower|codegen|compiler|grammar|lexer|
parser|reader|searcher|writer>]
[--mib-source=<URI>]
[--cache-directory=<DIRECTORY>]
[--ignore-errors]
[--dry-run]
<SOURCE [SOURCE...]> <DESTINATION>
Where:
URI - file, zip, http, https, ftp, sftp schemes are
supported. Use @mib@ placeholder token in URI to
refer directly to the required MIB module when
source does not support directory listing
(e.g. HTTP).
Specifying MIB source
---------------------
The --mib-source option can be given multiple times. Each instance of
--mib-source must specify a URL where ASN.1 MIB modules should be
looked up and downloaded from. At this moment three MIB sourcing
methods are supported:
* Local files. This could be a top-level directory where MIB files are
located. Subdirectories will be automatically traversed as well.
Example: file:///usr/share/snmp
* ZIP archives containing MIB files. Subdirectories and embedded ZIP
archives will be automatically traversed.
Example: zip://mymibs.zip
* HTTP/HTTPS. A fully specified URL where MIB module name is specified by
a @mib@ placeholder. When specific MIB is looked up, PySMI will replace
that placeholder with MIB module name it is looking for.
Example: `http://mibs.snmplabs.com/asn1/@mib@ <http://mibs.snmplabs.com/asn1/>`_
* SFTP/FTP. A fully specified URL including FTP username and password.
MIB module name is specified by a @mib@ placeholder. When specific MIB
is looked up, PySMI will replace that placeholder with MIB module name
it is looking for.
Example: `http://mibs.snmplabs.com/asn1/@mib@ <http://mibs.snmplabs.com/asn1/>`_
When trying to fetch a MIB module, the *mibcopy.py* tool will try each of
configured --mib-source transports in order of specification till
first successful hit.
By default *mibcopy.py* will search:
* file:///usr/share/snmp
* http://mibs.snmplabs.com/asn1/@mib@
Once another --mib-source option is given, those defaults will not be used
and should be manually given to *mibcopy.py* if needed.
Setting destination directory
-----------------------------
The *mibcopy.py* writes MIBs into the *<DESTINATION>* directory.
Ignoring transformation errors
------------------------------
By default PySMI will stop on first fatal error occurred during
transformations of a series of MIBs. If you wish PySMI to ignore
fatal errors and therefore skipping failed MIB, use the --ignore-errors
option.
Keep in mind that skipping transformation of MIBs that are imported
by other MIBs might make dependant MIBs inconsistent for use.
Minor speedups
--------------
The --cache-directory option may be used to point to a temporary
writable directory where PySMI parser (e.g. Ply) would store its
lookup tables. That should improve PySMI performance a tad bit.
================================================
FILE: docs/source/mibdump.rst
================================================
The *mibdump* tool
==================
.. toctree::
:maxdepth: 2
The *mibdump.py* tool is a command-line frontend to the PySMI library. This
tool can be used for automatic downloading and transforming SNMP MIB modules
into various formats.
.. code-block:: bash
$ mibdump.py --help
Synopsis:
SNMP SMI/MIB files conversion tool
Documentation:
http://snmplabs.com/pysmi
Usage: mibdump.py [--help]
[--version]
[--quiet]
[--debug=<all|borrower|codegen|compiler|grammar|lexer|parser|reader|searcher|writer>]
[--mib-source=<URI>]
[--mib-searcher=<PATH|PACKAGE>]
[--mib-stub=<MIB-NAME>]
[--mib-borrower=<PATH>]
[--destination-format=<FORMAT>]
[--destination-directory=<DIRECTORY>]
[--cache-directory=<DIRECTORY>]
[--disable-fuzzy-source]
[--no-dependencies]
[--no-python-compile]
[--python-optimization-level]
[--ignore-errors]
[--build-index]
[--rebuild]
[--dry-run]
[--no-mib-writes]
[--generate-mib-texts]
[--keep-texts-layout]
<MIB-NAME> [MIB-NAME [...]]]
Where:
URI - file, zip, http, https, ftp, sftp schemes are supported.
Use @mib@ placeholder token in URI to refer directly to
the required MIB module when source does not support
directory listing (e.g. HTTP).
FORMAT - pysnmp, json, null
When JSON destination format is requested, for each MIB module *mibdump.py*
will produce a JSON document containing all MIB objects. For example,
`IF-MIB <http://mibs.snmplabs.com/asn1/IF-MIB>`_ module in JSON form
would look like:
.. code-block:: python
{
"ifMIB": {
"name": "ifMIB",
"oid": "1.3.6.1.2.1.31",
"class": "moduleidentity",
"revisions": [
"2007-02-15 00:00",
"1996-02-28 21:55",
"1993-11-08 21:55"
]
},
...
"ifTestTable": {
"name": "ifTestTable",
"oid": "1.3.6.1.2.1.31.1.3",
"class": "objecttype",
"maxaccess": "not-accessible"
},
"ifTestEntry": {
"name": "ifTestEntry",
"oid": "1.3.6.1.2.1.31.1.3.1",
"class": "objecttype",
"maxaccess": "not-accessible",
"augmention": {
"name": "ifTestEntry",
"module": "IF-MIB",
"object": "ifEntry"
}
},
"ifTestId": {
"name": "ifTestId",
"oid": "1.3.6.1.2.1.31.1.3.1.1",
"class": "objecttype",
"syntax": {
"type": "TestAndIncr",
"class": "type"
},
"maxaccess": "read-write"
},
...
}
In general, JSON MIB captures all aspects of original (ASN.1) MIB contents
and layout. The snippet above is just an example, here is the complete
`IF-MIB.json <http://mibs.snmplabs.com/json/fulltext/IF-MIB.json>`_
file.
Specifying MIB source
---------------------
The --mib-source option can be given multiple times. Each instance of
--mib-source must specify a URL where ASN.1 MIB modules should be
looked up and downloaded from. At this moment three MIB sourcing
methods are supported:
* Local files. This could be a top-level directory where MIB files are
located. Subdirectories will be automatically traversed as well.
Example: file:///usr/share/snmp
* ZIP archives containing MIB files. Subdirectories and embedded ZIP
archives will be automatically traversed.
Example: zip://mymibs.zip
* HTTP/HTTPS. A fully specified URL where MIB module name is specified by
a @mib@ placeholder. When specific MIB is looked up, PySMI will replace
that placeholder with MIB module name it is looking for.
Example: `http://mibs.snmplabs.com/asn1/@mib@ <http://mibs.snmplabs.com/asn1/>`_
* SFTP/FTP. A fully specified URL including FTP username and password.
MIB module name is specified by a @mib@ placeholder. When specific MIB
is looked up, PySMI will replace that placeholder with MIB module name
it is looking for.
Example: `http://mibs.snmplabs.com/asn1/@mib@ <http://mibs.snmplabs.com/asn1/>`_
When trying to fetch a MIB module, the *mibdump.py* tool will try each of
configured --mib-source transports in order of specification till
first successful hit.
By default *mibdump.py* will search:
* file:///usr/share/snmp
* http://mibs.snmplabs.com/asn1/@mib@
Once another --mib-source option is given, those defaults will not be used
and should be manually given to *mibdump.py* if needed.
Fuzzying MIB module names
-------------------------
There is no single convention on how MIB module files should be named. By
default *mibdump.py* will try a handful of guesses when trying to find a file
containing specific MIB module. It will try upper and lower cases, a file
named after MIB module, try adding different extensions to a file (.mib,
.my etc), try adding/cutting the '-MIB' part of the file name.
If nothing matches, *mibdump.py* will consider that probed --mib-source
does not contain MIB module it is looking for.
There is a small chance, though, that fuzzy natching may result in getting
a wrong MIB. If that happens, you can disable the above fuzzyness by
giving *mibdump.py* the --disable-fuzzy-source flag.
Avoiding excessive transformation
---------------------------------
It well may happen that many MIB modules refer to a common single MIB
module. In that case *mibdump.py* may transform it many times unless you
tell *mibdump.py* where to search for already transformed MIBs. That place
could of course be a directory where *mibdump.py* writes its transforms into
and/or some other local locations.
The --mib-searcher option specifies either local directory or importable
Python package (applicable to pysnmp transformation) containing transformed
MIB modules. Multiple --mib-searcher options could be given, *mibdump.py*
will use each of them in order of specification till first hit.
If no transformed MIB module is found, *mibdump.py* will go on running its full
transformation cycle.
By default *mibdump.py* will use:
* --mib-searcher=$HOME/.pysnmp/mibs
* --mib-searcher=pysnmp_mibs
Once another --mib-searcher option is given, those defaults will not be used
and should be manually given to *mibdump.py* if needed.
Blacklisting MIBs
-----------------
Some MIBs may not be automatically transformed into another form and
therefore must be explicitly excluded from processing. Such MIBs are
normally manually implemented for each target MIB format. Examples
include MIBs containing base SMI types or ASN.1 MACRO definitions
(SNMPv2-SMI, SNMPV2-TC), initially compiled but later manually modified
MIBs and others.
Default list of blacklisted MIBs for pysnmp transformation target
is: RFC-1212, RFC-1215, RFC1065-SMI, RFC1155-SMI, RFC1158-MIB,
RFC1213-MIB, SNMP-FRAMEWORK-MIB, SNMP-TARGET-MIB, SNMPv2-CONF, SNMPv2-SMI,
SNMPv2-TC, SNMPv2-TM, TRANSPORT-ADDRESS-MIB.
If you need to modify this list use the --mib-stub option.
Dealing with broken MIBs
------------------------
Curiously enough, some MIBs coming from quite prominent vendors
appear syntactically incorrect. That leads to MIB compilers fail on
such MIBs. While many MIB compiler implementations (PySMI included)
introduce workarounds and grammar relaxations allowing slightly
broken MIBs to compile, however severely broken MIBs can't be
reliably compiled.
As another workaround PySMI offers the *borrow* feature. It allows
PySMI to fetch already transformed MIBs even if corresponding
ASN.1 MIB can't be found or parsed.
Default source of pre-compiled MIBs for pysnmp target is:
* http://mibs.snmplabs.com/pysnmp/fulltexts/@mib@
* http://mibs.snmplabs.com/pysnmp/notexts/@mib@
If you wish to modify this default list use one or more
--mib-borrower options.
Choosing target transformation
------------------------------
PySMI design allows many transformation formats to be
supported in form of specialized code generation components.
At the moment PySMI can produce MIBs in form of pysnmp classes
and JSON documents.
JSON document schema is chosen to preserve as much of MIB
information as possible. There's no established JSON schema
known to the authors.
Setting destination directory
-----------------------------
By default *mibdump.py* writes pysnmp MIBs into:
* $HOME/.pysnmp/mibs (on UNIX)
* @HOME@\PySNMP Configuration\MIBs\ (on Windows)
and JSON files in current working directory.
Use --destination-directory option to change default output
directory.
Performing unconditional transformation
---------------------------------------
By default PySMI will avoid creating new transformations if fresh
enough versions already exist. By using --rebuild option you could
trick PySMI doing requested transformation for all given MIB modules.
Ignoring transformation errors
------------------------------
By default PySMI will stop on first fatal error occurred during
transformations of a series of MIBs. If you wish PySMI to ignore
fatal errors and therefore skipping failed MIB, use the --ignore-errors
option.
Keep in mind that skipping transformation of MIBs that are imported
by other MIBs might make dependant MIBs inconsistent for use.
Skipping dependencies
---------------------
Most MIBs rely on other MIBs for their operations. This is indicated
by the IMPORT statement in ASN.1 language. PySMI attempts to transform
all MIBs IMPORT'ed by MIB being transformed. That is done in recursive
manner.
By using --no-dependencies flag you can tell PySMI not to transform any
MIBs other than those explicitly requested to be transformed.
Keep in mind that skipping dependencies may make the whole set of
transformed MIBs inconsistent.
Generating MIB texts
--------------------
Most MIBs are very verbose. They contain many human-oriented descriptions
and clarifications written in plain English. Those texts may be useful
for MIB browser applications (to display those texts to human operator)
but might not make any sense in other applications.
To save space and CPU time, PySMI does not by default include those texts
into transformed MIBs. However this can be reverted by adding
--generate-mib-texts option.
When MIB texts are generated, whitespaces and new lines are stripped by
default. Sometimes that breaks down ASCII art should it occur in MIB texts.
To preserve original text formatting, --keep-texts-layout option may
be used.
Building MIB indices
--------------------
If --build-index option is given, depending on the destination format chosen,
the *mibdump.py* tool may create new (or update existing) document containing
MIB information in a form that is convenient for querying cornerstone
properties of MIB files.
For example, building JSON index for
`IP-MIB.json <http://mibs.snmplabs.com/json/asn1/IP-MIB>`_,
`TCP-MIB.json <http://mibs.snmplabs.com/json/asn1/TCP-MIB>`_ and
`UDP-MIB.json <http://mibs.snmplabs.com/json/asn1/UDP-MIB>`_
MIB modules would emit something like this:
.. code-block:: json
{
"compliance": {
"1.3.6.1.2.1.48.2.1.1": [
"IP-MIB"
],
"1.3.6.1.2.1.49.2.1.1": [
"TCP-MIB"
],
"1.3.6.1.2.1.50.2.1.1": [
"UDP-MIB"
]
},
"identity": {
"1.3.6.1.2.1.48": [
"IP-MIB"
],
"1.3.6.1.2.1.49": [
"TCP-MIB"
],
"1.3.6.1.2.1.50": [
"UDP-MIB"
]
},
"oids": {
"1.3.6.1.2.1.4": [
"IP-MIB"
],
"1.3.6.1.2.1.5": [
"IP-MIB"
],
"1.3.6.1.2.1.6": [
"TCP-MIB"
],
"1.3.6.1.2.1.7": [
"UDP-MIB"
],
"1.3.6.1.2.1.49": [
"TCP-MIB"
],
"1.3.6.1.2.1.50": [
"UDP-MIB"
]
}
}
With this example, *compliance* and *identity* keys point to
*MODULE-COMPLIANCE* and *MODULE-IDENTITY* MIB objects, *oids*
list top-level OIDs branches defined in MIB modules. Full index
build over thousands of MIBs could be seen
`here <http://mibs.snmplabs.com/json/index.json>`_.
Minor speedups
--------------
There are a few options that may improve PySMI performance.
The --cache-directory option may be used to point to a temporary
writable directory where PySMI parser (e.g. Ply) would store its
lookup tables.
By default PySMI performing transformation into pysnmp format will
also pre-compile Python source into interpreter bytecode. That takes
some time and space. If you wish not to cache Python bytecode
or to do that later, use the --no-python-compile option.
================================================
FILE: docs/source/pysmi/borrower/anyfile/anyfileborrower.rst
================================================
.. _borrower.anyfile.AnyFileBorrower:
Any file borrower
-----------------
.. autoclass:: pysmi.borrower.anyfile.AnyFileBorrower
:members:
================================================
FILE: docs/source/pysmi/borrower/pyfile/pyfileborrower.rst
================================================
.. _borrower.pyfile.PyFileBorrower:
Python file borrower
--------------------
.. autoclass:: pysmi.borrower.pyfile.PyFileBorrower
:members:
================================================
FILE: docs/source/pysmi/codegen/jsondoc/jsoncodegen.rst
================================================
.. _codegen.jsondoc.JsonCodeGen:
JSON document generator
-----------------------
.. autoclass:: pysmi.codegen.jsondoc.JsonCodeGen
:members:
================================================
FILE: docs/source/pysmi/codegen/null/nullcodegen.rst
================================================
.. _codegen.null.NullCodeGen:
Code generation stub
--------------------
.. autoclass:: pysmi.codegen.null.NullCodeGen
:members:
================================================
FILE: docs/source/pysmi/codegen/pysnmp/pysnmpcodegen.rst
================================================
.. _codegen.pysnmp.PySnmpCodeGen:
PySNMP MIB generator
--------------------
.. autoclass:: pysmi.codegen.pysnmp.PySnmpCodeGen
:members:
================================================
FILE: docs/source/pysmi/compiler/mibcompiler.rst
================================================
.. _compiler.MibCompiler:
MIB compiler
------------
.. autoclass:: pysmi.compiler.MibCompiler
:members:
================================================
FILE: docs/source/pysmi/compiler/mibstatus.rst
================================================
.. _reader.compiler.MibStatus:
Compilation status
------------------
*MibStatus* class instance is used by :func:`MibCompiler.compiler` to
indicate the outcome of MIB transformation operation.
.. autoclass:: pysmi.compiler.MibStatus
:members:
================================================
FILE: docs/source/pysmi/parser/smi/dialect.rst
================================================
.. _parser.smi.dialect:
SMI language dialects
---------------------
PySMI offers a pre-built collection of parser grammar relaxation options
to simplify its use:
* *pysmi.parser.dialect.smiV2* - canonical SMIv2 grammar
* *pysmi.parser.dialect.smiV1* - canonical SMIv1 grammar
* *pysmi.parser.dialect.smiV1Relaxed* - relaxed SMIv1 grammar allowing some deviations
The grammar object should be passed to the :ref:`parserFactory <parser.smi.parserFactory>` function.
.. code-block:: python
from pysmi.parser.dialect import smiV1
from pysmi.parser.smi import parserFactory
SmiV1Parser = parserFactory(**smiV1)
Apparently, many production MIBs were shipped in syntactically broken
condition. PySMI attempts to work around such issues by allowing some
extra SMI grammar relaxations. You can enable all those relaxations at
once to maximize the number of MIBs, found in the wild, successfully
compiled.
.. code-block:: python
from pysmi.parser.dialect import smiV1Relaxed
from pysmi.parser.smi import parserFactory
RelaxedSmiV1Parser = parserFactory(**smiV1Relaxed)
================================================
FILE: docs/source/pysmi/parser/smi/parserfactory.rst
================================================
.. _parser.smi.parserFactory:
SMI parser
----------
SNMP MIBs are written in two kinds of special language - SMIv1 and SMIv2.
The first SMI version is obsolete, most MIBs by now are written in SMIv2
grammar. There are also efforts aimed at improving SMIv2, but those MIBs
are in great minority at the time of this writing.
PySMI is designed to handle both SMIv1 and SMIv2. The way it is done is
that SMIv2 is considered the most basic and complete, whereas SMIv1 is a
specialization of SMIv2 syntax.
For a user to acquire SMIv2 parser the *parserFactory* function should
be called with the :ref:`SMI dialect object <parser.smi.dialect>`.
The parser object should be passed to the :ref:`MibCompiler <compiler.MibCompiler>` object.
.. autofunction:: pysmi.parser.smi.parserFactory
.. note::
Please, note that *parserFactory* function returns a class, not
class instance. Make sure to instantiate it when passing to
:ref:`MibCompiler <compiler.MibCompiler>` class constructor.
================================================
FILE: docs/source/pysmi/reader/callback/callbackreader.rst
================================================
.. _reader.callback.CallbackReader:
Callback reader
---------------
*CallbackReader* class instance tries to fetch MIB files by calling user object.
.. autoclass:: pysmi.reader.callback.CallbackReader
:members:
================================================
FILE: docs/source/pysmi/reader/ftpclient/ftpreader.rst
================================================
.. _reader.ftpclient.FtpReader:
FTP reader
----------
*FtpReader* class instance tries to download MIB files from configured FTP server.
.. autoclass:: pysmi.reader.ftpclient.FtpReader
:members:
================================================
FILE: docs/source/pysmi/reader/httpclient/httpreader.rst
================================================
.. _reader.httpclient.HttpReader:
HTTP reader
-----------
*HttpReader* class instance tries to download MIB files using configured URL.
.. autoclass:: pysmi.reader.httpclient.HttpReader
:members:
================================================
FILE: docs/source/pysmi/reader/localfile/filereader.rst
================================================
.. _reader.localfile.FileReader:
Local file reader
-----------------
*FileReader* class instance looks up MIB files in given directories on
the host running PySMI.
.. autoclass:: pysmi.reader.localfile.FileReader
:members:
================================================
FILE: docs/source/pysmi/reader/zipreader/zipreader.rst
================================================
.. _reader.zipreader.ZipReader:
ZIP archive reader
------------------
*ZipReader* class instance looks up MIB files in local ZIP archive.
ZIP subdirectories and embedded ZIP archives would be traversed.
.. autoclass:: pysmi.reader.zipreader.ZipReader
:members:
================================================
FILE: docs/source/pysmi/searcher/pyfile/pyfilesearcher.rst
================================================
.. _searcher.pyfile.PyFileSearcher:
Python files searcher
---------------------
Transformed MIBs that were saved in form of Python files can be checked
with *PyFileSearcher* class instances.
.. autoclass:: pysmi.searcher.pyfile.PyFileSearcher
:members:
================================================
FILE: docs/source/pysmi/searcher/pypackage/pypackagesearcher.rst
================================================
.. _searcher.pypackage.PyPackageSearcher:
Search Python packages
----------------------
Some MIBs, most frequently the base ones, can be stored at a Python package.
There existence can be checked with the *PyPackageSearcher* class instances.
.. autoclass:: pysmi.searcher.pypackage.PyPackageSearcher
:members:
================================================
FILE: docs/source/pysmi/searcher/stub/stubsearcher.rst
================================================
.. _searcher.stub.StubSearcher:
Unconditionally ignore MIBs
---------------------------
Foundation or obsolete MIBs that should never be transformed can be
blindly excluded by listing their names at the *StubSearcher* class
instance.
.. autoclass:: pysmi.searcher.stub.StubSearcher
:members:
.. note::
A pysnmp-specific list of MIB names to be permanently excluded from
transformation can be found at :py:const:`pysmi.codegen.pysnmp.baseMibs`.
================================================
FILE: docs/source/pysmi/writer/callback/callbackwriter.rst
================================================
.. _writer.callback.CallbackReader:
Callback writer
---------------
*CallbackWriter* class instance passes the contents of the compiled MIB files to a user object.
.. autoclass:: pysmi.writer.callback.CallbackWriter
:members:
================================================
FILE: docs/source/pysmi/writer/localfile/filewriter.rst
================================================
.. _writer.localfile.FileWriter:
File writer
-----------
.. autoclass:: pysmi.writer.localfile.FileWriter
:members:
================================================
FILE: docs/source/pysmi/writer/pyfile/pyfilewriter.rst
================================================
.. _writer.pyfile.PyFileWriter:
Python file writer
------------------
.. autoclass:: pysmi.writer.pyfile.PyFileWriter
:members:
================================================
FILE: examples/always-borrow-precompiled-pysnmp-files.py
================================================
"""
Always borrow pysnmp MIBs
+++++++++++++++++++++++++
Try to borrow precompiled pysnmp MIB file(s) from a web-site.
In this example no attempt is made to find and compile ASN.1
MIB source.
Fetched pysnmp MIB(s) are stored in a local directory.
"""#
from pysmi.reader import HttpReader
from pysmi.searcher import PyFileSearcher
from pysmi.borrower import PyFileBorrower
from pysmi.writer import PyFileWriter
from pysmi.parser import NullParser
from pysmi.codegen import NullCodeGen
from pysmi.compiler import MibCompiler
inputMibs = ['BORROWED-MIB']
httpBorrowers = [
('mibs.snmplabs.com', 80, '/pysnmp/notexts/@mib@')
]
dstDirectory = '.pysnmp-mibs'
# Initialize compiler infrastructure
mibCompiler = MibCompiler(
NullParser(), NullCodeGen(), PyFileWriter(dstDirectory)
)
# check compiled/borrowed MIBs in our own productions
mibCompiler.addSearchers(PyFileSearcher(dstDirectory))
# search for precompiled MIBs at Web sites
mibCompiler.addBorrowers(
*[PyFileBorrower(HttpReader(*x)) for x in httpBorrowers]
)
# run MIB compilation
results = mibCompiler.compile(*inputMibs)
print('Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
================================================
FILE: examples/borrow-precompiled-pysnmp-files-on-failure.py
================================================
"""
Borrow pysnmp MIBs on failure
+++++++++++++++++++++++++++++
Look up specific ASN.1 MIBs at configured Web/FTP sites.
If no required MIB is found or its compilation fails for
some reason, attempt to download precompiled version of
failed MIB and store it locally as if we had compiled it.
"""#
from pysmi.reader import HttpReader
from pysmi.searcher import PyFileSearcher
from pysmi.searcher import StubSearcher
from pysmi.borrower import PyFileBorrower
from pysmi.writer import PyFileWriter
from pysmi.parser import SmiStarParser
from pysmi.codegen import PySnmpCodeGen
from pysmi.compiler import MibCompiler
# from pysmi import debug
# debug.setLogger(debug.Debug('borrower', 'reader', 'searcher'))
inputMibs = ['BORROWED-MIB']
httpSources = [
('mibs.snmplabs.com', 80, '/asn1/@mib@')
]
httpBorrowers = [
('mibs.snmplabs.com', 80, '/pysnmp/notexts/@mib@')
]
dstDirectory = '.pysnmp-mibs'
# Initialize compiler infrastructure
mibCompiler = MibCompiler(
SmiStarParser(), PySnmpCodeGen(), PyFileWriter(dstDirectory)
)
# search for source MIBs at Web sites
mibCompiler.addSources(*[HttpReader(*x) for x in httpSources])
# never recompile MIBs with MACROs
mibCompiler.addSearchers(StubSearcher(*PySnmpCodeGen.baseMibs))
# check compiled/borrowed MIBs in our own productions
mibCompiler.addSearchers(PyFileSearcher(dstDirectory))
# search for compiled MIBs at Web sites if source is not available or broken
mibCompiler.addBorrowers(*[PyFileBorrower(HttpReader(*x)).setOptions(genTexts=False) for x in httpBorrowers])
# run non-recursive MIB compilation
results = mibCompiler.compile(*inputMibs)
print('Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
================================================
FILE: examples/compile-smistar-mibs-into-pysnmp-files-if-needed.py
================================================
"""
Compile SMIv1/v2 MIBs
+++++++++++++++++++++
Look up specific ASN.1 MIBs at configured local directories,
compile them into pysnmp form if not done yet and save Python
modules as plain-text files in a local directory.
Try to support both SMIv1 and SMIv2 flavors of SMI as well as
popular deviations from official syntax found in the wild.
When figuring out if compilation is needed, check all known
places where pysnmp MIBs could possibly be found.
You can force MIB re-compilation by passing rebuild flag to
MIB compiler (see below).
Default invocation of MIB compiler does not generate [potentially
large] comments and texts found in MIBs. If you need them in pysnmp
MIB modules, just pass genTexts flag to MIB compiler.
"""#
from pysmi.reader import FileReader
from pysmi.searcher import PyFileSearcher, PyPackageSearcher, StubSearcher
from pysmi.writer import PyFileWriter
from pysmi.parser import SmiStarParser
from pysmi.codegen import PySnmpCodeGen
from pysmi.compiler import MibCompiler
inputMibs = ['IF-MIB', 'IP-MIB']
srcDirectories = ['/usr/share/snmp/mibs']
dstDirectory = '.pysnmp-mibs'
# Initialize compiler infrastructure
mibCompiler = MibCompiler(SmiStarParser(),
PySnmpCodeGen(),
PyFileWriter(dstDirectory))
# search for source MIBs here
mibCompiler.addSources(*[FileReader(x) for x in srcDirectories])
# check compiled MIBs in our own productions
mibCompiler.addSearchers(PyFileSearcher(dstDirectory))
# ...and at default PySNMP MIBs packages
mibCompiler.addSearchers(*[PyPackageSearcher(x) for x in PySnmpCodeGen.defaultMibPackages])
# never recompile MIBs with MACROs
mibCompiler.addSearchers(StubSearcher(*PySnmpCodeGen.baseMibs))
# run [possibly recursive] MIB compilation
results = mibCompiler.compile(*inputMibs) #, rebuild=True, genTexts=True)
print('Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
================================================
FILE: examples/compile-smiv2-mibs-from-text-into-pysnmp-code.py
================================================
"""
Compile SMIv2 MIBs
++++++++++++++++++
Invoke user callback function to provide MIB text,
compile given text string into pysnmp MIB form and pass
results to another user callback function for storing.
Here we expect to deal only with SMIv2-valid MIBs.
We use noDeps flag to prevent MIB compiler from attemping
to compile IMPORT'ed MIBs as well.
"""#
import sys
from pysmi.reader import CallbackReader
from pysmi.searcher import StubSearcher
from pysmi.writer import CallbackWriter
from pysmi.parser import SmiV2Parser
from pysmi.codegen import PySnmpCodeGen
from pysmi.compiler import MibCompiler
inputMibs = ['IF-MIB', 'IP-MIB']
srcDir = '/usr/share/snmp/mibs/' # we will read MIBs from here
# Initialize compiler infrastructure
mibCompiler = MibCompiler(
SmiV2Parser(),
PySnmpCodeGen(),
# out own callback function stores results in its own way
CallbackWriter(lambda m, d, c: sys.stdout.write(d))
)
# our own callback function serves as a MIB source here
mibCompiler.addSources(
CallbackReader(lambda m, c: open(srcDir+m+'.txt').read())
)
# never recompile MIBs with MACROs
mibCompiler.addSearchers(StubSearcher(*PySnmpCodeGen.baseMibs))
# run non-recursive MIB compilation
results = mibCompiler.compile(*inputMibs, **dict(noDeps=True))
print('Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
================================================
FILE: examples/download-and-compile-smistar-mibs-into-json.py
================================================
"""
Compile MIBs into JSON
++++++++++++++++++++++
Look up specific ASN.1 MIBs at configured Web and FTP sites,
compile them into JSON documents and print them out to stdout.
Try to support both SMIv1 and SMIv2 flavors of SMI as well as
popular deviations from official syntax found in the wild.
"""#
from pysmi.reader import FileReader, HttpReader
from pysmi.searcher import StubSearcher
from pysmi.writer import CallbackWriter
from pysmi.parser import SmiStarParser
from pysmi.codegen import JsonCodeGen
from pysmi.compiler import MibCompiler
# from pysmi import debug
# debug.setLogger(debug.Debug('reader', 'compiler'))
inputMibs = ['IF-MIB', 'IP-MIB']
srcDirectories = ['/usr/share/snmp/mibs']
httpSources = [
('mibs.snmplabs.com', 80, '/asn1/@mib@')
]
def printOut(mibName, jsonDoc, cbCtx):
print('\n\n# MIB module %s' % mibName)
print(jsonDoc)
# Initialize compiler infrastructure
mibCompiler = MibCompiler(
SmiStarParser(), JsonCodeGen(), CallbackWriter(printOut)
)
# search for source MIBs here
mibCompiler.addSources(*[FileReader(x) for x in srcDirectories])
# search for source MIBs at Web sites
mibCompiler.addSources(*[HttpReader(*x) for x in httpSources])
# never recompile MIBs with MACROs
mibCompiler.addSearchers(StubSearcher(*JsonCodeGen.baseMibs))
# run recursive MIB compilation
results = mibCompiler.compile(*inputMibs)
print('\n# Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
================================================
FILE: examples/download-and-compile-smistar-mibs-into-pysnmp-files.py
================================================
"""
Compile MIBs from web
+++++++++++++++++++++
Look up specific ASN.1 MIBs at configured Web and FTP sites,
compile them into pysnmp form and save Python modules as plain-text
files in a local directory.
Try to support both SMIv1 and SMIv2 flavors of SMI as well as
popular deviations from official syntax found in the wild.
In this example we disable automatic dependency checking on MIB
compilation using noDeps flag.
Also, we do not check if target file already exists thus MIB
compilation occurs on every invocation.
"""#
from pysmi.reader import HttpReader
from pysmi.reader import FtpReader
from pysmi.searcher import StubSearcher
from pysmi.writer import PyFileWriter
from pysmi.parser import SmiStarParser
from pysmi.codegen import PySnmpCodeGen
from pysmi.compiler import MibCompiler
inputMibs = ['IF-MIB', 'IP-MIB']
httpSources = [
('mibs.snmplabs.com', 80, '/asn1/@mib@')
]
ftpSources = [
('ftp.cisco.com', '/pub/mibs/v2/@mib@')
]
dstDirectory = '.pysnmp-mibs'
# Initialize compiler infrastructure
mibCompiler = MibCompiler(
SmiStarParser(), PySnmpCodeGen(), PyFileWriter(dstDirectory)
)
# search for source MIBs at Web and FTP sites
mibCompiler.addSources(*[HttpReader(*x) for x in httpSources])
mibCompiler.addSources(*[FtpReader(*x) for x in ftpSources])
# never recompile MIBs with MACROs
mibCompiler.addSearchers(StubSearcher(*PySnmpCodeGen.baseMibs))
# run non-recursive MIB compilation
results = mibCompiler.compile(*inputMibs, **dict(noDeps=True))
print('Results: %s' % ', '.join(['%s:%s' % (x, results[x]) for x in results]))
================================================
FILE: pysmi/__init__.py
================================================
# http://www.python.org/dev/peps/pep-0396/
__version__ = '0.4.0'
import sys
if sys.version_info[:2] < (2, 4):
raise RuntimeError('PySMI requires Python 2.4 or later')
================================================
FILE: pysmi/borrower/__init__.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
from pysmi.borrower.pyfile import PyFileBorrower
from pysmi.borrower.anyfile import AnyFileBorrower
================================================
FILE: pysmi/borrower/anyfile.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
from pysmi.borrower.base import AbstractBorrower
class AnyFileBorrower(AbstractBorrower):
"""Create arbitrary MIB file borrowing object"""
================================================
FILE: pysmi/borrower/base.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
from pysmi import error
from pysmi import debug
class AbstractBorrower(object):
genTexts = False
exts = ''
def __init__(self, reader, genTexts=False):
"""Creates an instance of *Borrower* class.
Args:
reader: a *reader* object
Keyword Args:
genText: indicates whether this borrower should be looking
for transformed MIBs that include human-oriented texts
"""
if genTexts is not None:
self.genTexts = genTexts
self._reader = reader
def __str__(self):
return '%s{%s, genTexts=%s, exts=%s}' % (self.__class__.__name__,
self._reader, self.genTexts,
self.exts)
def setOptions(self, **kwargs):
self._reader.setOptions(**kwargs)
for k in kwargs:
setattr(self, k, kwargs[k])
return self
def getData(self, mibname, **options):
if bool(options.get('genTexts')) != self.genTexts:
debug.logger & debug.flagBorrower and debug.logger(
'skipping incompatible borrower %s for file %s' % (self, mibname))
raise error.PySmiFileNotFoundError(mibname=mibname, reader=self._reader)
debug.logger & debug.flagBorrower and (
debug.logger('trying to borrow file %s from %s' % (mibname, self._reader))
)
if 'exts' not in options:
options['exts'] = self.exts
return self._reader.getData(mibname, **options)
================================================
FILE: pysmi/borrower/pyfile.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
try:
import importlib
try:
SOURCE_SUFFIXES = importlib.machinery.SOURCE_SUFFIXES
except Exception:
raise ImportError()
except ImportError:
import imp
SOURCE_SUFFIXES = [s[0] for s in imp.get_suffixes()
if s[2] == imp.PY_SOURCE]
from pysmi.borrower.base import AbstractBorrower
class PyFileBorrower(AbstractBorrower):
"""Create PySNMP MIB file borrowing object"""
exts = SOURCE_SUFFIXES
================================================
FILE: pysmi/codegen/__init__.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
from pysmi.codegen.pysnmp import PySnmpCodeGen
from pysmi.codegen.jsondoc import JsonCodeGen
from pysmi.codegen.null import NullCodeGen
================================================
FILE: pysmi/codegen/base.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
import sys
from pysmi import error
if sys.version_info[0] > 2:
# noinspection PyShadowingBuiltins
unicode = str
# noinspection PyShadowingBuiltins
long = int
def dorepr(s):
return repr(s)
else:
def dorepr(s):
return repr(s.encode('utf-8')).decode('utf-8')
def updateDict(d1, d2):
d1.update(d2)
return d1
class AbstractCodeGen(object):
# never compile these, they either:
# - define MACROs (implementation supplies them)
# - or carry conflicting OIDs (so that all IMPORT's of them will be rewritten)
# - or have manual fixes
# - or import base ASN.1 types from implementation-specific MIBs
baseMibs = ('RFC1065-SMI',
'RFC1155-SMI',
'RFC1158-MIB',
'RFC-1212',
'RFC1213-MIB',
'RFC-1215',
'SNMPv2-SMI',
'SNMPv2-TC',
'SNMPv2-TM',
'SNMPv2-CONF')
# Explicit SMIv1 -> SMIv2 mapping for standard MIBs
commonSyms = {'RFC1155-SMI/RFC1065-SMI':
{'internet': [('SNMPv2-SMI', 'internet')],
'directory': [('SNMPv2-SMI', 'directory')],
'mgmt': [('SNMPv2-SMI', 'mgmt')],
'experimental': [('SNMPv2-SMI', 'experimental')],
'private': [('SNMPv2-SMI', 'private')],
'enterprises': [('SNMPv2-SMI', 'enterprises')],
'OBJECT-TYPE': [('SNMPv2-SMI', 'OBJECT-TYPE')],
'ObjectName': [('SNMPv2-SMI', 'ObjectName')],
'ObjectSyntax': [('SNMPv2-SMI', 'ObjectSyntax')],
'SimpleSyntax': [('SNMPv2-SMI', 'SimpleSyntax')],
'ApplicationSyntax': [('SNMPv2-SMI', 'ApplicationSyntax')],
'NetworkAddress': [('SNMPv2-SMI', 'IpAddress')],
'IpAddress': [('SNMPv2-SMI', 'IpAddress')],
'Counter': [('SNMPv2-SMI', 'Counter32')],
'Gauge': [('SNMPv2-SMI', 'Gauge32')],
'TimeTicks': [('SNMPv2-SMI', 'TimeTicks')],
'Opaque': [('SNMPv2-SMI', 'Opaque')]},
'RFC1158-MIB/RFC1213-MIB':
{'mib-2': [('SNMPv2-SMI', 'mib-2')],
'DisplayString': [('SNMPv2-TC', 'DisplayString')],
'system': [('SNMPv2-MIB', 'system')],
'interfaces': [('IF-MIB', 'interfaces')],
'ip': [('IP-MIB', 'ip')],
'icmp': [('IP-MIB', 'icmp')],
'tcp': [('TCP-MIB', 'tcp')],
'udp': [('UDP-MIB', 'udp')],
'transmission': [('SNMPv2-SMI', 'transmission')],
'snmp': [('SNMPv2-MIB', 'snmp')],
'sysDescr': [('SNMPv2-MIB', 'sysDescr')],
'sysObjectID': [('SNMPv2-MIB', 'sysObjectID')],
'sysUpTime': [('SNMPv2-MIB', 'sysUpTime')],
'sysContact': [('SNMPv2-MIB', 'sysContact')],
'sysName': [('SNMPv2-MIB', 'sysName')],
'sysLocation': [('SNMPv2-MIB', 'sysLocation')],
'sysServices': [('SNMPv2-MIB', 'sysServices')],
'ifNumber': [('IF-MIB', 'ifNumber')],
'ifTable': [('IF-MIB', 'ifTable')],
'ifEntry': [('IF-MIB', 'ifEntry')],
'ifIndex': [('IF-MIB', 'ifIndex')],
'ifDescr': [('IF-MIB', 'ifDescr')],
'ifType': [('IF-MIB', 'ifType')],
'ifMtu': [('IF-MIB', 'ifMtu')],
'ifSpeed': [('IF-MIB', 'ifSpeed')],
'ifPhysAddress': [('IF-MIB', 'ifPhysAddress')],
'ifAdminStatus': [('IF-MIB', 'ifAdminStatus')],
'ifOperStatus': [('IF-MIB', 'ifOperStatus')],
'ifLastChange': [('IF-MIB', 'ifLastChange')],
'ifInOctets': [('IF-MIB', 'ifInOctets')],
'ifInUcastPkts': [('IF-MIB', 'ifInUcastPkts')],
'ifInNUcastPkts': [('IF-MIB', 'ifInNUcastPkts')],
'ifInDiscards': [('IF-MIB', 'ifInDiscards')],
'ifInErrors': [('IF-MIB', 'ifInErrors')],
'ifInUnknownProtos': [('IF-MIB', 'ifInUnknownProtos')],
'ifOutOctets': [('IF-MIB', 'ifOutOctets')],
'ifOutUcastPkts': [('IF-MIB', 'ifOutUcastPkts')],
'ifOutNUcastPkts': [('IF-MIB', 'ifOutNUcastPkts')],
'ifOutDiscards': [('IF-MIB', 'ifOutDiscards')],
'ifOutErrors': [('IF-MIB', 'ifOutErrors')],
'ifOutQLen': [('IF-MIB', 'ifOutQLen')],
'ifSpecific': [('IF-MIB', 'ifSpecific')],
'ipForwarding': [('IP-MIB', 'ipForwarding')],
'ipDefaultTTL': [('IP-MIB', 'ipDefaultTTL')],
'ipInReceives': [('IP-MIB', 'ipInReceives')],
'ipInHdrErrors': [('IP-MIB', 'ipInHdrErrors')],
'ipInAddrErrors': [('IP-MIB', 'ipInAddrErrors')],
'ipForwDatagrams': [('IP-MIB', 'ipForwDatagrams')],
'ipInUnknownProtos': [('IP-MIB', 'ipInUnknownProtos')],
'ipInDiscards': [('IP-MIB', 'ipInDiscards')],
'ipInDelivers': [('IP-MIB', 'ipInDelivers')],
'ipOutRequests': [('IP-MIB', 'ipOutRequests')],
'ipOutDiscards': [('IP-MIB', 'ipOutDiscards')],
'ipOutNoRoutes': [('IP-MIB', 'ipOutNoRoutes')],
'ipReasmTimeout': [('IP-MIB', 'ipReasmTimeout')],
'ipReasmReqds': [('IP-MIB', 'ipReasmReqds')],
'ipReasmOKs': [('IP-MIB', 'ipReasmOKs')],
'ipReasmFails': [('IP-MIB', 'ipReasmFails')],
'ipFragOKs': [('IP-MIB', 'ipFragOKs')],
'ipFragFails': [('IP-MIB', 'ipFragFails')],
'ipFragCreates': [('IP-MIB', 'ipFragCreates')],
'ipAddrTable': [('IP-MIB', 'ipAddrTable')],
'ipAddrEntry': [('IP-MIB', 'ipAddrEntry')],
'ipAdEntAddr': [('IP-MIB', 'ipAdEntAddr')],
'ipAdEntIfIndex': [('IP-MIB', 'ipAdEntIfIndex')],
'ipAdEntNetMask': [('IP-MIB', 'ipAdEntNetMask')],
'ipAdEntBcastAddr': [('IP-MIB', 'ipAdEntBcastAddr')],
'ipAdEntReasmMaxSize': [('IP-MIB', 'ipAdEntReasmMaxSize')],
'ipNetToMediaTable': [('IP-MIB', 'ipNetToMediaTable')],
'ipNetToMediaEntry': [('IP-MIB', 'ipNetToMediaEntry')],
'ipNetToMediaIfIndex': [('IP-MIB', 'ipNetToMediaIfIndex')],
'ipNetToMediaPhysAddress': [('IP-MIB', 'ipNetToMediaPhysAddress')],
'ipNetToMediaNetAddress': [('IP-MIB', 'ipNetToMediaNetAddress')],
'ipNetToMediaType': [('IP-MIB', 'ipNetToMediaType')],
'icmpInMsgs': [('IP-MIB', 'icmpInMsgs')],
'icmpInErrors': [('IP-MIB', 'icmpInErrors')],
'icmpInDestUnreachs': [('IP-MIB', 'icmpInDestUnreachs')],
'icmpInTimeExcds': [('IP-MIB', 'icmpInTimeExcds')],
'icmpInParmProbs': [('IP-MIB', 'icmpInParmProbs')],
'icmpInSrcQuenchs': [('IP-MIB', 'icmpInSrcQuenchs')],
'icmpInRedirects': [('IP-MIB', 'icmpInRedirects')],
'icmpInEchos': [('IP-MIB', 'icmpInEchos')],
'icmpInEchoReps': [('IP-MIB', 'icmpInEchoReps')],
'icmpInTimestamps': [('IP-MIB', 'icmpInTimestamps')],
'icmpInTimestampReps': [('IP-MIB', 'icmpInTimestampReps')],
'icmpInAddrMasks': [('IP-MIB', 'icmpInAddrMasks')],
'icmpInAddrMaskReps': [('IP-MIB', 'icmpInAddrMaskReps')],
'icmpOutMsgs': [('IP-MIB', 'icmpOutMsgs')],
'icmpOutErrors': [('IP-MIB', 'icmpOutErrors')],
'icmpOutDestUnreachs': [('IP-MIB', 'icmpOutDestUnreachs')],
'icmpOutTimeExcds': [('IP-MIB', 'icmpOutTimeExcds')],
'icmpOutParmProbs': [('IP-MIB', 'icmpOutParmProbs')],
'icmpOutSrcQuenchs': [('IP-MIB', 'icmpOutSrcQuenchs')],
'icmpOutRedirects': [('IP-MIB', 'icmpOutRedirects')],
'icmpOutEchos': [('IP-MIB', 'icmpOutEchos')],
'icmpOutEchoReps': [('IP-MIB', 'icmpOutEchoReps')],
'icmpOutTimestamps': [('IP-MIB', 'icmpOutTimestamps')],
'icmpOutTimestampReps': [('IP-MIB', 'icmpOutTimestampReps')],
'icmpOutAddrMasks': [('IP-MIB', 'icmpOutAddrMasks')],
'icmpOutAddrMaskReps': [('IP-MIB', 'icmpOutAddrMaskReps')],
'tcpRtoAlgorithm': [('TCP-MIB', 'tcpRtoAlgorithm')],
'tcpRtoMin': [('TCP-MIB', 'tcpRtoMin')],
'tcpRtoMax': [('TCP-MIB', 'tcpRtoMax')],
'tcpMaxConn': [('TCP-MIB', 'tcpMaxConn')],
'tcpActiveOpens': [('TCP-MIB', 'tcpActiveOpens')],
'tcpPassiveOpens': [('TCP-MIB', 'tcpPassiveOpens')],
'tcpAttemptFails': [('TCP-MIB', 'tcpAttemptFails')],
'tcpEstabResets': [('TCP-MIB', 'tcpEstabResets')],
'tcpCurrEstab': [('TCP-MIB', 'tcpCurrEstab')],
'tcpInSegs': [('TCP-MIB', 'tcpInSegs')],
'tcpOutSegs': [('TCP-MIB', 'tcpOutSegs')],
'tcpRetransSegs': [('TCP-MIB', 'tcpRetransSegs')],
'tcpConnTable': [('TCP-MIB', 'tcpConnTable')],
'tcpConnEntry': [('TCP-MIB', 'tcpConnEntry')],
'tcpConnState': [('TCP-MIB', 'tcpConnState')],
'tcpConnLocalAddress': [('TCP-MIB', 'tcpConnLocalAddress')],
'tcpConnLocalPort': [('TCP-MIB', 'tcpConnLocalPort')],
'tcpConnRemAddress': [('TCP-MIB', 'tcpConnRemAddress')],
'tcpConnRemPort': [('TCP-MIB', 'tcpConnRemPort')],
'tcpInErrs': [('TCP-MIB', 'tcpInErrs')],
'tcpOutRsts': [('TCP-MIB', 'tcpOutRsts')],
'udpInDatagrams': [('UDP-MIB', 'udpInDatagrams')],
'udpNoPorts': [('UDP-MIB', 'udpNoPorts')],
'udpInErrors': [('UDP-MIB', 'udpInErrors')],
'udpOutDatagrams': [('UDP-MIB', 'udpOutDatagrams')],
'udpTable': [('UDP-MIB', 'udpTable')],
'udpEntry': [('UDP-MIB', 'udpEntry')],
'udpLocalAddress': [('UDP-MIB', 'udpLocalAddress')],
'udpLocalPort': [('UDP-MIB', 'udpLocalPort')],
'snmpInPkts': [('SNMPv2-MIB', 'snmpInPkts')],
'snmpOutPkts': [('SNMPv2-MIB', 'snmpOutPkts')],
'snmpInBadVersions': [('SNMPv2-MIB', 'snmpInBadVersions')],
'snmpInBadCommunityNames': [('SNMPv2-MIB', 'snmpInBadCommunityNames')],
'snmpInBadCommunityUses': [('SNMPv2-MIB', 'snmpInBadCommunityUses')],
'snmpInASNParseErrs': [('SNMPv2-MIB', 'snmpInASNParseErrs')],
'snmpInTooBigs': [('SNMPv2-MIB', 'snmpInTooBigs')],
'snmpInNoSuchNames': [('SNMPv2-MIB', 'snmpInNoSuchNames')],
'snmpInBadValues': [('SNMPv2-MIB', 'snmpInBadValues')],
'snmpInReadOnlys': [('SNMPv2-MIB', 'snmpInReadOnlys')],
'snmpInGenErrs': [('SNMPv2-MIB', 'snmpInGenErrs')],
'snmpInTotalReqVars': [('SNMPv2-MIB', 'snmpInTotalReqVars')],
'snmpInTotalSetVars': [('SNMPv2-MIB', 'snmpInTotalSetVars')],
'snmpInGetRequests': [('SNMPv2-MIB', 'snmpInGetRequests')],
'snmpInGetNexts': [('SNMPv2-MIB', 'snmpInGetNexts')],
'snmpInSetRequests': [('SNMPv2-MIB', 'snmpInSetRequests')],
'snmpInGetResponses': [('SNMPv2-MIB', 'snmpInGetResponses')],
'snmpInTraps': [('SNMPv2-MIB', 'snmpInTraps')],
'snmpOutTooBigs': [('SNMPv2-MIB', 'snmpOutTooBigs')],
'snmpOutNoSuchNames': [('SNMPv2-MIB', 'snmpOutNoSuchNames')],
'snmpOutBadValues': [('SNMPv2-MIB', 'snmpOutBadValues')],
'snmpOutGenErrs': [('SNMPv2-MIB', 'snmpOutGenErrs')],
'snmpOutGetRequests': [('SNMPv2-MIB', 'snmpOutGetRequests')],
'snmpOutGetNexts': [('SNMPv2-MIB', 'snmpOutGetNexts')],
'snmpOutSetRequests': [('SNMPv2-MIB', 'snmpOutSetRequests')],
'snmpOutGetResponses': [('SNMPv2-MIB', 'snmpOutGetResponses')],
'snmpOutTraps': [('SNMPv2-MIB', 'snmpOutTraps')],
'snmpEnableAuthenTraps': [('SNMPv2-MIB', 'snmpEnableAuthenTraps')]}}
convertImportv2 = {
'RFC1065-SMI': commonSyms['RFC1155-SMI/RFC1065-SMI'],
'RFC1155-SMI': commonSyms['RFC1155-SMI/RFC1065-SMI'],
'RFC1158-MIB': updateDict(
dict(commonSyms['RFC1155-SMI/RFC1065-SMI']),
(('nullSpecific', [('SNMPv2-SMI', 'zeroDotZero')]),
('ipRoutingTable', [('RFC1213-MIB', 'ipRouteTable')]),
('ipRouteEntry', [('RFC1213-MIB', 'ipRouteEntry')]),
('ipRouteDest', [('RFC1213-MIB', 'ipRouteDest')]),
('ipRouteIfIndex', [('RFC1213-MIB', 'ipRouteIfIndex')]),
('ipRouteMetric1', [('RFC1213-MIB', 'ipRouteMetric1')]),
('ipRouteMetric2', [('RFC1213-MIB', 'ipRouteMetric2')]),
('ipRouteMetric3', [('RFC1213-MIB', 'ipRouteMetric3')]),
('ipRouteMetric4', [('RFC1213-MIB', 'ipRouteMetric4')]),
('ipRouteNextHop', [('RFC1213-MIB', 'ipRouteNextHop')]),
('ipRouteType', [('RFC1213-MIB', 'ipRouteType')]),
('ipRouteProto', [('RFC1213-MIB', 'ipRouteProto')]),
('ipRouteAge', [('RFC1213-MIB', 'ipRouteAge')]),
('ipRouteMask', [('RFC1213-MIB', 'ipRouteMask')]),
('egpInMsgs', [('RFC1213-MIB', 'egpInMsgs')]),
('egpInErrors', [('RFC1213-MIB', 'egpInErrors')]),
('egpOutMsgs', [('RFC1213-MIB', 'egpOutMsgs')]),
('egpOutErrors', [('RFC1213-MIB', 'egpOutErrors')]),
('egpNeighTable', [('RFC1213-MIB', 'egpNeighTable')]),
('egpNeighEntry', [('RFC1213-MIB', 'egpNeighEntry')]),
('egpNeighState', [('RFC1213-MIB', 'egpNeighState')]),
('egpNeighAddr', [('RFC1213-MIB', 'egpNeighAddr')]),
('egpNeighAs', [('RFC1213-MIB', 'egpNeighAs')]),
('egpNeighInMsgs', [('RFC1213-MIB', 'egpNeighInMsgs')]),
('egpNeighInErrs', [('RFC1213-MIB', 'egpNeighInErrs')]),
('egpNeighOutMsgs', [('RFC1213-MIB', 'egpNeighOutMsgs')]),
('egpNeighOutErrs', [('RFC1213-MIB', 'egpNeighOutErrs')]),
('egpNeighInErrMsgs', [('RFC1213-MIB', 'egpNeighInErrMsgs')]),
('egpNeighOutErrMsgs', [('RFC1213-MIB', 'egpNeighOutErrMsgs')]),
('egpNeighStateUps', [('RFC1213-MIB', 'egpNeighStateUps')]),
('egpNeighStateDowns', [('RFC1213-MIB', 'egpNeighStateDowns')]),
('egpNeighIntervalHello', [('RFC1213-MIB', 'egpNeighIntervalHello')]),
('egpNeighIntervalPoll', [('RFC1213-MIB', 'egpNeighIntervalPoll')]),
('egpNeighMode', [('RFC1213-MIB', 'egpNeighMode')]),
('egpNeighEventTrigger', [('RFC1213-MIB', 'egpNeighEventTrigger')]),
('egpAs', [('RFC1213-MIB', 'egpAs')]),
('snmpEnableAuthTraps', [('SNMPv2-MIB', 'snmpEnableAuthenTraps')]))
),
'RFC-1212': {'OBJECT-TYPE': [('SNMPv2-SMI', 'OBJECT-TYPE')]},
# XXX 'IndexSyntax': ???
'RFC1213-MIB': updateDict(dict(commonSyms['RFC1158-MIB/RFC1213-MIB']),
(('PhysAddress', [('SNMPv2-TC', 'PhysAddress')]),)),
'RFC-1215': {'TRAP-TYPE': [('SNMPv2-SMI', 'TRAP-TYPE')]}
}
def genCode(self, ast, symbolTable, **kwargs):
raise NotImplementedError()
def genIndex(self, mibsMap, **kwargs):
raise NotImplementedError()
@staticmethod
def isBinary(s):
return (isinstance(s, (str, unicode)) and
s[0] == '\'' and s[-2:] in ('\'b', '\'B'))
@staticmethod
def isHex(s):
return (isinstance(s, (str, unicode)) and s[0] == '\''
and s[-2:] in ('\'h', '\'H'))
def str2int(self, s):
if self.isBinary(s):
if s[1:-2]:
return int(s[1:-2], 2)
else:
raise error.PySmiSemanticError('empty binary string to int conversion')
elif self.isHex(s):
if s[1:-2]:
return int(s[1:-2], 16)
else:
raise error.PySmiSemanticError('empty hex string to int conversion')
else:
return int(s)
================================================
FILE: pysmi/codegen/intermediate.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
import sys
import re
from time import strptime, strftime
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from pysmi.mibinfo import MibInfo
from pysmi.codegen.base import AbstractCodeGen
from pysmi import error
from pysmi import debug
if sys.version_info[0] > 2:
unicode = str
long = int
class IntermediateCodeGen(AbstractCodeGen):
"""Turns MIB AST into an intermediate representation.
This intermediate representation is based on built-in Python types
and structures that could easily be used from within the template
engines.
"""
constImports = {
'SNMPv2-SMI': ('iso',
'NOTIFICATION-TYPE', # bug in some MIBs (e.g. A3COM-HUAWEI-DHCPSNOOP-MIB)
'MODULE-IDENTITY', 'OBJECT-TYPE', 'OBJECT-IDENTITY'),
'SNMPv2-TC': ('DisplayString', 'TEXTUAL-CONVENTION',), # XXX
'SNMPv2-CONF': ('MODULE-COMPLIANCE', 'NOTIFICATION-GROUP',), # XXX
}
# never compile these, they either:
# - define MACROs (implementation supplies them)
# - or carry conflicting OIDs (so that all IMPORT's of them will be rewritten)
# - or have manual fixes
# - or import base ASN.1 types from implementation-specific MIBs
fakeMibs = ('ASN1',
'ASN1-ENUMERATION',
'ASN1-REFINEMENT') + AbstractCodeGen.baseMibs
baseTypes = ['Integer', 'Integer32', 'Bits', 'ObjectIdentifier', 'OctetString']
SMI_TYPES = {
'NetworkAddress': 'IpAddress', # RFC1065-SMI, RFC1155-SMI -> SNMPv2-SMI
'nullSpecific': 'zeroDotZero', # RFC1158-MIB -> SNMPv2-SMI
'ipRoutingTable': 'ipRouteTable', # RFC1158-MIB -> RFC1213-MIB
'snmpEnableAuthTraps': 'snmpEnableAuthenTraps' # RFC1158-MIB -> SNMPv2-MIB
}
smiv1IdxTypes = ['INTEGER', 'OCTET STRING', 'IPADDRESS', 'NETWORKADDRESS']
indent = ' ' * 4
fakeidx = 1000 # starting index for fake symbols
def __init__(self):
self._rows = set()
self._cols = {} # k, v = name, datatype
self._seenSyms = set()
self._importMap = {}
self._out = {} # k, v = name, generated code
self._moduleIdentityOid = None
self._moduleRevision = None
self._enterpriseOid = None
self._oids = set()
self._complianceOids = []
self.moduleName = ['DUMMY']
self.genRules = {'text': True}
self.symbolTable = {}
@staticmethod
def transOpers(symbol):
return symbol.replace('-', '_')
def prepData(self, pdata):
data = []
for el in pdata:
if not isinstance(el, tuple):
data.append(el)
elif len(el) == 1:
data.append(el[0])
else:
data.append(
self.handlersTable[el[0]](self, self.prepData(el[1:]))
)
return data
def genImports(self, imports):
# convertion to SNMPv2
toDel = []
for module in list(imports):
if module in self.convertImportv2:
for symbol in imports[module]:
if symbol in self.convertImportv2[module]:
toDel.append((module, symbol))
for newImport in self.convertImportv2[module][symbol]:
newModule, newSymbol = newImport
if newModule in imports:
imports[newModule].append(newSymbol)
else:
imports[newModule] = [newSymbol]
# removing converted symbols
for d in toDel:
imports[d[0]].remove(d[1])
# merging mib and constant imports
for module in self.constImports:
if module in imports:
imports[module] += self.constImports[module]
else:
imports[module] = self.constImports[module]
outDict = OrderedDict()
outDict['class'] = 'imports'
for module in sorted(imports):
symbols = []
for symbol in set(imports[module]):
symbols.append(symbol)
if symbols:
self._seenSyms.update(
[self.transOpers(s) for s in symbols]
)
self._importMap.update(
[(self.transOpers(s), module) for s in symbols]
)
if module not in outDict:
outDict[module] = []
outDict[module].extend(symbols)
return OrderedDict(imports=outDict), tuple(sorted(imports))
# noinspection PyMethodMayBeStatic
def genLabel(self, symbol):
return '-' in symbol and symbol or ''
def addToExports(self, symbol, moduleIdentity=0):
self._seenSyms.add(symbol)
# noinspection PyUnusedLocal
def regSym(self, symbol, outDict, parentOid=None, moduleIdentity=False, moduleCompliance=False):
if symbol in self._seenSyms and symbol not in self._importMap:
raise error.PySmiSemanticError('Duplicate symbol found: %s' % symbol)
self.addToExports(symbol, moduleIdentity)
self._out[symbol] = outDict
if 'oid' in outDict:
self._oids.add(outDict['oid'])
if not self._enterpriseOid and outDict['oid'].startswith('1.3.6.1.4.1.'):
self._enterpriseOid = '.'.join(outDict['oid'].split('.')[:7])
if moduleIdentity:
if self._moduleIdentityOid:
raise error.PySmiSemanticError('Duplicate module identity')
self._moduleIdentityOid = outDict['oid']
if moduleCompliance:
self._complianceOids.append(outDict['oid'])
def genNumericOid(self, oid):
numericOid = ()
for part in oid:
if isinstance(part, tuple):
parent, module = part
if parent == 'iso':
numericOid += (1,)
continue
if module not in self.symbolTable:
# XXX do getname for possible future borrowed mibs
raise error.PySmiSemanticError('no module "%s" in symbolTable' % module)
if parent not in self.symbolTable[module]:
raise error.PySmiSemanticError('no symbol "%s" in module "%s"' % (parent, module))
numericOid += self.genNumericOid(self.symbolTable[module][parent]['oid'])
else:
numericOid += (part,)
return numericOid
def getBaseType(self, symName, module):
if module not in self.symbolTable:
raise error.PySmiSemanticError('no module "%s" in symbolTable' % module)
if symName not in self.symbolTable[module]:
raise error.PySmiSemanticError('no symbol "%s" in module "%s"' % (symName, module))
symType, symSubtype = self.symbolTable[module][symName].get('syntax', (('', ''), ''))
if not symType[0]:
raise error.PySmiSemanticError('unknown type for symbol "%s"' % symName)
if symType[0] in self.baseTypes:
return symType, symSubtype
else:
baseSymType, baseSymSubtype = self.getBaseType(*symType)
if isinstance(baseSymSubtype, list):
if isinstance(symSubtype, list):
symSubtype += baseSymSubtype
else:
symSubtype = baseSymSubtype
return baseSymType, symSubtype
# Clause generation functions
# noinspection PyUnusedLocal
def genAgentCapabilities(self, data):
name, productRelease, status, description, reference, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'agentcapabilities'
if productRelease:
outDict['productrelease'] = productRelease
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid)
return outDict
# noinspection PyUnusedLocal
def genModuleIdentity(self, data):
name, lastUpdated, organization, contactInfo, description, revisions, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'moduleidentity'
if revisions:
outDict['revisions'] = revisions
self._moduleRevision = revisions[0]['revision']
if self.genRules['text']:
if lastUpdated:
outDict['lastupdated'] = lastUpdated
if organization:
outDict['organization'] = organization
if contactInfo:
outDict['contactinfo'] = contactInfo
if description:
outDict['description'] = description
self.regSym(name, outDict, parentOid, moduleIdentity=True)
return outDict
# noinspection PyUnusedLocal
def genModuleCompliance(self, data):
name, status, description, reference, compliances, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'modulecompliance'
if compliances:
outDict['modulecompliance'] = compliances
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid, moduleCompliance=True)
return outDict
# noinspection PyUnusedLocal
def genNotificationGroup(self, data):
name, objects, status, description, reference, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'notificationgroup'
if objects:
outDict['objects'] = [{'module': self._importMap.get(obj, self.moduleName[0]), 'object': self.transOpers(obj)} for obj in objects]
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid)
return outDict
# noinspection PyUnusedLocal
def genNotificationType(self, data):
name, objects, status, description, reference, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'notificationtype'
if objects:
outDict['objects'] = [{'module': self._importMap.get(obj, self.moduleName[0]), 'object': self.transOpers(obj)} for obj in objects]
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid)
return outDict
# noinspection PyUnusedLocal
def genObjectGroup(self, data):
name, objects, status, description, reference, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict({'name': name,
'oid': oidStr,
'class': 'objectgroup'})
if objects:
outDict['objects'] = [{'module': self._importMap.get(obj, self.moduleName[0]), 'object': self.transOpers(obj)} for obj in objects]
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid)
return outDict
# noinspection PyUnusedLocal
def genObjectIdentity(self, data):
name, status, description, reference, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'objectidentity'
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid)
return outDict
# noinspection PyUnusedLocal
def genObjectType(self, data):
name, syntax, units, maxaccess, status, description, reference, augmention, index, defval, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
indexStr, fakeStrlist, fakeSyms = index or ('', '', [])
defval = self.genDefVal(defval, objname=name)
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
if syntax[0]:
nodetype = syntax[0] == 'Bits' and 'scalar' or syntax[0] # Bits hack
nodetype = name in self.symbolTable[self.moduleName[0]]['_symtable_cols'] and 'column' or nodetype
outDict['nodetype'] = nodetype
outDict['class'] = 'objecttype'
if syntax[1]:
outDict['syntax'] = syntax[1]
if defval:
outDict['default'] = defval
if units:
outDict['units'] = units
if maxaccess:
outDict['maxaccess'] = maxaccess
if indexStr:
outDict['indices'] = indexStr
if self.genRules['text'] and reference:
outDict['reference'] = reference
if augmention:
augmention = self.transOpers(augmention)
outDict['augmention'] = OrderedDict()
outDict['augmention']['name'] = name
outDict['augmention']['module'] = self.moduleName[0]
outDict['augmention']['object'] = augmention
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
self.regSym(name, outDict, parentOid)
# TODO
# if fakeSyms: # fake symbols for INDEX to support SMIv1
# for i in range(len(fakeSyms)):
# fakeOutStr = fakeStrlist[i] % oidStr
# self.regSym(fakeSyms[i], fakeOutStr, name)
return outDict
# noinspection PyUnusedLocal
def genTrapType(self, data):
name, enterprise, variables, description, reference, value = data
label = self.genLabel(name)
name = self.transOpers(name)
enterpriseStr, parentOid = enterprise
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = enterpriseStr + '.0.' + str(value)
outDict['class'] = 'notificationtype'
if variables:
outDict['objects'] = [{'module': self._importMap.get(obj, self.moduleName[0]), 'object': self.transOpers(obj)} for obj in variables]
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
self.regSym(name, outDict, parentOid)
return outDict
# noinspection PyUnusedLocal
def genTypeDeclaration(self, data):
name, declaration = data
outDict = OrderedDict()
outDict['name'] = name
outDict['class'] = 'type'
if declaration:
parentType, attrs = declaration
if parentType: # skipping SEQUENCE case
name = self.transOpers(name)
outDict.update(attrs)
self.regSym(name, outDict)
return outDict
# noinspection PyUnusedLocal
def genValueDeclaration(self, data):
name, oid = data
label = self.genLabel(name)
name = self.transOpers(name)
oidStr, parentOid = oid
outDict = OrderedDict()
outDict['name'] = name
outDict['oid'] = oidStr
outDict['class'] = 'objectidentity'
self.regSym(name, outDict, parentOid)
return outDict
# Subparts generation functions
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genBitNames(self, data):
names = data[0]
return names
def genBits(self, data):
bits = data[0]
outDict = OrderedDict()
outDict['type'] = 'Bits'
outDict['class'] = 'type'
outDict['bits'] = OrderedDict()
for name, bit in sorted(bits, key=lambda x: x[1]):
outDict['bits'][name] = bit
return 'scalar', outDict
# noinspection PyUnusedLocal
def genCompliances(self, data):
compliances = []
for complianceModule in data[0]:
name = complianceModule[0] or self.moduleName[0]
compliances += [{'object': self.transOpers(compl), 'module': name} for compl in complianceModule[1]]
return compliances
# noinspection PyUnusedLocal
def genConceptualTable(self, data):
row = data[0]
if row[1] and row[1][-2:] == '()':
row = row[1][:-2]
self._rows.add(row)
return 'table', ''
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genContactInfo(self, data):
text = data[0]
return self.textFilter('contact-info', text)
# noinspection PyUnusedLocal
def genDisplayHint(self, data):
return data[0]
# noinspection PyUnusedLocal
def genDefVal(self, data, objname=None):
if not data:
return {}
if not objname:
return data
defval = data[0]
defvalType = self.getBaseType(objname, self.moduleName[0])
outDict = OrderedDict(basetype=defvalType[0][0])
if isinstance(defval, (int, long)): # number
outDict.update(
value=defval,
format='decimal'
)
elif self.isHex(defval): # hex
# common bug in MIBs
if defvalType[0][0] in ('Integer32', 'Integer'):
outDict.update(
value=str(int(len(defval) > 3 and
defval[1:-2] or '0', 16)),
format='hex'
)
else:
outDict.update(
value=defval[1:-2],
format='hex'
)
elif self.isBinary(defval): # binary
binval = defval[1:-2]
# common bug in MIBs
if defvalType[0][0] in ('Integer32', 'Integer'):
outDict.update(
value=str(int(binval or '0', 2)),
format='bin'
)
else:
hexval = binval and hex(int(binval, 2))[2:] or ''
outDict.update(value=hexval, format='hex')
# quoted string
elif defval[0] == defval[-1] and defval[0] == '"':
# common bug in MIBs
if defval[1:-1] == '' and defvalType != 'OctetString':
# a warning should be here
return {} # we will set no default value
outDict.update(
value=defval[1:-1],
format='string'
)
# symbol (oid as defval) or name for enumeration member
else:
# oid
if (defvalType[0][0] == 'ObjectIdentifier' and
(defval in self.symbolTable[self.moduleName[0]] or
defval in self._importMap)):
module = self._importMap.get(defval, self.moduleName[0])
try:
val = str(self.genNumericOid(
self.symbolTable[module][defval]['oid']))
outDict.update(
value=val,
format='oid'
)
except Exception:
# or no module if it will be borrowed later
raise error.PySmiSemanticError(
'no symbol "%s" in module "%s"' % (defval, module))
# enumeration
elif (defvalType[0][0] in ('Integer32', 'Integer') and
isinstance(defvalType[1], list)):
# buggy MIB: DEFVAL { { ... } }
if isinstance(defval, list):
defval = [dv for dv in defval
if dv in dict(defvalType[1])]
if defval:
outDict.update(
value=defval[0],
format='enum'
)
# good MIB: DEFVAL { ... }
elif defval in dict(defvalType[1]):
outDict.update(
value=defval,
format='enum'
)
elif defvalType[0][0] == 'Bits':
defvalBits = []
bits = dict(defvalType[1])
for bit in defval:
bitValue = bits.get(bit, None)
if bitValue is not None:
defvalBits.append((bit, bitValue))
else:
raise error.PySmiSemanticError(
'no such bit as "%s" for symbol "%s"' % (
bit, objname))
outDict.update(
value=self.genBits([defvalBits])[1],
format='bits'
)
return outDict
else:
raise error.PySmiSemanticError(
'unknown type "%s" for defval "%s" of symbol "%s"' % (
defvalType, defval, objname))
return {'default': outDict}
# noinspection PyMethodMayBeStatic
def genDescription(self, data):
return self.textFilter('description', data[0])
# noinspection PyMethodMayBeStatic
def genReference(self, data):
return self.textFilter('reference', data[0])
# noinspection PyMethodMayBeStatic
def genStatus(self, data):
return data[0]
def genProductRelease(self, data):
return data[0]
def genEnumSpec(self, data):
items = data[0]
return {'enumeration': dict(items)}
# noinspection PyUnusedLocal
def genTableIndex(self, data):
def genFakeSyms(fakeidx, idxType):
objType = self.SMI_TYPES.get(idxType, idxType)
objType = self.transOpers(objType)
return {'module': self.moduleName[0],
object: objType}
indexes = data[0]
idxStrlist, fakeSyms, fakeStrlist = [], [], []
for idx in indexes:
isImplied = idx[0]
idxName = idx[1]
if idxName in self.smiv1IdxTypes: # SMIv1 support
idxType = idxName
fakeSymStr, idxName = genFakeSyms(self.fakeidx, idxType)
fakeStrlist.append(fakeSymStr)
fakeSyms.append(idxName)
self.fakeidx += 1
index = OrderedDict()
index['module'] = self._importMap.get(idxName, self.moduleName[0])
index['object'] = idxName
index['implied'] = isImplied
idxStrlist.append(index)
return idxStrlist, fakeStrlist, fakeSyms
def genIntegerSubType(self, data):
ranges = []
for rng in data[0]:
vmin, vmax = len(rng) == 1 and (rng[0], rng[0]) or rng
vmin, vmax = self.str2int(vmin), self.str2int(vmax)
ran = OrderedDict()
ran['min'] = vmin
ran['max'] = vmax
ranges.append(ran)
return {'range': ranges}
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genMaxAccess(self, data):
return data[0]
def genOctetStringSubType(self, data):
sizes = []
for rng in data[0]:
vmin, vmax = len(rng) == 1 and (rng[0], rng[0]) or rng
vmin, vmax = self.str2int(vmin), self.str2int(vmax)
size = OrderedDict()
size['min'] = vmin
size['max'] = vmax
sizes.append(size)
return {'size': sizes}
# noinspection PyUnusedLocal
def genOid(self, data):
out = ()
parent = ''
for el in data[0]:
if isinstance(el, (str, unicode)):
parent = self.transOpers(el)
out += ((parent, self._importMap.get(parent, self.moduleName[0])),)
elif isinstance(el, (int, long)):
out += (el,)
elif isinstance(el, tuple):
out += (el[1],) # XXX Do we need to create a new object el[0]?
else:
raise error.PySmiSemanticError('unknown datatype for OID: %s' % el)
return '.'.join([str(x) for x in self.genNumericOid(out)]), parent
# noinspection PyUnusedLocal
def genObjects(self, data):
if data[0]:
return [self.transOpers(obj) for obj in data[0]] # XXX self.transOpers or not??
return []
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genTime(self, data):
times = []
for timeStr in data:
if len(timeStr) == 11:
timeStr = '19' + timeStr
# XXX raise in strict mode
# elif lenTimeStr != 13:
# raise error.PySmiSemanticError("Invalid date %s" % t)
try:
times.append(strftime('%Y-%m-%d %H:%M', strptime(timeStr, '%Y%m%d%H%MZ')))
except ValueError:
# XXX raise in strict mode
# raise error.PySmiSemanticError("Invalid date %s: %s" % (t, sys.exc_info()[1]))
timeStr = '197001010000Z' # dummy date for dates with typos
times.append(strftime('%Y-%m-%d %H:%M', strptime(timeStr, '%Y%m%d%H%MZ')))
return times
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genLastUpdated(self, data):
return data[0]
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genOrganization(self, data):
return self.textFilter('organization', data[0])
# noinspection PyUnusedLocal
def genRevisions(self, data):
revisions = []
for x in data[0]:
revision = OrderedDict()
revision['revision'] = self.genTime([x[0]])[0]
revision['description'] = self.textFilter('description', x[1][1])
revisions.append(revision)
return revisions
def genRow(self, data):
row = data[0]
row = self.transOpers(row)
return row in self.symbolTable[self.moduleName[0]]['_symtable_rows'] and (
'row', '') or self.genSimpleSyntax(data)
# noinspection PyUnusedLocal
def genSequence(self, data):
cols = data[0]
self._cols.update(cols)
return '', ''
def genSimpleSyntax(self, data):
objType = data[0]
objType = self.SMI_TYPES.get(objType, objType)
objType = self.transOpers(objType)
subtype = len(data) == 2 and data[1] or {}
outDict = OrderedDict()
outDict['type'] = objType
outDict['class'] = 'type'
if subtype:
outDict['constraints'] = subtype
return 'scalar', outDict
# noinspection PyUnusedLocal
def genTypeDeclarationRHS(self, data):
if len(data) == 1:
parentType, attrs = data[0]
outDict = OrderedDict()
if not attrs:
return outDict
# just syntax
outDict['type'] = attrs
else:
# Textual convention
display, status, description, reference, syntax = data
parentType, attrs = syntax
outDict = OrderedDict()
outDict['type'] = attrs
outDict['class'] = 'textualconvention'
if display:
outDict['displayhint'] = display
if status:
outDict['status'] = status
if self.genRules['text'] and description:
outDict['description'] = description
if self.genRules['text'] and reference:
outDict['reference'] = reference
return parentType, outDict
# noinspection PyMethodMayBeStatic,PyUnusedLocal
def genUnits(self, data):
text = data[0]
return self.textFilter('units', text)
handlersTable = {
'agentCapabilitiesClause': genAgentCapabilities,
'moduleIdentityClause': genModuleIdentity,
'moduleComplianceClause': genModuleCompliance,
'notificationGroupClause': genNotificationGroup,
'notificationTypeClause': genNotificationType,
'objectGroupClause': genObjectGroup,
'objectIdentityClause': genObjectIdentity,
'objectTypeClause': genObjectType,
'trapTypeClause': genTrapType,
'typeDeclaration': genTypeDeclaration,
'valueDeclaration': genValueDeclaration,
'PRODUCT-RELEASE': genProductRelease,
'ApplicationSyntax': genSimpleSyntax,
'BitNames': genBitNames,
'BITS': genBits,
'ComplianceModules': genCompliances,
'conceptualTable': genConceptualTable,
'CONTACT-INFO': genContactInfo,
'DISPLAY-HINT': genDisplayHint,
'DEFVAL': genDefVal,
'DESCRIPTION': genDescription,
'REFERENCE': genReference,
'Status': genStatus,
'enumSpec': genEnumSpec,
'INDEX': genTableIndex,
'integerSubType': genIntegerSubType,
'MaxAccessPart': genMaxAccess,
'Notifications': genObjects,
'octetStringSubType': genOctetStringSubType,
'objectIdentifier': genOid,
'Objects': genObjects,
'LAST-UPDATED': genLastUpdated,
'ORGANIZATION': genOrganization,
'Revisions': genRevisions,
'row': genRow,
'SEQUENCE': genSequence,
'SimpleSyntax': genSimpleSyntax,
'typeDeclarationRHS': genTypeDeclarationRHS,
'UNITS': genUnits,
'VarTypes': genObjects,
# 'a': lambda x: genXXX(x, 'CONSTRAINT')
}
# TODO: make intermediate format less tied to JSON
# One thing is to produce OIDs in a tuple form
# The other thing is index data - may be we should
# have it prepared at the intermediate stage...?
def genCode(self, ast, symbolTable, **kwargs):
self.genRules['text'] = kwargs.get('genTexts', False)
self.textFilter = kwargs.get('textFilter') or (lambda symbol, text: re.sub(r'\s+', ' ', text))
self.symbolTable = symbolTable
self._rows.clear()
self._cols.clear()
self._seenSyms.clear()
self._importMap.clear()
self._out.clear()
self._moduleIdentityOid = None
self._enterpriseOid = None
self._oids = set()
self._complianceOids = []
self.moduleName[0], moduleOid, imports, declarations = ast
outDict, importedModules = self.genImports(imports and imports or {})
for declr in declarations or []:
if declr:
self.handlersTable[declr[0]](self, self.prepData(declr[1:]))
for sym in self.symbolTable[self.moduleName[0]]['_symtable_order']:
if sym not in self._out:
raise error.PySmiCodegenError('No generated code for symbol %s' % sym)
outDict[sym] = self._out[sym]
outDict['meta'] = OrderedDict()
outDict['meta']['module'] = self.moduleName[0]
if 'comments' in kwargs:
outDict['meta']['comments'] = kwargs['comments']
debug.logger & debug.flagCodegen and debug.logger(
'canonical MIB name %s (%s), imported MIB(s) %s' % (
self.moduleName[0], moduleOid, ','.join(importedModules) or '<none>'))
return MibInfo(oid=moduleOid,
identity=self._moduleIdentityOid,
name=self.moduleName[0],
revision=self._moduleRevision,
oids=self._oids,
enterprise=self._enterpriseOid,
compliance=self._complianceOids,
imported=tuple([x for x in importedModules if x not in self.fakeMibs])), outDict
================================================
FILE: pysmi/codegen/jfilters.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2019, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
def capfirst(text):
if not text:
return text
return text[0].upper() + text[1:]
================================================
FILE: pysmi/codegen/jsondoc.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
import sys
import os
try:
import json
except ImportError:
import simplejson as json
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from pysmi.codegen.intermediate import IntermediateCodeGen
from pysmi.codegen import jfilters
from pysmi import error
from pysmi import debug
import jinja2
if sys.version_info[0] > 2:
# noinspection PyShadowingBuiltins
unicode = str
# noinspection PyShadowingBuiltins
long = int
class JsonCodeGen(IntermediateCodeGen):
"""Turns MIB AST into JSON document.
Builds JSON document representing MIB module supplied in form of
an Abstract Syntax Tree on input.
Instance of this class is supposed to be passed to *MibCompiler*,
the rest is internal to *MibCompiler*.
"""
TEMPLATE_NAME = 'jsondoc/base.j2'
def genCode(self, ast, symbolTable, **kwargs):
mibInfo, context = IntermediateCodeGen.genCode(self, ast, symbolTable, **kwargs)
# TODO: reduce code duplication with the other codegens
searchPath = os.path.join(os.path.dirname(__file__), 'templates')
dstTemplate = kwargs.get('dstTemplate')
if dstTemplate:
searchPath.insert(0, os.path.dirname(os.path.abspath(dstTemplate)))
env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchPath),
trim_blocks=True, lstrip_blocks=True)
env.filters['capfirst'] = jfilters.capfirst
try:
tmpl = env.get_template(dstTemplate or self.TEMPLATE_NAME)
text = tmpl.render(mib=context)
except jinja2.exceptions.TemplateError:
err = sys.exc_info()[1]
raise error.PySmiCodegenError('Jinja template rendering error: %s' % err)
debug.logger & debug.flagCodegen and debug.logger(
'canonical MIB name %s (%s), imported MIB(s) %s, rendered from '
'%s, JSON document size %d bytes' % (
mibInfo.name, mibInfo.identity,
','.join(mibInfo.imported) or '<none>',
dstTemplate, len(text)))
return mibInfo, text
# TODO: move this to a template
def genIndex(self, processed, **kwargs):
outDict = {
'meta': {},
'identity': {},
'enterprise': {},
'compliance': {},
'oids': {},
}
if kwargs.get('old_index_data'):
try:
outDict.update(
json.loads(kwargs['old_index_data'])
)
except Exception:
raise error.PySmiCodegenError('Index load error: %s' % sys.exc_info()[1])
def order(top):
if isinstance(top, dict):
new_top = OrderedDict()
try:
# first try to sort keys as OIDs
for k in sorted(top, key=lambda x: [int(y) for y in x.split('.')]):
new_top[k] = order(top[k])
except ValueError:
for k in sorted(top):
new_top[k] = order(top[k])
return new_top
elif isinstance(top, list):
new_top = []
for e in sorted(set(top)):
new_top.append(order(e))
return new_top
return top
for module, status in processed.items():
modData = outDict['identity']
identity_oid = getattr(status, 'identity', None)
if identity_oid:
if identity_oid not in modData:
modData[identity_oid] = []
modData[identity_oid].append(module)
modData = outDict['enterprise']
enterprise_oid = getattr(status, 'enterprise', None)
if enterprise_oid:
if enterprise_oid not in modData:
modData[enterprise_oid] = []
modData[enterprise_oid].append(module)
modData = outDict['compliance']
compliance_oids = getattr(status, 'compliance', ())
for compliance_oid in compliance_oids:
if compliance_oid not in modData:
modData[compliance_oid] = []
modData[compliance_oid].append(module)
modData = outDict['oids']
objects_oids = getattr(status, 'oids', ())
for object_oid in objects_oids:
if object_oid not in modData:
modData[object_oid] = []
modData[object_oid].append(module)
if modData:
unique_prefixes = {}
for oid in sorted(modData, key=lambda x: x.count('.')):
for oid_prefix, modules in unique_prefixes.items():
if oid.startswith(oid_prefix) and set(modules).issuperset(modData[oid]):
break
else:
unique_prefixes[oid] = modData[oid]
outDict['oids'] = unique_prefixes
if 'comments' in kwargs:
outDict['meta']['comments'] = kwargs['comments']
debug.logger & debug.flagCodegen and debug.logger(
'OID->MIB index built, %s entries' % len(processed))
return json.dumps(order(outDict), indent=2)
================================================
FILE: pysmi/codegen/null.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
from pysmi.mibinfo import MibInfo
from pysmi.codegen.base import AbstractCodeGen
from pysmi import debug
class NullCodeGen(AbstractCodeGen):
"""Dummy code generation backend.
Could be used for disabling code generation at *MibCompiler*.
"""
def genCode(self, ast, symbolTable, **kwargs):
debug.logger & debug.flagCodegen and debug.logger('%s invoked' % self.__class__.__name__)
return MibInfo(oid=None, name='', imported=[]), ''
def genIndex(self, mibsMap, **kwargs):
return ''
================================================
FILE: pysmi/codegen/pysnmp.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
import sys
import os
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from pysmi.codegen.intermediate import IntermediateCodeGen
from pysmi.codegen import jfilters
from pysmi import error
from pysmi import debug
import jinja2
if sys.version_info[0] > 2:
# noinspection PyShadowingBuiltins
unicode = str
# noinspection PyShadowingBuiltins
long = int
class PySnmpCodeGen(IntermediateCodeGen):
"""Turns MIB AST into pysnmp Python code.
Builds Python module representing MIB module in terms of pysnmp objects
from MIB supplied in form of an Abstract Syntax Tree on input.
Instance of this class is supposed to be passed to *MibCompiler*,
the rest is internal to *MibCompiler*.
"""
defaultMibPackages = ('pysnmp.smi.mibs', 'pysnmp_mibs')
TEMPLATE_NAME = 'pysnmp/mib-definitions.j2'
SMI_OBJECTS = {
'MODULE-IDENTITY': ['ModuleIdentity'],
'OBJECT-TYPE': ['MibScalar', 'MibTable', 'MibTableRow', 'MibTableColumn'],
'NOTIFICATION-TYPE': ['NotificationType'],
'TEXTUAL-CONVENTION': ['TextualConvention'],
'MODULE-COMPLIANCE': ['ModuleCompliance'],
'OBJECT-GROUP': ['ObjectGroup'],
'NOTIFICATION-GROUP': ['NotificationGroup'],
'AGENT-CAPABILITIES': ['AgentCapabilities'],
'OBJECT-IDENTITY': ['ObjectIdentity'],
'TRAP-TYPE': ['NotificationType'],
'BITS': ['Bits']
}
SMI_TYPES = {
'COUNTER32': 'Counter32',
'COUNTER64': 'Counter64',
'GAUGE32': 'Gauge32',
'INTEGER': 'Integer32', # XXX
'INTEGER32': 'Integer32',
'IPADDRESS': 'IpAddress',
'NETWORKADDRESS': 'IpAddress',
'OBJECT IDENTIFIER': 'ObjectIdentifier',
'OCTET STRING': 'OctetString',
'OPAQUE': 'Opaque',
'TIMETICKS': 'TimeTicks',
'UNSIGNED32': 'Unsigned32',
'Counter': 'Counter32',
'Gauge': 'Gauge32',
'NetworkAddress': 'IpAddress', # RFC1065-SMI, RFC1155-SMI -> SNMPv2-SMI
'nullSpecific': 'zeroDotZero', # RFC1158-MIB -> SNMPv2-SMI
'ipRoutingTable': 'ipRouteTable', # RFC1158-MIB -> RFC1213-MIB
'snmpEnableAuthTraps': 'snmpEnableAuthenTraps' # RFC1158-MIB -> SNMPv2-MIB
}
# never compile these, they either:
# - define MACROs (implementation supplies them)
# - or carry conflicting OIDs (so that all IMPORT's of them will be rewritten)
# - or have manual fixes
# - or import base ASN.1 types from implementation-specific MIBs
fakeMibs = ('ASN1',
'ASN1-ENUMERATION',
'ASN1-REFINEMENT')
baseMibs = ('PYSNMP-USM-MIB',
'SNMP-FRAMEWORK-MIB',
'SNMP-TARGET-MIB',
'TRANSPORT-ADDRESS-MIB',
'INET-ADDRESS-MIB') + IntermediateCodeGen.baseMibs
def genCode(self, ast, symbolTable, **kwargs):
mibInfo, context = IntermediateCodeGen.genCode(self, ast, symbolTable, **kwargs)
# Adapt intermediate context to pysnmp template requirements
# Translate SMI objects names in IMPORT
imports = OrderedDict()
for module, symbols in context.get('imports', {}).items():
if not isinstance(symbols, list):
continue
imports[module] = []
for symbol in symbols:
if symbol in self.SMI_OBJECTS:
imports[module].extend(self.SMI_OBJECTS[symbol])
else:
imports[module].append(symbol)
context['imports'] = imports
# Turn string OIDs into tuples which is native to pysnmp
# TODO: we should make intermediate format producing tuples
def translateOids(dct):
for key, value in tuple(dct.items()):
if isinstance(value, dict):
translateOids(value)
elif key == 'oid':
dct[key] = tuple(int(x) for x in value.split('.'))
translateOids(context)
# Translate SMI types into pysnmp class names
# Sort Managed Objects by OID
objects = OrderedDict()
for symbol, definition in sorted(
context.items(), key=lambda x: x[1].get('oid', ())):
objects[symbol] = definition
context = objects
# Render Python code
searchPath = [os.path.join(os.path.dirname(__file__), 'templates')]
# TODO: add unit test on custom template
dstTemplate = kwargs.get('dstTemplate')
if dstTemplate:
searchPath.insert(0, os.path.dirname(os.path.abspath(dstTemplate)))
env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchPath),
trim_blocks=True, lstrip_blocks=True)
env.filters['capfirst'] = jfilters.capfirst
try:
tmpl = env.get_template(dstTemplate or self.TEMPLATE_NAME)
text = tmpl.render(mib=context)
except jinja2.exceptions.TemplateError:
err = sys.exc_info()[1]
raise error.PySmiCodegenError('Jinja template rendering error: %s' % err)
debug.logger & debug.flagCodegen and debug.logger(
'canonical MIB name %s (%s), imported MIB(s) %s, rendered from '
'%s, Python code size %d bytes' % (
mibInfo.name, mibInfo.identity,
','.join(mibInfo.imported) or '<none>',
dstTemplate, len(text)))
return mibInfo, text
# backward compatibility
baseMibs = PySnmpCodeGen.baseMibs
fakeMibs = PySnmpCodeGen.fakeMibs
================================================
FILE: pysmi/codegen/symtable.py
================================================
#
# This file is part of pysmi software.
#
# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pysmi/license.html
#
# Build an internally used symbol table for each passed MIB.
#
import sys
from keyword import iskeyword
from pysmi.mibinfo import MibInfo
from pysmi.codegen.base import AbstractCodeGen, dorepr
from pysmi import error
from pysmi import debug
if sys.version_info[0] > 2:
# noinspection PyShadowingBuiltins
unicode = str
# noinspection PyShadowingBuiltins
long = int
class SymtableCodeGen(AbstractCodeGen):
symsTable = {
'MODULE-IDENTITY': ('ModuleIdentity',),
'OBJECT-TYPE': ('MibScalar', 'MibTable', 'MibTableRow', 'MibTableColumn'),
'NOTIFICATION-TYPE': ('NotificationType',),
'TEXTUAL-CONVENTION': ('TextualConvention',),
'MODULE-COMPLIANCE': ('ModuleCompliance',),
'OBJECT-GROUP': ('ObjectGroup',),
'NOTIFICATION-GROUP': ('NotificationGroup',),
'AGENT-CAPABILITIES': ('AgentCapabilities',),
'OBJECT-IDENTITY': ('ObjectIdentity',),
'TRAP-TYPE': ('NotificationType',), # smidump always uses NotificationType
'BITS': ('Bits',),
}
constImports = {
'SNMPv2-SMI': ('iso',
'Bits', # XXX
'Integer32', # XXX
'TimeTicks', # bug in some IETF MIBs
'Counter32', # bug in some IETF MIBs (e.g. DSA-MIB)
'Counter64', # bug in some MIBs (e.g.A3COM-HUAWEI-LswINF-MIB)
'NOTIFICATION-TYPE', # bug in some MIBs (e.g. A3COM-HUAWEI-DHCPSNOOP-MIB)
'Gauge32', # bug in some IETF MIBs (e.g. DSA-MIB)
'MODULE-IDENTITY', 'OBJECT-TYPE', 'OBJECT-IDENTITY', 'Unsigned32', 'IpAddress', # XXX
'MibIdentifier'), # OBJECT IDENTIFIER
'SNMPv2-TC': ('DisplayString', 'TEXTUAL-CONVENTION',), # XXX
'SNMPv2-CONF': ('MODULE-COMPLIANCE', 'NOTIFICATION-GROUP',), # XXX
}
baseTypes = ['Integer', 'Integer32', 'Bits', 'ObjectIdentifier', 'OctetString']
typeClasses = {
'COUNTER32': 'Counter32',
'COUNTER64': 'Counter64',
'GAUGE32': 'Gauge32',
'INTEGER': 'Integer32', # XXX
'INTEGER32': 'Integer32',
'IPADDRESS': 'IpAddress',
'NETWORKADDRESS': 'IpAddress',
'OBJECT IDENTIFIER': 'ObjectIdentifier',
'OCTET STRING': 'OctetString',
'OPAQUE': 'Opaque',
'TIMETICKS': 'TimeTicks',
'UNSIGNED32': 'Unsigned32',
'Counter': 'Counter32',
'Gauge': 'Gauge32',
'NetworkAddress': 'IpAddress', # RFC1065-SMI, RFC1155-SMI -> SNMPv2-SMI
'nullSpecific': 'zeroDotZero', # RFC1158-MIB -> SNMPv2-SMI
'ipRoutingTable': 'ipRouteTable', # RFC1158-MIB -> RFC1213-MIB
'snmpEnableAuthTraps': 'snmpEnableAuthenTraps' # RFC1158-MIB -> SNMPv2-MIB
}
smiv1IdxTypes = ['INTEGER', 'OCTET STRING', 'IPADDRESS', 'NETWORKADDRESS']
ifTextStr = 'if mibBuilder.loadTexts: '
indent = ' ' * 4
fakeidx = 1000 # starting index for fake symbols
def __init__(self):
self._rows = set()
self._cols = {} # k, v = name, datatype
self._exports = set()
self._postponedSyms = {} # k, v = symbol, (parents, properties)
self._parentOids = set()
self._importMap = {} # k, v = symbol, MIB
self._symsOrder = []
self._out = {} # k, v = symbol, properties
self.moduleName = ['DUMMY']
self._moduleRevision = None
self.genRules = {'text': True}
def symTrans(self, symbol):
if symbol in self.symsTable:
return self.symsTable[symbol]
return symbol,
@staticmethod
def transOpers(symbol):
if iskeyword(symbol):
symbol = 'pysmi_' + symbol
return symbol.replace('-', '_')
def prepData(self, pdata, classmode=False):
data = []
for el in pdata:
if not isinstance(el, tuple):
data.append(el)
elif len(el) == 1:
data.append(el[0])
else:
data.append(self.handlersTable[el[0]](self, self.prepData(el[1:], classmode=classmode), classmode=classmode))
return data
def genImports(self, imports):
# convertion to SNMPv2
toDel = []
for module in list(imports):
if module in self.convertImportv2:
for symbol in imports[module]:
if symbol in self.convertImportv2[module]:
toDel.append((module, symbol))
for newImport in self.convertImportv2[module][symbol]:
newModule, newSymbol = newImport
if newModule in imports:
imports[newModule].append(newSymbol)
else:
imports[newModule] = [newSymbol]
# removing converted symbols
for d in toDel:
imports[d[0]].remove(d[1])
# merging mib and constant imports
for module in self.constImports:
if module in imports:
imports[module] += self.constImports[module]
else:
imports[module] = self.constImports[module]
for module in sorted(imports):
symbols = ()
for symbol in set(imports[module]):
symbols += self.symTrans(symbol)
if symbols:
self._importMap.update([(self.transOpers(s), module) for s in symbols])
return {}, tuple(sorted(imports))
def allParentsExists(self, parents):
parentsExists = True
for parent in parents:
if not (parent in self._out or
parent in self._importMap or
parent in self.baseTypes or
parent in ('MibTable', 'MibTableRow', 'MibTableColumn') or
parent in self._rows):
parentsExists = False
break
return parentsExists
def regSym(self, symbol, symProps, parents=()):
if symbol in self._out or symbol in self._postponedSyms: # add to strict mode - or symbol in self._importMap:
raise error.PySmiSemanticError('Duplicate symbol found: %s' % symbol)
if self.allParentsExists(parents):
self._out[symbol] = symProps
self._symsOrder.append(symbol)
self.regPostponedSyms()
else:
self._postponedSyms[symbol] = (parents, symProps)
def regPostponedSyms(self):
regedSyms = []
for sym, val in self._postponedSyms.items():
parents, symProps = val
if self.allParentsExists(parents):
self._out[sym] = symProps
self._symsOrder.append(sym)
regedSyms.append(sym)
for sym in regedSyms:
self._postponedSyms.pop(sym)
# Clause handlers
# noinspection PyUnusedLocal
def genAgentCapabilities(self, data, classmode=False):
origName, release, status, description, reference, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'AgentCapabilities',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genModuleIdentity(self, data, classmode=False):
origName, lastUpdated, organization, contactInfo, description, revisions, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'ModuleIdentity',
'oid': oid,
'origName': origName}
if revisions:
self._moduleRevision = revisions[0]
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genModuleCompliance(self, data, classmode=False):
origName, status, description, reference, compliances, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'ModuleCompliance',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genNotificationGroup(self, data, classmode=False):
origName, objects, status, description, reference, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'NotificationGroup',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genNotificationType(self, data, classmode=False):
origName, objects, status, description, reference, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'NotificationType',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genObjectGroup(self, data, classmode=False):
origName, objects, status, description, reference, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'ObjectGroup',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genObjectIdentity(self, data, classmode=False):
origName, status, description, reference, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'ObjectIdentity',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genObjectType(self, data, classmode=False):
origName, syntax, units, maxaccess, status, description, reference, augmention, index, defval, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'ObjectType',
'oid': oid,
'syntax': syntax, # (type, module), subtype
'origName': origName}
parents = [syntax[0][0]]
if augmention:
parents.append(self.transOpers(augmention))
if defval: # XXX
symProps['defval'] = defval
if index and index[1]:
namepart, fakeIndexes, fakeSymSyntax = index
for fakeIdx, fakeSyntax in zip(fakeIndexes, fakeSymSyntax):
fakeName = namepart + str(fakeIdx)
fakeSymProps = {'type': 'fakeColumn',
'oid': oid + (fakeIdx,),
'syntax': fakeSyntax,
'origName': fakeName}
self.regSym(fakeName, fakeSymProps)
self.regSym(pysmiName, symProps, parents)
# noinspection PyUnusedLocal
def genTrapType(self, data, classmode=False):
origName, enterprise, variables, description, reference, value = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'NotificationType',
'oid': enterprise + (0, value),
'origName': origName}
self.regSym(pysmiName, symProps)
# noinspection PyUnusedLocal
def genTypeDeclaration(self, data, classmode=False):
origName, declaration = data
pysmiName = self.transOpers(origName)
if declaration:
parentType, attrs = declaration
if parentType: # skipping SEQUENCE case
symProps = {'type': 'TypeDeclaration',
'syntax': declaration, # (type, module), subtype
'origName': origName}
self.regSym(pysmiName, symProps, [declaration[0][0]])
# noinspection PyUnusedLocal
def genValueDeclaration(self, data, classmode=False):
origName, oid = data
pysmiName = self.transOpers(origName)
symProps = {'type': 'MibIdentifier',
'oid': oid,
'origName': origName}
self.regSym(pysmiName, symProps)
# Subparts generation functions
# noinspection PyUnusedLocal,PyMethodMayBeStatic
def genBitNames(self, data, classmode=False):
names = data[0]
return names
# noinspection PyUnusedLocal,PyMethodMayBeStatic
def genBits(self, data, classmode=False):
bits = data[0]
return ('Bits', ''), bits
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genCompliances(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal
def genConceptualTable(self, data, classmode=False):
row = data[0]
if row[0] and row[0][0]:
self._rows.add(self.transOpers(row[0][0]))
return ('MibTable', ''), ''
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genContactInfo(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genDisplayHint(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal
def genDefVal(self, data, classmode=False): # XXX should be fixed, see pysnmp.py
defval = data[0]
if isinstance(defval, (int, long)): # number
val = str(defval)
elif self.isHex(defval): # hex
val = 'hexValue="' + defval[1:-2] + '"' # not working for Integer baseTypes
elif self.isBinary(defval): # binary
binval = defval[1:-2]
hexval = binval and hex(int(binval, 2))[2:] or ''
val = 'hexValue="' + hexval + '"'
elif isinstance(defval, list): # bits list
val = defval
elif defval[0] == defval[-1] and defval[0] == '"': # quoted strimg
val = dorepr(defval[1:-1])
else: # symbol (oid as defval) or name for enumeration member
if defval in self._out or defval in self._importMap:
val = defval + '.getName()'
else:
val = dorepr(defval)
return val
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genDescription(self, data, classmode=False):
return ''
def genReference(self, data, classmode=False):
return ''
def genStatus(self, data, classmode=False):
return ''
def genProductRelease(self, data, classmode=False):
return ''
def genEnumSpec(self, data, classmode=False):
return self.genBits(data, classmode=classmode)[1]
def genIndex(self, data, classmode=False):
indexes = data[0]
fakeIdxName = 'pysmiFakeCol'
fakeIndexes, fakeSymsSyntax = [], []
for idx in indexes:
idxName = idx[1]
if idxName in self.smiv1IdxTypes: # SMIv1 support
idxType = idxName
objType = self.typeClasses.get(idxType, idxType)
objType = self.transOpers(objType)
fakeIndexes.append(self.fakeidx)
fakeSymsSyntax.append((('MibTableColumn', ''), objType))
self.fakeidx += 1
return fakeIdxName, fakeIndexes, fakeSymsSyntax
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genIntegerSubType(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genMaxAccess(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genOctetStringSubType(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal
def genOid(self, data, classmode=False):
out = ()
for el in data[0]:
if isinstance(el, (str, unicode)):
parent = self.transOpers(el)
self._parentOids.add(parent)
out += ((parent, self._importMap.get(parent, self.moduleName[0])),)
elif isinstance(el, (int, long)):
out += (el,)
elif isinstance(el, tuple):
out += (el[1],) # XXX Do we need to create a new object el[0]?
else:
raise error.PySmiSemanticError('unknown datatype for OID: %s' % el)
return out
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genObjects(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genTime(self, data, classmode=False):
return ''
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genLastUpdated(self, data, classmode=False):
return data[0]
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genOrganization(self, data, classmode=False):
return data[0]
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genRevisions(self, data, classmode=False):
lastRevision, lastDescription = data[0][0][0], data[0][0][1][1]
return lastRevision, lastDescription
def genRow(self, data, classmode=False):
row = data[0]
row = self.transOpers(row)
return row in self._rows and (('MibTableRow', ''), '') or self.genSimpleSyntax(data, classmode=classmode)
# noinspection PyUnusedLocal
def genSequence(self, data, classmode=False):
cols = data[0]
self._cols.update(cols)
return '', ''
# noinspection PyUnusedLocal
def genSimpleSyntax(self, data, classmode=False):
objType = data[0]
module = ''
objType = self.typeClasses.get(objType, objType)
objType = self.transOpers(objType)
if objType not in self.baseTypes:
module = self._importMap.get(objType, self.moduleName[0])
subtype = len(data) == 2 and data[1] or ''
return (objType, module), subtype
# noinspection PyUnusedLocal,PyMethodMayBeStatic
def genTypeDeclarationRHS(self, data, classmode=False):
if len(data) == 1:
parentType, attrs = data[0] # just syntax
else:
# Textual convention
display, status, description, reference, syntax = data
parentType, attrs = syntax
return parentType, attrs
# noinspection PyUnusedLocal,PyUnusedLocal,PyMethodMayBeStatic
def genUnits(self, data, classmode=False):
return ''
handlersTable = {
'agentCapabilitiesClause': genAgentCapabilities,
'moduleIdentityClause': genModuleIdentity,
'moduleComplianceClause': genModuleCompliance,
'notificationGroupClause': genNotificationGroup,
'notificationTypeClause': genNotificationType,
'objectGroupClause': genObjectGroup,
'objectIdentityClause': genObjectIdentity,
'objectTypeClause': genObjectType,
'trapTypeClause': genTrapType,
'typeDeclaration': genTypeDeclaration,
'valueDeclaration': genValueDeclaration,
'ApplicationSyntax': genSimpleSyntax,
'BitNames': genBitNames,
'BITS': genBits,
'ComplianceModules': genCompliances,
'conceptualTable': genConceptualTable,
'CONTACT-INFO': genContactInfo,
'DISPLAY-HINT': genDisplayHint,
'DEFVAL': genDefVal,
'DESCRIPTION': genDescription,
'REFERENCE': genReference,
'Status': genStatus,
'PRODUCT-RELEASE': genProductRelease,
'enumSpec': genEnumSpec,
'INDEX': genIndex,
'integerSubType': genIntegerSubType,
'MaxAccessPart': genMaxAccess,
'Notifications': genObjects,
'octetStringSubType': genOctetStringSubType,
'objectIdentifier': genOid,
'Objects': genObjects,
'LAST-UPDATED': genLastUpdated,
'ORGANIZATION': genOrganization,
'Revisions': genRevisions,
'row': genRow,
'SEQUENCE': genSequence,
'SimpleSyntax': genSimpleSyntax,
'typeDeclarationRHS': genTypeDeclarationRHS,
'UNITS': genUnits,
'VarTypes': genObjects,
}
def genCode(self, ast, symbolTable, **kwargs):
self.genRules['text'] = kwargs.get('genTexts', False)
self._rows.clear()
self._cols.clear()
self._parentOids.clear()
self._symsOrder = []
self._postponedSyms.clear()
self._importMap.clear()
self._out = {} # should be new object, do not use `clear` method
self.moduleName[0], moduleOid, imports, declarations = ast
out, importedModules = self.genImports(imports or {})
for declr in declarations or []:
if declr:
clausetype = declr[0]
classmode = clausetype == 'typeDeclaration'
self.handlersTable[declr[0]](self, self.prepData(declr[1:], classmode), classmode)
if self._postponedSyms:
raise error.PySmiSemanticError('Unknown parents for symbols: %s' % ', '.join(self._postponedSyms))
for sym in self._parentOids:
if sym not in self._out and sym not in self._importMap:
raise error.PySmiSemanticError('Unknown parent symbol: %s' % sym)
self._out['_symtable_order'] = list(self._symsOrder)
self._out['_symtable_cols'] = list(self._cols)
self._out['_symtable_rows'] = list(self._rows)
debug.logger & debug.flagCodegen and debug.logger(
'canonical MIB name %s (%s), imported MIB(s) %s, Symbol table size %s symbols' % (
self.moduleName[0], moduleOid, ','.join(importedModules) or '<none>', len(self._out)))
return MibInfo(oid=None,
name=self.moduleName[0],
revision=self._moduleRevision,
imported=tuple([x for x in importedModules])), self._out
================================================
FILE: pysmi/codegen/templates/jsondoc/base.j2
================================================
{% block jsondump %}
{{ mib|tojson(indent=2) }}
{% endblock %}
================================================
FILE: pysmi/codegen/templates/pysnmp/base.j2
================================================
{% block init scoped %}
{% endblock %}
{% block docstring scoped %}
"""SNMP MIB module ({{ mib['meta']['module'] }}) expressed in pysnmp data model.
This Python module is designed to be imported and executed by the
pysnmp library.
See http://snmplabs.com/pysnmp for further information.
Notes
-----
{% for comment in mib['meta']['comments'] -%}
{{ comment }}
{% endfor -%}
"""
{% endblock %}
{% block api_version_check scoped %}
if 'mibBuilder' not in globals():
import sys
sys.stderr.write(__doc__)
sys.exit(1)
{% endblock %}
================================================
FILE: pysmi/codegen/templates/pysnmp/managed-objects-instances.j2
================================================
{#
This template renders (commented out) Managed Objects Instances
for scalar and columnar Managed Objects.
The user is expected to provide:
* values for all Managed Objects
* proper indices and values for zero or more tables rows
#}
{% include "pysnmp/base.j2" %}
{% block smi_imports scoped %}
MibScalarInstance, = mibBuilder.importSymbols(
'SNMPv2-SMI',
'MibScalarInstance'
)
# Import Managed Objects to base Managed Objects Instances on
{% for symbol, definition in mib.items()|sort
if definition['class'] == 'objecttype' and
definition['nodetype'] in ('scalar', 'column') %}
{% if loop.first and loop.last %}
({{ symbol|replace('-', '_') }},) = mibBuilder.importSymbols(
"{{ mib['meta']['module'] }}",
{% elif loop.first %}
({{ symbol|replace('-', '_') }},
{% elif loop.last %}
{{ symbol|replace('-', '_') }}) = mibBuilder.importSymbols(
"{{ mib['meta']['module'] }}",
{% else %}
{{ symbol|replace('-', '_') }},
{% endif %}
{% endfor %}
{% for symbol, definition in mib.items()|sort
if definition['class'] == 'objecttype' and
definition['nodetype'] in ('scalar', 'column') %}
{% if loop.last %}
"{{ symbol }}")
{% else %}
"{{ symbol }}",
{% endif %}
{% endfor %}
{% endblock %}
{% block managed_objects_instances scoped %}
# MIB Managed Objects in the order of their OIDs
{% for symbol, definition in mib.items() %}
{% if definition['nodetype'] == 'scalar' %}
{% block mib_scalar_object_instance_definition scoped %}
{{ symbol|replace('-', '_')|capfirst }}_ObjectInstance = MibScalarInstance
{% endblock %}
{% block mib_scalar_object_instantiation scoped %}
# TODO: uncomment Managed Object Instance instantiation optionally
# setting a default value (via `.syntax.clone()`)
# _{{ symbol|replace('-', '_') }} = {{ symbol|replace('-', '_')|capfirst }}_ObjectInstance(
# {{ symbol|replace('-', '_') }}.name,
# (0,),
# {{ symbol|replace('-', '_') }}.syntax
# )
{% endblock %}
{% elif definition['nodetype'] == 'column' %}
{% block mib_table_column_object_instance_definition scoped %}
{{ symbol|replace('-', '_')|capfirst }}_ObjectInstance = MibScalarInstance
{% endblock %}
{% block mib_column_instantiation scoped %}
# TODO: Set proper OID for Managed Object Instance (see INDEX clause in MIB)
# TODO: Initialize Managed Object Instance value (via `.syntax.clone()`)
# _{{ symbol|replace('-', '_') }} = {{ symbol|replace('-', '_')|capfirst }}_ObjectInstance(
# {{ symbol|replace('-', '_') }}.name,
# (<add columnar indices here>,),
# {{ symbol|replace('-', '_') }}.syntax
# )
{% endblock %}
{% endif %}
{% endfor %}
{% endblock %}
{% block exports scoped %}
# Export Managed Objects Instances to the MIB builder
# TODO: complete Managed Objects Instances initialization above
# and uncomment the exports below
mibBuilder.exportSymbols(
"__{{ mib['meta']['module'] }}",
{% for symbol, definition in mib.items()
if definition['class'] == 'objecttype' and
definition['nodetype'] in ('scalar', 'column') %}
{% if loop.first and loop.last %}
# **{"{{ symbol }}": _{{ symbol|replace('-', '_') }}}
{% elif loop.first %}
# **{"{{ symbol }}": _{{ symbol|replace('-', '_') }},
{% elif loop.last %}
# "{{ symbol }}": _{{ symbol|replace('-', '_') }}}
{% else %}
# "{{ symbol }}": _{{ symbol|replace('-', '_') }},
{% endif %}
{% endfor %}
)
{% endblock %}
================================================
FILE: pysmi/codegen/templates/pysnmp/mib-definitions.j2
================================================
{#
This template renders most of the MIB objects definitions but
Managed Objects Instances.
#}
{% include "pysnmp/base.j2" %}
{% block asn1_imports scoped %}
# Import base ASN.1 objects even if this MIB does not use it
(Integer,
OctetString,
ObjectIdentifier) = mibBuilder.importSymbols(
"ASN1",
"Integer",
"OctetString",
"ObjectIdentifier")
(NamedValues,) = mibBuilder.importSymbols(
"ASN1-ENUMERATION",
"NamedValues")
{% endblock -%}
{% block asn1_constraints_imports scoped %}
(ConstraintsIntersection,
SingleValueConstraint,
ValueRangeConstraint,
ValueSizeConstraint,
ConstraintsUnion) = mibBuilder.importSymbols(
"ASN1-REFINEMENT",
"ConstraintsIntersection",
"SingleValueConstraint",
"ValueRangeConstraint",
"ValueSizeConstraint",
"ConstraintsUnion")
{% endblock -%}
{% block smi_imports scoped %}
# Import SMI symbols from the MIBs this MIB depends on
{% for module, symbols in mib['imports'].items() %}
{% for symbol in symbols %}
{% if loop.first and loop.last %}
({{ symbol|replace('-', '_') }},) = mibBuilder.importSymbols(
"{{ module }}",
{% elif loop.first %}
({{ symbol|replace('-', '_') }},
{% elif loop.last %}
{{ symbol|replace('-', '_') }}) = mibBuilder.importSymbols(
"{{ module }}",
{% else %}
{{ symbol|replace('-', '_') }},
{% endif %}
{% endfor %}
{% for symbol in symbols %}
{% if loop.last %}
"{{ symbol }}")
{% else %}
"{{ symbol }}",
{% endif %}
{% endfor %}
{% endfor %}
{% endblock -%}
{% block module_identity scoped %}
# MODULE-IDENTITY
{% for symbol, definition in mib.items() if definition['class'] == 'moduleidentity' %}
{{ symbol }} = ModuleIdentity(
{{ definition['oid'] }}
)
{% if 'revisions' in definition %}
{{ symbol }}.setRevisions(
{% for revision in definition.get('revisions', ()) %}
{% if loop.first and loop.last %}
("{{ revision['revision'] }}",)
{% elif loop.first %}
("{{ revision['revision'] }}",
{% elif loop.last %}
"{{ revision['revision'] }}")
{% else %}
"{{ revision['revision'] }}",
{% endif %}
{% endfor %}
)
{% endif %}
{% if 'lastupdated' in definition %}
{{ symbol }}.setLastUpdated("{{ definition['lastupdated'] }}")
{% endif %}
{% if 'organization' in definition %}
if mibBuilder.loadTexts:
{{ symbol }}.setOrganization("""\
{{ definition['organization']|wordwrap }}
""")
{% endif %}
{% if 'contactinfo' in definition %}
{{ symbol }}.setContactInfo("""\
{{ definition['contactinfo']|wordwrap }}
""")
{% endif %}
{% if 'description' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setDescription("""\
{{ definition['description']|wordwrap }}
""")
{% endif %}
{% endfor %}
{% endblock -%}
{% macro constraints(type, spec) %}
subtypeSpec = {{ type }}.subtypeSpec
{% if 'enumeration' in spec %}
subtypeSpec += ConstraintsUnion(
SingleValueConstraint(
{% for iden in spec['enumeration'].values()|sort %}
{% if loop.first and loop.last %}
{{ iden }}
{% elif loop.first %}
*({{ iden }},
{% elif loop.last %}
{{ iden }})
{% else %}
{{ iden }},
{% endif %}
{% endfor %}
)
)
namedValues = NamedValues(
{% for name, iden in spec['enumeration'].items()|sort %}
{% if loop.first and loop.last %}
("{{ name}}", {{ iden }})
{% elif loop.first %}
*(("{{ name}}", {{ iden }}),
{% elif loop.last %}
("{{ name}}", {{ iden }}))
{% else %}
("{{ name}}", {{ iden }}),
{% endif %}
{% endfor %}
)
{% elif 'range' in spec %}
subtypeSpec += ConstraintsUnion(
{% for range in spec['range'] %}
ValueRangeConstraint({{ range['min'] }}, {{ range['max'] }}),
{% endfor %}
)
{% elif 'size' in spec %}
subtypeSpec += ConstraintsUnion(
{% for range in spec['size'] %}
ValueSizeConstraint({{ range['min'] }}, {{ range['max'] }}),
{% endfor %}
)
{% endif %}
{% endmacro -%}
{% macro default(definition) %}
{% if definition['default']['default']['format'] == 'decimal' %}
defaultValue = {{ definition['default']['default']['value'] }}
{% elif definition['default']['default']['format'] == 'hex' %}
{# TODO: pyasn1 Integer does not have defaultHexValue #}
{% if definition['default']['default']['basetype'] in ('Integer', 'Integer32') %}
defaultHexValue = {{ definition['default']['default']['value'] }}
{% else %}
defaultHexValue = "{{ definition['default']['default']['value'] }}"
{% endif %}
{# TODO: pyasn1 Integer does not have defaultBinValue #}
{% elif definition['default']['default']['format'] == 'bin' %}
{% if definition['default']['default']['basetype'] in ('Integer', 'Integer32') %}
defaultBinValue = {{ definition['default']['default']['value'] }}
{% else %}
defaultBinValue = "{{ definition['default']['default']['value'] }}"
{% endif %}
{% elif definition['default']['default']['format'] == 'string' %}
{# TODO: pyasn1 does not like defaulted strings #}
defaultValue = OctetString("{{ definition['default']['default']['value'] }}")
{% elif definition['default']['default']['format'] == 'oid' %}
{# TODO: this OID might be in a string form #}
defaultValue = "{{ definition['default']['default']['value'] }}"
{% elif definition['default']['default']['format'] == 'enum'
and 'constraints' in definition['syntax'] %}
{# TODO: pyasn1 does not like default enum #}
defaultValue = {{ definition['syntax']['constraints']['enumeration'][definition['default']['default']['value']] }}
{% elif definition['default']['default']['format'] == 'bits' %}
{# TODO: pyasn1 does not like default named bits #}
defaultValue = {{ definition['syntax']['constraints']['enumeration'][definition['default']['default']['value']] }}
{% endif %}
{% endmacro -%}
{% block types_definitions scoped %}
# Types definitions
{% for symbol, definition in mib.items() if definition['class'] == 'type' %}
class {{ symbol }}({{ definition['type']['type'] }}):
"""Custom type {{ symbol }} based on {{ definition['type']['type'] }}"""
{% if 'default' in definition %}
{{ default(definition) }}
{% endif %}
{% if 'constraints' in definition['type'] %}
{{ constraints(definition['type']['type'], definition['type']['constraints']) }}
{% endif %}
{% endfor %}
{% endblock -%}
{% block textual_conventions scoped %}
# TEXTUAL-CONVENTIONS
{% for symbol, definition in mib.items() if definition['class'] == 'textualconvention' %}
class {{ symbol }}(TextualConvention, {{ definition['type']['type'] }}):
status = "{{ definition.get('status', 'current') }}"
{% if 'displayhint' in definition %}
displayHint = "{{ definition['displayhint'] }}"
{% endif %}
{% if 'constraints' in definition['type'] %}
{{ constraints(definition['type']['type'], definition['type']['constraints']) }}
{% endif %}
{% if 'description' in definition %}
if mibBuilder.loadTexts:
description = """\
{{ definition['description']|wordwrap }}
"""
{% endif %}
{% endfor %}
{% endblock -%}
{% block managed_objects scoped %}
# MIB Managed Objects in the order of their OIDs
{% for symbol, definition in mib.items()
if definition['class'] in ('objecttype', 'objectidentity') %}
{% if 'syntax' in definition %}
{% block mib_object_syntax_definition scoped %}
{% if 'default' in definition or 'constraints' in definition['syntax'] or 'bits' in definition['syntax'] %}
class _{{ symbol|replace('-', '_')|capfirst }}_Type({{ definition['syntax']['type'] }}):
"""Custom type {{ symbol }} based on {{ definition['syntax']['type'] }}"""
{% if 'default' in definition %}
{{ default(definition) }}
{% endif %}
{% if 'constraints' in definition['syntax'] %}
{{ constraints(definition['syntax']['type'], definition['syntax']['constraints']) }}
{% endif %}
{% if 'bits' in definition['syntax'] %}
namedValues = NamedValues(
{% for name, iden in definition['syntax']['bits'].items()|sort %}
{% if loop.first and loop.last %}
("{{ name}}", {{ iden }})
{% elif loop.first %}
*(("{{ name}}", {{ iden }}),
{% elif loop.last %}
("{{ name}}", {{ iden }}))
{% else %}
("{{ name}}", {{ iden }}),
{% endif %}
{% endfor %}
)
{% endif %}
{% if 'constraints' in definition['syntax'] or 'bits' in definition['syntax'] %}
_{{ symbol|replace('-', '_')|capfirst }}_Type.__name__ = "{{ definition['syntax']['type'] }}"
{% endif %}
{% else %}
_{{ symbol|replace('-', '_')|capfirst }}_Type = {{ definition['syntax']['type'] }}
{% endif %}
{% endblock %}
{% endif %}
{% if definition['class'] == 'objectidentity' %}
{% block mib_scalar_object_identity_definition scoped %}
_{{ symbol|replace('-', '_')|capfirst }}_ObjectIdentity = ObjectIdentity
{% endblock %}
{% block mib_object_identity_instantiation scoped %}
{{ symbol|replace('-', '_') }} = _{{ symbol|replace('-', '_')|capfirst }}_ObjectIdentity(
{{ definition['oid'] }}
)
{% endblock %}
{% elif definition['nodetype'] == 'scalar' %}
{% block mib_scalar_object_definition scoped %}
_{{ symbol|replace('-', '_')|capfirst }}_Object = MibScalar
{% endblock %}
{% block mib_scalar_object_instantiation scoped %}
{{ symbol|replace('-', '_') }} = _{{ symbol|replace('-', '_')|capfirst }}_Object(
{{ definition['oid'] }},
_{{ symbol|replace('-', '_')|capfirst }}_Type()
)
{% endblock %}
{{ symbol|replace('-', '_') }}.setMaxAccess("{{ definition['maxaccess'] }}")
{% elif definition['nodetype'] == 'table' %}
{% block mib_table_object_definition scoped %}
_{{ symbol|replace('-', '_')|capfirst }}_Object = MibTable
{% endblock %}
{% block mib_table_object_instantiation scoped %}
{{ symbol|replace('-', '_') }} = _{{ symbol|replace('-', '_')|capfirst }}_Object(
{{ definition['oid'] }}
)
{% endblock %}
{% elif definition['nodetype'] == 'row' %}
{% block mib_table_row_object_definition scoped %}
_{{ symbol|replace('-', '_')|capfirst }}_Object = MibTableRow
{% endblock %}
{% block mib_table_row_object_instantiation scoped %}
{{ symbol|replace('-', '_') }} = _{{ symbol|replace('-', '_')|capfirst }}_Object(
{{ definition['oid'] }}
)
{% endblock %}
{% if 'indices' in definition %}
{{ symbol|replace('-', '_') }}.setIndexNames(
{% for index in definition['indices'] %}
({{ index['implied'] }}, "{{ index['module'] }}", "{{ index['object'] }}"),
{% endfor %}
)
{% endif %}
{% if 'augmention' in definition %}
{{ definition['augmention']['object'] }}.registerAugmentions(
("{{ mib['meta']['module'] }}",
"{{ symbol|replace('-', '_') }}")
)
{{ symbol|replace('-', '_') }}.setIndexNames(*{{ definition['augmention']['object'] }}.getIndexNames())
{% endif %}
{% elif definition['nodetype'] == 'column' %}
{% block mib_table_column_object_definition scoped %}
_{{ symbol|replace('-', '_')|capfirst }}_Object = MibTableColumn
{% endblock %}
{% block mib_table_column_object_instantiation scoped %}
{{ symbol|replace('-', '_') }} = _{{ symbol|replace('-', '_')|capfirst }}_Object(
{{ definition['oid'] }},
_{{ symbol|replace('-', '_')|capfirst }}_Type()
)
{% endblock %}
{{ symbol|replace('-', '_') }}.setMaxAccess("{{ definition['maxaccess'] }}")
{% endif %}
{% if 'status' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setStatus("{{ definition['status'] }}")
{% endif %}
{% if 'units' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setUnits("{{ definition['units'] }}")
{% endif %}
{% if 'reference' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setReference("""\
{{ definition['reference']|wordwrap }}
""")
{% endif %}
{% if 'description' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setDescription("""\
{{ definition['description']|wordwrap }}
""")
{% endif %}
{% endfor %}
{% endblock -%}
{% block managed_objects_groups scoped %}
# Managed Objects groups
{% for symbol, definition in mib.items()
if definition['class'] == 'objectgroup' %}
{{ symbol|replace('-', '_') }} = ObjectGroup(
{{ definition['oid'] }}
)
{% if 'objects' in definition %}
{{ symbol|replace('-', '_') }}.setObjects(
{% for obj in definition['objects'] %}
{% if loop.first and loop.last %}
("{{ obj['module'] }}", "{{ obj['object'] }}")
{% elif loop.first %}
*(("{{ obj['module'] }}", "{{ obj['object'] }}"),
{% elif loop.last %}
("{{ obj['module'] }}", "{{ obj['object'] }}"))
{% else %}
("{{ obj['module'] }}", "{{ obj['object'] }}"),
{% endif %}
{% endfor %}
)
{% endif %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setStatus("{{ definition['status'] }}")
{% if 'description' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setDescription("""\
{{ definition['description']|wordwrap }}
""")
{% endif %}
{% endfor %}
{% endblock -%}
{% block notification_objects scoped %}
# Notification objects
{% for symbol, definition in mib.items()
if definition['class'] == 'notificationtype' %}
{{ symbol|replace('-', '_') }} = NotificationType(
{{ definition['oid'] }}
)
{% if 'objects' in definition %}
{{ symbol|replace('-', '_') }}.setObjects(
{% for obj in definition['objects'] %}
{% if loop.first and loop.last %}
("{{ obj['module'] }}", "{{ obj['object'] }}")
{% elif loop.first %}
*(("{{ obj['module'] }}", "{{ obj['object'] }}"),
{% elif loop.last %}
("{{ obj['module'] }}", "{{ obj['object'] }}"))
{% else %}
("{{ obj['module'] }}", "{{ obj['object'] }}"),
{% endif %}
{% endfor %}
)
{% endif %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setStatus(
"{{ definition['status'] }}"
)
{% if 'description' in definition %}
if mibBuilder.loadTexts:
{{ symbol|replace('-', '_') }}.setDescription("""\
{{ definition['description']|wordwrap }}
""")
{% endif %}
{% endfor %}
{% endblock -%}
{% block notification_groups scoped %}
# Notifications groups
{% for symbol, definition in mib.items()
if definition['class'] == 'notificationgroup' %}
{{ symbol|replace('-', '_') }} = NotificationGroup(
{{ definition['oid'] }}
)
{% if 'objects' in definition %}
{{ symbol|replace('-', '_') }}.setObjects(
{% for obj in definition['objects']
gitextract_1dgs2gwy/ ├── .bandit.yml ├── .flake8.ini ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── CHANGES.rst ├── LICENSE.rst ├── MANIFEST.in ├── README.md ├── THANKS.txt ├── TODO.txt ├── devel-requirements.txt ├── docs/ │ ├── Makefile │ ├── README.txt │ └── source/ │ ├── .static/ │ │ └── css/ │ │ └── rtdimproved.css │ ├── changelog.rst │ ├── conf.py │ ├── contents.rst │ ├── documentation.rst │ ├── download.rst │ ├── examples/ │ │ ├── always-borrow-precompiled-pysnmp-files.rst │ │ ├── borrow-precompiled-pysnmp-files-on-failure.rst │ │ ├── compile-smistar-mibs-into-pysnmp-files-if-needed.rst │ │ ├── compile-smiv2-mibs-from-text-into-pysnmp-code.rst │ │ ├── download-and-compile-smistar-mibs-into-json.rst │ │ └── download-and-compile-smistar-mibs-into-pysnmp-files.rst │ ├── library-reference.rst │ ├── license.rst │ ├── mibcopy.rst │ ├── mibdump.rst │ └── pysmi/ │ ├── borrower/ │ │ ├── anyfile/ │ │ │ └── anyfileborrower.rst │ │ └── pyfile/ │ │ └── pyfileborrower.rst │ ├── codegen/ │ │ ├── jsondoc/ │ │ │ └── jsoncodegen.rst │ │ ├── null/ │ │ │ └── nullcodegen.rst │ │ └── pysnmp/ │ │ └── pysnmpcodegen.rst │ ├── compiler/ │ │ ├── mibcompiler.rst │ │ └── mibstatus.rst │ ├── parser/ │ │ └── smi/ │ │ ├── dialect.rst │ │ └── parserfactory.rst │ ├── reader/ │ │ ├── callback/ │ │ │ └── callbackreader.rst │ │ ├── ftpclient/ │ │ │ └── ftpreader.rst │ │ ├── httpclient/ │ │ │ └── httpreader.rst │ │ ├── localfile/ │ │ │ └── filereader.rst │ │ └── zipreader/ │ │ └── zipreader.rst │ ├── searcher/ │ │ ├── pyfile/ │ │ │ └── pyfilesearcher.rst │ │ ├── pypackage/ │ │ │ └── pypackagesearcher.rst │ │ └── stub/ │ │ └── stubsearcher.rst │ └── writer/ │ ├── callback/ │ │ └── callbackwriter.rst │ ├── localfile/ │ │ └── filewriter.rst │ └── pyfile/ │ └── pyfilewriter.rst ├── examples/ │ ├── always-borrow-precompiled-pysnmp-files.py │ ├── borrow-precompiled-pysnmp-files-on-failure.py │ ├── compile-smistar-mibs-into-pysnmp-files-if-needed.py │ ├── compile-smiv2-mibs-from-text-into-pysnmp-code.py │ ├── download-and-compile-smistar-mibs-into-json.py │ └── download-and-compile-smistar-mibs-into-pysnmp-files.py ├── pysmi/ │ ├── __init__.py │ ├── borrower/ │ │ ├── __init__.py │ │ ├── anyfile.py │ │ ├── base.py │ │ └── pyfile.py │ ├── codegen/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── intermediate.py │ │ ├── jfilters.py │ │ ├── jsondoc.py │ │ ├── null.py │ │ ├── pysnmp.py │ │ ├── symtable.py │ │ └── templates/ │ │ ├── jsondoc/ │ │ │ └── base.j2 │ │ └── pysnmp/ │ │ ├── base.j2 │ │ ├── managed-objects-instances.j2 │ │ ├── mib-definitions.j2 │ │ └── mib-instrumentation/ │ │ ├── managed-objects-instances.j2 │ │ └── managed-objects.j2 │ ├── compat.py │ ├── compiler.py │ ├── debug.py │ ├── error.py │ ├── lexer/ │ │ ├── __init__.py │ │ ├── base.py │ │ └── smi.py │ ├── mibinfo.py │ ├── parser/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── dialect.py │ │ ├── null.py │ │ ├── smi.py │ │ ├── smiv1.py │ │ ├── smiv1compat.py │ │ └── smiv2.py │ ├── reader/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── callback.py │ │ ├── ftpclient.py │ │ ├── httpclient.py │ │ ├── localfile.py │ │ ├── url.py │ │ └── zipreader.py │ ├── searcher/ │ │ ├── __init__.py │ │ ├── anyfile.py │ │ ├── base.py │ │ ├── pyfile.py │ │ ├── pypackage.py │ │ └── stub.py │ └── writer/ │ ├── __init__.py │ ├── base.py │ ├── callback.py │ ├── localfile.py │ └── pyfile.py ├── requirements.txt ├── scripts/ │ ├── mibcopy.py │ └── mibdump.py ├── setup.cfg ├── setup.py ├── test-requirements.txt ├── tests/ │ ├── __init__.py │ ├── __main__.py │ ├── test_agentcapabilities_smiv2_pysnmp.py │ ├── test_imports_smiv2_pysnmp.py │ ├── test_modulecompliance_smiv2_pysnmp.py │ ├── test_moduleidentity_smiv2_pysnmp.py │ ├── test_notificationgroup_smiv2_pysnmp.py │ ├── test_notificationtype_smiv2_pysnmp.py │ ├── test_objectgroup_smiv2_pysnmp.py │ ├── test_objectidentity_smiv2_pysnmp.py │ ├── test_objecttype_smiv2_pysnmp.py │ ├── test_smiv1_smiv2_pysnmp.py │ ├── test_traptype_smiv2_pysnmp.py │ ├── test_typedeclaration_smiv1_pysnmp.py │ ├── test_typedeclaration_smiv2_pysnmp.py │ ├── test_valuedeclaration_smiv2_pysnmp.py │ └── test_zipreader.py └── tox.ini
SYMBOL INDEX (601 symbols across 54 files)
FILE: examples/download-and-compile-smistar-mibs-into-json.py
function printOut (line 28) | def printOut(mibName, jsonDoc, cbCtx):
FILE: pysmi/borrower/anyfile.py
class AnyFileBorrower (line 10) | class AnyFileBorrower(AbstractBorrower):
FILE: pysmi/borrower/base.py
class AbstractBorrower (line 11) | class AbstractBorrower(object):
method __init__ (line 15) | def __init__(self, reader, genTexts=False):
method __str__ (line 30) | def __str__(self):
method setOptions (line 35) | def setOptions(self, **kwargs):
method getData (line 43) | def getData(self, mibname, **options):
FILE: pysmi/borrower/pyfile.py
class PyFileBorrower (line 25) | class PyFileBorrower(AbstractBorrower):
FILE: pysmi/codegen/base.py
function dorepr (line 17) | def dorepr(s):
function dorepr (line 20) | def dorepr(s):
function updateDict (line 23) | def updateDict(d1, d2):
class AbstractCodeGen (line 28) | class AbstractCodeGen(object):
method genCode (line 274) | def genCode(self, ast, symbolTable, **kwargs):
method genIndex (line 277) | def genIndex(self, mibsMap, **kwargs):
method isBinary (line 281) | def isBinary(s):
method isHex (line 286) | def isHex(s):
method str2int (line 290) | def str2int(self, s):
FILE: pysmi/codegen/intermediate.py
class IntermediateCodeGen (line 24) | class IntermediateCodeGen(AbstractCodeGen):
method __init__ (line 62) | def __init__(self):
method transOpers (line 78) | def transOpers(symbol):
method prepData (line 81) | def prepData(self, pdata):
method genImports (line 94) | def genImports(self, imports):
method genLabel (line 147) | def genLabel(self, symbol):
method addToExports (line 150) | def addToExports(self, symbol, moduleIdentity=0):
method regSym (line 154) | def regSym(self, symbol, outDict, parentOid=None, moduleIdentity=False...
method genNumericOid (line 175) | def genNumericOid(self, oid):
method getBaseType (line 198) | def getBaseType(self, symName, module):
method genAgentCapabilities (line 225) | def genAgentCapabilities(self, data):
method genModuleIdentity (line 255) | def genModuleIdentity(self, data):
method genModuleCompliance (line 288) | def genModuleCompliance(self, data):
method genNotificationGroup (line 318) | def genNotificationGroup(self, data):
method genNotificationType (line 347) | def genNotificationType(self, data):
method genObjectGroup (line 376) | def genObjectGroup(self, data):
method genObjectIdentity (line 404) | def genObjectIdentity(self, data):
method genObjectType (line 431) | def genObjectType(self, data):
method genTrapType (line 487) | def genTrapType(self, data):
method genTypeDeclaration (line 514) | def genTypeDeclaration(self, data):
method genValueDeclaration (line 531) | def genValueDeclaration(self, data):
method genBitNames (line 550) | def genBitNames(self, data):
method genBits (line 554) | def genBits(self, data):
method genCompliances (line 568) | def genCompliances(self, data):
method genConceptualTable (line 578) | def genConceptualTable(self, data):
method genContactInfo (line 588) | def genContactInfo(self, data):
method genDisplayHint (line 593) | def genDisplayHint(self, data):
method genDefVal (line 597) | def genDefVal(self, data, objname=None):
method genDescription (line 730) | def genDescription(self, data):
method genReference (line 734) | def genReference(self, data):
method genStatus (line 738) | def genStatus(self, data):
method genProductRelease (line 741) | def genProductRelease(self, data):
method genEnumSpec (line 744) | def genEnumSpec(self, data):
method genTableIndex (line 749) | def genTableIndex(self, data):
method genIntegerSubType (line 778) | def genIntegerSubType(self, data):
method genMaxAccess (line 791) | def genMaxAccess(self, data):
method genOctetStringSubType (line 794) | def genOctetStringSubType(self, data):
method genOid (line 808) | def genOid(self, data):
method genObjects (line 828) | def genObjects(self, data):
method genTime (line 834) | def genTime(self, data):
method genLastUpdated (line 856) | def genLastUpdated(self, data):
method genOrganization (line 860) | def genOrganization(self, data):
method genRevisions (line 864) | def genRevisions(self, data):
method genRow (line 873) | def genRow(self, data):
method genSequence (line 881) | def genSequence(self, data):
method genSimpleSyntax (line 886) | def genSimpleSyntax(self, data):
method genTypeDeclarationRHS (line 903) | def genTypeDeclarationRHS(self, data):
method genUnits (line 933) | def genUnits(self, data):
method genCode (line 986) | def genCode(self, ast, symbolTable, **kwargs):
FILE: pysmi/codegen/jfilters.py
function capfirst (line 9) | def capfirst(text):
FILE: pysmi/codegen/jsondoc.py
class JsonCodeGen (line 32) | class JsonCodeGen(IntermediateCodeGen):
method genCode (line 43) | def genCode(self, ast, symbolTable, **kwargs):
method genIndex (line 77) | def genIndex(self, processed, **kwargs):
FILE: pysmi/codegen/null.py
class NullCodeGen (line 12) | class NullCodeGen(AbstractCodeGen):
method genCode (line 18) | def genCode(self, ast, symbolTable, **kwargs):
method genIndex (line 22) | def genIndex(self, mibsMap, **kwargs):
FILE: pysmi/codegen/pysnmp.py
class PySnmpCodeGen (line 28) | class PySnmpCodeGen(IntermediateCodeGen):
method genCode (line 91) | def genCode(self, ast, symbolTable, **kwargs):
FILE: pysmi/codegen/symtable.py
class SymtableCodeGen (line 23) | class SymtableCodeGen(AbstractCodeGen):
method __init__ (line 81) | def __init__(self):
method symTrans (line 94) | def symTrans(self, symbol):
method transOpers (line 101) | def transOpers(symbol):
method prepData (line 107) | def prepData(self, pdata, classmode=False):
method genImports (line 121) | def genImports(self, imports):
method allParentsExists (line 162) | def allParentsExists(self, parents):
method regSym (line 175) | def regSym(self, symbol, symProps, parents=()):
method regPostponedSyms (line 187) | def regPostponedSyms(self):
method genAgentCapabilities (line 203) | def genAgentCapabilities(self, data, classmode=False):
method genModuleIdentity (line 215) | def genModuleIdentity(self, data, classmode=False):
method genModuleCompliance (line 230) | def genModuleCompliance(self, data, classmode=False):
method genNotificationGroup (line 242) | def genNotificationGroup(self, data, classmode=False):
method genNotificationType (line 254) | def genNotificationType(self, data, classmode=False):
method genObjectGroup (line 266) | def genObjectGroup(self, data, classmode=False):
method genObjectIdentity (line 278) | def genObjectIdentity(self, data, classmode=False):
method genObjectType (line 290) | def genObjectType(self, data, classmode=False):
method genTrapType (line 323) | def genTrapType(self, data, classmode=False):
method genTypeDeclaration (line 335) | def genTypeDeclaration(self, data, classmode=False):
method genValueDeclaration (line 350) | def genValueDeclaration(self, data, classmode=False):
method genBitNames (line 363) | def genBitNames(self, data, classmode=False):
method genBits (line 368) | def genBits(self, data, classmode=False):
method genCompliances (line 373) | def genCompliances(self, data, classmode=False):
method genConceptualTable (line 377) | def genConceptualTable(self, data, classmode=False):
method genContactInfo (line 384) | def genContactInfo(self, data, classmode=False):
method genDisplayHint (line 388) | def genDisplayHint(self, data, classmode=False):
method genDefVal (line 392) | def genDefVal(self, data, classmode=False): # XXX should be fixed, se...
method genDescription (line 421) | def genDescription(self, data, classmode=False):
method genReference (line 424) | def genReference(self, data, classmode=False):
method genStatus (line 427) | def genStatus(self, data, classmode=False):
method genProductRelease (line 430) | def genProductRelease(self, data, classmode=False):
method genEnumSpec (line 433) | def genEnumSpec(self, data, classmode=False):
method genIndex (line 436) | def genIndex(self, data, classmode=False):
method genIntegerSubType (line 457) | def genIntegerSubType(self, data, classmode=False):
method genMaxAccess (line 461) | def genMaxAccess(self, data, classmode=False):
method genOctetStringSubType (line 465) | def genOctetStringSubType(self, data, classmode=False):
method genOid (line 469) | def genOid(self, data, classmode=False):
method genObjects (line 489) | def genObjects(self, data, classmode=False):
method genTime (line 493) | def genTime(self, data, classmode=False):
method genLastUpdated (line 497) | def genLastUpdated(self, data, classmode=False):
method genOrganization (line 501) | def genOrganization(self, data, classmode=False):
method genRevisions (line 505) | def genRevisions(self, data, classmode=False):
method genRow (line 509) | def genRow(self, data, classmode=False):
method genSequence (line 515) | def genSequence(self, data, classmode=False):
method genSimpleSyntax (line 521) | def genSimpleSyntax(self, data, classmode=False):
method genTypeDeclarationRHS (line 537) | def genTypeDeclarationRHS(self, data, classmode=False):
method genUnits (line 549) | def genUnits(self, data, classmode=False):
method genCode (line 596) | def genCode(self, ast, symbolTable, **kwargs):
FILE: pysmi/compat.py
function encode (line 10) | def encode(s):
function decode (line 16) | def decode(s):
function encode (line 21) | def encode(s):
function decode (line 27) | def decode(s):
FILE: pysmi/compiler.py
class MibStatus (line 24) | class MibStatus(str):
method setOptions (line 40) | def setOptions(self, **kwargs):
class MibCompiler (line 55) | class MibCompiler(object):
method __init__ (line 78) | def __init__(self, parser, codegen, writer):
method addSources (line 94) | def addSources(self, *sources):
method addSearchers (line 115) | def addSearchers(self, *searchers):
method addBorrowers (line 136) | def addBorrowers(self, *borrowers):
method _get_system_info (line 159) | def _get_system_info(self):
method compile (line 175) | def compile(self, *mibnames, **options):
method buildIndex (line 532) | def buildIndex(self, processedMibs, **options):
FILE: pysmi/debug.py
class Printer (line 37) | class Printer(object):
method __init__ (line 38) | def __init__(self, logger=None, handler=None, formatter=None):
method __call__ (line 57) | def __call__(self, msg):
method __str__ (line 60) | def __str__(self):
method getCurrentLogger (line 63) | def getCurrentLogger(self):
class NullHandler (line 71) | class NullHandler(logging.Handler):
method emit (line 72) | def emit(self, record):
class Debug (line 76) | class Debug(object):
method __init__ (line 79) | def __init__(self, *flags, **options):
method __str__ (line 116) | def __str__(self):
method __call__ (line 119) | def __call__(self, msg):
method __and__ (line 122) | def __and__(self, flag):
method __rand__ (line 125) | def __rand__(self, flag):
method getCurrentPrinter (line 128) | def getCurrentPrinter(self):
method getCurrentLogger (line 131) | def getCurrentLogger(self):
function setLogger (line 140) | def setLogger(l):
FILE: pysmi/error.py
class PySmiError (line 17) | class PySmiError(Exception):
method __init__ (line 18) | def __init__(self, *args, **kwargs):
method __repr__ (line 24) | def __repr__(self):
method __str__ (line 28) | def __str__(self):
class PySmiLexerError (line 32) | class PySmiLexerError(PySmiError):
method __str__ (line 35) | def __str__(self):
class PySmiParserError (line 39) | class PySmiParserError(PySmiLexerError):
class PySmiSyntaxError (line 43) | class PySmiSyntaxError(PySmiParserError):
class PySmiSearcherError (line 47) | class PySmiSearcherError(PySmiError):
class PySmiFileNotModifiedError (line 51) | class PySmiFileNotModifiedError(PySmiSearcherError):
class PySmiFileNotFoundError (line 55) | class PySmiFileNotFoundError(PySmiSearcherError):
class PySmiReaderError (line 59) | class PySmiReaderError(PySmiError):
class PySmiReaderFileNotModifiedError (line 63) | class PySmiReaderFileNotModifiedError(PySmiReaderError):
class PySmiReaderFileNotFoundError (line 67) | class PySmiReaderFileNotFoundError(PySmiReaderError):
class PySmiCodegenError (line 71) | class PySmiCodegenError(PySmiError):
class PySmiSemanticError (line 75) | class PySmiSemanticError(PySmiCodegenError):
class PySmiWriterError (line 79) | class PySmiWriterError(PySmiError):
FILE: pysmi/lexer/base.py
class AbstractLexer (line 9) | class AbstractLexer(object):
method reset (line 10) | def reset(self):
FILE: pysmi/lexer/smi.py
class SmiV2Lexer (line 20) | class SmiV2Lexer(AbstractLexer):
method __init__ (line 89) | def __init__(self, tempdir=''):
method reset (line 94) | def reset(self):
method t_newline (line 117) | def t_newline(self, t):
method t_MACRO (line 122) | def t_MACRO(self, t):
method t_macro_newline (line 127) | def t_macro_newline(self, t):
method t_macro_END (line 131) | def t_macro_END(self, t):
method t_macro_body (line 136) | def t_macro_body(self, t):
method t_EXPORTS (line 141) | def t_EXPORTS(self, t):
method t_exports_newline (line 146) | def t_exports_newline(self, t):
method t_exports_end (line 150) | def t_exports_end(self, t):
method t_exports_body (line 154) | def t_exports_body(self, t):
method t_CHOICE (line 159) | def t_CHOICE(self, t):
method t_choice_newline (line 164) | def t_choice_newline(self, t):
method t_choice_end (line 168) | def t_choice_end(self, t):
method t_choice_body (line 172) | def t_choice_body(self, t):
method t_begin_comment (line 177) | def t_begin_comment(self, t):
method t_comment_newline (line 181) | def t_comment_newline(self, t):
method t_comment_body (line 190) | def t_comment_body(self, t):
method t_UPPERCASE_IDENTIFIER (line 194) | def t_UPPERCASE_IDENTIFIER(self, t):
method t_LOWERCASE_IDENTIFIER (line 206) | def t_LOWERCASE_IDENTIFIER(self, t):
method t_NUMBER (line 212) | def t_NUMBER(self, t):
method t_BIN_STRING (line 236) | def t_BIN_STRING(self, t):
method t_HEX_STRING (line 246) | def t_HEX_STRING(self, t):
method t_QUOTED_STRING (line 256) | def t_QUOTED_STRING(self, t):
method t_error (line 261) | def t_error(self, t):
class SupportSmiV1Keywords (line 268) | class SupportSmiV1Keywords(object):
method reserved (line 270) | def reserved():
method forbidden_words (line 302) | def forbidden_words():
method tokens (line 311) | def tokens():
function lexerFactory (line 350) | def lexerFactory(**grammarOptions):
FILE: pysmi/mibinfo.py
class MibInfo (line 9) | class MibInfo(object):
method __init__ (line 46) | def __init__(self, **kwargs):
FILE: pysmi/parser/base.py
class AbstractParser (line 9) | class AbstractParser(object):
method reset (line 10) | def reset(self):
method parse (line 13) | def parse(self, data, **kwargs):
FILE: pysmi/parser/null.py
class NullParser (line 10) | class NullParser(AbstractParser):
method __init__ (line 11) | def __init__(self, startSym='mibFile', tempdir=''):
method reset (line 14) | def reset(self):
method parse (line 17) | def parse(self, data, **kwargs):
FILE: pysmi/parser/smi.py
class SmiV2Parser (line 19) | class SmiV2Parser(AbstractParser):
method __init__ (line 22) | def __init__(self, startSym='mibFile', tempdir=''):
method reset (line 61) | def reset(self):
method parse (line 65) | def parse(self, data, **kwargs):
method p_mibFile (line 82) | def p_mibFile(self, p):
method p_modules (line 87) | def p_modules(self, p):
method p_module (line 96) | def p_module(self, p):
method p_moduleOid (line 103) | def p_moduleOid(self, p):
method p_linkagePart (line 110) | def p_linkagePart(self, p):
method p_linkageClause (line 116) | def p_linkageClause(self, p):
method p_exportsClause (line 120) | def p_exportsClause(self, p):
method p_importPart (line 124) | def p_importPart(self, p):
method p_imports (line 139) | def p_imports(self, p):
method p_import (line 148) | def p_import(self, p):
method p_importIdentifiers (line 155) | def p_importIdentifiers(self, p):
method p_importIdentifier (line 165) | def p_importIdentifier(self, p):
method p_importedKeyword (line 171) | def p_importedKeyword(self, p):
method p_importedSMIKeyword (line 188) | def p_importedSMIKeyword(self, p):
method p_moduleName (line 198) | def p_moduleName(self, p):
method p_declarationPart (line 202) | def p_declarationPart(self, p):
method p_declarations (line 208) | def p_declarations(self, p):
method p_declaration (line 217) | def p_declaration(self, p):
method p_macroClause (line 233) | def p_macroClause(self, p):
method p_macroName (line 236) | def p_macroName(self, p):
method p_choiceClause (line 248) | def p_choiceClause(self, p):
method p_fuzzy_lowercase_identifier (line 252) | def p_fuzzy_lowercase_identifier(self, p):
method p_valueDeclaration (line 257) | def p_valueDeclaration(self, p):
method p_typeDeclaration (line 262) | def p_typeDeclaration(self, p):
method p_typeName (line 267) | def p_typeName(self, p):
method p_typeSMI (line 272) | def p_typeSMI(self, p):
method p_typeSMIandSPPI (line 277) | def p_typeSMIandSPPI(self, p):
method p_typeSMIonly (line 285) | def p_typeSMIonly(self, p):
method p_typeDeclarationRHS (line 291) | def p_typeDeclarationRHS(self, p):
method p_conceptualTable (line 306) | def p_conceptualTable(self, p):
method p_row (line 310) | def p_row(self, p):
method p_entryType (line 315) | def p_entryType(self, p):
method p_sequenceItems (line 319) | def p_sequenceItems(self, p):
method p_sequenceItem (line 329) | def p_sequenceItem(self, p):
method p_Syntax (line 333) | def p_Syntax(self, p):
method p_sequenceSyntax (line 344) | def p_sequenceSyntax(self, p):
method p_NamedBits (line 350) | def p_NamedBits(self, p):
method p_NamedBit (line 359) | def p_NamedBit(self, p):
method p_objectIdentityClause (line 363) | def p_objectIdentityClause(self, p):
method p_objectTypeClause (line 372) | def p_objectTypeClause(self, p):
method p_descriptionClause (line 387) | def p_descriptionClause(self, p):
method p_trapTypeClause (line 393) | def p_trapTypeClause(self, p):
method p_VarPart (line 404) | def p_VarPart(self, p):
method p_VarTypes (line 409) | def p_VarTypes(self, p):
method p_VarType (line 418) | def p_VarType(self, p):
method p_DescrPart (line 422) | def p_DescrPart(self, p):
method p_MaxOrPIBAccessPart (line 428) | def p_MaxOrPIBAccessPart(self, p):
method p_MaxAccessPart (line 434) | def p_MaxAccessPart(self, p):
method p_notificationTypeClause (line 439) | def p_notificationTypeClause(self, p):
method p_moduleIdentityClause (line 450) | def p_moduleIdentityClause(self, p):
method p_SubjectCategoriesPart (line 464) | def p_SubjectCategoriesPart(self, p):
method p_SubjectCategories (line 470) | def p_SubjectCategories(self, p):
method p_CategoryIDs (line 474) | def p_CategoryIDs(self, p):
method p_CategoryID (line 483) | def p_CategoryID(self, p):
method p_ObjectSyntax (line 494) | def p_ObjectSyntax(self, p):
method p_typeTag (line 507) | def p_typeTag(self, p):
method p_sequenceObjectSyntax (line 511) | def p_sequenceObjectSyntax(self, p):
method p_valueofObjectSyntax (line 517) | def p_valueofObjectSyntax(self, p):
method p_SimpleSyntax (line 521) | def p_SimpleSyntax(self, p):
method p_valueofSimpleSyntax (line 546) | def p_valueofSimpleSyntax(self, p):
method p_sequenceSimpleSyntax (line 567) | def p_sequenceSimpleSyntax(self, p):
method p_ApplicationSyntax (line 578) | def p_ApplicationSyntax(self, p):
method p_sequenceApplicationSyntax (line 598) | def p_sequenceApplicationSyntax(self, p):
method p_anySubType (line 612) | def p_anySubType(self, p):
method p_integerSubType (line 620) | def p_integerSubType(self, p):
method p_octetStringSubType (line 624) | def p_octetStringSubType(self, p):
method p_ranges (line 628) | def p_ranges(self, p):
method p_range (line 637) | def p_range(self, p):
method p_value (line 646) | def p_value(self, p):
method p_enumSpec (line 655) | def p_enumSpec(self, p):
method p_enumItems (line 659) | def p_enumItems(self, p):
method p_enumItem (line 668) | def p_enumItem(self, p):
method p_enumNumber (line 672) | def p_enumNumber(self, p):
method p_Status (line 678) | def p_Status(self, p):
method p_DisplayPart (line 682) | def p_DisplayPart(self, p):
method p_UnitsPart (line 688) | def p_UnitsPart(self, p):
method p_Access (line 694) | def p_Access(self, p):
method p_IndexPart (line 698) | def p_IndexPart(self, p):
method p_MibIndex (line 704) | def p_MibIndex(self, p):
method p_IndexTypes (line 710) | def p_IndexTypes(self, p):
method p_IndexType (line 719) | def p_IndexType(self, p):
method p_Index (line 728) | def p_Index(self, p):
method p_Entry (line 734) | def p_Entry(self, p):
method p_DefValPart (line 738) | def p_DefValPart(self, p):
method p_Value (line 744) | def p_Value(self, p):
method p_BitsValue (line 753) | def p_BitsValue(self, p):
method p_BitNames (line 759) | def p_BitNames(self, p):
method p_ObjectName (line 768) | def p_ObjectName(self, p):
method p_NotificationName (line 772) | def p_NotificationName(self, p):
method p_ReferPart (line 776) | def p_ReferPart(self, p):
method p_RevisionPart (line 782) | def p_RevisionPart(self, p):
method p_Revisions (line 788) | def p_Revisions(self, p):
method p_Revision (line 797) | def p_Revision(self, p):
method p_NotificationObjectsPart (line 802) | def p_NotificationObjectsPart(self, p):
method p_ObjectGroupObjectsPart (line 807) | def p_ObjectGroupObjectsPart(self, p):
method p_Objects (line 811) | def p_Objects(self, p):
method p_Object (line 820) | def p_Object(self, p):
method p_NotificationsPart (line 824) | def p_NotificationsPart(self, p):
method p_Notifications (line 828) | def p_Notifications(self, p):
method p_Notification (line 837) | def p_Notification(self, p):
method p_Text (line 841) | def p_Text(self, p):
method p_ExtUTCTime (line 845) | def p_ExtUTCTime(self, p):
method p_objectIdentifier (line 849) | def p_objectIdentifier(self, p):
method p_subidentifiers (line 853) | def p_subidentifiers(self, p):
method p_subidentifier (line 862) | def p_subidentifier(self, p):
method p_objectIdentifier_defval (line 874) | def p_objectIdentifier_defval(self, p):
method p_subidentifiers_defval (line 878) | def p_subidentifiers_defval(self, p):
method p_subidentifier_defval (line 887) | def p_subidentifier_defval(self, p):
method p_objectGroupClause (line 896) | def p_objectGroupClause(self, p):
method p_notificationGroupClause (line 906) | def p_notificationGroupClause(self, p):
method p_moduleComplianceClause (line 916) | def p_moduleComplianceClause(self, p):
method p_ComplianceModulePart (line 927) | def p_ComplianceModulePart(self, p):
method p_ComplianceModules (line 931) | def p_ComplianceModules(self, p):
method p_ComplianceModule (line 940) | def p_ComplianceModule(self, p):
method p_ComplianceModuleName (line 947) | def p_ComplianceModuleName(self, p):
method p_MandatoryPart (line 953) | def p_MandatoryPart(self, p):
method p_MandatoryGroups (line 959) | def p_MandatoryGroups(self, p):
method p_MandatoryGroup (line 968) | def p_MandatoryGroup(self, p):
method p_CompliancePart (line 972) | def p_CompliancePart(self, p):
method p_Compliances (line 978) | def p_Compliances(self, p):
method p_Compliance (line 987) | def p_Compliance(self, p):
method p_ComplianceGroup (line 993) | def p_ComplianceGroup(self, p):
method p_ComplianceObject (line 999) | def p_ComplianceObject(self, p):
method p_SyntaxPart (line 1008) | def p_SyntaxPart(self, p):
method p_WriteSyntaxPart (line 1014) | def p_WriteSyntaxPart(self, p):
method p_WriteSyntax (line 1020) | def p_WriteSyntax(self, p):
method p_AccessPart (line 1024) | def p_AccessPart(self, p):
method p_agentCapabilitiesClause (line 1030) | def p_agentCapabilitiesClause(self, p):
method p_ModulePart_Capabilities (line 1041) | def p_ModulePart_Capabilities(self, p):
method p_Modules_Capabilities (line 1047) | def p_Modules_Capabilities(self, p):
method p_Module_Capabilities (line 1056) | def p_Module_Capabilities(self, p):
method p_CapabilitiesGroups (line 1062) | def p_CapabilitiesGroups(self, p):
method p_CapabilitiesGroup (line 1071) | def p_CapabilitiesGroup(self, p):
method p_ModuleName_Capabilities (line 1075) | def p_ModuleName_Capabilities(self, p):
method p_VariationPart (line 1084) | def p_VariationPart(self, p):
method p_Variations (line 1090) | def p_Variations(self, p):
method p_Variation (line 1099) | def p_Variation(self, p):
method p_VariationAccessPart (line 1110) | def p_VariationAccessPart(self, p):
method p_VariationAccess (line 1116) | def p_VariationAccess(self, p):
method p_CreationPart (line 1120) | def p_CreationPart(self, p):
method p_Cells (line 1126) | def p_Cells(self, p):
method p_Cell (line 1135) | def p_Cell(self, p):
method p_empty (line 1139) | def p_empty(self, p):
method p_error (line 1143) | def p_error(self, p):
class SupportSmiV1Keywords (line 1163) | class SupportSmiV1Keywords(object):
method p_importedKeyword (line 1166) | def p_importedKeyword(self, p):
method p_typeSMIandSPPI (line 1186) | def p_typeSMIandSPPI(self, p):
method p_ApplicationSyntax (line 1197) | def p_ApplicationSyntax(self, p):
method p_sequenceApplicationSyntax (line 1219) | def p_sequenceApplicationSyntax(self, p):
class SupportIndex (line 1236) | class SupportIndex(object):
method p_Index (line 1239) | def p_Index(self, p):
method p_typeSMIv1 (line 1249) | def p_typeSMIv1(self, p):
class CommaInImport (line 1264) | class CommaInImport(object):
method p_importIdentifiers (line 1267) | def p_importIdentifiers(self, p):
class CommaInSequence (line 1281) | class CommaInSequence(object):
method p_sequenceItems (line 1284) | def p_sequenceItems(self, p):
class CommaAndSpaces (line 1299) | class CommaAndSpaces(object):
method p_enumItems (line 1302) | def p_enumItems(self, p):
class UppercaseIdentifier (line 1320) | class UppercaseIdentifier(object):
method p_enumItem (line 1323) | def p_enumItem(self, p):
class LowcaseIdentifier (line 1330) | class LowcaseIdentifier(object):
method p_notificationTypeClause (line 1333) | def p_notificationTypeClause(self, p):
class CurlyBracesInEnterprises (line 1345) | class CurlyBracesInEnterprises(object):
method p_trapTypeClause (line 1348) | def p_trapTypeClause(self, p):
method p_EnterprisePart (line 1360) | def p_EnterprisePart(self, p):
class NoCells (line 1371) | class NoCells(object):
method p_CreationPart (line 1374) | def p_CreationPart(self, p):
function parserFactory (line 1407) | def parserFactory(**grammarOptions):
FILE: pysmi/reader/base.py
class AbstractReader (line 10) | class AbstractReader(object):
method setOptions (line 20) | def setOptions(self, **kwargs):
method getMibVariants (line 25) | def getMibVariants(self, mibname, **options):
method getData (line 51) | def getData(self, filename, **options):
FILE: pysmi/reader/callback.py
class CallbackReader (line 14) | class CallbackReader(AbstractReader):
method __init__ (line 20) | def __init__(self, cbFun, cbCtx=None):
method __str__ (line 33) | def __str__(self):
method getData (line 36) | def getData(self, mibname, **options):
FILE: pysmi/reader/ftpclient.py
class FtpReader (line 17) | class FtpReader(AbstractReader):
method __init__ (line 23) | def __init__( # nosec
method __str__ (line 52) | def __str__(self):
method getData (line 55) | def getData(self, mibname, **options):
FILE: pysmi/reader/httpclient.py
class HttpReader (line 27) | class HttpReader(AbstractReader):
method __init__ (line 35) | def __init__(self, host, port, locationTemplate, timeout=5, ssl=False):
method __str__ (line 62) | def __str__(self):
method getData (line 65) | def getData(self, mibname, **options):
FILE: pysmi/reader/localfile.py
class FileReader (line 17) | class FileReader(AbstractReader):
method __init__ (line 26) | def __init__(self, path, recursive=True, ignoreErrors=True):
method __str__ (line 42) | def __str__(self):
method getSubdirs (line 45) | def getSubdirs(self, path, recursive=True, ignoreErrors=True):
method loadIndex (line 69) | def loadIndex(indexFile):
method getMibVariants (line 86) | def getMibVariants(self, mibname, **options):
method getData (line 101) | def getData(self, mibname, **options):
FILE: pysmi/reader/url.py
function getReadersFromUrls (line 26) | def getReadersFromUrls(*sourceUrls, **options):
FILE: pysmi/reader/zipreader.py
class FileLike (line 19) | class FileLike(object):
method __init__ (line 21) | def __init__(self, buf, name):
method close (line 31) | def close(self):
method seek (line 37) | def seek(self, pos, mode = 0):
method tell (line 50) | def tell(self):
method read (line 53) | def read(self, n=-1):
class ZipReader (line 70) | class ZipReader(AbstractReader):
method __init__ (line 78) | def __init__(self, path, ignoreErrors=True):
method _readZipDirectory (line 101) | def _readZipDirectory(self, fileObj):
method _readZipFile (line 138) | def _readZipFile(self, refs):
method __str__ (line 156) | def __str__(self):
method getData (line 159) | def getData(self, mibname, **options):
FILE: pysmi/searcher/anyfile.py
class AnyFileSearcher (line 16) | class AnyFileSearcher(AbstractSearcher):
method __init__ (line 21) | def __init__(self, path):
method __str__ (line 29) | def __str__(self):
method fileExists (line 32) | def fileExists(self, mibname, mtime, rebuild=False):
FILE: pysmi/searcher/base.py
class AbstractSearcher (line 9) | class AbstractSearcher(object):
method setOptions (line 11) | def setOptions(self, **kwargs):
method fileExists (line 16) | def fileExists(self, mibname, mtime, rebuild=False):
FILE: pysmi/searcher/pyfile.py
class PyFileSearcher (line 37) | class PyFileSearcher(AbstractSearcher):
method __init__ (line 41) | def __init__(self, path):
method __str__ (line 49) | def __str__(self):
method fileExists (line 52) | def fileExists(self, mibname, mtime, rebuild=False):
FILE: pysmi/searcher/pypackage.py
class PyPackageSearcher (line 37) | class PyPackageSearcher(AbstractSearcher):
method __init__ (line 43) | def __init__(self, package):
method __str__ (line 54) | def __str__(self):
method _parseDosTime (line 58) | def _parseDosTime(dosdate, dostime):
method fileExists (line 70) | def fileExists(self, mibname, mtime, rebuild=False):
FILE: pysmi/searcher/stub.py
class StubSearcher (line 12) | class StubSearcher(AbstractSearcher):
method __init__ (line 16) | def __init__(self, *mibnames):
method __str__ (line 25) | def __str__(self):
method fileExists (line 28) | def fileExists(self, mibname, mtime, rebuild=False):
FILE: pysmi/writer/base.py
class AbstractWriter (line 8) | class AbstractWriter(object):
method setOptions (line 9) | def setOptions(self, **kwargs):
method putData (line 14) | def putData(self, mibname, data, comments=(), dryRun=False):
method getData (line 17) | def getData(self, filename):
FILE: pysmi/writer/callback.py
class CallbackWriter (line 13) | class CallbackWriter(AbstractWriter):
method __init__ (line 23) | def __init__(self, cbFun, cbCtx=None):
method __str__ (line 34) | def __str__(self):
method putData (line 37) | def putData(self, mibname, data, comments=(), dryRun=False):
method getData (line 51) | def getData(self, filename):
FILE: pysmi/writer/localfile.py
class FileWriter (line 16) | class FileWriter(AbstractWriter):
method __init__ (line 24) | def __init__(self, path):
method __str__ (line 32) | def __str__(self):
method getData (line 35) | def getData(self, mibname, dryRun=False):
method putData (line 51) | def putData(self, mibname, data, comments=(), dryRun=False):
FILE: pysmi/writer/pyfile.py
class PyFileWriter (line 33) | class PyFileWriter(AbstractWriter):
method __init__ (line 42) | def __init__(self, path):
method __str__ (line 50) | def __str__(self):
method putData (line 53) | def putData(self, mibname, data, comments=(), dryRun=False):
method getData (line 109) | def getData(self, filename):
FILE: scripts/mibcopy.py
function getMibRevision (line 146) | def getMibRevision(mibDir, mibFile):
function shortenPath (line 183) | def shortenPath(path, maxLength=45):
FILE: setup.py
function howto_install_setuptools (line 47) | def howto_install_setuptools():
class PyTest (line 142) | class PyTest(Command):
method initialize_options (line 145) | def initialize_options(self): pass
method finalize_options (line 147) | def finalize_options(self): pass
method run (line 149) | def run(self):
FILE: tests/test_agentcapabilities_smiv2_pysnmp.py
class AgentCapabilitiesTestCase (line 20) | class AgentCapabilitiesTestCase(unittest.TestCase):
method setUp (line 56) | def setUp(self):
method testAgentCapabilitiesSymbol (line 69) | def testAgentCapabilitiesSymbol(self):
method testAgentCapabilitiesName (line 75) | def testAgentCapabilitiesName(self):
method testAgentCapabilitiesDescription (line 82) | def testAgentCapabilitiesDescription(self):
method testAgentCapabilitiesClass (line 91) | def testAgentCapabilitiesClass(self):
FILE: tests/test_imports_smiv2_pysnmp.py
class ImportClauseTestCase (line 20) | class ImportClauseTestCase(unittest.TestCase):
method setUp (line 33) | def setUp(self):
method testModuleImportsRequiredMibs (line 43) | def testModuleImportsRequiredMibs(self):
method testModuleCheckImportedSymbol (line 50) | def testModuleCheckImportedSymbol(self):
FILE: tests/test_modulecompliance_smiv2_pysnmp.py
class ModuleComplianceTestCase (line 20) | class ModuleComplianceTestCase(unittest.TestCase):
method setUp (line 43) | def setUp(self):
method testModuleComplianceSymbol (line 56) | def testModuleComplianceSymbol(self):
method testModuleComplianceName (line 62) | def testModuleComplianceName(self):
method testModuleComplianceDescription (line 69) | def testModuleComplianceDescription(self):
method testModuleComplianceClass (line 76) | def testModuleComplianceClass(self):
FILE: tests/test_moduleidentity_smiv2_pysnmp.py
class ModuleIdentityTestCase (line 20) | class ModuleIdentityTestCase(unittest.TestCase):
method setUp (line 39) | def setUp(self):
method testModuleIdentitySymbol (line 52) | def testModuleIdentitySymbol(self):
method testModuleIdentityName (line 58) | def testModuleIdentityName(self):
method testModuleIdentityLastUpdated (line 65) | def testModuleIdentityLastUpdated(self):
method testModuleIdentityOrganization (line 72) | def testModuleIdentityOrganization(self):
method testModuleIdentityRevisions (line 79) | def testModuleIdentityRevisions(self):
method testModuleIdentityContactInfo (line 92) | def testModuleIdentityContactInfo(self):
method testModuleIdentityDescription (line 99) | def testModuleIdentityDescription(self):
method testModuleIdentityClass (line 106) | def testModuleIdentityClass(self):
FILE: tests/test_notificationgroup_smiv2_pysnmp.py
class NotificationGroupTestCase (line 20) | class NotificationGroupTestCase(unittest.TestCase):
method setUp (line 41) | def setUp(self):
method testNotificationGroupSymbol (line 54) | def testNotificationGroupSymbol(self):
method testNotificationGroupName (line 60) | def testNotificationGroupName(self):
method testNotificationGroupDescription (line 67) | def testNotificationGroupDescription(self):
method testNotificationGroupClass (line 74) | def testNotificationGroupClass(self):
FILE: tests/test_notificationtype_smiv2_pysnmp.py
class NotificationTypeTestCase (line 20) | class NotificationTypeTestCase(unittest.TestCase):
method setUp (line 40) | def setUp(self):
method testNotificationTypeSymbol (line 53) | def testNotificationTypeSymbol(self):
method testNotificationTypeName (line 59) | def testNotificationTypeName(self):
method testNotificationTypeDescription (line 66) | def testNotificationTypeDescription(self):
method testNotificationTypeClass (line 73) | def testNotificationTypeClass(self):
FILE: tests/test_objectgroup_smiv2_pysnmp.py
class ObjectGroupTestCase (line 21) | class ObjectGroupTestCase(unittest.TestCase):
method setUp (line 41) | def setUp(self):
method testObjectGroupSymbol (line 54) | def testObjectGroupSymbol(self):
method testObjectGroupName (line 60) | def testObjectGroupName(self):
method testObjectGroupDescription (line 67) | def testObjectGroupDescription(self):
method testObjectGroupObjects (line 74) | def testObjectGroupObjects(self):
method testObjectGroupClass (line 81) | def testObjectGroupClass(self):
FILE: tests/test_objectidentity_smiv2_pysnmp.py
class ObjectIdentityTestCase (line 20) | class ObjectIdentityTestCase(unittest.TestCase):
method setUp (line 37) | def setUp(self):
method testObjectIdentitySymbol (line 50) | def testObjectIdentitySymbol(self):
method testObjectIdentityName (line 56) | def testObjectIdentityName(self):
method testObjectIdentityDescription (line 63) | def testObjectIdentityDescription(self):
method testObjectIdentityReference (line 70) | def testObjectIdentityReference(self):
method testObjectIdentityClass (line 77) | def testObjectIdentityClass(self):
FILE: tests/test_objecttype_smiv2_pysnmp.py
class ObjectTypeBasicTestCase (line 21) | class ObjectTypeBasicTestCase(unittest.TestCase):
method setUp (line 40) | def setUp(self):
method testObjectTypeSymbol (line 53) | def testObjectTypeSymbol(self):
method testObjectTypeName (line 59) | def testObjectTypeName(self):
method testObjectTypeDescription (line 66) | def testObjectTypeDescription(self):
method testObjectTypeStatus (line 73) | def testObjectTypeStatus(self):
method testObjectTypeMaxAccess (line 87) | def testObjectTypeMaxAccess(self):
method testObjectTypeUnits (line 94) | def testObjectTypeUnits(self):
method testObjectTypeSyntax (line 101) | def testObjectTypeSyntax(self):
method testObjectTypeClass (line 108) | def testObjectTypeClass(self):
class ObjectTypeIntegerDefaultTestCase (line 116) | class ObjectTypeIntegerDefaultTestCase(unittest.TestCase):
method setUp (line 135) | def setUp(self):
method testObjectTypeSyntax (line 145) | def testObjectTypeSyntax(self):
class ObjectTypeEnumDefaultTestCase (line 153) | class ObjectTypeEnumDefaultTestCase(unittest.TestCase):
method setUp (line 174) | def setUp(self):
method testObjectTypeSyntax (line 184) | def testObjectTypeSyntax(self):
class ObjectTypeStringDefaultTestCase (line 192) | class ObjectTypeStringDefaultTestCase(unittest.TestCase):
method setUp (line 210) | def setUp(self):
method testObjectTypeSyntax (line 221) | def testObjectTypeSyntax(self):
class ObjectTypeWithIntegerConstraintTestCase (line 228) | class ObjectTypeWithIntegerConstraintTestCase(unittest.TestCase):
method setUp (line 247) | def setUp(self):
method testObjectTypeSyntax (line 257) | def testObjectTypeSyntax(self):
class ObjectTypeWithIntegerSetConstraintTestCase (line 265) | class ObjectTypeWithIntegerSetConstraintTestCase(unittest.TestCase):
method setUp (line 283) | def setUp(self):
method testObjectTypeSyntax (line 293) | def testObjectTypeSyntax(self):
class ObjectTypeWithStringSizeConstraintTestCase (line 301) | class ObjectTypeWithStringSizeConstraintTestCase(unittest.TestCase):
method setUp (line 319) | def setUp(self):
method testObjectTypeSyntax (line 329) | def testObjectTypeSyntax(self):
class ObjectTypeBitsTestCase (line 336) | class ObjectTypeBitsTestCase(unittest.TestCase):
method setUp (line 354) | def setUp(self):
method testObjectTypeSyntax (line 364) | def testObjectTypeSyntax(self):
class ObjectTypeMibTableTestCase (line 371) | class ObjectTypeMibTableTestCase(unittest.TestCase):
method setUp (line 415) | def setUp(self):
method testObjectTypeTableClass (line 425) | def testObjectTypeTableClass(self):
method testObjectTypeTableRowClass (line 432) | def testObjectTypeTableRowClass(self):
method testObjectTypeTableColumnClass (line 439) | def testObjectTypeTableColumnClass(self):
method testObjectTypeTableRowIndex (line 446) | def testObjectTypeTableRowIndex(self):
class ObjectTypeMibTableImpliedIndexTestCase (line 454) | class ObjectTypeMibTableImpliedIndexTestCase(unittest.TestCase):
method setUp (line 490) | def setUp(self):
method testObjectTypeTableRowIndex (line 500) | def testObjectTypeTableRowIndex(self):
class ObjectTypeMibTableMultipleIndicesTestCase (line 508) | class ObjectTypeMibTableMultipleIndicesTestCase(unittest.TestCase):
method setUp (line 552) | def setUp(self):
method testObjectTypeTableRowIndex (line 562) | def testObjectTypeTableRowIndex(self):
class ObjectTypeAurmentingMibTableTestCase (line 570) | class ObjectTypeAurmentingMibTableTestCase(unittest.TestCase):
method setUp (line 632) | def setUp(self):
method testObjectTypeTableRowAugmention (line 642) | def testObjectTypeTableRowAugmention(self):
FILE: tests/test_smiv1_smiv2_pysnmp.py
class SmiV1TestCase (line 20) | class SmiV1TestCase(unittest.TestCase):
method setUp (line 49) | def setUp(self):
method testSmiV1Symbol (line 62) | def testSmiV1Symbol(self):
method testSmiV1Name (line 68) | def testSmiV1Name(self):
method testSmiV1Description (line 75) | def testSmiV1Description(self):
method testSmiV1Class (line 82) | def testSmiV1Class(self):
FILE: tests/test_traptype_smiv2_pysnmp.py
class TrapTypeTestCase (line 20) | class TrapTypeTestCase(unittest.TestCase):
method setUp (line 49) | def setUp(self):
method testTrapTypeSymbol (line 62) | def testTrapTypeSymbol(self):
method testTrapTypeName (line 68) | def testTrapTypeName(self):
method testTrapTypeDescription (line 75) | def testTrapTypeDescription(self):
method testTrapTypeClass (line 82) | def testTrapTypeClass(self):
FILE: tests/test_typedeclaration_smiv1_pysnmp.py
class TypeDeclarationTestCase (line 21) | class TypeDeclarationTestCase(unittest.TestCase):
method setUp (line 50) | def setUp(self):
method protoTestSymbol (line 63) | def protoTestSymbol(self, symbol, klass):
method protoTestClass (line 68) | def protoTestClass(self, symbol, klass):
function decor (line 90) | def decor(func, symbol, klass):
FILE: tests/test_typedeclaration_smiv2_pysnmp.py
class TypeDeclarationTestCase (line 20) | class TypeDeclarationTestCase(unittest.TestCase):
method setUp (line 88) | def setUp(self):
method protoTestSymbol (line 101) | def protoTestSymbol(self, symbol, klass):
method protoTestClass (line 106) | def protoTestClass(self, symbol, klass):
method TestTextualConventionSymbol (line 112) | def TestTextualConventionSymbol(self):
method TestTextualConventionDisplayHint (line 118) | def TestTextualConventionDisplayHint(self):
method TestTextualConventionStatus (line 125) | def TestTextualConventionStatus(self):
method TestTextualConventionDescription (line 132) | def TestTextualConventionDescription(self):
method TestTextualConventionReference (line 139) | def TestTextualConventionReference(self):
method TestTextualConventionClass (line 146) | def TestTextualConventionClass(self):
function decor (line 177) | def decor(func, symbol, klass):
FILE: tests/test_valuedeclaration_smiv2_pysnmp.py
class ValueDeclarationTestCase (line 20) | class ValueDeclarationTestCase(unittest.TestCase):
method setUp (line 55) | def setUp(self):
method testValueDeclarationSymbol (line 68) | def testValueDeclarationSymbol(self):
method testValueDeclarationName1 (line 76) | def testValueDeclarationName1(self):
method testValueDeclarationName2 (line 83) | def testValueDeclarationName2(self):
method testValueDeclarationName3 (line 90) | def testValueDeclarationName3(self):
FILE: tests/test_zipreader.py
class ZipReaderTestCase (line 26) | class ZipReaderTestCase(unittest.TestCase):
method testGetDataFromFile (line 171) | def testGetDataFromFile(self):
method testGetInnerZipData (line 196) | def testGetInnerZipData(self):
Condensed preview — 134 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (464K chars).
[
{
"path": ".bandit.yml",
"chars": 174,
"preview": "skips:\n- B603 # Ignore warnings about calling subprocess.Popen without shell=True\n- B607 # Ignore warnings about calli"
},
{
"path": ".flake8.ini",
"chars": 237,
"preview": "[flake8]\nshow-source = True\n# E123, E125 seem invalid\nignore = E123,E125,D104,D100,D101,D102,D103,D106,D107,D412,W504\n#e"
},
{
"path": ".github/FUNDING.yml",
"chars": 45,
"preview": "custom: http://snmplabs.com/sponsorship.html\n"
},
{
"path": ".gitignore",
"chars": 267,
"preview": "# Python stuff\n*.pyc\n__pycache__\n\n# vim swapfiles\n*.sw?\n\n# python packaging\nMANIFEST\ndist/\nbuild/\n*.egg-info/\n\n# PyCharm"
},
{
"path": ".travis.yml",
"chars": 913,
"preview": "language: python\ncache: pip\nmatrix:\n include:\n - os: linux\n dist: trusty\n python: '2.6'\n - os: linux\n dist: "
},
{
"path": "CHANGES.rst",
"chars": 7653,
"preview": "Revision 0.4.0, XX-03-2020\n--------------------------\n\n- Introduced Jinja2 templates for code generation.\n\n This change"
},
{
"path": "LICENSE.rst",
"chars": 1333,
"preview": "Copyright (c) 2015-2020 Ilya Etingof <etingof@gmail.com>\nAll rights reserved.\n\nRedistribution and use in source and bina"
},
{
"path": "MANIFEST.in",
"chars": 141,
"preview": "include *.txt *.rst *.md\nrecursive-include tests *.py\nrecursive-include examples *.py\nrecursive-include docs *.txt *.rst"
},
{
"path": "README.md",
"chars": 6518,
"preview": "\nSNMP MIB parser\n---------------\n[](https://pypi.org"
},
{
"path": "THANKS.txt",
"chars": 33,
"preview": "Lars Michelsen\nTanya Tereschenko\n"
},
{
"path": "TODO.txt",
"chars": 1915,
"preview": "* add more tests on edge cases\n* generate reverse OID -> MIB index\n* handle SMIv1 MAX clause in range constraint\n* suppo"
},
{
"path": "devel-requirements.txt",
"chars": 91,
"preview": "Sphinx <= 1.6; python_version < '2.7'\nSphinx > 1.6; python_version >= '2.7'\npysnmp < 5.0.0\n"
},
{
"path": "docs/Makefile",
"chars": 7414,
"preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS =\nSPHINXBUILD "
},
{
"path": "docs/README.txt",
"chars": 218,
"preview": "You need Sphinx too build this documentation. Or you can read it in ASCII. ;)\n\nBetter run:\n\n# pip sphinx\n\nand once Sphin"
},
{
"path": "docs/source/.static/css/rtdimproved.css",
"chars": 232,
"preview": "@import url(\"../pygments.css\");\n@import url(\"theme.css\");\n\n/* fix horizontal padding to accomodate adsense banners */\n.w"
},
{
"path": "docs/source/changelog.rst",
"chars": 53,
"preview": "\nChangelog\n=========\n\n.. include:: ../../CHANGES.rst\n"
},
{
"path": "docs/source/conf.py",
"chars": 10396,
"preview": "# -*- coding: utf-8 -*-\n#\n# PySMI documentation build configuration file, created by\n# sphinx-quickstart on Sat Jun 27 2"
},
{
"path": "docs/source/contents.rst",
"chars": 1768,
"preview": "\nSNMP SMI compiler\n=================\n\n.. toctree::\n :maxdepth: 2\n\nThe PySMI library and tools are designed to parse, v"
},
{
"path": "docs/source/documentation.rst",
"chars": 1968,
"preview": "\nPySMI documentation\n===================\n\nPySMI library is highly modular. The top-level component is called\n*compiler* "
},
{
"path": "docs/source/download.rst",
"chars": 355,
"preview": "\nDownload & Install\n==================\n\nThe best way to obtain SNMP SMI library is by running `pip`:\n\n.. code-block:: ba"
},
{
"path": "docs/source/examples/always-borrow-precompiled-pysnmp-files.rst",
"chars": 326,
"preview": "\n.. include:: /../../examples/always-borrow-precompiled-pysnmp-files.py\n :start-after: \"\"\"\n :end-before: \"\"\"#\n\n.. li"
},
{
"path": "docs/source/examples/borrow-precompiled-pysnmp-files-on-failure.rst",
"chars": 338,
"preview": "\n.. include:: /../../examples/borrow-precompiled-pysnmp-files-on-failure.py\n :start-after: \"\"\"\n :end-before: \"\"\"#\n\n."
},
{
"path": "docs/source/examples/compile-smistar-mibs-into-pysnmp-files-if-needed.rst",
"chars": 356,
"preview": "\n.. include:: /../../examples/compile-smistar-mibs-into-pysnmp-files-if-needed.py\n :start-after: \"\"\"\n :end-before: \""
},
{
"path": "docs/source/examples/compile-smiv2-mibs-from-text-into-pysnmp-code.rst",
"chars": 347,
"preview": "\n.. include:: /../../examples/compile-smiv2-mibs-from-text-into-pysnmp-code.py\n :start-after: \"\"\"\n :end-before: \"\"\"#"
},
{
"path": "docs/source/examples/download-and-compile-smistar-mibs-into-json.rst",
"chars": 341,
"preview": "\n.. include:: /../../examples/download-and-compile-smistar-mibs-into-json.py\n :start-after: \"\"\"\n :end-before: \"\"\"#\n\n"
},
{
"path": "docs/source/examples/download-and-compile-smistar-mibs-into-pysnmp-files.rst",
"chars": 365,
"preview": "\n.. include:: /../../examples/download-and-compile-smistar-mibs-into-pysnmp-files.py\n :start-after: \"\"\"\n :end-before"
},
{
"path": "docs/source/library-reference.rst",
"chars": 4802,
"preview": "\nPySMI library\n=============\n\nThe *MibCompiler* object is the top-most interface to PySMI library features.\nIt holds tog"
},
{
"path": "docs/source/license.rst",
"chars": 49,
"preview": "\nLicense\n=======\n\n.. include:: ../../LICENSE.rst\n"
},
{
"path": "docs/source/mibcopy.rst",
"chars": 4624,
"preview": "\nThe *mibcopy* tool\n==================\n\n.. toctree::\n :maxdepth: 2\n\nThe *mibcopy.py* tool attempts to normalize the fi"
},
{
"path": "docs/source/mibdump.rst",
"chars": 12707,
"preview": "\nThe *mibdump* tool\n==================\n\n.. toctree::\n :maxdepth: 2\n\nThe *mibdump.py* tool is a command-line frontend t"
},
{
"path": "docs/source/pysmi/borrower/anyfile/anyfileborrower.rst",
"chars": 144,
"preview": "\n.. _borrower.anyfile.AnyFileBorrower:\n\nAny file borrower\n-----------------\n\n.. autoclass:: pysmi.borrower.anyfile.AnyFi"
},
{
"path": "docs/source/pysmi/borrower/pyfile/pyfileborrower.rst",
"chars": 146,
"preview": "\n.. _borrower.pyfile.PyFileBorrower:\n\nPython file borrower\n--------------------\n\n.. autoclass:: pysmi.borrower.pyfile.Py"
},
{
"path": "docs/source/pysmi/codegen/jsondoc/jsoncodegen.rst",
"chars": 146,
"preview": "\n.. _codegen.jsondoc.JsonCodeGen:\n\nJSON document generator\n-----------------------\n\n.. autoclass:: pysmi.codegen.jsondoc"
},
{
"path": "docs/source/pysmi/codegen/null/nullcodegen.rst",
"chars": 134,
"preview": "\n.. _codegen.null.NullCodeGen:\n\nCode generation stub\n--------------------\n\n.. autoclass:: pysmi.codegen.null.NullCodeGen"
},
{
"path": "docs/source/pysmi/codegen/pysnmp/pysnmpcodegen.rst",
"chars": 142,
"preview": "\n.. _codegen.pysnmp.PySnmpCodeGen:\n\nPySNMP MIB generator\n--------------------\n\n.. autoclass:: pysmi.codegen.pysnmp.PySnm"
},
{
"path": "docs/source/pysmi/compiler/mibcompiler.rst",
"chars": 109,
"preview": "\n.. _compiler.MibCompiler:\n\nMIB compiler\n------------\n\n.. autoclass:: pysmi.compiler.MibCompiler\n :members:\n"
},
{
"path": "docs/source/pysmi/compiler/mibstatus.rst",
"chars": 249,
"preview": "\n.. _reader.compiler.MibStatus:\n\nCompilation status\n------------------\n\n*MibStatus* class instance is used by :func:`Mib"
},
{
"path": "docs/source/pysmi/parser/smi/dialect.rst",
"chars": 1083,
"preview": "\n.. _parser.smi.dialect:\n\nSMI language dialects\n---------------------\n\nPySMI offers a pre-built collection of parser gra"
},
{
"path": "docs/source/pysmi/parser/smi/parserfactory.rst",
"chars": 992,
"preview": "\n.. _parser.smi.parserFactory:\n\nSMI parser\n----------\n\nSNMP MIBs are written in two kinds of special language - SMIv1 an"
},
{
"path": "docs/source/pysmi/reader/callback/callbackreader.rst",
"chars": 217,
"preview": "\n.. _reader.callback.CallbackReader:\n\nCallback reader\n---------------\n\n*CallbackReader* class instance tries to fetch MI"
},
{
"path": "docs/source/pysmi/reader/ftpclient/ftpreader.rst",
"chars": 201,
"preview": "\n.. _reader.ftpclient.FtpReader:\n\nFTP reader\n----------\n\n*FtpReader* class instance tries to download MIB files from con"
},
{
"path": "docs/source/pysmi/reader/httpclient/httpreader.rst",
"chars": 202,
"preview": "\n.. _reader.httpclient.HttpReader:\n\nHTTP reader\n-----------\n\n*HttpReader* class instance tries to download MIB files usi"
},
{
"path": "docs/source/pysmi/reader/localfile/filereader.rst",
"chars": 229,
"preview": "\n.. _reader.localfile.FileReader:\n\nLocal file reader\n-----------------\n\n*FileReader* class instance looks up MIB files i"
},
{
"path": "docs/source/pysmi/reader/zipreader/zipreader.rst",
"chars": 267,
"preview": "\n.. _reader.zipreader.ZipReader:\n\nZIP archive reader\n------------------\n\n*ZipReader* class instance looks up MIB files i"
},
{
"path": "docs/source/pysmi/searcher/pyfile/pyfilesearcher.rst",
"chars": 260,
"preview": "\n.. _searcher.pyfile.PyFileSearcher:\n\nPython files searcher\n---------------------\n\nTransformed MIBs that were saved in f"
},
{
"path": "docs/source/pysmi/searcher/pypackage/pypackagesearcher.rst",
"chars": 317,
"preview": "\n.. _searcher.pypackage.PyPackageSearcher:\n\nSearch Python packages\n----------------------\n\nSome MIBs, most frequently th"
},
{
"path": "docs/source/pysmi/searcher/stub/stubsearcher.rst",
"chars": 468,
"preview": "\n.. _searcher.stub.StubSearcher:\n\nUnconditionally ignore MIBs\n---------------------------\n\nFoundation or obsolete MIBs t"
},
{
"path": "docs/source/pysmi/writer/callback/callbackwriter.rst",
"chars": 232,
"preview": "\n.. _writer.callback.CallbackReader:\n\nCallback writer\n---------------\n\n*CallbackWriter* class instance passes the conten"
},
{
"path": "docs/source/pysmi/writer/localfile/filewriter.rst",
"chars": 121,
"preview": "\n.. _writer.localfile.FileWriter:\n\nFile writer\n-----------\n\n.. autoclass:: pysmi.writer.localfile.FileWriter\n :members:"
},
{
"path": "docs/source/pysmi/writer/pyfile/pyfilewriter.rst",
"chars": 133,
"preview": "\n.. _writer.pyfile.PyFileWriter:\n\nPython file writer\n------------------\n\n.. autoclass:: pysmi.writer.pyfile.PyFileWriter"
},
{
"path": "examples/always-borrow-precompiled-pysnmp-files.py",
"chars": 1177,
"preview": "\"\"\"\nAlways borrow pysnmp MIBs\n+++++++++++++++++++++++++\n\nTry to borrow precompiled pysnmp MIB file(s) from a web-site.\n\n"
},
{
"path": "examples/borrow-precompiled-pysnmp-files-on-failure.py",
"chars": 1697,
"preview": "\"\"\"\nBorrow pysnmp MIBs on failure\n+++++++++++++++++++++++++++++\n\nLook up specific ASN.1 MIBs at configured Web/FTP sites"
},
{
"path": "examples/compile-smistar-mibs-into-pysnmp-files-if-needed.py",
"chars": 1917,
"preview": "\"\"\"\nCompile SMIv1/v2 MIBs\n+++++++++++++++++++++\n\nLook up specific ASN.1 MIBs at configured local directories,\ncompile th"
},
{
"path": "examples/compile-smiv2-mibs-from-text-into-pysnmp-code.py",
"chars": 1350,
"preview": "\"\"\"\nCompile SMIv2 MIBs\n++++++++++++++++++\n\nInvoke user callback function to provide MIB text,\ncompile given text string "
},
{
"path": "examples/download-and-compile-smistar-mibs-into-json.py",
"chars": 1452,
"preview": "\"\"\"\nCompile MIBs into JSON\n++++++++++++++++++++++\n\nLook up specific ASN.1 MIBs at configured Web and FTP sites,\ncompile "
},
{
"path": "examples/download-and-compile-smistar-mibs-into-pysnmp-files.py",
"chars": 1570,
"preview": "\"\"\"\nCompile MIBs from web\n+++++++++++++++++++++\n\nLook up specific ASN.1 MIBs at configured Web and FTP sites,\ncompile th"
},
{
"path": "pysmi/__init__.py",
"chars": 173,
"preview": "# http://www.python.org/dev/peps/pep-0396/\n__version__ = '0.4.0'\n\nimport sys\n\nif sys.version_info[:2] < (2, 4):\n rais"
},
{
"path": "pysmi/borrower/__init__.py",
"chars": 255,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/borrower/anyfile.py",
"chars": 300,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/borrower/base.py",
"chars": 1739,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/borrower/pyfile.py",
"chars": 615,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/__init__.py",
"chars": 292,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/base.py",
"chars": 18048,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/intermediate.py",
"chars": 33589,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2019, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/jfilters.py",
"chars": 253,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2019, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/jsondoc.py",
"chars": 5492,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/null.py",
"chars": 685,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/pysnmp.py",
"chars": 5766,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/symtable.py",
"chars": 21905,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/codegen/templates/jsondoc/base.j2",
"chars": 62,
"preview": "{% block jsondump %}\n{{ mib|tojson(indent=2) }}\n{% endblock %}"
},
{
"path": "pysmi/codegen/templates/pysnmp/base.j2",
"chars": 543,
"preview": "{% block init scoped %}\n{% endblock %}\n{% block docstring scoped %}\n\"\"\"SNMP MIB module ({{ mib['meta']['module'] }}) exp"
},
{
"path": "pysmi/codegen/templates/pysnmp/managed-objects-instances.j2",
"chars": 3545,
"preview": "{#\nThis template renders (commented out) Managed Objects Instances\nfor scalar and columnar Managed Objects.\n\nThe user is"
},
{
"path": "pysmi/codegen/templates/pysnmp/mib-definitions.j2",
"chars": 19012,
"preview": "{#\nThis template renders most of the MIB objects definitions but\nManaged Objects Instances.\n#}\n{% include \"pysnmp/base.j"
},
{
"path": "pysmi/codegen/templates/pysnmp/mib-instrumentation/managed-objects-instances.j2",
"chars": 6289,
"preview": "{#\nThis template renders MIB instrumentation hooks to the SMI classes\nrepresenting Managed Objects Instances for scalar "
},
{
"path": "pysmi/codegen/templates/pysnmp/mib-instrumentation/managed-objects.j2",
"chars": 5838,
"preview": "{#\nThis template renders MIB instrumentation hooks to the SMI classes\nrepresenting \"leaf\" Managed Objects (but not Manag"
},
{
"path": "pysmi/compat.py",
"chars": 655,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/compiler.py",
"chars": 21584,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/debug.py",
"chars": 3462,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/error.py",
"chars": 1732,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/lexer/__init__.py",
"chars": 194,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/lexer/base.py",
"chars": 243,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/lexer/smi.py",
"chars": 11888,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/mibinfo.py",
"chars": 822,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/__init__.py",
"chars": 352,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/base.py",
"chars": 318,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/dialect.py",
"chars": 630,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/null.py",
"chars": 396,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/smi.py",
"chars": 49556,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/smiv1.py",
"chars": 296,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/smiv1compat.py",
"chars": 350,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/parser/smiv2.py",
"chars": 296,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/__init__.py",
"chars": 435,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/base.py",
"chars": 1552,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/callback.py",
"chars": 1516,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/ftpclient.py",
"chars": 4755,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/httpclient.py",
"chars": 3910,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/localfile.py",
"chars": 4937,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/url.py",
"chars": 2734,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/reader/zipreader.py",
"chars": 5635,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/searcher/__init__.py",
"chars": 355,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/searcher/anyfile.py",
"chars": 1937,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/searcher/base.py",
"chars": 405,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/searcher/pyfile.py",
"chars": 3794,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/searcher/pypackage.py",
"chars": 5189,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/searcher/stub.py",
"chars": 1292,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/writer/__init__.py",
"chars": 295,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/writer/base.py",
"chars": 479,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/writer/callback.py",
"chars": 1521,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/writer/localfile.py",
"chars": 2597,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "pysmi/writer/pyfile.py",
"chars": 3332,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "requirements.txt",
"chars": 268,
"preview": "ply==3.4; python_version < '2.6'\nply; python_version >= '2.6'\nordereddict; python_version < '2.7'\nsimplejson; python_ver"
},
{
"path": "scripts/mibcopy.py",
"chars": 8583,
"preview": "#!/usr/bin/env python\n#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail."
},
{
"path": "scripts/mibdump.py",
"chars": 12811,
"preview": "#!/usr/bin/env python\n#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail."
},
{
"path": "setup.cfg",
"chars": 67,
"preview": "[bdist_wheel]\nuniversal = 1\n\n[metadata]\nlicense_file = LICENSE.rst\n"
},
{
"path": "setup.py",
"chars": 4189,
"preview": "#!/usr/bin/env python\n#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail."
},
{
"path": "test-requirements.txt",
"chars": 15,
"preview": "pysnmp>=4.3.10\n"
},
{
"path": "tests/__init__.py",
"chars": 59,
"preview": "# This file is necessary to make this directory a package.\n"
},
{
"path": "tests/__main__.py",
"chars": 950,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_agentcapabilities_smiv2_pysnmp.py",
"chars": 2651,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_imports_smiv2_pysnmp.py",
"chars": 1615,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_modulecompliance_smiv2_pysnmp.py",
"chars": 2275,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_moduleidentity_smiv2_pysnmp.py",
"chars": 3342,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_notificationgroup_smiv2_pysnmp.py",
"chars": 2326,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_notificationtype_smiv2_pysnmp.py",
"chars": 2270,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_objectgroup_smiv2_pysnmp.py",
"chars": 2452,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_objectidentity_smiv2_pysnmp.py",
"chars": 2221,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_objecttype_smiv2_pysnmp.py",
"chars": 17335,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_smiv1_smiv2_pysnmp.py",
"chars": 2361,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_traptype_smiv2_pysnmp.py",
"chars": 2249,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_typedeclaration_smiv1_pysnmp.py",
"chars": 2949,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_typedeclaration_smiv2_pysnmp.py",
"chars": 5387,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_valuedeclaration_smiv2_pysnmp.py",
"chars": 2668,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tests/test_zipreader.py",
"chars": 13262,
"preview": "#\n# This file is part of pysmi software.\n#\n# Copyright (c) 2015-2020, Ilya Etingof <etingof@gmail.com>\n# License: http:/"
},
{
"path": "tox.ini",
"chars": 2125,
"preview": "[tox]\nminversion = 3.4.0\nskip_missing_interpreters = true\nenvlist =\n {py27, py35, py36, py37, py38}-{unittest},\n c"
}
]
About this extraction
This page contains the full source code of the etingof/pysmi GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 134 files (428.9 KB), approximately 120.3k tokens, and a symbol index with 601 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.