Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't configure banner in IOS (Cisco) or EOS (Arista) using conn.execute or conn.send #55

Closed
yaserelkhatib opened this issue Aug 6, 2014 · 9 comments

Comments

@yaserelkhatib
Copy link

Hi,

We have a massdeploy.py script that basically reads a file with switch names, a file with IOS or EOS commands, then executes the commands on the switches. We basically configured the following:

from Exscript.util.interact import read_login
from Exscript.protocols import SSH2
from Exscript import Queue, Logger
from Exscript.util.log import log_to
from Exscript.util.decorator import autologin
from Exscript.util.file import get_hosts_from_file, get_accounts_from_file
from Exscript.util.report import status, summarize

def execute_commands(job, host, conn):
for sendcommand in commandlist:
conn.execute(sendcommand)

queue = Queue(verbose = verbosity, max_threads = 1)
queue.add_account(accounts)
queue.run(hosts, execute_commands)
queue.shutdown()

I left the rest of the script out. Basically the commandlist is the IOS or EOS commands in the file, line by line. For example if the commandlist had this in it then it would work without a problem:

conf t
interface "bla"
description "whatever"
end

However, I'm trying to configure this on an EOS device and is not working:

banner motd (add ^ or ^C in case of IOS)


  •   THIS SYSTEM IS FOR THE USE OF AUTHORISED USERS ONLY!           *
    

    EOF (replace with ^ in case of IOS)
    end

In both IOS and EOS cases I get this, which is my problem and where our script fails:
In EOS case:

banner motd

Enter TEXT message. Type 'EOF' on its own line to end.
Or in IOS case:

banner motd ^

Enter TEXT message. End with the character '^'.

This is because conn.execute waits for an answer from the switch that the command was complete, and in this case the banner motd command waiting for text input. I don't want to update every switch manually and I tried to change it to conn.send, which doesn't wait for an answer, but that did nothing.

Does anyone know how to work around this problem with a tested and proven to work script/work around?

Thank you,

@matejv
Copy link

matejv commented Sep 5, 2014

After every command sent exscript searches the reposnse from router for a prompt. By default the regex for the prompt is something like /^\w#/ which will obviusly fail when the router is waiting for you to enter each line of your banner.

Before you start configuring the banner you should set the prompt to empty (/.*/) and reset it before you send the last line of the banner. This template works for me on a Cisco router:

conf t
{connection.set_prompt(/(Enter TEXT|.*)/)}
banner motd |
 test1
 multiple lines
 good
{connection.set_prompt()}
|
end

@yaserelkhatib
Copy link
Author

Thank you for the explanation. This makes sense.

Yaser Elkhatib
Network Engineer

IMC Financial Markets

W# (312) 244-3339
C# (708) 790-5644

On Friday, September 5, 2014 3:05 AM, Matej Vadnjal notifications@github.com wrote:

After every command sent exscript searches the reposnse from router for a prompt. By default the regex for the prompt is something like /^\w#/ which will obviusly fail when the router is waiting for you to enter each line of your banner.
Before you start configuring the banner you should set the prompt to empty (/./) and reset it before you send the last line of the banner. This template works for me on a Cisco router:
conf t
{connection.set_prompt(/(Enter TEXT|.
)/)}
banner motd | test1 multiple lines good
{connection.set_prompt()}
|
end

Reply to this email directly or view it on GitHub.

@yaserelkhatib
Copy link
Author

BTW, I couldn't get your code to work on Arista switches. Here is the prompt:

xxx01(config)#banner motd
Enter TEXT message. Type 'EOF' on its own line to end.

So I tried this and other veriations of regex without luck:

conf t
{connection.set_prompt(/(Enter\ TEXT\ message.\ Type\ 'EOF'\ on\ its\ own\ line\ to\ end.)/)}
banner motd |
test1
multiple lines
good
EOF
{connection.set_prompt()}
|
end

What do you think the problem is?

sxxxx01 error: Device said:
{connection.set_prompt(/(Enter\ TEXT\ message.\ Type\ 'EOF'\ on\ its\ own\ line\ to\ end.)/)}
% Invalid input
sxxxx01(config)#
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/workqueue/Job.py", line 64, in run
self.function(self)
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/Queue.py", line 80, in _wrapped
result = func(job, host, conn, _args, *_kwargs)
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/util/decorator.py", line 110, in decorated
return function(job, host, conn, _args, *_kwargs)
File "/usr/local/bin/massdeploy.py", line 88, in execute_commands
conn.execute(sendcommand)
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/protocols/Protocol.py", line 888, in execute
return self.expect_prompt()
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/protocols/Protocol.py", line 998, in expect_prompt
raise InvalidCommandException('Device said:\n' + self.response)
InvalidCommandException: Device said:
{connection.set_prompt(/(Enter\ TEXT\ message.\ Type\ 'EOF'\ on\ its\ own\ line\ to\ end.)/)}
% Invalid input
sxxxx01(config)#

sxxxx01 finally failed.
sxxxx01: Device said:
{connection.set_prompt(/(Enter\ TEXT\ message.\ Type\ 'EOF'\ on\ its\ own\ line\ to\ end.)/)}
% Invalid input
sxxxx01(config)#

Thank you for your time.

Yaser Elkhatib
Network Engineer

IMC Financial Markets

W# (312) 244-3339
C# (708) 790-5644

On Friday, September 5, 2014 3:05 AM, Matej Vadnjal notifications@github.com wrote:

After every command sent exscript searches the reposnse from router for a prompt. By default the regex for the prompt is something like /^\w#/ which will obviusly fail when the router is waiting for you to enter each line of your banner.
Before you start configuring the banner you should set the prompt to empty (/./) and reset it before you send the last line of the banner. This template works for me on a Cisco router:
conf t
{connection.set_prompt(/(Enter TEXT|.
)/)}
banner motd | test1 multiple lines good
{connection.set_prompt()}
|
end

Reply to this email directly or view it on GitHub.

@matejv
Copy link

matejv commented Sep 24, 2014

I'm not familiar with Arista switches, so I'm not sure this will be correct.

Why are you sending a pipe (|) at the end of banner motd command? From your example this is not needed on Arista. That's a special character that tells a Cisco switch that you are finished with your banner. I bet this is the line that causes your Invalid input error.

Also your prompt regex will only allow you to configure the first line of the banner since you are matching only the string "Enter TEXT message. Type 'EOF' on its own line to end.". All the subsequent lines will have nothing you could match as a prompt so you might as well match anything (.*).

Try this:

conf t
{connection.set_prompt(/(.*)/)}
banner motd
test1
multiple lines
good
{connection.set_prompt()}
EOF
end

@yaserelkhatib
Copy link
Author

That didn't work either:

xxxx01 error: Device said:
{connection.set_prompt(/(._)/)}
% Invalid input
xxxx01(config)#
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/workqueue/Job.py", line 64, in run
self.function(self)
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/Queue.py", line 80, in _wrapped
result = func(job, host, conn, *args, *_kwargs)
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/util/decorator.py", line 110, in decorated
return function(job, host, conn, _args, _kwargs)
File "/usr/local/bin/massdeploy.py", line 88, in execute_commands
conn.execute(sendcommand)
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/protocols/Protocol.py", line 888, in execute
return self.expect_prompt()
File "/usr/lib/python2.6/site-packages/Exscript-DEVELOPMENT-py2.6.egg/Exscript/protocols/Protocol.py", line 998, in expect_prompt
raise InvalidCommandException('Device said:\n' + self.response)
InvalidCommandException: Device said:
{connection.set_prompt(/(.
)/)}
% Invalid input
xxxx01(config)#

I have a definition in my massdeploy script that basically tells it to to take the command list, which is what you gave me in the previous email, and paste it line by line on the device like this:

def execute_commands(job, host, conn):
for sendcommand in commandlist:
conn.execute(sendcommand)

Could that be the problem for that fact that python is not reading this line but instead is trying to execute it on the switch?{connection.set_prompt(/(.*)/)}
I also tried to make it conn instead of connection and still had the same error above. I'll continue working and trying this today and I appreciate your help.

Yaser Elkhatib
Network Engineer

IMC Financial Markets

W# (312) 244-3339
C# (708) 790-5644

On Wednesday, September 24, 2014 1:09 AM, Matej Vadnjal notifications@github.com wrote:

I'm not familiar with Arista switches, so I'm not sure this will be correct.
Why are you sending a pipe (|) at the end of banner motd command? From your example this is not needed on Arista. That's a special character that tells a Cisco switch that you are finished with your banner. I bet this is the line that causes your Invalid input error.
Also your prompt regex will only allow you to configure the first line of the banner since you are matching only the string "Enter TEXT message. Type 'EOF' on its own line to end.". All the subsequent lines will have nothing you could match as a prompt so you might as well match anything (.).
Try this:
conf t
{connection.set_prompt(/(.
)/)}
banner motd
test1
multiple lines
good
{connection.set_prompt()}
EOF
end

Reply to this email directly or view it on GitHub.

@matejv
Copy link

matejv commented Sep 24, 2014

Could that be the problem for that fact that python is not reading this line but instead is trying to execute it on the switch?{connection.set_prompt(/(.*)/)}

Well, yeah. The example I gave you was for a template (https://github.com/knipknap/exscript/wiki/Template-Examples) that you use with the exscript command. But you are using the Python API.

So instead of passing the string "{connection.set_prompt(/(.*)/)}" to conn.execute() method you want to call conn.set_prompt() with the right regex.

@yaserelkhatib
Copy link
Author

Metaj,

Here is how I fixed it:

Send commands to individual switches

def execute_commands(job, host, conn):
if "banner motd" in commandlist:
conn.set_prompt(r'.+')
for sendcommand in commandlist:
if "EOF" in sendcommand:
conn.set_prompt()
conn.execute(sendcommand)
else:
for sendcommand in commandlist:
conn.execute(sendcommand)

Thank you for your help and pointing me in the right direction.

Yaser Elkhatib
Network Engineer

IMC Financial Markets

W# (312) 244-3339
C# (708) 790-5644

On Wednesday, September 24, 2014 8:11 AM, Matej Vadnjal notifications@github.com wrote:

Could that be the problem for that fact that python is not reading this line but instead is trying to execute it on the switch?{connection.set_prompt(/(.)/)}
Well, yeah. The example I gave you was for a template (https://github.com/knipknap/exscript/wiki/Template-Examples) that you use with the exscript command. But you are using the Python API.
So instead of passing the string "{connection.set_prompt(/(.
)/)}" to conn.execute() method you want to call conn.set_prompt() with the right regex.

Reply to this email directly or view it on GitHub.

@matejv
Copy link

matejv commented Sep 26, 2014

Thank you for your help and pointing me in the right direction.

Sure, no problem.

@egroeper
Copy link
Collaborator

Seems like the problem is solved.

BTW: I think the mailinglist would be a better place for asking such questions:
http://groups.google.com/group/exscript/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants