forked from extremenetworks/ExtremeScripting
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrmtscript.py
More file actions
223 lines (194 loc) · 8 KB
/
rmtscript.py
File metadata and controls
223 lines (194 loc) · 8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env python2
# Python Scripts provided by Extreme Networks.
# This script is provided free of charge by Extreme. We hope such scripts are
# helpful when used in conjunction with Extreme products and technology;
# however, scripts are provided simply as an accommodation and are not
# supported nor maintained by Extreme. ANY SCRIPTS PROVIDED BY EXTREME ARE
# HEREBY PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL EXTREME OR ITS
# THIRD PARTY LICENSORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
# IN CONNECTION WITH THE USE OR DISTRIBUTION OF SUCH SCRIPTS.
#
# This script requires a python environment to run.
# In addition the requests module must also be installed
#
# This is an example of using the EXOS JSONRPC 'runscript' method.
# The command line expects a number of arguments
#usage: rmtscript [-h] -i IPADDRESS [-u USERNAME] [-p PASSWORD]
#
#optional arguments:
# -h, --help show this help message and exit
# -i IPADDRESS, --ipaddress IPADDRESS
# IP address of remote system
# -u USERNAME, --username USERNAME
# Login username for the remote system
# -p PASSWORD, --password PASSWORD
# Login password for the remote system
# -d, --debug Enable debug
#
# The -s option specifies the path of a script that would be run localy on the switch
# using the CLI command 'run script <pythonscript>.py'
#
# E.g. The following is in a file sample.py on your local pc
# exsh.clicmd('create vlan 10-20')
# exsh.clicmd('config vlan 10-20 add ports all tagged')
# print exsh.clicmd('show vlan',capture=True)
#
# To pass this to an EXOS switch using this script:
# on your server:
#
# python rmtscript.py -i 10.10.10.1 -u admin
#
# The rmtscript.py starts running and prompts:
#
# run script <file> [args]: sample.py -a -b def
# sample.py is sent to the switch with the command line args -a -b def
# It would be the same as transfering sample.py to a switch and running the following command
# run script sample.py -a -b def
# The sample.py stdout and stderr are captured and returned to the server
#
#
from __future__ import print_function
import argparse
import json
import requests
import getpass
import sys
# Readline is never used.
# try:
# import readline
# except:
# pass
#
# This class contains the specifics of constructing a JSONRPC message and
# returning the results
class JsonRPC(object):
def __init__(self, ipaddress, username=None, password=None, method='runscript'):
self.ipaddress = ipaddress
self.username = username
self.password = password
self.transaction = 0
self.cookie = None
# construct a URL template for the EXOS JSONRPC POST message
self.url = 'http://{ip}/jsonrpc'.format(ip=self.ipaddress)
self.json_request = {'method' : method,
'id' : self.transaction,
'jsonrpc' : '2.0',
'params' : None
}
def send(self, params):
# This method:
# fills out the JSONRPC POST data structures
# Sends the POST via HTTP to the EXOS switch
# gets the POST response
# returns the decoded JSON in native python structures
# http headers
headers = {'Content-Type': 'application/json'}
# increment the JSONRPC transaction counter
self.transaction += 1
self.json_request['id'] = self.transaction
# JSONRPC defines params as a list
# EXOS expects the CLI command to be a string in a single list entry
self.json_request['params'] = params
# after the first authentication, EXOS returns a cookie we can use
# in JSONRCP transactions to avoid re-authenticating for every transaction
#
# if we have a cookie from previsous authentication, use it
# send the JSONRPC message to the EXOS switch
if self.cookie:
headers['Cookie'] = 'session={0}'.format(self.cookie)
response = requests.post(self.url,
headers=headers,
json=self.json_request)
else:
response = requests.post(self.url,
headers=headers,
auth=(self.username, self.password),
json=self.json_request)
# interpret the response from the EXOS switch
# first check the HTTP error code to see if HTTP was successful
# delivering the message
if response.status_code == requests.codes.ok:
# if we have a cookie, store it so we can use it later
self.cookie = response.cookies.get('session')
try:
# ensure the response is JSON encoded
jsonrpc_response = response.json()
# return the JSONRPC response to the caller
return jsonrpc_response
except Exception as e:
raise e
# raise http exception
response.raise_for_status()
def get_params():
# These are the command line options for rmtscript
parser = argparse.ArgumentParser(prog = 'rmtscript')
parser.add_argument('-i', '--ipaddress',
help='IP address of remote system',
default=None)
parser.add_argument('-u', '--username',
help='Login username for the remote system')
parser.add_argument('-p', '--password',
help='Login password for the remote system',
default='')
args = parser.parse_args()
return args
def version_independent_input( str ):
# This Script needs to keep support for Python 2 so this function will allways use the right input method
if sys.version_info[0] == 2 :
return raw_input(str)
else:
return input(str)
def main():
args = get_params()
if args.ipaddress is None:
# prompt for ip address of the remote system
args.ipaddress = version_independent_input('Enter remote system IP address: ')
if args.username is None:
# prompt for username
args.username = version_independent_input('Enter remote system username: ')
# also get password
args.password = getpass.getpass('Remote system password: ')
# create a JSONRPC interface object
jsonrpc = JsonRPC(args.ipaddress, username=args.username, password=args.password, method='runscript')
while True:
# prompt the user for an EXOS command
cmd = version_independent_input('run script <file> [args]: ')
if cmd in ['q','quit','exit']:
break
# split the user input into parts
script_args = cmd.split()
# first token must be the local script file name
script_name = script_args[0]
# where there any additional command line args to pass to the script on the switch
script_options = script_args[1:] if len(script_args) > 1 else []
try:
# open up the script name provided by the user
with open(script_name, 'r') as fd:
# read the entire script into the first params entry
params = [fd.read()]
except Exception as e:
print(e)
continue
# add any additional parameters to the params list
params += script_options
# send the script and parameters to the switch for processing
try:
response = jsonrpc.send(params)
except Exception as e:
print(e)
continue
# extract the response stored in 2 variables 'stdout' and 'stderr'
result = response.get('result')
if result:
if result.get('stdout'):
print(result.get('stdout'))
# if something was output to stderr, print that last
if result.get('stderr'):
print('STDERR\n',result.get('stderr'))
try:
main()
except KeyboardInterrupt:
pass