whilechannel.recv_ready()ornotcmdout[-2:]=='> ':# Fetch new output, if there is any or look for '> ' (prompt ready). The latter is useful when connecting to blades.
Allbute)areknowntodropyoubackintotheenc's shell, in what case we'llbeinaproblematicspot,sincewe're going to exit out of the enc ssh, not the blade's.
#TODO: somehow magically detect if we've successfully connected to the blade. There's no standard way to determine.
Theprobablewaywouldbetolookattheprompt.Blade's seem to all be '</>hpiLO->'.
Iwouldfetchthepromptonconnectiontotheenc,thencomparethecurrentprompttodetermineifwe're connected to a blade.
"""
lockedoutCounter+=1
iflockedoutCounter>30:
raiseEOFError("Waited for a prompt for 15s. Something is probably wrong. Aborting.")
else:
logging.info("No prompt, waiting for more data.")
sleep(0.5)
cmdout+=channel.recv(65536).decode("ascii")# Get output, capped to 64KiB, format ascii. | Must get, otherwise next command will get this command's output.
ssh.connect(hostname,username=sshuser,key_filename=sshkeypath)# Attempt to connect
channel=ssh.invoke_shell()# Get a new shell(, and keep it open, since we need to exec multiple commands depending on the last command being executed successfully.)
logging.debug(ssh_runcmd('show date'))# Get rid of motd, init for next cmds. This is better than indefinitely reading buffer before any command as to counter this. Reading buffer before each command isn't a good idea and doesn't work either, trust me.
serverName=ssh_runcmd('show server names')# Testing data: serverName = ['Bay Server Name Serial Number Status Power UID Partner\r', '--- ------------------------------------------------- --------------- -------- ------- --- -------\r', ' 1 foo-lab-1 OK On Off \r', ' 2 foo-lab-2 CZ302243P9 OK On Off \r', ' 3 foo-lab-3 CZJI441OKP Failed On Off \r', ' 4 kspve1 CZJ18450FK OK On Off \r', ' 5 kspve2-2 OK On Off \r', ' 6 kspve3 OK On Off \r', ' 7 foo-blade OK On Off \r', ' 8 Bar-01 CZ241274CC OK On Off \r', ' 9 baz-sar CZ3217FNYE OK On Off \r', ' 10 baz-sar2 CZ3217FFSS OK On Off \r', ' 11 [Absent] \r', ' 12 bee-bar OK On Off \r', ' 13 [Absent] \r', ' 14 [Absent] \r', ' 15 [Absent] \r', ' 16 [Absent] \r']
baysInUse=[x[0]forxinservers]# List of blades in use.
baysInUseCount=len(baysInUse)# How many bays in use.
logging.info("There are "+str(baysInUseCount+1)+"servers presenet.")# Further optimizations could be made by not connecting to servers, what are turned off.
## Get blade data ##
forninrange(baysInUseCount):
bay=servers[n][0]# We want the bay, not how many times we have looped over.
logging.info("Accessing server "+str(bay))
logging.debug(ssh_runcmd('connect server '+str(bay)))# Use the enc as a jump host.
powerInfoTmp=ssh_runcmd('show system1/oemhp_power1')# Get the data
presentPower=[iforiinpowerInfoTmpifi.startswith(' oemhp_PresentPower=')][0][23:-7]# Get the line with PresentPower, then remove first 23, and last 7 chars to end up with the Watts DC the blade is directly using.
ifpresentPower=='Not Ava':# When the server is powered off, it's not zero (LIKE LITERALLY EVERYWHERE ELSE). It is NoT aVaILAbLe. 'Not Ava' because the previous command takes last 7 chars (normally 'Watts') off of it. Ah my fault for not checking all possible input from hpe.
presentPower=0
elifnotpresentPower.isdigit():# Just in case some other anomalities come up in the future, like negative power draw or something…
warn('presentPower for bay '+bay+'was corrected to 0 from it\'s abnormal state: '+presentPower)
presentPower=0
servers[n].append(int(presentPower))# And push it to our miniDB of the servers list.
logging.info("UsageRawDC: "+str(presentPower))
logging.debug(ssh_runcmd('exit'))# Exit the blade's iLO, return to the enc's iLO SSH interface.