Skip to content

Commit

Permalink
Merge pull request #85 from arista-eosplus/release-0.6.0
Browse files Browse the repository at this point in the history
Release 0.6.0
  • Loading branch information
phil-dileo committed Feb 22, 2016
2 parents f8b70cd + e7f4a31 commit 825915d
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 4 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.0
0.6.0
6 changes: 5 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@
# Assume PEP 440 version strings
p = re.compile(r'(\d+!)?((\d+)(.\d+)*(.\d+)*)(.?[a|b|rc]\d*)?(.post\d*)?(.dev\d*)?', re.IGNORECASE)
vers = p.search(release)
version = vers.group(2)

if vers:
version = vers.group(2)
else:
version = 'develop'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
72 changes: 72 additions & 0 deletions docs/release-notes-0.6.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
######
v0.6.0
######

2016-02-22

New Modules
^^^^^^^^^^^
* None

Enhancements
^^^^^^^^^^^^

* Added support for multiline commands without having to pass them as a dictionary (`78 <https://github.com/arista-eosplus/pyeapi/pull/78>`_) [`dbarrosop <https://github.com/dbarrosop>`_]
(See example below)

.. code-block:: python
>>> import pyeapi
>>> connection = pyeapi.client.connect(
... transport='https',
... host='192.168.56.201',
... username='vagrant',
... password='vagrant',
... port=443,
... timeout=60
... )
>>> device = pyeapi.client.Node(connection)
>>> device.run_commands('show hostname')
[{u'hostname': u'localhost', u'fqdn': u'localhost'}]
>>> device.run_commands('show banner login')
[{u'loginBanner': u''}]
>>> my_commands = [
... 'configure session whatever',
... 'hostname new-hostname',
... 'banner login MULTILINE:This is a new banner\nwith different lines!!!',
... 'end'
... ]
>>>
>>> device.run_commands(my_commands)
[{}, {}, {}, {}]
>>> print device.run_commands(['show session-config named whatever diffs'], encoding='text')[0]['output']
--- system:/running-config
+++ session:/whatever-session-config
@@ -3,6 +3,8 @@
! boot system flash:/vEOS-lab.swi
!
transceiver qsfp default-mode 4x10G
+!
+hostname new-hostname
!
spanning-tree mode mstp
!
@@ -22,6 +24,11 @@
!
no ip routing
!
+banner login
+This is a new banner
+with different lines!!!
+EOF
+!
management api http-commands
no shutdown
!
>>> device.run_commands(['configure session whatever', 'commit'])
[{}, {}]
>>> device.run_commands('show hostname')
[{u'hostname': u'new-hostname', u'fqdn': u'new-hostname'}]
>>> device.run_commands('show banner login')
[{u'loginBanner': u'This is a new banner\nwith different lines!!!\n'}]
>>>
1 change: 1 addition & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ Release Notes
release-notes-0.3.3.rst
release-notes-0.4.0.rst
release-notes-0.5.0.rst
release-notes-0.6.0.rst
2 changes: 1 addition & 1 deletion pyeapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
__version__ = '0.5.0'
__version__ = '0.6.0'
__author__ = 'Arista EOS+'


Expand Down
2 changes: 1 addition & 1 deletion pyeapi/api/staticroute.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def getall(self):
Returns:
dict: An dict object of static route entries in the form::
{ ip_dest:
{ next_hop:
{ next_hop_ip:
Expand Down
12 changes: 12 additions & 0 deletions pyeapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,18 @@ def run_commands(self, commands, encoding='json'):
"""
commands = make_iterable(commands)

# Some commands are multiline commands. These are banner commands and
# SSL commands. So with this two lines we
# can support those by passing commands by doing:
# banner login MULTILINE: This is my banner.\nAnd I even support
# multiple lines.
# Why this? To be able to read a configuration from a file, split it
# into lines and pass it as it is
# to pyeapi without caring about multiline commands.
commands = [{'cmd': c.split('MULTILINE:')[0],
'input': '%s\n' % (c.split('MULTILINE:')[1].strip())}
if 'MULTILINE:' in c else c for c in commands]

if self._enablepwd:
commands.insert(0, {'cmd': 'enable', 'input': self._enablepwd})
else:
Expand Down
15 changes: 15 additions & 0 deletions test/system/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ def test_config_single_command(self):
hostname, 'text')
self.assertEqual(result[0]['output'].strip(), hostname)

def test_config_single_multiline_command(self):
for dut in self.duts:
# Clear any current banner
dut.config('no banner login')

banner = 'This is a new banner\nwith different lines!!!'
cmd = 'banner login MULTILINE:%s' % banner
result = dut.config(cmd)
self.assertIsInstance(result, list, 'dut=%s' % dut)
self.assertEqual(len(result), 1, 'dut=%s' % dut)
self.assertEqual(result[0], {}, 'dut=%s' % dut)
result = dut.run_commands('show banner login', 'text')
self.assertEqual(result[0]['output'].strip().split('\n'),
banner.split('\n'))

def test_config_multiple_commands(self):
for dut in self.duts:
commands = list()
Expand Down
18 changes: 18 additions & 0 deletions test/unit/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ def test_config_with_multiple_commands(self):
result = self.node.config(commands)
self.assertEqual(result, [{}, {}])

def test_config_with_single_multiline(self):
command = ('banner login MULTILINE:This is a new banner\n'
'with different lines!!!')

self.node.run_commands = Mock(return_value=[{}, {}])
result = self.node.config(command)
self.assertEqual(result, [{}])

def test_config_with_multiple_multilines(self):
commands = [random_string(),
('banner login MULTILINE:This is a new banner\n'
'with different lines!!!'),
random_string()]

self.node.run_commands = Mock(return_value=[{}, {}, {}, {}])
result = self.node.config(commands)
self.assertEqual(result, [{}, {}, {}])

def test_get_config(self):
config = [dict(output='test\nconfig')]
self.node.run_commands = Mock(return_value=config)
Expand Down

0 comments on commit 825915d

Please sign in to comment.