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,674 @@
1
+ # Default Trigger settings. Override these with settings in the module
2
+ # pointed-to by the TRIGGER_SETTINGS environment variable. This is pretty much
3
+ # an exact duplication of how Django does this.
4
+
5
+ import os
6
+ import socket
7
+
8
+ import IPy
9
+
10
+ # ===============================
11
+ # Global Settings
12
+ # ===============================
13
+
14
+ # This is where Trigger should look for its files.
15
+ PREFIX = "/etc/trigger"
16
+
17
+ # Set to True to enable GPG Authentication
18
+ # Set to False to use the old .tackf encryption method.
19
+ # Should be False unless instructions/integration is ready for GPG
20
+ USE_GPG_AUTH = False
21
+
22
+ # This is used for old auth method. It sucks and needs to die.
23
+ # TODO (jathan): This is deprecated. Remove all references to this and make GPG
24
+ # the default and only method.
25
+ USER_HOME = os.getenv("HOME")
26
+ TACACSRC = os.getenv("TACACSRC", os.path.join(USER_HOME, ".tacacsrc"))
27
+ TACACSRC_KEYFILE = os.getenv("TACACSRC_KEYFILE", os.path.join(PREFIX, ".tackf"))
28
+
29
+ # If set, use the TACACSRC_PASSPHRASE, otherwise default to TACACSRC_KEYFILE
30
+ TACACSRC_USE_PASSPHRASE = False
31
+
32
+ # Use this passphrase to encrypt credentials.CHANGE THIS IN YOUR FILE BEFORE
33
+ # USING THIS IN YOUR ENVIRONMENT.
34
+ TACACSRC_PASSPHRASE = ""
35
+
36
+ # Default login realm to store user credentials (username, password) for
37
+ # general use within the .tacacsrc
38
+ DEFAULT_REALM = "aol"
39
+
40
+ # Default terminal type of xterm if TERM isn't set
41
+ TERM_TYPE = os.getenv("TERM", "xterm")
42
+
43
+ # List of plugins allowed to be importd by Commando. Plugins should be listed as
44
+ # strings depicting the absolute paths.
45
+ #
46
+ # e.g. ['trigger.contrib.config_device', 'trigger.contrib.show_clock', 'bacon.cool_plugin']
47
+ #
48
+ # Currently config_device and execute_commands are automatically imported.
49
+ BUILTIN_PLUGINS = [
50
+ "trigger.contrib.commando.plugins.config_device",
51
+ "trigger.contrib.commando.plugins.show_clock",
52
+ "trigger.contrib.commando.plugins.show_version",
53
+ ]
54
+ COMMANDO_PLUGINS = BUILTIN_PLUGINS
55
+
56
+ # Location of firewall policies
57
+ FIREWALL_DIR = "/data/firewalls"
58
+
59
+ # Location of tftproot.
60
+ TFTPROOT_DIR = "/data/tftproot"
61
+ TFTP_HOST = ""
62
+
63
+ # Add internally owned networks here. All network blocks owned/operated and
64
+ # considered part of your network should be included.
65
+ INTERNAL_NETWORKS = [
66
+ IPy.IP("10.0.0.0/8"),
67
+ IPy.IP("172.16.0.0/12"),
68
+ IPy.IP("192.168.0.0/16"),
69
+ ]
70
+
71
+ # A dictionary keyed by manufacturer name containing a list of the device types
72
+ # for each that is officially supported by Trigger.
73
+ SUPPORTED_PLATFORMS = {
74
+ "a10": ["SWITCH"],
75
+ "arista": ["SWITCH"], # Your "Cloud" network vendor
76
+ "aruba": ["SWITCH"], # Aruba Wi-Fi controllers
77
+ "avocent": ["CONSOLE"],
78
+ "brocade": ["ROUTER", "SWITCH"],
79
+ "cisco": ["ROUTER", "SWITCH", "FIREWALL"],
80
+ "citrix": ["SWITCH"], # Assumed to be NetScalers
81
+ "cumulus": ["SWITCH"], # Any white-label hardware running Cumulus Linux
82
+ "dell": ["SWITCH"],
83
+ "f5": ["LOAD_BALANCER", "SWITCH"],
84
+ "force10": ["ROUTER", "SWITCH"],
85
+ "foundry": ["ROUTER", "SWITCH"],
86
+ "juniper": ["FIREWALL", "ROUTER", "SWITCH"], # Any devices running Junos
87
+ "mrv": ["CONSOLE", "SWITCH"],
88
+ "netscreen": ["FIREWALL"], # Pre-Juniper NetScreens
89
+ "paloalto": ["FIREWALL"],
90
+ "pica8": ["ROUTER", "SWITCH"],
91
+ }
92
+
93
+ # List of supported vendor names derived from SUPPORTED_PLATFORMS
94
+ SUPPORTED_VENDORS = list(SUPPORTED_PLATFORMS)
95
+ VALID_VENDORS = SUPPORTED_VENDORS # For backwards compatibility
96
+
97
+ # A mapping of manufacturer attribute values to canonical vendor name used by
98
+ # Trigger. These single-word, lowercased canonical names are used throughout
99
+ # Trigger.
100
+ #
101
+ # If your internal definition differs from the UPPERCASED ones specified below
102
+ # (which they probably do), customize them here.
103
+ VENDOR_MAP = {
104
+ "A10 NETWORKS": "a10",
105
+ "ARISTA NETWORKS": "arista",
106
+ "ARUBA NETWORKS": "aruba",
107
+ "AVOCENT": "avocent",
108
+ "BROCADE": "brocade",
109
+ "CELESTICA": "cumulus",
110
+ "CISCO SYSTEMS": "cisco",
111
+ "CITRIX": "citrix",
112
+ "CUMULUS": "cumulus",
113
+ "DELL": "dell",
114
+ "F5 NETWORKS": "f5",
115
+ "FORCE10": "force10",
116
+ "FOUNDRY": "foundry",
117
+ "JUNIPER": "juniper",
118
+ "MRV": "mrv",
119
+ "NETSCREEN TECHNOLOGIES": "netscreen",
120
+ "PICA8": "pica8",
121
+ }
122
+
123
+ # The tuple of support device types
124
+ SUPPORTED_TYPES = ("CONSOLE", "DWDM", "FIREWALL", "LOAD_BALANCER", "ROUTER", "SWITCH")
125
+
126
+ # A mapping of of vendor names to the default device type for each in the
127
+ # event that a device object is created and the deviceType attribute isn't set
128
+ # for some reason.
129
+ DEFAULT_TYPES = {
130
+ "a10": "SWITCH",
131
+ "arista": "SWITCH",
132
+ "aruba": "SWITCH",
133
+ "avocent": "CONSOLE",
134
+ "brocade": "SWITCH",
135
+ "citrix": "SWITCH",
136
+ "cisco": "ROUTER",
137
+ "cumulus": "SWITCH",
138
+ "dell": "SWITCH",
139
+ "f5": "LOAD_BALANCER",
140
+ "force10": "ROUTER",
141
+ "foundry": "SWITCH",
142
+ "juniper": "ROUTER",
143
+ "mrv": "CONSOLE",
144
+ "netscreen": "FIREWALL",
145
+ "paloalto": "FIREWALL",
146
+ "pica8": "SWITCH",
147
+ }
148
+
149
+ # When a vendor is not explicitly defined within `DEFAULT_TYPES`, fallback to
150
+ # this type.
151
+ FALLBACK_TYPE = "ROUTER"
152
+
153
+ # When a manufacturer/vendor is not explicitly defined, fallback to to this
154
+ # value.
155
+ FALLBACK_MANUFACTURER = "UNKNOWN"
156
+
157
+ # ===============================
158
+ # Twister
159
+ # ===============================
160
+
161
+ # Default timeout in seconds for commands executed during a session. If a
162
+ # response is not received within this window, the connection is terminated.
163
+ DEFAULT_TIMEOUT = 5 * 60
164
+
165
+ # Default timeout in seconds for initial telnet connections.
166
+ TELNET_TIMEOUT = 60
167
+
168
+ # Whether or not to allow telnet fallback
169
+ TELNET_ENABLED = True
170
+
171
+ # Default ports for SSH
172
+ SSH_PORT = 22
173
+
174
+ # Default port for Telnet
175
+ TELNET_PORT = 23
176
+
177
+ # The preferred order in which SSH authentication methods are tried.
178
+ SSH_AUTHENTICATION_ORDER = ["password", "keyboard-interactive", "publickey"]
179
+
180
+ # A mapping of vendors to the types of devices for that vendor for which you
181
+ # would like to disable interactive (pty) SSH sessions, such as when using
182
+ # bin/gong.
183
+ SSH_PTY_DISABLED = {
184
+ "dell": ["SWITCH"], # Dell SSH is just straight up broken
185
+ }
186
+
187
+ # A mapping of vendors to the types of devices for that vendor for which you
188
+ # would like to disable asynchronous (NON-interactive) SSH sessions, such as
189
+ # when using twister or Commando to remotely control a device.
190
+ SSH_ASYNC_DISABLED = {
191
+ "dell": ["SWITCH"], # Dell SSH is just straight up broken
192
+ "foundry": ["SWITCH"], # Old Foundry switches only do SSHv1
193
+ }
194
+
195
+ # Vendors that basically just emulate Cisco's IOS and can be treated
196
+ # accordingly for the sake of interaction.
197
+ IOSLIKE_VENDORS = (
198
+ "a10",
199
+ "arista",
200
+ "aruba",
201
+ "brocade",
202
+ "cisco",
203
+ "cumulus",
204
+ "dell",
205
+ "force10",
206
+ "foundry",
207
+ )
208
+
209
+ # Commands executed on devices by default.
210
+ STARTUP_COMMANDS_DEFAULT = ["terminal length 0"]
211
+
212
+ # Startup commands are executed upon login to setup the terminal session for
213
+ # automated execution. Typically these are just to disable pagination or other
214
+ # settings related to capturing output asynchronously. Each vendor is mapped by
215
+ # name. Vendor platforms with differing startup commands based on their device
216
+ # type are now mapped with an underscore separation (e.g. 'Cisco ASA' becomes
217
+ # 'cisco_asa'). The platform-specific lookups are still done in code for now.
218
+ STARTUP_COMMANDS_MAP = {
219
+ "a10": STARTUP_COMMANDS_DEFAULT,
220
+ "arista": STARTUP_COMMANDS_DEFAULT + ["terminal width 999"],
221
+ "aruba": ["no paging"], # v6.2.x this is not necessary
222
+ "brocade": ["skip-page-display"],
223
+ "brocade_vdx": STARTUP_COMMANDS_DEFAULT,
224
+ "cisco": STARTUP_COMMANDS_DEFAULT,
225
+ "cisco_asa": ["terminal pager 0"],
226
+ "citrix": ["set cli mode page off"],
227
+ "cumulus": [], # No startup commands for Cumulus by default!
228
+ "dell": ["terminal datadump"],
229
+ "f5": ["modify cli preference pager disabled"],
230
+ "force10": STARTUP_COMMANDS_DEFAULT,
231
+ "foundry": ["skip-page-display"],
232
+ "juniper": ["set cli screen-length 0"],
233
+ "mrv": ["no pause"],
234
+ "netscreen": ["set console page 0"],
235
+ "paloalto": ["set cli scripting-mode on", "set cli pager off"],
236
+ }
237
+
238
+ # Prompts sent by devices that indicate the device is awaiting user
239
+ # confirmation when interacting with the device. If a continue prompt is
240
+ # detected, Trigger will temporarily set this value to the prompt and send
241
+ # along the next command (for example if you're expecting such a prompt and you
242
+ # want to send along "yes"). These should be as specific as possible because we
243
+ # want to make sure bad things don't happen.
244
+ CONTINUE_PROMPTS = [
245
+ "continue?",
246
+ "proceed?",
247
+ "(y/n):",
248
+ "[y/n]:",
249
+ "[confirm]",
250
+ "[yes/no]: ",
251
+ "overwrite file [startup-config] ?[yes/press any key for no]....",
252
+ "Destination filename [running-config]? ",
253
+ ]
254
+
255
+ # The file path where .gorc is expected to be found.
256
+ GORC_FILE = "~/.gorc"
257
+
258
+ # The only root commands that are allowed to be executed when defined within
259
+ # ``~.gorc``. They will be filtered out by `~trigger.gorc.filter_commands()`.
260
+ GORC_ALLOWED_COMMANDS = (
261
+ "cli",
262
+ "enable",
263
+ "exit",
264
+ "get",
265
+ "monitor",
266
+ "ping",
267
+ "quit",
268
+ "set",
269
+ "show",
270
+ "start",
271
+ "term",
272
+ "terminal",
273
+ "traceroute",
274
+ "who",
275
+ "whoami",
276
+ )
277
+
278
+ # ===============================
279
+ # NetDevices
280
+ # ===============================
281
+
282
+ # Globally toggle whether to load ACL associations from the Redis database. If
283
+ # you don't have Redis or aren't using Trigger to manage ACLs set this to
284
+ # False.
285
+ WITH_ACLS = False
286
+
287
+ # The default administrative status (production vs. non-production) of new
288
+ # devices.
289
+ DEFAULT_ADMIN_STATUS = "PRODUCTION"
290
+
291
+ # Path to the explicit module file for autoacl.py so that we can still perform
292
+ # 'from trigger.acl.autoacl import autoacl' without modifying sys.path.
293
+ AUTOACL_FILE = os.environ.get("AUTOACL_FILE", os.path.join(PREFIX, "autoacl.py"))
294
+
295
+ # A tuple of data loader classes, specified as strings. Optionally, a tuple can
296
+ # be used instead of a string. The first item in the tuple should be the
297
+ # Loader's module, subsequent items are passed to the Loader during
298
+ # initialization.
299
+ NETDEVICES_LOADERS = (
300
+ "trigger.netdevices.loaders.filesystem.JSONLoader",
301
+ "trigger.netdevices.loaders.filesystem.XMLLoader",
302
+ "trigger.netdevices.loaders.filesystem.SQLiteLoader",
303
+ "trigger.netdevices.loaders.filesystem.RancidLoader",
304
+ "trigger.netdevices.loaders.filesystem.CSVLoader",
305
+ )
306
+
307
+ # A path or URL to netdevices device metadata source data, which is used to
308
+ # populate trigger.netdevices.NetDevices. For more information on this, see
309
+ # NETDEVICES_LOADERS.
310
+ NETDEVICES_SOURCE = os.environ.get(
311
+ "NETDEVICES_SOURCE", os.path.join(PREFIX, "netdevices.json")
312
+ )
313
+
314
+ # TextFSM Vendor Mappings. Override this if you have defined your own TextFSM
315
+ # templates.
316
+ TEXTFSM_VENDOR_MAPPINGS = {"cisco": ["ios", "nxos"], "arista": ["eos"]}
317
+
318
+ # TextFSM Template Path. Commando will attempt to match a given show command
319
+ # with a template within this folder.
320
+ TEXTFSM_TEMPLATE_DIR = os.getenv(
321
+ "TEXTFSM_TEMPLATE_DIR", os.path.join(PREFIX, "vendor/ntc_templates")
322
+ )
323
+
324
+ # TextFSM Vendor Mappings. Override this if you have defined your own TextFSM templates.
325
+ TEXTFSM_VENDOR_MAPPINGS = {"cisco": ["ios", "nxos"], "arista": ["eos"]}
326
+
327
+ # TextFSM Template Path. Commando will attempt to match a given show command with a template within this folder.
328
+ TEXTFSM_TEMPLATE_DIR = os.getenv(
329
+ "TEXTFSM_TEMPLATE_DIR", os.path.join(PREFIX, "vendor/ntc_templates")
330
+ )
331
+
332
+ # Whether to treat the RANCID root as a normal instance, or as the root to
333
+ # multiple instances. This is only checked when using RANCID as a data source.
334
+ RANCID_RECURSE_SUBDIRS = os.environ.get("RANCID_RECURSE_SUBDIRS", False)
335
+
336
+ # Valid owning teams (e.g. device.owningTeam) go here. These are examples and
337
+ # should be changed to match your environment.
338
+ VALID_OWNERS = (
339
+ #'Data Center',
340
+ #'Backbone Engineering',
341
+ #'Enterprise Networking',
342
+ )
343
+
344
+ # Fields and values defined here will dictate which Juniper devices receive a
345
+ # ``commit-configuration full`` when populating ``NetDevice.commit_commands`.
346
+ # The fields and values must match the objects exactly or it will fallback to
347
+ # ``commit-configuration``.
348
+ JUNIPER_FULL_COMMIT_FIELDS = {
349
+ #'deviceType': 'SWITCH',
350
+ #'make': 'EX4200',
351
+ }
352
+
353
+ # ===============================
354
+ # Prompt Patterns
355
+ # ===============================
356
+ # Specially-defined, per-vendor prompt patterns. If a vendor isn't defined here,
357
+ # try to use IOSLIKE_PROMPT_PAT or fallback to DEFAULT_PROMPT_PAT.
358
+ PROMPT_PATTERNS = {
359
+ "aruba": r"\(\S+\)(?: \(\S+\))?\s?#$", # ArubaOS 6.1
360
+ #'aruba': r'\S+(?: \(\S+\))?\s?#\s$', # ArubaOS 6.2
361
+ "avocent": r"\S+[#\$]|->\s?$",
362
+ "citrix": r"\sDone\n$",
363
+ # This pattern is a regex "or" combination of the Cumulus bash login prompt
364
+ # and IOSLIKE_PROMPT_PAT (for vtysh support)
365
+ "cumulus": r"(?:\S+(\(config(-[a-z:1-9]+)?\))?[\r\s]*#[\s\b]*$)|(?:.*(?:\$|#)\s?$)",
366
+ "f5": r".*\(tmos\).*?#\s{1,2}\r?$",
367
+ "juniper": r"(?:\S+\@)?\S+(?:\>|#)\s$",
368
+ "mrv": r"\r\n?.*(?:\:\d{1})?\s\>\>?$",
369
+ "netscreen": r"(\w+?:|)[\w().-]*\(?([\w.-])?\)?\s*->\s*$",
370
+ "paloalto": r"\r\n\S+(?:\>|#)\s?$",
371
+ "pica8": r"\S+(?:\>|#)\s?$",
372
+ }
373
+
374
+ # When a pattern is not explicitly defined for a vendor, this is what we'll try
375
+ # next (since most vendors are in fact IOS-like).
376
+ IOSLIKE_PROMPT_PAT = r"\S+(\(config(-[a-z:1-9]+)?\))?[\r\s]*#[\s\b]*$"
377
+ IOSLIKE_ENABLE_PAT = r"\S+(\(config(-[a-z:1-9]+)?\))?[\r\s]*>[\s\b]*$"
378
+
379
+ # Generic prompt to match most vendors. It assumes that you'll be greeted with
380
+ # a "#" prompt.
381
+ DEFAULT_PROMPT_PAT = r"\S+#\s?$"
382
+
383
+ # ===============================
384
+ # Bounce Windows/Change Mgmt
385
+ # ===============================
386
+
387
+ # Path of the explicit module file for bounce.py containing custom bounce
388
+ # window mappings.
389
+ BOUNCE_FILE = os.environ.get("BOUNCE_FILE", os.path.join(PREFIX, "bounce.py"))
390
+
391
+ # Default bounce timezone. All BounceWindow objects are configured using
392
+ # US/Eastern for now.
393
+ BOUNCE_DEFAULT_TZ = "US/Eastern"
394
+
395
+ # The default fallback window color for bounce windows. Must be one of
396
+ # ('green', 'yellow', or 'red').
397
+ #
398
+ # green: Low risk
399
+ # yellow: Medium risk
400
+ # red: High risk
401
+ BOUNCE_DEFAULT_COLOR = "red"
402
+
403
+ # ===============================
404
+ # Redis Settings
405
+ # ===============================
406
+
407
+ # Redis master server. This will be used unless it is unreachable.
408
+ REDIS_HOST = "127.0.0.1"
409
+
410
+ # The Redis port. Default is 6379.
411
+ REDIS_PORT = 6379
412
+
413
+ # The Redis DB. Default is 0.
414
+ REDIS_DB = 0
415
+
416
+ # ===============================
417
+ # Database Settings
418
+ # ===============================
419
+
420
+ # These are self-explanatory, I hope. Use the ``init_task_db`` to initialize
421
+ # your database after you've created it! :)
422
+ DATABASE_ENGINE = "mysql" # Choose 'postgresql', 'mysql', 'sqlite3'
423
+ DATABASE_NAME = "" # Or path to database file if using sqlite3
424
+ DATABASE_USER = "" # Not used with sqlite3
425
+ DATABASE_PASSWORD = "" # Not used with sqlite3
426
+ DATABASE_HOST = "" # Set to '' for localhost. Not used with sqlite3
427
+ DATABASE_PORT = "" # Set to '' for default. Not used with sqlite3.
428
+
429
+ # ===============================
430
+ # ACL Management
431
+ # ===============================
432
+ # Whether to allow multi-line comments to be used in Juniper firewall filters.
433
+ # Defaults to False.
434
+ ALLOW_JUNIPER_MULTILINE_COMMENTS = False
435
+
436
+ # FILTER names of ACLs that should be skipped or ignored by tools
437
+ # NOTE: These should be the names of the filters as they appear on devices. We
438
+ # want this to be mutable so it can be modified at runtime.
439
+ # TODO (jathan): Move this into Redis and maintain with 'acl' command?
440
+ IGNORED_ACLS = []
441
+
442
+ # FILE names ACLs that shall not be modified by tools
443
+ # NOTE: These should be the names of the files as they exist in FIREWALL_DIR.
444
+ # Trigger expects ACLs to be prefixed with 'acl.'. These are examples and
445
+ # should be replaced.
446
+ NONMOD_ACLS = []
447
+
448
+ # Mapping of real IP to external NAT. This is used by load_acl in the event
449
+ # that a TFTP or connection from a real IP fails or explicitly when passing the
450
+ # --no-vip flag.
451
+ # format: {local_ip: external_ip}
452
+ VIPS = {}
453
+
454
+ # ===============================
455
+ # ACL Loading/Rate-Limiting
456
+ # ===============================
457
+ # All of the following settings are currently only used in ``load_acl``. If
458
+ # and when the load_acl functionality gets moved into the API, this might
459
+ # change.
460
+
461
+ # Any FILTER name (not filename) in this list will be skipped during automatic loads.
462
+ AUTOLOAD_BLACKLIST = []
463
+
464
+ # Assign blacklist to filter for backwards compatibility
465
+ AUTOLOAD_FILTER = AUTOLOAD_BLACKLIST
466
+
467
+ # Modify this if you want to create a list that if over the specified number of
468
+ # routers will be treated as bulk loads.
469
+ # TODO (jathan): Provide examples so that this has more context/meaning. The
470
+ # current implementation is kind of broken and doesn't scale for data centers
471
+ # with a large of number of devices.
472
+ #
473
+ # Format:
474
+ # { 'filter_name': threshold_count }
475
+ AUTOLOAD_FILTER_THRESH = {}
476
+
477
+ # Any ACL applied on a number of devices >= to this number will be treated as
478
+ # bulk loads.
479
+ AUTOLOAD_BULK_THRESH = 10
480
+
481
+ # Add an acl:max_hits here if you want to override BULK_MAX_HITS_DEFAULT
482
+ # Keep in mind this number is PER EXECUTION of load_acl --auto (typically once
483
+ # per hour or 3 per bounce window).
484
+ #
485
+ # 1 per load_acl execution; ~3 per day, per bounce window
486
+ # 2 per load_acl execution; ~6 per day, per bounce window
487
+ # etc.
488
+ #
489
+ # Format:
490
+ # { 'filter_name': max_hits }
491
+ BULK_MAX_HITS = {}
492
+
493
+ # If an ACL is bulk but not in BULK_MAX_HITS, use this number as max_hits
494
+ BULK_MAX_HITS_DEFAULT = 1
495
+
496
+
497
+ # ===============================
498
+ # Stage ACL changes
499
+ # ===============================
500
+ # This variable should be a function that returns the contents of the ACL
501
+ # files that are being pushed and the tftp location for all of them
502
+ #
503
+ # input
504
+ # list of file names, optional log file and boolean for sanitizing
505
+ #
506
+ # return
507
+ # (
508
+ # [<list of string of file contents an each file to push>],
509
+ # [<list of the path to files on the tftp server to push>],
510
+ # [<list of files that failed to stage>]
511
+ # )
512
+ def _stage_acls(acls, log=None, sanitize_acl=False):
513
+ """stage the new ACL files for load_acl"""
514
+
515
+ import os
516
+ import shutil
517
+
518
+ from trigger.acl import parse as acl_parse
519
+ from trigger.conf import settings
520
+
521
+ acl_contents = []
522
+ tftp_paths = []
523
+
524
+ fails = []
525
+
526
+ for acl in acls:
527
+ nonce = os.urandom(8).encode("hex")
528
+ acl_nonce = f"{acl}.{nonce}"
529
+ src_file = os.path.join(settings.FIREWALL_DIR, acl)
530
+ dst_file = os.path.join(settings.TFTPROOT_DIR, acl_nonce)
531
+
532
+ if not os.path.exists(dst_file):
533
+ try:
534
+ shutil.copyfile(src_file, dst_file)
535
+ except Exception:
536
+ fails.append(f"Unable to stage TFTP File {str(acls)}")
537
+ continue
538
+ else:
539
+ os.chmod(dst_file, 0o644)
540
+
541
+ with open(src_file) as src_acl:
542
+ file_contents = src_acl.read()
543
+ acl_contents.append(file_contents)
544
+
545
+ tftp_paths.append(acl_nonce)
546
+
547
+ # strip comments if brocade
548
+ if sanitize_acl:
549
+ msg = f"Sanitizing ACL {src_file} as {dst_file}"
550
+ log.msg(msg)
551
+ aclobj = acl_parse(file_contents)
552
+ aclobj.strip_comments()
553
+ output = "\n".join(aclobj.output(replace=True)) + "\n"
554
+ with open(dst_file, "w") as dst_acl:
555
+ dst_acl.write(output)
556
+
557
+ return acl_contents, tftp_paths, fails
558
+
559
+
560
+ STAGE_ACLS = _stage_acls
561
+
562
+
563
+ # ===============================
564
+ # Get the TFTP source
565
+ # ===============================
566
+ def _get_tftp_source(dev=None, no_vip=True): # False): #True):
567
+ """
568
+ Determine the right TFTP source-address to use (public vs. private)
569
+ based on ``settings.VIPS``, and return that address.
570
+
571
+ :param dev:
572
+ A `~trigger.netdevices.NetDevice` object
573
+ """
574
+ import socket
575
+
576
+ from trigger.conf import settings
577
+
578
+ host = socket.gethostbyname(socket.getfqdn())
579
+
580
+ if no_vip:
581
+ return host
582
+ elif host not in settings.VIPS:
583
+ return host
584
+
585
+ return settings.VIPS[host]
586
+
587
+
588
+ GET_TFTP_SOURCE = _get_tftp_source
589
+
590
+
591
+ # ===============================
592
+ # OnCall Engineer Display
593
+ # ===============================
594
+ # This should be a callable that returns data for your on-call engineer, or
595
+ # failing that None. The function should return a dictionary that looks like
596
+ # this:
597
+ #
598
+ # {'username': 'joegineer',
599
+ # 'name': 'Joe Engineer',
600
+ # 'email': 'joe.engineer@example.notreal'}
601
+ #
602
+ # If you want to disable it, just have it return a non-False value.
603
+ # If you want to use it and have it block, have it return a False value (such
604
+ # as None)
605
+ #
606
+ # This example is just providing a string that indicates that on-call lookup is
607
+ # disabled.
608
+ #
609
+ # Default: returns 'disabled'
610
+ def _get_current_oncall_stub(*args, **kwargs):
611
+ return "disabled"
612
+
613
+
614
+ GET_CURRENT_ONCALL = _get_current_oncall_stub
615
+
616
+
617
+ # ===============================
618
+ # CM Ticket Creation
619
+ # ===============================
620
+ # This should be a callable that creates a CM ticket and returns the ticket
621
+ # number.
622
+ #
623
+ # If you want to disable it, just have it return a non-False value.
624
+ # If you want to use it and have it block, have it return a False value (such
625
+ # as None)
626
+ #
627
+ # This example is just providing a string that indicates that CM ticket
628
+ # creation is disabled.
629
+ #
630
+ # Default: returns ' N/A (CM ticket creation is disabled)'
631
+ def _create_cm_ticket_stub(*args, **kwargs):
632
+ return " N/A (CM ticket creation is disabled)"
633
+
634
+
635
+ CREATE_CM_TICKET = _create_cm_ticket_stub
636
+
637
+ # ===============================
638
+ # Notifications
639
+ # ===============================
640
+ # Email sender for integrated toosl. Usually a good idea to make this a
641
+ # no-reply address.
642
+ EMAIL_SENDER = "nobody@not.real"
643
+
644
+ # Who to email when things go well (e.g. load_acl --auto)
645
+ SUCCESS_EMAILS = [
646
+ #'neteng@example.com',
647
+ ]
648
+
649
+ # Who to email when things go not well (e.g. load_acl --auto)
650
+ FAILURE_EMAILS = [
651
+ #'primarypager@example.com',
652
+ #'secondarypager@example.com',
653
+ ]
654
+
655
+ # The default sender for integrated notifications. This defaults to the fqdn
656
+ # for the localhost.
657
+ NOTIFICATION_SENDER = socket.gethostname()
658
+
659
+ # Destinations (hostnames, addresses) to notify when things go well.
660
+ SUCCESS_RECIPIENTS = [
661
+ # 'foo.example.com',
662
+ ]
663
+
664
+ # Destinations (hostnames, addresses) to notify when things go not well.
665
+ FAILURE_RECIPIENTS = [
666
+ # socket.gethostname(), # The fqdn for the localhost
667
+ ]
668
+
669
+ # This is a list of fully-qualified paths. Each path should end with a callable
670
+ # that handles a notification event and returns ``True`` in the event of a
671
+ # successful notification, or ``None``.
672
+ NOTIFICATION_HANDLERS = [
673
+ "trigger.utils.notifications.handlers.email_handler",
674
+ ]
@@ -0,0 +1,7 @@
1
+ """
2
+ trigger.contrib
3
+ ~~~~~~~~~~~~~~~
4
+
5
+ Extra, optional tools that solve common problems, extend, or modify core
6
+ functionality.
7
+ """