diff --git a/README.md b/README.md index 6b2f4ac..c906f27 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,11 @@ func main() { Sample Lab Machines 172.19.100.107 +User: root Default PW: 9XW9FR9PN3FF 172.19.100.108 +User: root Default PW: K4P4NVAK9KVK TODO: diff --git a/cli/board.go b/cli/board.go new file mode 100644 index 0000000..6863457 --- /dev/null +++ b/cli/board.go @@ -0,0 +1,25 @@ +package main + +import ( + "github.com/urfave/cli/v2" +) + +var boardCmd = &cli.Command{ + Name: "board", + Usage: "gather machine board details", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + board := c.Board() + log.Infow("board", "bandtype", bandtype, "host", host, "result", board.String(), "bios", board.BIOS, "powermetric", board.PowerMetric, "powersupplies", board.PowerSupplies, "ledstate", board.IndicatorLED) + bmc, err := outBandBMCConnection.BMC() + if err != nil { + return err + } + log.Infow("bmc", "result", bmc) + return nil + }, +} diff --git a/cli/led.go b/cli/led.go new file mode 100644 index 0000000..15e73f4 --- /dev/null +++ b/cli/led.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/urfave/cli/v2" +) + +var ledCmd = &cli.Command{ + Name: "led", + Usage: "gather machine led state", + Flags: flags, + Action: func(ctx *cli.Context) error { + // c, err := getHalConnection(log) + // if err != nil { + // return err + // } + // ledstate := c.IdentifyLEDState() + // log.Infow("board", "bandtype", bandtype, "host", host, "result", board.String(), "bios", board.BIOS, "powermetric", board.PowerMetric, "powersupplies", board.PowerSupplies) + return nil + }, +} diff --git a/cli/main.go b/cli/main.go index 4d84c59..f492208 100644 --- a/cli/main.go +++ b/cli/main.go @@ -1,154 +1,209 @@ package main import ( - "errors" - "flag" "fmt" "os" - "time" "github.com/metal-stack/go-hal" - "github.com/metal-stack/go-hal/connect" + "github.com/metal-stack/go-hal/pkg/api" "github.com/metal-stack/go-hal/pkg/logger" + "github.com/urfave/cli/v2" ) var ( - band = flag.String("bandtype", "outband", "inband/outband") - user = flag.String("user", "ADMIN", "bmc username") - password = flag.String("password", "ADMIN", "bmc password") - host = flag.String("host", "localhost", "bmc host") - port = flag.Int("port", 623, "bmc port") - - errHelp = errors.New("usage: -bandtype inband|outband") -) - -func main() { - flag.Parse() - - log := logger.New() - switch *band { - case "inband": - inband(log) - case "outband": - outband(log) - default: - fmt.Printf("%s\n", errHelp) - os.Exit(1) + log logger.Logger + + bandtype string + user string + password string + host string + port int + + bandtypeFlag = &cli.StringFlag{ + Name: "bandtype", + Value: "outband", + Usage: "inband/outband", + Destination: &bandtype, } -} - -func inband(log logger.Logger) { - ib, err := connect.InBand(log) - if err != nil { - panic(err) + userFlag = &cli.StringFlag{ + Name: "user", + Value: "ADMIN", + Usage: "bmc user", + Destination: &user, } - uuid, err := ib.UUID() - if err != nil { - panic(err) + passwordFlag = &cli.StringFlag{ + Name: "password", + Value: "", + Usage: "bmc password", + Destination: &password, } - fmt.Printf("UUID:%s\n", uuid) -} - -func outband(log logger.Logger) { - ob, err := connect.OutBand(*host, *port, *user, *password, log) - if err != nil { - panic(err) + hostFlag = &cli.StringFlag{ + Name: "host", + Value: "localhost", + Usage: "bmc host", + Destination: &host, } - - uu := make(map[string]string) - ee := make(map[string]error) - - b := ob.Board() - fmt.Printf("Board:\n%#v\n", b) - fmt.Printf("Power:\n%#v\n", b.PowerMetric) - fmt.Printf("PowerSupplies:\n%#v\n", b.PowerSupplies) - - bmc, err := ob.BMCConnection().BMC() - if err != nil { - ee["BMCConnection.BMC"] = err + portFlag = &cli.IntFlag{ + Name: "port", + Value: 623, + Usage: "bmc port", + Destination: &port, } - fmt.Printf("BMC:\n%#v\n", bmc) - - _, err = ob.UUID() - if err != nil { - ee["UUID"] = err + flags = []cli.Flag{ + bandtypeFlag, + hostFlag, + portFlag, + userFlag, + passwordFlag, } + outBandBMCConnection api.OutBandBMCConnection +) - ps, err := ob.PowerState() - if err != nil { - ee["PowerState"] = err - } - if ps == hal.PowerUnknownState { - uu["PowerState"] = "unexpected power state: PowerUnknownState" - } - err = ob.PowerOff() - if err != nil { - fmt.Printf("error during power off: %v\n", err) +func main() { + log = logger.New() + + app := &cli.App{ + Name: "hal", + Usage: "try bmc commands", + Commands: []*cli.Command{ + uuidCmd, + boardCmd, + ledCmd, + powerCmd, + }, } - board := ob.Board() - fmt.Println("LED: " + board.IndicatorLED) - - err = ob.PowerCycle() - if err != nil { - ee["PowerCycle"] = err + if err := app.Run(os.Args); err != nil { + panic(err) } - board = ob.Board() - fmt.Println("LED: " + board.IndicatorLED) - - if false { - err = ob.PowerOff() - if err != nil { - fmt.Printf("error during power off: %v\n", err) - } - - time.Sleep(10 * time.Second) + if outBandBMCConnection != nil { + outBandBMCConnection.Close() + } - err = ob.PowerOn() - if err != nil { - fmt.Printf("error during power on: %v\n", err) - } + os.Exit(1) +} - // ipmitool sel - err = ob.IdentifyLEDState(hal.IdentifyLEDStateOff) - if err != nil { - ee["IdentifyLEDState"] = err - } - err = ob.IdentifyLEDOn() +func getHalConnection(log logger.Logger) (hal.Hal, error) { + switch bandtype { + case "inband": + ib, err := connect.InBand(log) if err != nil { - ee["IdentifyLEDOn"] = err + return nil, err } - err = ob.IdentifyLEDOff() + return ib, nil + case "outband": + ob, err := connect.OutBand(host, port, user, password, log) if err != nil { - ee["IdentifyLEDOff"] = err - } - - //_, err = ob.UpdateBIOS() - //if err != nil { - // ee["UpdateBIOS"] = err - //} - // - //_, err = ob.UpdateBMC() - //if err != nil { - // ee["UpdateBMC"] = err - //} - } - - if len(uu) > 0 { - fmt.Println("Unexpected things:") - for m, u := range uu { - fmt.Printf("%s: %s\n", m, u) + return nil, err } - } - - if len(ee) > 0 { - fmt.Println("Failed checks:") - for m, err := range ee { - fmt.Printf("%s: %s\n", m, err.Error()) - } - } else { - fmt.Println("Check succeeded") + outBandBMCConnection = ob.BMCConnection() + return ob, nil + default: + return nil, fmt.Errorf("unknown bandtype %s", bandtype) } } + +// func outband(log logger.Logger) { +// ob, err := connect.OutBand(*host, *port, *user, *password, log) +// if err != nil { +// panic(err) +// } + +// uu := make(map[string]string) +// ee := make(map[string]error) + +// b := ob.Board() +// fmt.Printf("Board:\n%#v\n", b) +// fmt.Printf("Power:\n%#v\n", b.PowerMetric) +// fmt.Printf("PowerSupplies:\n%#v\n", b.PowerSupplies) + +// bmc, err := ob.BMCConnection().BMC() +// if err != nil { +// ee["BMCConnection.BMC"] = err +// } +// fmt.Printf("BMC:\n%#v\n", bmc) + +// _, err = ob.UUID() +// if err != nil { +// ee["UUID"] = err +// } + +// ps, err := ob.PowerState() +// if err != nil { +// ee["PowerState"] = err +// } +// if ps == hal.PowerUnknownState { +// uu["PowerState"] = "unexpected power state: PowerUnknownState" +// } +// err = ob.PowerOff() +// if err != nil { +// fmt.Printf("error during power off: %v\n", err) +// } + +// board := ob.Board() +// fmt.Println("LED: " + board.IndicatorLED) + +// err = ob.PowerCycle() +// if err != nil { +// ee["PowerCycle"] = err +// } + +// board = ob.Board() +// fmt.Println("LED: " + board.IndicatorLED) + +// if false { +// err = ob.PowerOff() +// if err != nil { +// fmt.Printf("error during power off: %v\n", err) +// } + +// time.Sleep(10 * time.Second) + +// err = ob.PowerOn() +// if err != nil { +// fmt.Printf("error during power on: %v\n", err) +// } + +// // ipmitool sel +// err = ob.IdentifyLEDState(hal.IdentifyLEDStateOff) +// if err != nil { +// ee["IdentifyLEDState"] = err +// } +// err = ob.IdentifyLEDOn() +// if err != nil { +// ee["IdentifyLEDOn"] = err +// } +// err = ob.IdentifyLEDOff() +// if err != nil { +// ee["IdentifyLEDOff"] = err +// } + +// //_, err = ob.UpdateBIOS() +// //if err != nil { +// // ee["UpdateBIOS"] = err +// //} +// // +// //_, err = ob.UpdateBMC() +// //if err != nil { +// // ee["UpdateBMC"] = err +// //} +// } + +// if len(uu) > 0 { +// fmt.Println("Unexpected things:") +// for m, u := range uu { +// fmt.Printf("%s: %s\n", m, u) +// } +// } + +// if len(ee) > 0 { +// fmt.Println("Failed checks:") +// for m, err := range ee { +// fmt.Printf("%s: %s\n", m, err.Error()) +// } +// } else { +// fmt.Println("Check succeeded") +// } +// } diff --git a/cli/power.go b/cli/power.go new file mode 100644 index 0000000..09761e1 --- /dev/null +++ b/cli/power.go @@ -0,0 +1,137 @@ +package main + +import ( + "fmt" + + "github.com/avast/retry-go/v4" + "github.com/metal-stack/go-hal" + "github.com/urfave/cli/v2" +) + +var powerCmd = &cli.Command{ + Name: "power", + Usage: "gather and modify machine power state", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + return nil + }, + Subcommands: []*cli.Command{ + { + Name: "on", + Usage: "power machine on", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + err = c.PowerOn() + if err != nil { + return err + } + retry.Do(func() error { + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + if state != hal.PowerOnState { + return fmt.Errorf("state is still not %s", hal.PowerOnState.String()) + } + return nil + }) + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + return nil + }, + }, + { + Name: "off", + Usage: "power machine off", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + err = c.PowerOff() + if err != nil { + return err + } + retry.Do(func() error { + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + if state != hal.PowerOffState { + return fmt.Errorf("state is still not %s", hal.PowerOffState.String()) + } + return nil + }) + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + return nil + }, + }, + { + Name: "cycle", + Usage: "power cycle machine", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + + err = c.PowerCycle() + if err != nil { + return err + } + return nil + }, + }, + { + Name: "reset", + Usage: "power reset machine", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + state, err := c.PowerState() + if err != nil { + return err + } + log.Infow("power", "state", state.String()) + + err = c.PowerReset() + if err != nil { + return err + } + return nil + }, + }, + }, +} diff --git a/cli/uuid.go b/cli/uuid.go new file mode 100644 index 0000000..4cfc852 --- /dev/null +++ b/cli/uuid.go @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/urfave/cli/v2" +) + +var uuidCmd = &cli.Command{ + Name: "uuid", + Usage: "gather machine uuid", + Flags: flags, + Action: func(ctx *cli.Context) error { + c, err := getHalConnection(log) + if err != nil { + return err + } + uid, err := c.UUID() + if err != nil { + return err + } + log.Infow("uuid", "bandtype", bandtype, "host", host, "result", uid.String()) + return nil + }, +} diff --git a/go.mod b/go.mod index d5ec376..be71178 100644 --- a/go.mod +++ b/go.mod @@ -16,9 +16,13 @@ require ( require ( github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/urfave/cli/v2 v2.27.5 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.19.0 // indirect diff --git a/go.sum b/go.sum index 16a626d..5998804 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= @@ -19,6 +21,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU= github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs= github.com/stmcginnis/gofish v0.20.0 h1:hH2V2Qe898F2wWT1loApnkDUrXXiLKqbSlMaH3Y1n08= @@ -26,8 +30,12 @@ github.com/stmcginnis/gofish v0.20.0/go.mod h1:PzF5i8ecRG9A2ol8XT64npKUunyraJ+7t github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/vmware/goipmi v0.0.0-20181114221114-2333cd82d702 h1:yx587LNBbOpIxzCBHBiI94Wx8ryIAFlu1w0lDwm64cA= github.com/vmware/goipmi v0.0.0-20181114221114-2333cd82d702/go.mod h1:YiWonbS/PuCtti3wt9jl+FvNEJ7c0nvmjGoEYxdjyk0= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= diff --git a/hal.go b/hal.go index 54ebffc..ca85c64 100644 --- a/hal.go +++ b/hal.go @@ -94,6 +94,36 @@ func GuessPowerState(powerState string) PowerState { return PowerUnknownState } +type Hal interface { + // Board return board information of the current connection + Board() *api.Board + + // UUID get the machine UUID + // current usage in metal-hammer + UUID() (*uuid.UUID, error) + + // PowerState returns the power state of the server + PowerState() (PowerState, error) + // PowerOn set power state of the server to on + PowerOn() error + // PowerOff set power state of the server to off + PowerOff() error + // PowerReset reset the power state of the server + PowerReset() error + // PowerCycle cycle the power state of the server + PowerCycle() error + + // IdentifyLEDState get the identify LED state + IdentifyLEDState(IdentifyLEDState) error + // IdentifyLEDOn set the identify LED to on + IdentifyLEDOn() error + // IdentifyLEDOff set the identify LED to off + IdentifyLEDOff() error + + // Describe print a basic information about this connection + Describe() string +} + // InBand get and set settings from the server via the inband interface. type InBand interface { // Board return board information of the current connection @@ -103,6 +133,10 @@ type InBand interface { // current usage in metal-hammer UUID() (*uuid.UUID, error) + // PowerState returns the power state of the server + PowerState() (PowerState, error) + // PowerOn set power state of the server to on + PowerOn() error // PowerOff set power state of the server to off PowerOff() error // PowerReset reset the power state of the server diff --git a/internal/redfish/redfish.go b/internal/redfish/redfish.go index 1c5c899..ff0b7ad 100644 --- a/internal/redfish/redfish.go +++ b/internal/redfish/redfish.go @@ -176,11 +176,24 @@ func (c *APIClient) PowerState() (hal.PowerState, error) { } func (c *APIClient) PowerOn() error { - // TODO: check if this is enough for supermicro + state, err := c.PowerState() + if err != nil { + return err + } + if state == hal.PowerOnState { + return nil + } return c.setPower(redfish.OnResetType) } func (c *APIClient) PowerOff() error { + state, err := c.PowerState() + if err != nil { + return err + } + if state == hal.PowerOffState { + return nil + } return c.setPower(redfish.ForceOffResetType) } diff --git a/internal/vendors/dell/dell.go b/internal/vendors/dell/dell.go index 28a88e2..fce6b7e 100644 --- a/internal/vendors/dell/dell.go +++ b/internal/vendors/dell/dell.go @@ -40,6 +40,10 @@ func (ob *outBand) BMCConnection() api.OutBandBMCConnection { } } +func (ob *outBand) Close() { + ob.Redfish.APIClient.Logout() +} + func (c *bmcConnectionOutBand) BMC() (*api.BMC, error) { board, err := c.outBand.Redfish.BoardInfo() if err != nil { diff --git a/internal/vendors/lenovo/lenovo.go b/internal/vendors/lenovo/lenovo.go index 3c46995..6bba51d 100644 --- a/internal/vendors/lenovo/lenovo.go +++ b/internal/vendors/lenovo/lenovo.go @@ -56,11 +56,23 @@ func OutBand(r *redfish.APIClient, board *api.Board) hal.OutBand { } } +func (ob *outBand) Close() { + ob.Redfish.APIClient.Logout() +} + // InBand + +// PowerState implements hal.InBand. +func (ib *inBand) PowerState() (hal.PowerState, error) { + return hal.PowerOnState, nil +} + +func (ib *inBand) PowerOn() error { + return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerDown) +} func (ib *inBand) PowerOff() error { return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerDown) } - func (ib *inBand) PowerCycle() error { return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerCycle) } diff --git a/internal/vendors/supermicro/supermicro.go b/internal/vendors/supermicro/supermicro.go index 7a25ac7..b2094ad 100644 --- a/internal/vendors/supermicro/supermicro.go +++ b/internal/vendors/supermicro/supermicro.go @@ -45,6 +45,11 @@ type ( } ) +// PowerState implements hal.InBand. +func (ib *inBand) PowerState() (hal.PowerState, error) { + return hal.PowerOnState, nil +} + // InBand creates an inband connection to a supermicro server. func InBand(board *api.Board, log logger.Logger) (hal.InBand, error) { s, err := newSum(sumBin, board.Model, log) @@ -81,6 +86,9 @@ func OutBand(r *redfish.APIClient, board *api.Board, ip string, ipmiPort int, us func (ib *inBand) PowerOff() error { return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerDown) } +func (ib *inBand) PowerOn() error { + return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerDown) +} func (ib *inBand) PowerCycle() error { return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerCycle) @@ -148,6 +156,10 @@ func (c *bmcConnection) User() api.BMCUser { } } +func (ob *outBand) Close() { + ob.Redfish.APIClient.Logout() +} + func (c *bmcConnection) Present() bool { return c.IpmiTool.DevicePresent() } diff --git a/internal/vendors/vagrant/vagrant.go b/internal/vendors/vagrant/vagrant.go index c978db7..62af4cd 100644 --- a/internal/vendors/vagrant/vagrant.go +++ b/internal/vendors/vagrant/vagrant.go @@ -54,7 +54,20 @@ func OutBand(board *api.Board, ip string, ipmiPort int, user, password string) h } } +func (ob *outBand) Close() { + ob.Redfish.APIClient.Logout() +} + // InBand + +// PowerState implements hal.InBand. +func (ib *inBand) PowerState() (hal.PowerState, error) { + return hal.PowerOnState, nil +} +func (ib *inBand) PowerOn() error { + return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerDown) +} + func (ib *inBand) PowerOff() error { return ib.IpmiTool.SetChassisControl(ipmi.ChassisControlPowerDown) } diff --git a/pkg/api/types.go b/pkg/api/types.go index b8bcb25..a534467 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -115,6 +115,8 @@ type BMCConnection interface { type OutBandBMCConnection interface { // BMC returns the actual BMC details BMC() (*BMC, error) + // Close this session + Close() } // BMC Base Management Controller details