trigger 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. trigger/__init__.py +7 -0
  2. trigger/acl/__init__.py +32 -0
  3. trigger/acl/autoacl.py +70 -0
  4. trigger/acl/db.py +324 -0
  5. trigger/acl/dicts.py +357 -0
  6. trigger/acl/grammar.py +112 -0
  7. trigger/acl/ios.py +222 -0
  8. trigger/acl/junos.py +422 -0
  9. trigger/acl/models.py +118 -0
  10. trigger/acl/parser.py +168 -0
  11. trigger/acl/queue.py +296 -0
  12. trigger/acl/support.py +1431 -0
  13. trigger/acl/tools.py +746 -0
  14. trigger/bin/__init__.py +0 -0
  15. trigger/bin/acl.py +233 -0
  16. trigger/bin/acl_script.py +574 -0
  17. trigger/bin/aclconv.py +82 -0
  18. trigger/bin/check_access.py +93 -0
  19. trigger/bin/check_syntax.py +66 -0
  20. trigger/bin/fe.py +197 -0
  21. trigger/bin/find_access.py +191 -0
  22. trigger/bin/gnng.py +434 -0
  23. trigger/bin/gong.py +86 -0
  24. trigger/bin/load_acl.py +841 -0
  25. trigger/bin/load_config.py +18 -0
  26. trigger/bin/netdev.py +317 -0
  27. trigger/bin/optimizer.py +638 -0
  28. trigger/bin/run_cmds.py +18 -0
  29. trigger/changemgmt/__init__.py +352 -0
  30. trigger/changemgmt/bounce.py +57 -0
  31. trigger/cmds.py +1217 -0
  32. trigger/conf/__init__.py +94 -0
  33. trigger/conf/global_settings.py +674 -0
  34. trigger/contrib/__init__.py +7 -0
  35. trigger/exceptions.py +307 -0
  36. trigger/gorc.py +172 -0
  37. trigger/netdevices/__init__.py +1288 -0
  38. trigger/netdevices/loader.py +174 -0
  39. trigger/netscreen.py +1030 -0
  40. trigger/packages/__init__.py +6 -0
  41. trigger/packages/peewee.py +8084 -0
  42. trigger/rancid.py +463 -0
  43. trigger/tacacsrc.py +584 -0
  44. trigger/twister.py +2203 -0
  45. trigger/twister2.py +745 -0
  46. trigger/utils/__init__.py +88 -0
  47. trigger/utils/cli.py +349 -0
  48. trigger/utils/importlib.py +77 -0
  49. trigger/utils/network.py +157 -0
  50. trigger/utils/rcs.py +178 -0
  51. trigger/utils/templates.py +81 -0
  52. trigger/utils/url.py +78 -0
  53. trigger/utils/xmltodict.py +298 -0
  54. trigger-2.0.0.dist-info/METADATA +146 -0
  55. trigger-2.0.0.dist-info/RECORD +61 -0
  56. trigger-2.0.0.dist-info/WHEEL +5 -0
  57. trigger-2.0.0.dist-info/entry_points.txt +15 -0
  58. trigger-2.0.0.dist-info/licenses/AUTHORS.md +20 -0
  59. trigger-2.0.0.dist-info/licenses/LICENSE.md +28 -0
  60. trigger-2.0.0.dist-info/top_level.txt +2 -0
  61. twisted/plugins/trigger_xmlrpc.py +124 -0
@@ -0,0 +1,174 @@
1
+ """
2
+ Wrapper for loading metadata from storage of some sort (e.g. filesystem,
3
+ database)
4
+
5
+ This uses NETDEVICE_LOADERS settings, which is a list of loaders to use.
6
+ Each loader is expected to have this interface::
7
+
8
+ callable(data_source, **kwargs)
9
+
10
+ ``data_source`` is typically a file path from which to load the metadata, but can
11
+ be also be a list/tuple of [data_source, *args]
12
+ ``kwargs`` are any optional keyword arguments you wish to send along.
13
+
14
+ The loader must return an iterable of key/value pairs (dicts, 2-tuples, etc.).
15
+
16
+ Each loader should have an ``is_usable`` attribute set. This is a boolean that
17
+ specifies whether the loader can be used with this Python installation. Each
18
+ loader is responsible for setting this when it is initialized.
19
+
20
+ This code is based on Django's template loader code: http://bit.ly/WWOLU3
21
+ """
22
+
23
+ from collections import namedtuple
24
+
25
+ from twisted.python import log
26
+
27
+ from trigger.conf import settings
28
+ from trigger.exceptions import ImproperlyConfigured, LoaderFailed
29
+ from trigger.utils.importlib import import_module
30
+
31
+ # Exports
32
+ __all__ = ("BaseLoader", "load_metadata")
33
+
34
+
35
+ # Classes
36
+ class BaseLoader:
37
+ is_usable = False
38
+
39
+ def __init__(self, *args, **kwargs):
40
+ pass
41
+
42
+ def __call__(self, data_source, **kwargs):
43
+ return self.load_data(data_source, **kwargs)
44
+
45
+ def load_data(self, data_source, **kwargs):
46
+ data = self.load_data_source(data_source, **kwargs)
47
+ return data
48
+
49
+ def load_data_source(self, data_source, **kwargs):
50
+ """
51
+ Returns an iterable of key/value pairs for the given ``data_source``.
52
+ """
53
+ raise NotImplementedError
54
+
55
+ def reset(self):
56
+ """
57
+ Resets any state maintained by the loader instance.
58
+ """
59
+ pass
60
+
61
+
62
+ # Functions
63
+ def find_data_loader(loader):
64
+ """
65
+ Given a ``loader`` string/list/tuple, try to unpack, load it, and return the
66
+ callable loader object.
67
+
68
+ If ``loader`` is specified as string, treat it as the fully-qualified
69
+ Python path to the callable Loader object.
70
+
71
+ Optionally, if `loader`` is a list/tuple, the first item in the tuple should be the
72
+ Loader's module path, and subsequent items are passed to the Loader object
73
+ during initialization. This could be useful in initializing a custom Loader
74
+ for a database backend, for example.
75
+
76
+ :param loader:
77
+ A string represnting the Python path to a Loader object, or list/tuple
78
+ of loader path and args to pass to the Loader.
79
+ """
80
+ if isinstance(loader, (tuple, list)):
81
+ loader, args = loader[0], loader[1:]
82
+ else:
83
+ args = []
84
+
85
+ log.msg(f"BUILDING LOADER: {loader}; WITH ARGS: {args}")
86
+ err_template = "Error importing data source loader %s: '%s'"
87
+ if isinstance(loader, str):
88
+ module, attr = loader.rsplit(".", 1)
89
+ try:
90
+ mod = import_module(module)
91
+ except ImportError as err:
92
+ raise ImproperlyConfigured(err_template % (loader, err))
93
+
94
+ try:
95
+ DataLoader = getattr(mod, attr)
96
+ except AttributeError as err:
97
+ raise ImproperlyConfigured(err_template % (loader, err))
98
+
99
+ if hasattr(DataLoader, "load_data_source"):
100
+ func = DataLoader(*args)
101
+ else:
102
+ # Try loading module the old-fashioned way where string is full
103
+ # path to callabale.
104
+ if args:
105
+ raise ImproperlyConfigured(
106
+ f"Error importing data source loader {loader}: Can't pass arguments to function-based loader!"
107
+ )
108
+ func = DataLoader
109
+
110
+ if not func.is_usable:
111
+ import warnings
112
+
113
+ warnings.warn(
114
+ f"Your NETDEVICES_LOADERS setting includes {loader!r}, but your Python installation doesn't support that type of data loading. Consider removing that line from NETDEVICES_LOADERS."
115
+ )
116
+ return None
117
+ else:
118
+ return func
119
+ else:
120
+ raise ImproperlyConfigured(
121
+ 'Loader does not define a "load_data" callable data source loader.'
122
+ )
123
+
124
+
125
+ #: Namedtuple that holds loader instance and device metadata
126
+ LoaderMetadata = namedtuple("LoaderMetadata", "loader metadata")
127
+
128
+
129
+ def load_metadata(data_source, **kwargs):
130
+ """
131
+ Iterate thru data loaders to load metadata.
132
+
133
+ Loaders should return an iterable of dict/2-tuples or ``None``. It will try
134
+ each one until it can return data. The first one to return data wins.
135
+
136
+ :param data_source:
137
+ Typically a file path, but it can be any data format you desire that
138
+ can be passed onto a Loader object to retrieve metadata.
139
+
140
+ :param kwargs:
141
+ Optional keyword arguments you wish to pass to the Loader.
142
+
143
+ :returns:
144
+ `~trigger.netdevices.loader.LoaderMetadata` instance
145
+ """
146
+ # Iterate and build a loader callables, call them, stop when we get data.
147
+ tried = []
148
+ log.msg("LOADING DATA FROM:", data_source)
149
+ for loader_name in settings.NETDEVICES_LOADERS:
150
+ loader = find_data_loader(loader_name)
151
+ log.msg("TRYING LOADER:", loader)
152
+ if loader is None:
153
+ log.msg("CANNOT USE LOADER:", loader)
154
+ continue
155
+
156
+ try:
157
+ # Pass the args to the loader!
158
+ data = loader(data_source, **kwargs)
159
+ log.msg("LOADER: SUCCESS!")
160
+ except LoaderFailed as err:
161
+ tried.append(loader)
162
+ log.msg(f"LOADER - FAILURE: {err}")
163
+ continue
164
+ else:
165
+ # Successfully parsed (we hope)
166
+ if data is not None:
167
+ log.msg(f"LOADERS TRIED: {tried!r}")
168
+ return LoaderMetadata(loader, data)
169
+ else:
170
+ tried.append(loader)
171
+ continue
172
+
173
+ # All loaders failed. We don't want to get to this point!
174
+ raise RuntimeError(f"No data loaders succeeded. Tried: {tried!r}")