ncouture / MockSSH

Mock an SSH server and define all commands it supports (Python, Twisted)
Other
123 stars 23 forks source link

mocksshy and command validation #10

Closed mpenning closed 7 years ago

mpenning commented 9 years ago

I'm trying to build a hy-based test fixture, but I'm hitting a wall when it comes to command validation... this is my script:

#!/usr/bin/env hy

; A mocked-up Cisco Router to test SSH connections

(import MockSSH)
(require mocksshy.language)

(def *crlf* "\r\n")
(def *MockHostname* "MockRouter")
(def *MockPrompt1* (+ *MockHostname* ">"))
(def *MockPrompt15* (+ *MockHostname* "#"))
(def *MockConfPrompt* (+ *MockHostname* "(config)" "#"))
(def *MockConfIntfPrompt* (+ *MockHostname* "(config-if)" "#"))
(def *SyntaxError* (+ "           ^" *crlf* "% Invalid input detected at '^' marker." *crlf*))
(def *AccessDenied* (+ "% Access denied" *crlf*))
(def *ConfigMessage* (+ "Enter configuration commands, one per line.  End with CNTL/Z." *crlf*))

(mock-ssh :users {"admin" "cisco"}
          :host "127.0.0.1"
          :port 2222
          :prompt *MockPrompt1*
          :commands [
  (command :name "enable"
           :type "prompt"
           :output "Password: "
           :required-input "cisco123"
           :on-success ["prompt" *MockPrompt15*]
           :on-failure ["write" *AccessDenied*])
  (command :name "term"
           :type "output"
           :args ["len 0"]
           :on-success ["prompt" *MockPrompt15*]
           :on-failure ["write" *SyntaxError*])])

The problem is no matter what I type for term ..., the session gladly accepts it. Using the example above...

(py27_test)[mpenning@tsunami src]$ ssh -p 2222 admin@localhost
admin@localhost's password:
MockRouter>term len guacamole
MockRouter>term
MockRouter>t
MockSSH: t: command not found
MockRouter>

I wanted the script to require a literal term len 0; however, it takes anything. Is this expected behavior? Is there a way to fix the mocksshy script above?

Version info (all on Debian linux 7.1, Python 2.7.3, kernel 3.2.0)...

(py27_sshmock)[mpenning@tsunami ~]$ pip freeze
MockSSH==1.4.1
Twisted==15.0.0
argparse==1.2.1
astor==0.4.1
ecdsa==0.13
graphite-web==0.9.10
hy==0.10.1
paramiko==1.15.2
pyasn1==0.1.7
pycrypto==2.6.1
rply==0.7.3
wsgiref==0.1.2
zope.interface==4.1.2
(py27_sshmock)[mpenning@tsunami ~]$
ncouture commented 9 years ago

Hi @mpenning

I have tested argument validation using the mock.hy example and it works as I expected it to for commands of type "output", which is what you are using.

Have a look at https://github.com/ncouture/MockSSH/blob/master/examples/mock.hy and see if you are using it differently.

testuser@0's password: 
hostname>ls
MockSSH: supported usage: ls -1
hostname>ls -1 2 3 4
MockSSH: supported usage: ls -1
hostname>ls -1
bin/
README.txt
hostname>

As per your code a way to accept no argument would be like so:

(command :name "term"
         :type "output"
         :args []
         :on-success ["prompt" *MockPrompt15*]
         :on-failure ["write" *SyntaxError*])])
(mockssh)self ~/MockSSH $ pip freeze
MockSSH==1.4.2
Twisted==15.0.0
argparse==1.2.1
astor==0.4.1
ecdsa==0.13
hy==0.10.1
paramiko==1.15.2
pyasn1==0.1.7
pycrypto==2.6.1
rply==0.7.3
wsgiref==0.1.2
zope.interface==4.1.2
ncouture commented 9 years ago

If this does not work try using version 1.4.2 I doubt it is related to the version you are using.

You are raising a good question as I designed the command argument validator to expect a single set of specific arguments which may very well not be representative of the real world, then again I don't think it's right to say "this command should expect N arguments regardless of what they are" so allowing definition of multiple aruments may be the way to go (patches accepted).

What is your use case?