Skip to content
This repository was archived by the owner on Jul 15, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions ansible/eos_install_config
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ DOCUMENTATION = '''
module: eos_install_config
author: David Barroso <dbarroso@spotify.net>
version_added: "1.0.0"
short_description: Replaces the configuration taken from a file on a device running EOS.
description:
This library will take the configuration from a file and load it into a device running EOS. The old configuration
will be replaced using the feature 'config replace terminal: force'. The use this module you need to enable access
to the device via the eAPI.
short_description: Takes configuration from a file and loads it onto a device running EOS.
description: This library will take the configuration from a file and load it into a device running EOS. The old
configuration will be replaced by using the feature 'config replace terminal: force'. To use this module you
need to enable access to the device via the eAPI.

requirements:
- pyEOS
Expand All @@ -50,19 +49,19 @@ options:
description: Password
required: true
use_ssl:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should actually remove that option and make everybody use SSL always. Why? Napalm doesn´t support non-ssl protocols (https is kind of hardcoded for EOS and netconf and expect uses ssh as transport so...)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that for a brief moment yesterday, but I feel like the device libs (eos same as iosxr for that matter) are closer to the actual hardware and are ok to support vendor specific things, where napalm should unify them into one common interface (I would not include it there). But if someone uses pyEOS standalone and has https trouble - I find it ok to leave this option in for that use case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, disregard. I was thinking in napalm. I personally don´t think we should support/provide this plugin at all. I put it there as a proof of concept but I am not planning to use it so I don´t want to spend time or effort in working on that. But if you want to... feel free ; )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not, if it's already there, as long as it is consistent :) we can always delete it in the future, if we get sick of supporting this

description: If set to True we will connect via https, if False we will use http instead. Default is True.
description: If set to true we will connect via https, if false we will use http instead. Default is true.
required: false
config_file:
description: Where to load the configuration from.
description: File to load the configuration from.
required: true
commit_changes:
description: If set to True the configuration will be actually replaced. If the set to False, we will not
apply the changes, just check the differences.
required: true
description: If set to true the commit will be performed. If set to false, we will not apply the changes,
only check the differences. Default: false.
required: false
diff_file:
description: A file where to store the "diff" between the running configuration and the new configuration. If
it's not set the diff between configurations is not saved.
required: False
description: A file where to store the "diff" between the running configuration and the new configuration.
If it's not set the diff between configurations is not saved. Default: none.
required: false
'''

EXAMPLES = '''
Expand All @@ -77,9 +76,9 @@ EXAMPLES = '''
hostname={{ inventory_hostname }}
username=admin
password=p4ssw0rd
use_ssl=False
use_ssl=false
config_file=~/spotify/network-ansible/compiled/{{ inventory_hostname }}/running.conf
commit_changes={{commit_changes}}
commit_changes={{ commit_changes }}
diff_file=logs/{{ inventory_hostname }}.log

From the CLI we would trigger the playbook like:
Expand Down Expand Up @@ -131,7 +130,6 @@ def main():
device.open()
device.load_candidate_config(filename=config_file)

#content of the
diff = device.compare_config()
changed = len(diff) > 0

Expand All @@ -151,4 +149,4 @@ def main():

from ansible.module_utils.basic import *

main()
main()
26 changes: 17 additions & 9 deletions pyEOS/eos.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def __init__(self, hostname, username, password, use_ssl=True):
The object will contain the following interesting attributes:

* **running_config** - The configuration retrieved from the device using the method load_running_config
* **candidate_config** - The configuration we desire for the device. Can be populated using the method load_candidate_config
* **candidate_config** - The configuration we desire for the device. Can be populated using the method
load_candidate_config

:param hostname: IP or FQDN of the device you want to connect to
:param username: Username
Expand Down Expand Up @@ -71,9 +72,13 @@ def run_commands(self, commands, version=1, auto_format=False, format='json', ti

:param commands: List of commands you want to run
:param version: Version of the eAPI you want to connect to. By default is 1.
:param auto_format: If set to True API calls not supporting returning JSON messages will be converted automatically to text. By default is False.
:param format: Format you want to get; 'json' or 'text'. By default is json. This will trigger a CommandUnconverted exception if set to 'json' and auto_format is set to False. It will return text if set to 'json' but auto_format is set to True.
:param timestamps: This will return some useful information like when was the command executed and how long it took.
:param auto_format: If set to True API calls not supporting returning JSON messages will be converted
automatically to text. By default it is False.
:param format: Format you want to get; 'json' or 'text'. By default it is json. This will trigger a
CommandUnconverted exception if set to 'json' and auto_format is set to False. It will return text if set
to 'json' but auto_format is set to True.
:param timestamps: This will return some useful information like when was the command executed and how long
it took.

"""

Expand Down Expand Up @@ -125,7 +130,8 @@ def run_commands(self, commands, version=1, auto_format=False, format='json', ti

def close(self):
"""
Dummy, method. Today it does not do anything but it would be interesting to use it to fake closing a connection.
Dummy, method. Today it does not do anything but it would be interesting to use it to fake closing a
connection.

"""
pass
Expand All @@ -150,9 +156,10 @@ def load_running_config(self):
def load_candidate_config(self, filename=None, config=None):
"""
Populates the attribute candidate_config with the desired configuration. You can populate it from a file or
from a string. If you send both a filename and a string containing the configuration, the file takes precedence.
from a string. If you send both a filename and a string containing the configuration, the file takes
precedence.

:param filename: Path to the file containing the desired configuration. By default is None.
:param filename: Path to the file containing the desired configuration. By default it is None.
:param config: String containing the desired configuration.
"""

Expand All @@ -164,8 +171,9 @@ def load_candidate_config(self, filename=None, config=None):
def compare_config(self):
"""

:return: A string showing the difference between the running_config and the candidate_config. The running_config is
loaded automatically just before doing the comparison so there is no neeed for you to do it.
:return: A string showing the difference between the running_config and the candidate_config, assuming the
entire running conf will be replaced by the candidate. The running_config is loaded automatically just
before doing the comparison so there is no neeed for you to do it.
"""

# We get the config in text format because you get better printability by parsing and using an OrderedDict
Expand Down
2 changes: 1 addition & 1 deletion test/unit/TestEOS.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ def test_loading_modified_config_replace_config_and_rollback(self):
def test_get_interface_config(self):
self.device.load_running_config()
interface = self.device.running_config['interface Ethernet2']
self.assertGreater(len(interface), 0)
self.assertGreater(len(interface), 0)