Skip to content

Commit

Permalink
Release 1.2.4
Browse files Browse the repository at this point in the history
+ The commands required to commit/save the configuration on a device
are now attached to NetDevice objects under the commit_commands
attribute, to make it easier to execute these commands without having
to determine them for yourself.
+ Added a way to optionally perform a "commit full" operation on
Juniper devices by defining a dictionary of attributes and values for
matching devices using settings.JUNIPER_FULL_COMMIT_FIELDS. This
modifies the commit_commands that are assigned when the NetDevice
object is created.
+ Console paging is now disabled by default for async SSH channels.
  • Loading branch information
jathanism committed Dec 4, 2012
1 parent 64362d6 commit d5cc0cb
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 41 deletions.
6 changes: 4 additions & 2 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ Contributors
The following people have contributed to Trigger at some point during its
lifetime:

- Jathan McCollum
- `Jathan McCollum <https://github.com/jathanism>`_
- Eileen Tschetter
- Mark Ellzey Thomas
- `Mark Ellzey Thomas <https://github.com/ellzey>`_
- Michael Shields
- Jeff Sullivan (for the best error message ever)
- `Nick Sinopoli <https://github.com/NSinopoli>`_ (for graciously giving us the
name Trigger!)
- `Jason Long <https://github.com/sh0x>`_
- `Michael Harding <https://github.com/mvh>`_
- William White
16 changes: 11 additions & 5 deletions bin/load_acl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ __author__ = 'Jathan McCollum, Eileen Tschetter, Mark Ellzey Thomas, Michael Shi
__maintainer__ = 'Jathan McCollum'
__email__ = '[email protected]'
__copyright__ = 'Copyright 2003-2012, AOL Inc.'
__version__ = '1.7'
__version__ = '1.8'

# Dist imports
from collections import defaultdict
Expand Down Expand Up @@ -395,13 +395,16 @@ def get_work(opts, args):

return work

def junoscript_cmds(acls):
def junoscript_cmds(acls, dev):
"""
Return a list of Junoscript commands to load the given ACLs, and a
matching list of tuples (acls remaining, human-readable status message).
:param acls:
A collection of ACL names
:param dev:
A Juniper `~trigger.netdevices.NetDevice` object
"""
xml = [Element('lock-configuration')]
status = ['locking configuration']
Expand All @@ -413,7 +416,8 @@ def junoscript_cmds(acls):
xml.append(lc)
status.append('loading ACL ' + acl)

xml.append(Element('commit-configuration'))
# Add the proper commit command
xml.extend(dev.commit_commands)
status.append('committing for ' + ','.join(acls))
status.append('done for' + ','.join(acls) )

Expand Down Expand Up @@ -447,7 +451,9 @@ def ioslike_cmds(acls, dev, nonce):
template = template_base[dev.vendor.name]
cmds = [template % (get_tftp_source(dev), acl, nonce) for acl in acls]
status = ['loading ACL ' + acl for acl in acls]
cmds.append('write mem')

# Add the proper write mem command
cmds.extend(dev.commit_commands)
status.append('saving config for ' + ','.join(acls))
status.append('done for ' + ','.join(acls))

Expand Down Expand Up @@ -591,7 +597,7 @@ def activate(work, active, failures, jobs, redraw):
active[dev] = 'connecting'

if dev.vendor == 'juniper':
cmds, status = junoscript_cmds(acls)
cmds, status = junoscript_cmds(acls, dev)
execute = execute_junoscript
else:
nonce = os.urandom(8).encode('hex')
Expand Down
9 changes: 9 additions & 0 deletions conf/trigger_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@
'Enterprise Networking',
)

# Fields and values defined here will dictate which Juniper devices receive a#
# ``commit-configuration full`` when populating ``NetDevice.commit_commands`.#
# The fields and values must match the objects exactly or it will fallback to
# ``commit-configuration``.
JUNIPER_FULL_COMMIT_FIELDS = {
'deviceType': 'SWITCH',
'make': 'EX4200',
}

#===============================
# Redis Settings
#===============================
Expand Down
16 changes: 16 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
Changelog
=========

.. _v1.2.4:

1.2.4
=====

+ The commands required to commit/save the configuration on a device are now
attached to `~trigger.netdevices.NetDevice` objects under the
`~trigger.netdevices.NetDevice.commit_commands` attribute, to make it easier
to execute these commands without having to determine them for yourself.
+ :feature:`56` Added a way to optionally perform a ``commit full`` operation
on Juniper devices by defining a dictionary of attributes and values for
matching devices using :setting:`JUNIPER_FULL_COMMIT_FIELDS`. This modifies
the ``commit_commands`` that are assigned when the
`~trigger.netdevices.NetDevice` object is created.
+ :bug:`33` Console paging is now disabled by default for async SSH channels.

.. _v1.2.3:

1.2.3
Expand Down
22 changes: 22 additions & 0 deletions docs/usage/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,28 @@ Default::

()

.. setting:: JUNIPER_FULL_COMMIT_FIELDS

JUNIPER_FULL_COMMIT_FIELDS
~~~~~~~~~~~~~~~~~~~~~~~~~~

