| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| package pdu |
| |
| import ( |
| "strconv" |
| |
| "fuchsia.googlesource.com/infra/infra/telnet" |
| ) |
| |
| // CyberPowerClient is a wrapper over a telnet connection for communicating |
| // with CyberPower PDUs. |
| type CyberPowerConn struct { |
| // Conn is the underlying telnet connection. |
| *telnet.Conn |
| |
| // Username is the username by which we can log in to the PDU. |
| Username string |
| |
| // Password is the password by which we can log in to the PDU. |
| Password string |
| } |
| |
| // Reboot sends a signal to reboot a machine connection to the given PDU |
| // port number. |
| func (c *CyberPowerConn) Reboot(pduPort int) error { |
| // Log in to the telnet server |
| if err := c.Conn.ReadUntil("Login Name: "); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln(c.Username); err != nil { |
| return err |
| } |
| if err := c.Conn.ReadUntil("Login_Pass: "); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln(c.Password); err != nil { |
| return err |
| } |
| |
| // Cycle through a bunch of menu options. |
| if err := c.Conn.ReadUntil("Select&Reflash"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("1"); err != nil { |
| return err |
| } |
| if err := c.Conn.ReadUntil("Select&Reflash"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("2"); err != nil { |
| return err |
| } |
| if err := c.Conn.ReadUntil("Select&Reflash"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("1"); err != nil { |
| return err |
| } |
| |
| // Select the port. |
| if err := c.Conn.ReadUntil("Cancel"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln(strconv.Itoa(pduPort)); err != nil { |
| return err |
| } |
| |
| // Reboot (state 3). |
| if err := c.Conn.ReadUntil("Cancel"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("3"); err != nil { |
| return err |
| } |
| |
| // Confirm the reboot. |
| if err := c.Conn.ReadUntil("Cancel"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("YES"); err != nil { |
| return err |
| } |
| |
| // Send ESC to leave the submenus. |
| if err := c.Conn.ReadUntil("Select&Reflash"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("\033"); err != nil { |
| return err |
| } |
| if err := c.Conn.ReadUntil("Select&Reflash"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("\033"); err != nil { |
| return err |
| } |
| |
| // Send "4" to logout. |
| if err := c.Conn.ReadUntil("Select&Reflash"); err != nil { |
| return err |
| } |
| if err := c.Conn.Writeln("4"); err != nil { |
| return err |
| } |
| |
| return c.Conn.Close() |
| } |