admin | bae64d8 | 2013-08-01 10:50:15 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | ''' |
| 3 | Created on 11-Oct-2012 |
| 4 | |
| 5 | @authors: Anil Kumar (anilkumar.s@paxterrasolutions.com), |
| 6 | |
| 7 | TestON is free software: you can redistribute it and/or modify |
| 8 | it under the terms of the GNU General Public License as published by |
| 9 | the Free Software Foundation, either version 2 of the License, or |
| 10 | (at your option) any later version. |
| 11 | |
| 12 | TestON is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License |
| 18 | along with TestON. If not, see <http://www.gnu.org/licenses/>. |
| 19 | |
| 20 | |
| 21 | |
| 22 | ''' |
| 23 | import pexpect |
| 24 | import struct, fcntl, os, sys, signal |
admin | bae64d8 | 2013-08-01 10:50:15 -0700 | [diff] [blame] | 25 | import re |
admin | bae64d8 | 2013-08-01 10:50:15 -0700 | [diff] [blame] | 26 | from core import xmldict |
| 27 | |
| 28 | class GenerateDriver(): |
| 29 | ''' |
| 30 | This will |
| 31 | ''' |
| 32 | def __init__(self): |
| 33 | self.default = '' |
| 34 | self.prompt = '>' |
| 35 | self.LASTRSP ='' |
| 36 | self.command_dictionary = {} |
| 37 | self.config_details = {} |
| 38 | self.last_sub_command = None |
| 39 | self.commnads_ordered_list = [] |
| 40 | filePath = "generatedriver.cfg" |
| 41 | self.configFile = filePath |
| 42 | try : |
| 43 | xml = open(filePath).read() |
| 44 | self.config_details = xmldict.xml_to_dict(xml) |
| 45 | except : |
| 46 | print "Error : Config file " + self.configFile + " not defined properly or file path error" |
| 47 | sys.exit() |
| 48 | print self.config_details |
| 49 | self.device_name = '' |
| 50 | |
| 51 | def connect(self,**connectargs): |
| 52 | ''' |
| 53 | Connection will establish to the remote host using ssh. |
| 54 | It will take user_name ,ip_address and password as arguments<br> |
| 55 | and will return the handle. |
| 56 | ''' |
| 57 | for key in connectargs: |
| 58 | vars(self)[key] = connectargs[key] |
| 59 | |
| 60 | ssh_newkey = 'Are you sure you want to continue connecting' |
| 61 | refused = "ssh: connect to host "+self.ip_address+" port 22: Connection refused" |
| 62 | if self.port: |
| 63 | self.handle =pexpect.spawn('ssh -p '+self.port+' '+self.user_name+'@'+self.ip_address,maxread=50000) |
| 64 | else : |
| 65 | self.handle =pexpect.spawn('ssh '+self.user_name+'@'+self.ip_address,maxread=50000) |
| 66 | |
| 67 | self.logfile_handler = open(os.getcwd()+"/GenerateDriver.log","w+") |
| 68 | self.handle.logfile = self.logfile_handler |
| 69 | i=self.handle.expect([ssh_newkey,'password:',pexpect.EOF,pexpect.TIMEOUT,refused],10) |
| 70 | |
| 71 | if i==0: |
| 72 | self.handle.sendline('yes') |
| 73 | i=self.handle.expect([ssh_newkey,'password:',pexpect.EOF,pexpect.TIMEOUT]) |
| 74 | return self.handle |
| 75 | if i==1: |
| 76 | self.handle.sendline(self.pwd) |
| 77 | self.handle.expect('>|#|$') |
| 78 | return self.handle |
| 79 | elif i==2: |
| 80 | print "ssh: connect to host "+self.ip_address+": Error" |
| 81 | return False |
| 82 | elif i==3: #timeout |
| 83 | |
| 84 | print "ssh: connect to host "+self.ip_address+": Connection timed out" |
| 85 | return False |
| 86 | elif i==4: |
| 87 | print "ssh: connect to host "+self.ip_address+": Connection refused" |
| 88 | return False |
| 89 | |
| 90 | self.handle.sendline("\r") |
| 91 | return self.handle |
| 92 | |
| 93 | def execute(self, **execparams): |
| 94 | ''' |
| 95 | This method will execute the command and will check for the expected prompt. |
| 96 | ''' |
| 97 | self.LASTRSP = '' |
| 98 | defaultPrompt = '.*[\$>\#]' |
| 99 | for key in execparams: |
| 100 | vars(self)[key] = execparams[key] |
| 101 | |
| 102 | self.handle.sendline(self.cmd) |
| 103 | timeoutVar = self.timeout if self.timeout else 10 |
| 104 | |
| 105 | index = self.handle.expect([self.prompt, "byte\s\d+", 'Command not found.', pexpect.TIMEOUT,"\n:",pexpect.EOF], timeout = timeoutVar) |
| 106 | if index == 0: |
| 107 | self.LASTRSP = self.LASTRSP + self.handle.before |
| 108 | #print "Expected Prompt Found" |
| 109 | elif index == 1: |
| 110 | self.LASTRSP = self.LASTRSP + self.handle.before |
| 111 | self.handle.send("\r") |
| 112 | print("Found More screen to go , Sending a key to proceed") |
| 113 | indexMore = self.handle.expect(["byte\s\d+", self.prompt], timeout = timeoutVar) |
| 114 | while indexMore == 0: |
| 115 | print "Found another More screen to go , Sending a key to proceed" |
| 116 | self.handle.send("\r") |
| 117 | indexMore = self.handle.expect(["byte\s\d+", self.prompt,pexpect.EOF,pexpect.TIMEOUT], timeout = timeoutVar) |
| 118 | self.LASTRSP = self.LASTRSP + self.handle.before |
| 119 | #print self.LASTRSP |
| 120 | elif index ==2: |
| 121 | print "Command not found" |
| 122 | self.LASTRSP = self.LASTRSP + self.handle.before |
| 123 | elif index ==3: |
| 124 | print "Expected Prompt not found , Time Out!!" |
| 125 | return False |
| 126 | elif index == 4: |
| 127 | |
| 128 | self.LASTRSP = self.LASTRSP + self.handle.before |
| 129 | self.handle.sendcontrol("D") |
| 130 | #print "AA"*89 |
| 131 | indexMore = self.handle.expect(["\n:", self.prompt,pexpect.EOF,pexpect.TIMEOUT], timeout = timeoutVar) |
| 132 | while indexMore == 0: |
| 133 | self.handle.sendcontrol("D") |
| 134 | |
| 135 | indexMore = self.handle.expect(["\n:", self.prompt,".*",pexpect.EOF,pexpect.TIMEOUT], timeout = timeoutVar) |
| 136 | self.LASTRSP = self.LASTRSP + self.handle.before |
| 137 | |
| 138 | return self.LASTRSP |
| 139 | |
| 140 | def configure(self): |
| 141 | ''' |
| 142 | Will start the Configure mode of the device. |
| 143 | ''' |
| 144 | config_result = self.execute(cmd="configure",prompt='\#',timeout=10) |
| 145 | return config_result |
| 146 | |
| 147 | def get_command_help(self,command): |
| 148 | ''' |
| 149 | Will get the help of the Command |
| 150 | ''' |
| 151 | |
| 152 | self.handle.setecho(False) |
| 153 | help_keyword = self.config_details['device'][self.device_name]['help_keyword'] |
| 154 | interrupt_key = self.config_details['device'][self.device_name]['interrupt_key'] |
| 155 | command_details = self.execute(cmd=command+" "+help_keyword,prompt='\#',timeout=2) |
| 156 | #command_details = self.execute(cmd=command+" "+help_keyword,prompt='\#',timeout=2) |
| 157 | self.handle.sendcontrol(interrupt_key) |
| 158 | #print command_details |
| 159 | return command_details |
| 160 | |
| 161 | def get_command_details(self,command): |
| 162 | ''' |
| 163 | Will Update the command_dictionary with the available commands details |
| 164 | ''' |
| 165 | |
| 166 | temp_dictionary = {} |
| 167 | command_resulut = self.get_command_help(command) |
| 168 | try : |
| 169 | words = command_resulut.split("\n") |
| 170 | except AttributeError,e: |
| 171 | print e |
| 172 | return |
| 173 | lines = command_resulut.split("\n") |
| 174 | options_list = [] |
| 175 | for line in lines : |
| 176 | value_match = re.search('[\s|\>|\+|\-|\<]{3}(\<(\w+))\s*',line) |
| 177 | if value_match: |
| 178 | print " Enter Value for "+value_match.group(2) |
| 179 | #self.handle.interact() |
| 180 | else: |
| 181 | match = re.search(r"\s\s[\w|-]+\s\s",line) |
| 182 | if match : |
| 183 | match_command = match.group(0) |
| 184 | print match_command |
| 185 | options_list.append(match_command) |
| 186 | |
| 187 | temp_dictionary[command] = options_list |
| 188 | self.command_dictionary[command] = options_list |
| 189 | self.print_details(self.command_dictionary) |
| 190 | print "temp dir: --------" |
| 191 | print temp_dictionary |
| 192 | print "-------------" |
| 193 | return temp_dictionary |
| 194 | |
| 195 | def print_details(self,command_dictionary): |
| 196 | ''' |
| 197 | Will print the details in Tree Format |
| 198 | ''' |
| 199 | self.commnads_ordered_list = command_dictionary.keys() |
| 200 | # Sorting the output based on the length of the command string |
| 201 | length = len(self.commnads_ordered_list ) - 1 |
| 202 | sorted = False |
| 203 | |
| 204 | while not sorted: |
| 205 | sorted = True |
| 206 | for i in range(length): |
| 207 | if len(self.commnads_ordered_list[i]) > len(self.commnads_ordered_list[i+1]): |
| 208 | sorted = False |
| 209 | self.commnads_ordered_list[i], self.commnads_ordered_list[i+1] = self.commnads_ordered_list[i+1], self.commnads_ordered_list[i] |
| 210 | |
| 211 | for key in self.commnads_ordered_list: |
| 212 | print key +"\t "+str(command_dictionary[key]) |
| 213 | print "\n\n" |
| 214 | |
| 215 | |
| 216 | def get_details_recursive(self,main_comand): |
| 217 | try : |
| 218 | self.last_sub_command = main_comand.split()[len(main_comand.split())-1] |
| 219 | except : |
| 220 | self.last_sub_command = '' |
| 221 | main_result_dcitionary = self.get_command_details(main_comand) |
| 222 | if main_result_dcitionary : |
| 223 | for key in main_result_dcitionary.keys(): |
| 224 | for index, each_option in enumerate(main_result_dcitionary[key]) : |
| 225 | |
| 226 | if re.search(self.config_details['device'][self.device_name]['end_pattern']+"|^\.|^\d",str(main_result_dcitionary[key][index])): |
| 227 | print "Reached the last argument for this "+main_comand+" "+str(each_option)+"\n" |
| 228 | main_result_dcitionary[key].remove(each_option) |
| 229 | return |
| 230 | elif self.last_sub_command == str(main_result_dcitionary[key][index]): |
| 231 | print "Same command repeating, So Exiting "+main_comand+" "+str(each_option)+"\n" |
| 232 | main_result_dcitionary[key].remove(each_option) |
| 233 | break |
| 234 | result_dcitionary = self.get_details_recursive(main_comand+" "+str(each_option)) |
| 235 | |
| 236 | return |
| 237 | def create_driver(self): |
| 238 | name = self.device_name |
| 239 | driver_file_data = 'class '+name +":\n" |
| 240 | driver_file_data = driver_file_data + " def __init__( self ):\n" |
| 241 | driver_file_data = driver_file_data + " self.prompt = '(.*)'\n self.timeout = 60 \n\n" |
| 242 | |
| 243 | for index,command in enumerate(self.commnads_ordered_list) : |
| 244 | api_data = ' def ' |
| 245 | command_as_api = re.sub(" ","_" , command, 0) |
| 246 | command_as_api = re.sub("\.|\-|\\|\/|\/","" , command_as_api, 0) |
| 247 | current_letter = 0 |
| 248 | underscore_count = 0 |
| 249 | command_temp = "" |
| 250 | for c in command_as_api: |
| 251 | current_letter = current_letter + 1 |
| 252 | if c == "_": |
| 253 | underscore_count = underscore_count+1 |
| 254 | else: |
| 255 | underscore_count = 0 |
| 256 | if underscore_count > 1: |
| 257 | command_temp = command_temp + "" |
| 258 | else: |
| 259 | command_temp = command_temp + c |
| 260 | if command_temp[len(command_temp)-1] == "_": |
| 261 | command_temp = command_temp[0:len(command_temp)-1] |
| 262 | command_as_api = command_temp |
| 263 | #options = '' |
| 264 | #for option in self.command_dictionary[command]: |
| 265 | #options = options+',' + option |
| 266 | |
| 267 | #options = re.sub("^\s*,|,$","" , options, 0) |
| 268 | api_data = api_data + command_as_api+"(self, *options, **def_args ):\n" |
| 269 | api_data = api_data + " '''Possible Options :"+str(self.command_dictionary[command])+"'''\n" |
| 270 | api_data = api_data + " arguments= ''\n" |
| 271 | api_data = api_data + " for option in options:\n" |
| 272 | api_data = api_data + " arguments = arguments + option +' ' \n" |
| 273 | api_data = api_data + " prompt = def_args.setdefault('prompt',self.prompt)\n" |
| 274 | api_data = api_data + " timeout = def_args.setdefault('timeout',self.timeout)\n" |
| 275 | |
| 276 | api_data = api_data + " self.execute( cmd= \""+ command + " \"+ arguments, prompt = prompt, timeout = timeout ) \n" |
| 277 | api_data = api_data + " return main.TRUE\n" |
| 278 | |
| 279 | driver_file_data = driver_file_data + api_data +"\n" |
| 280 | driver_file = open(os.getcwd()+"/"+name.lower()+".py", 'w') |
| 281 | driver_file.write(driver_file_data) |
| 282 | print driver_file_data |
| 283 | |
| 284 | def disconnect(self): |
| 285 | result = True |
| 286 | return result |
| 287 | |
| 288 | import pexpect |
| 289 | |
| 290 | if __name__ == "__main__": |
| 291 | |
| 292 | generate = GenerateDriver() |
| 293 | import sys |
| 294 | device_name = sys.argv[1] |
| 295 | generate.device_name = device_name |
| 296 | ip_address = generate.config_details['device'][device_name]['ip_address'] |
| 297 | user_name = generate.config_details['device'][device_name]['user_name'] |
| 298 | password = generate.config_details['device'][device_name]['password'] |
| 299 | command = generate.config_details['device'][device_name]['command'] |
| 300 | commandlist = re.sub("(\[|\])", "", command) |
| 301 | commandlist = list(eval(command+',')) |
| 302 | connect_handle = generate.connect(user_name = user_name ,ip_address = ip_address, pwd = password , port = None) |
| 303 | if connect_handle : |
| 304 | # generate.configure() |
| 305 | |
| 306 | for root_command in commandlist : |
| 307 | generate.get_details_recursive(root_command) |
| 308 | |
| 309 | generate.create_driver() |
| 310 | generate.disconnect() |
| 311 | #generate.get_command_details(main_command) |
| 312 | else : |
| 313 | print "Connection Failed to the host" |
| 314 | |
| 315 | |