Fields and values defined here will dictate which Juniper devices receive a
``commit-configuration full`` when populating
`~trigger.netdevices.NetDevice.commit_commands`. The fields and values must
match the objects exactly or it will fallback to ``commit-configuration``.

Example::

# Perform "commit full" on all Juniper EX4200 switches.
JUNIPER_FULL_COMMIT_FIELDS = {
'deviceType': 'SWITCH',
'make': 'EX4200',
}

Default ::

{}

Redis settings
--------------

Expand Down
2 changes: 1 addition & 1 deletion trigger/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = (1, 2, 3)
__version__ = (1, 2, 4)

full_version = '.'.join(str(x) for x in __version__)
release = full_version
Expand Down
4 changes: 2 additions & 2 deletions trigger/cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,13 +531,13 @@ def ipv4_cidr_to_netmask(bits):
def to_cisco(self, dev, commands=None, extra=None):
"""This is the "show me all interface information" command we pass to
IOS devices"""
return ['show configuration | include ^(interface | ip address | ip access-group | description|!)']
return ['show configuration | include ^(interface | ip address | ip access-group | description|!)']

def to_arista(self, dev, commands=None, extra=None):
"""
Similar to IOS, but:
+ Arista has now "show conf" so we have to do "show run"
+ Arista has no "show conf" so we have to do "show run"
+ The regex used in the CLI for Arista is more "precise" so we have to change the pattern a little bit compared to the on in generate_ios_cmd
"""
Expand Down
9 changes: 9 additions & 0 deletions trigger/conf/global_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@
#'Enterprise Networking',
)

# Fields and values defined here will dictate which Juniper devices receive a
# ``commit-configuration full`` when populating ``NetDevice.commit_commands`.
# The fields and values must match the objects exactly or it will fallback to
# ``commit-configuration``.
JUNIPER_FULL_COMMIT_FIELDS = {
#'deviceType': 'SWITCH',
#'make': 'EX4200',
}

#===============================
# Redis Settings
#===============================
Expand Down
52 changes: 49 additions & 3 deletions trigger/netdevices.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
__maintainer__ = 'Jathan McCollum'
__email__ = '[email protected]'
__copyright__ = 'Copyright 2006-2012, AOL Inc.'
__version__ = '1.4.0'
__version__ = '1.4.1'

# Imports (duh?)
import copy
import itertools
import os
import sys
Expand All @@ -47,11 +48,14 @@
except ImportError:
import json
import sqlite3
from xml.etree.cElementTree import parse
import xml.etree.cElementTree as ET


# Constants
SUPPORTED_FORMATS = ('json', 'rancid', 'sqlite', 'xml')
JUNIPER_COMMIT = ET.Element('commit-configuration')
JUNIPER_COMMIT_FULL = copy.copy(JUNIPER_COMMIT)
ET.SubElement(JUNIPER_COMMIT_FULL, 'full')


# Exports
Expand Down Expand Up @@ -83,7 +87,7 @@ def _parse_xml(data_source):
"""
# Parsing the complete file into a tree once and extracting outthe device
# nodes is faster than using iterparse(). Curses!!
xml = parse(data_source).findall('device')
xml = ET.parse(data_source).findall('device')

# This is a generator within a generator. Trust me, it works in _populate()
data = (((e.tag, e.text) for e in node.getchildren()) for node in xml)
Expand Down Expand Up @@ -309,6 +313,9 @@ def __init__(self, data=None, with_acls=None):
# Bind the correct execute/connect methods based on deviceType
self._bind_dynamic_methods()

# Assign the configuration commit commands (e.g. 'write memory')
self.commit_commands = self._determine_commit_commands()

def _populate_data(self, data):
"""
Populate the custom attribute data
Expand Down Expand Up @@ -341,6 +348,45 @@ def _populate_deviceType(self):
self.deviceType = settings.DEFAULT_TYPES.get(self.vendor.name,
settings.FALLBACK_TYPE)

def _determine_commit_commands(self):
"""
Return the proper "commit" command. (e.g. write mem, etc.)
"""
if self.is_ioslike():
return self._ioslike_commit()
elif self.vendor == 'juniper':
return self._juniper_commit()
elif self.is_netscaler():
return ['save config']
else:
return []

def _ioslike_commit(self):
"""
Return proper 'write memory' command for IOS-like devices.
"""
if self.vendor == 'brocade' and self.is_switch():
return ['copy running-config startup-config', 'y']
else:
return ['write memory']

def _juniper_commit(self, fields=settings.JUNIPER_FULL_COMMIT_FIELDS):
"""
Return proper ``commit-configuration`` element for a Juniper
device.
"""
default = [JUNIPER_COMMIT]
if not fields:
return default

# Either it's a normal "commit-configuration"
for attr, val in fields.iteritems():
if not getattr(self, attr) == val:
return default

# Or it's a "commit-configuration full"
return [JUNIPER_COMMIT_FULL]

def _bind_dynamic_methods(self):
"""
Bind dynamic methods to the instance. Currently does these:
Expand Down
Loading

0 comments on commit d5cc0cb

Please sign in to comment.