3 from netaddr import EUI, mac_unix
4 from cloud import common
5 from ssh_client import SSHClient
10 S = {'bay': 0, 'ilo_name': 1, 'ilo_ip': 2, 'status': 3, 'power': 4,
13 class HpAdapter(object):
15 def __init__(self, mgmt_ip, username, password):
16 self.mgmt_ip = mgmt_ip
17 self.username = username
18 self.password = password
20 class mac_dhcp(mac_unix):
24 digit_list = self.mgmt_ip.split('.')
25 digit_list[3] = str(int(digit_list[3]) + 1)
26 self.mgmt_ip = '.'.join(digit_list)
29 verified_ips = [self.mgmt_ip]
30 ssh = SSHClient(self.mgmt_ip, self.username, self.password)
35 verified_ips.append(self.mgmt_ip)
36 ssh = SSHClient(self.mgmt_ip, self.username, self.password)
39 except Exception as e:
40 err('Could not connect to HP Onboard Administrator through '
41 'these IPs: %s, reason: %s' % (verified_ips, e))
43 lines = self.clean_lines(ssh.execute('show oa status'))
45 if 'Role: Standby' in line:
47 if self.mgmt_ip != verified_ips[0]:
48 err('Can only talk to OA %s which is the standby OA\n'
51 LOG.debug('%s is the standby OA, trying next OA\n'
54 verified_ips.append(self.mgmt_ip)
55 ssh = SSHClient(self.mgmt_ip, self.username, self.password)
58 except Exception as e:
59 err('Could not connect to HP Onboard Administrator'
60 ' through these IPs: %s, reason: %s'
63 elif 'Role: Active' in line:
65 err('Could not reach Active OA through these IPs %s' % verified_ips)
67 def get_blades_mac_addresses(self, shelf, blade_list):
68 macs_per_blade_dict = {}
69 LOG.debug('Getting MAC addresses for shelf %s, blades %s'
70 % (shelf, blade_list))
72 for blade in blade_list:
73 lines = self.clean_lines(
74 ssh.execute('show server info %s' % blade))
75 left, right = self.find_mac(lines, shelf, blade)
77 left = EUI(left, dialect=self.mac_dhcp)
78 right = EUI(right, dialect=self.mac_dhcp)
79 macs_per_blade_dict[blade] = [str(left), str(right)]
81 return macs_per_blade_dict
83 def find_mac(self, printout, shelf, blade):
87 if ('No Server Blade Installed' in line or
88 'Invalid Arguments' in line):
89 err('Blade %d in shelf %d does not exist' % (blade, shelf))
91 seobj = re.search(r'LOM1:1-a\s+([0-9A-F:]+)', line, re.I)
95 seobj = re.search(r'LOM1:2-a\s+([0-9A-F:]+)', line, re.I)
97 right = seobj.group(1)
101 def get_hardware_info(self, shelf, blade=None):
103 if ssh and not blade:
107 lines = self.clean_lines(ssh.execute('show server info %s' % blade))
110 match = r'Product Name:\s+(.+)\Z'
111 if not re.search(match, str(lines[:])):
112 LOG.debug('Blade %s in shelf %s does not exist\n' % (blade, shelf))
116 seobj = re.search(match, line)
118 return 'HP %s' % seobj.group(1)
121 def power_off_blades(self, shelf, blade_list):
122 return self.set_state(shelf, 'locked', blade_list)
124 def power_on_blades(self, shelf, blade_list):
125 return self.set_state(shelf, 'unlocked', blade_list)
127 def set_boot_order_blades(self, shelf, blade_list):
128 return self.set_boot_order(shelf, blade_list=blade_list)
130 def parse(self, lines):
132 for l in lines[5:-2]:
134 cluttered = [e.strip() for e in l.split(' ')]
138 parsed_list.append(parsed)
141 def set_state(self, shelf, state, blade_list):
142 if state not in ['locked', 'unlocked']:
143 LOG.debug('Incorrect state: %s' % state)
146 LOG.debug('Setting state %s for blades %s in shelf %s'
147 % (state, blade_list, shelf))
149 blade_list = sorted(blade_list)
152 LOG.debug('Check if blades are present')
153 server_list = self.parse(
154 self.clean_lines(ssh.execute('show server list')))
156 for blade in blade_list:
157 if server_list[S['status']] == 'Absent':
158 LOG.debug('Blade %s in shelf %s is missing. '
159 'Set state %s not performed\n'
160 % (blade, shelf, state))
161 blade_list.remove(blade)
163 bladelist = ','.join(blade_list)
165 # Use leading upper case on On/Off so it can be reused in match
167 if state == 'locked':
172 cmd = 'power%s server %s' % (powerstate, bladelist)
179 # Check that all blades reach the state which can take some time,
180 # so re-try a couple of times
181 LOG.debug('Check if state %s successfully set' % state)
188 for i in range(WAIT_LOOP):
189 server_list = self.parse(
190 self.clean_lines(ssh.execute('show server list')))
192 for blade in blade_list:
193 for server in server_list:
194 if (server[S['bay']] == blade and
195 server[S['power']] == powerstate):
196 set_blades.append(blade)
199 all_set = set(blade_list) == set(set_blades)
203 time.sleep(SLEEP_TIME)
208 LOG.debug('State %s successfully set on blades %s in shelf %d'
209 % (state, set_blades, shelf))
212 LOG.debug('Could not set state %s on blades %s in shelf %s\n'
213 % (state, set(blade_list) - set(set_blades), shelf))
217 def clean_lines(self, printout):
219 for p in [l.strip() for l in printout.splitlines()]:
225 def set_boot_order_blades(self, shelf, blade_list, boot_dev_list=None):
227 boot_dict = {'Hard Drive': 'hdd',
231 'Diskette Driver': 'disk'}
233 boot_options = [b for b in boot_dict.itervalues()]
234 diff = list(set(boot_dev_list) - set(boot_options))
236 err('The following boot options %s are not valid' % diff)
238 blade_list = sorted(blade_list)
239 LOG.debug('Setting boot order %s for blades %s in shelf %s'
240 % (boot_dev_list, blade_list, shelf))
244 LOG.debug('Check if blades are present')
245 server_list = self.parse(
246 self.clean_lines(ssh.execute('show server list')))
248 for blade in blade_list:
249 if server_list[S['status']] == 'Absent':
250 LOG.debug('Blade %s in shelf %s is missing. '
251 'Change boot order %s not performed.\n'
252 % (blade, shelf, boot_dev_list))
253 blade_list.remove(blade)
255 bladelist = ','.join(blade_list)
257 for boot_dev in reversed(boot_dev_list):
258 ssh.execute('set server boot first %s %s' % (boot_dev, bladelist))
260 LOG.debug('Check if boot order is successfully set')
263 boot_keys = [b for b in boot_dict.iterkeys()]
264 for blade in blade_list:
265 lines = self.clean_lines(ssh.execute('show server boot %s'
267 boot_order = lines[lines.index('IPL Devices (Boot Order):')+1:]
273 boot_list.append(boot_dict[k])
275 if boot_list == boot_dev_list:
279 success_list.append(success)
281 LOG.debug('Boot order %s successfully set on blade %s in '
282 'shelf %s\n' % (boot_dev_list, blade, shelf))
284 LOG.debug('Failed to set boot order %s on blade %s in '
285 'shelf %s\n' % (boot_dev_list, blade, shelf))
288 return all(success_list)