Skip to content

Instantly share code, notes, and snippets.

@ddelazerda
Created February 20, 2020 00:03
Show Gist options
  • Save ddelazerda/2f6b763a3fffe5e1a30b317acd4c4c41 to your computer and use it in GitHub Desktop.
Save ddelazerda/2f6b763a3fffe5e1a30b317acd4c4c41 to your computer and use it in GitHub Desktop.
golang gebn/bmc library test
package main
import (
"context"
"fmt"
"github.com/gebn/bmc"
"github.com/gebn/bmc/pkg/ipmi"
"io"
"log"
"time"
)
type Manager struct {
session bmc.Session
transport io.Closer
Context context.Context
Timeout time.Duration
Address string
Username string
Password string
}
func (m *Manager) newSession(ctx context.Context) error {
transport, err := bmc.DialV2(m.Address)
if err != nil {
return err
}
session, err := transport.NewSession(ctx, &bmc.SessionOpts{
Username: m.Username,
Password: []byte(m.Password),
MaxPrivilegeLevel: ipmi.PrivilegeLevelAdministrator,
})
if err != nil {
transport.Close()
return err
}
m.session = session
m.transport = transport
return nil
}
func (m *Manager) Close(ctx context.Context) {
if m.session == nil {
return
}
m.session.Close(ctx)
m.transport.Close()
m.session = nil
m.transport = nil
}
func (m *Manager) sendCommand(ctx context.Context, cmd ipmi.Command) error {
if m.session == nil {
if err := m.newSession(ctx); err != nil {
return fmt.Errorf("could not obtain session for %v: %v", m.Address, err)
}
}
cmdFirstCtx, cancel := context.WithTimeout(ctx, time.Second*2)
defer cancel()
if err := bmc.ValidateResponse(m.session.SendCommand(cmdFirstCtx, cmd)); err != nil {
cancelCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
m.Close(cancelCtx)
if err := m.newSession(ctx); err != nil {
return err
}
cmdSecondCtx, cancel := context.WithTimeout(ctx, time.Second*2)
defer cancel()
if err := bmc.ValidateResponse(m.session.SendCommand(cmdSecondCtx, cmd)); err != nil {
m.Close(ctx)
return err
}
}
return nil
}
func (m *Manager) chassisStatus(ctx context.Context) (*ipmi.GetChassisStatusRsp, error) {
cmd := &ipmi.GetChassisStatusCmd{}
if err := m.sendCommand(ctx, cmd); err != nil {
return nil, err
}
return &cmd.Rsp, nil
}
func printChassisStatus(status *ipmi.GetChassisStatusRsp) {
fmt.Println("Chassis:")
fmt.Printf("\tPowered on: %v\n", status.PoweredOn)
fmt.Printf("\tOn power restore: %v\n", status.PowerRestorePolicy)
fmt.Printf("\tIdentification: %v\n", status.ChassisIdentifyState)
fmt.Printf("\tIntrusion: %v\n", status.Intrusion)
fmt.Printf("\tPower fault: %v\n", status.PowerFault)
fmt.Printf("\tCooling fault: %v\n", status.CoolingFault)
fmt.Printf("\tDrive fault: %v\n", status.DriveFault)
}
func main() {
timeout := time.Second * 10
ctx := context.Background()
m := &Manager{
Address: "192.168.1.20",
Username: "user",
Password: "password",
Context: ctx,
Timeout: timeout,
}
s, err := m.chassisStatus(ctx)
if err != nil {
log.Fatal(err)
}
printChassisStatus(s)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment