Verify expect versions of DRAC, HPiLO and updates to APCControl, & OpenIPMI
[pcucontrol.git] / pcucontrol / models / APCControl.py
1 from pcucontrol.reboot import *
2 import subprocess
3
4 class APCControl(PCUControl):
5         supported_ports = [22,23,80,443]
6         reboot_sequence = []
7
8         def run(self, node_port, dryrun):
9                 print "RUNNING!!!!!!!!!!!!"
10                 if self.transport.type == Transport.HTTPS or self.type == Transport.HTTP:
11                         print "APC via http...."
12                         return self.run_http_or_https(node_port, dryrun)
13                 else:
14                         print "APC via telnet/ssh...."
15                         return self.run_telnet_or_ssh(node_port, dryrun)
16         
17         def run_ssh(self, node_port, dryrun):
18                 return self.run_telnet_or_ssh(node_port, dryrun)
19         def run_telnet(self, node_port, dryrun):
20                 return self.run_telnet_or_ssh(node_port, dryrun)
21
22         def run_telnet_or_ssh(self, node_port, dryrun):
23                 self.transport.open(self.host, self.username)
24                 self.transport.sendPassword(self.password)
25
26                 first = True
27                 for val in self.reboot_sequence:
28                         if first:
29                                 self.transport.ifThenSend("\r\n> ", val, ExceptionPassword)
30                                 first = False
31                         else:
32                                 self.transport.ifThenSend("\r\n> ", val)
33
34                 if not dryrun:
35                         self.transport.ifThenSend("Enter 'YES' to continue or <ENTER> to cancel", 
36                                                         "YES\r\n",
37                                                         ExceptionSequence)
38                 else:
39                         self.transport.ifThenSend("Enter 'YES' to continue or <ENTER> to cancel", 
40                                                         "", ExceptionSequence)
41                 self.transport.ifThenSend("Press <ENTER> to continue...", "", ExceptionSequence)
42
43                 self.transport.close()
44                 return 0
45
46         def run_http(self, node_port, dryrun):
47                 return self.run_http_or_https(node_port, dryrun)
48         def run_https(self, node_port, dryrun):
49                 return self.run_http_or_https(node_port, dryrun)
50
51         def run_http_or_https(self, node_port, dryrun):
52                 if not dryrun:
53                         # send reboot signal.
54                         # TODO: send a ManualPCU() reboot request for this PCU.
55                         # NOTE: this model defies automation because, the port numbering
56                         #       and the form numbers are not consistent across models.  There is
57                         #       not direct mapping from port# to form#.
58                         return "Manual Reboot Required"
59
60                 else:
61                         # TODO: also send message for https, since that doesn't work this way...
62                         if self.transport.type == Transport.HTTPS:
63                                 cmd = self.get_https_cmd()
64                         elif self.transport.type == Transport.HTTP:
65                                 cmd = self.get_http_cmd()
66                         else:
67                                 raise ExceptionNoTransport("Unsupported transport for http command")
68
69                 cmd = cmd % ( self.username, self.password, self.host)
70                 print "CMD: %s" % cmd
71
72                 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
73
74                 result = p.read()
75                 if len(result.split('\n')) > 2:
76                         self.logout()
77                         return 0
78                 else:
79                         # NOTE: an error has occurred, so no need to log out.
80                         print "RESULT: ", result
81                         return result
82
83         def get_https_cmd(self):
84                 version = self.get_version()
85                 print "VERSION: %s" % version
86                 if "AP96" in version:
87                         cmd = "curl -s --insecure --user '%s:%s' https://%s/outlets.htm " + \
88                                   " | grep -E '^[^<]+' " + \
89                                   " | grep -v 'Protected Object' "
90                 else:
91                         # NOTE: no other case known right now...
92                         cmd = "curl -s --insecure --user '%s:%s' https://%s/outlets.htm " + \
93                                   " | grep -E '^[^<]+' " + \
94                                   " | grep -v 'Protected Object' "
95                         
96                 return cmd
97         
98         def get_http_cmd(self):
99                 version = self.get_version()
100                 print "VERSION: %s" % version
101                 if "AP7900" in version:
102                         cmd = "curl -s --anyauth --user '%s:%s' http://%s/rPDUout.htm | grep -E '^[^<]+'" 
103                 elif "AP7920" in version:
104                         cmd = "curl -s --anyauth --user '%s:%s' http://%s/ms3out.htm | grep -E '^[^<]+' " 
105                 else:
106                         # default case...
107                         print "USING DEFAULT"
108                         cmd = "curl -s --anyauth --user '%s:%s' http://%s/ms3out.htm | grep -E '^[^<]+' " 
109                         
110                 return cmd
111
112         def get_version(self):
113                 # NOTE: this command returns and formats all data.
114                 #cmd = """curl -s --anyauth --user '%s:%s' http://%s/about.htm """ +
115                 #      """ | sed -e "s/<[^>]*>//g" -e "s/&nbsp;//g" -e "/^$/d" """ +
116                 #         """ | awk '{line=$0 ; if ( ! /:/ && length(pline) > 0 ) \
117                 #                            { print pline, line } else { pline=line} }' """ + 
118                 #         """ | grep Model """
119
120                 # NOTE: we may need to return software version, no model version to
121                 #               know which file to request on the server.
122
123                 if self.transport.type == Transport.HTTP:
124                         cmd = """curl -s --anyauth --user '%s:%s' http://%s/about.htm """ + \
125                                   """ | sed -e "s/<[^>]*>//g" -e "s/&nbsp;//g" -e "/^$/d" """ + \
126                                   """ | grep -E "AP[[:digit:]]+" """
127                                   #""" | grep -E "v[[:digit:]].*" """
128                 elif self.transport.type == Transport.HTTPS:
129                         cmd = """curl -s --insecure --user '%s:%s' https://%s/about.htm """ + \
130                                   """ | sed -e "s/<[^>]*>//g" -e "s/&nbsp;//g" -e "/^$/d" """ + \
131                                   """ | grep -E "AP[[:digit:]]+" """
132                                   #""" | grep -E "v[[:digit:]].*" """
133                 else:
134                         raise ExceptionNoTransport("Unsupported transport to get version")
135
136                 cmd = cmd % ( self.username, self.password, self.host)
137                 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
138                 result = p.read()
139                 return result.strip()
140
141         def logout(self):
142                 # NOTE: log out again, to allow other uses to access the machine.
143                 if self.transport.type == Transport.HTTP:
144                         cmd = """curl -s --anyauth --user '%s:%s' http://%s/logout.htm """ + \
145                                   """ | grep -E '^[^<]+' """
146                 elif self.transport.type == Transport.HTTPS:
147                         cmd = """curl -s --insecure --user '%s:%s' http://%s/logout.htm """ + \
148                                   """ | grep -E '^[^<]+' """
149                 else:
150                         raise ExceptionNoTransport("Unsupported transport to logout")
151
152                 cmd = cmd % ( self.username, self.password, self.host)
153                 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout
154                 print p.read()
155
156 class APCControl12p3(APCControl):
157         def run_telnet_or_ssh(self, node_port, dryrun):
158                 self.reboot_sequence = ["1", "2", str(node_port), "3"]
159                 return super(APCControl12p3, self).run_telnet_or_ssh(node_port, dryrun)
160
161 class APCControl1p4(APCControl):
162         def run_telnet_or_ssh(self, node_port, dryrun):
163                 self.reboot_sequence = ["1", str(node_port), "4"]
164                 return super(APCControl1p4, self).run_telnet_or_ssh(node_port, dryrun)
165
166 class APCControl121p3(APCControl):
167         def run_telnet_or_ssh(self, node_port, dryrun):
168                 self.reboot_sequence = ["1", "2", "1", str(node_port), "3"]
169                 return super(APCControl121p3, self).run_telnet_or_ssh(node_port, dryrun)
170
171 class APCControl121p1(APCControl):
172         def run_telnet_or_ssh(self, node_port, dryrun):
173                 self.reboot_sequence = ["1", "2", "1", str(node_port), "1", "3"]
174                 return super(APCControl121p1, self).run_telnet_or_ssh(node_port, dryrun)
175
176 class APCControl13p13(APCControl):
177         def run_telnet_or_ssh(self, node_port, dryrun):
178                 self.reboot_sequence = ["1", "3", str(node_port), "1", "3"]
179                 return super(APCControl13p13, self).run_telnet_or_ssh(node_port, dryrun)