Skip to content

Commit

Permalink
Show powersupply and power state (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
majst01 authored Oct 2, 2024
1 parent 647a984 commit 45c24e5
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 88 deletions.
112 changes: 96 additions & 16 deletions cmd/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,45 @@ var (
State: machine1.State,
Tags: machine1.Tags,
}
ipmiMachine2 = &models.V1MachineIPMIResponse{
Allocation: machine1.Allocation,
Bios: &models.V1MachineBIOS{
Version: pointer.Pointer("2.0"),
},
Changed: machine1.Changed,
Created: machine1.Created,
Description: machine1.Description,
Events: machine1.Events,
Hardware: machine1.Hardware,
ID: machine1.ID,
Ipmi: &models.V1MachineIPMI{
Address: pointer.Pointer("1.2.3.4"),
Bmcversion: pointer.Pointer("1.1"),
Fru: &models.V1MachineFru{
BoardPartNumber: "part123",
ChassisPartSerial: "chassis123",
ProductSerial: "product123",
},
LastUpdated: pointer.Pointer(strfmt.DateTime(testTime.Add(-5 * time.Second))),
Mac: pointer.Pointer("1.2.3.4"),
Powermetric: &models.V1PowerMetric{
Averageconsumedwatts: pointer.Pointer(float32(16.0)),
},
Powerstate: pointer.Pointer("ON"),
Powersupplies: []*models.V1PowerSupply{
{Status: &models.V1PowerSupplyStatus{Health: pointer.Pointer("OK")}},
{Status: &models.V1PowerSupplyStatus{Health: pointer.Pointer("NOT-OK")}},
},
},
Ledstate: &models.V1ChassisIdentifyLEDState{},
Liveliness: machine1.Liveliness,
Name: machine1.Name,
Partition: machine1.Partition,
Rackid: machine1.Rackid,
Size: machine1.Size,
State: machine1.State,
Tags: machine1.Tags,
}

machineIssue1 = &models.V1MachineIssue{
Description: pointer.Pointer("this is a test issue 1"),
Expand Down Expand Up @@ -458,21 +497,62 @@ func Test_MachineIPMICmd_MultiResult(t *testing.T) {
ipmiMachine1,
},
wantTable: pointer.Pointer(`
ID POWER IP MAC BOARD PART NUMBER BIOS BMC SIZE PARTITION RACK UPDATED
1 ●  (16.0W) 1.2.3.4 1.2.3.4 part123 2.0 1.1 1 1 rack-1 5s ago
ID POWER IP MAC BOARD PART NUMBER BIOS BMC SIZE PARTITION RACK UPDATED
1 ⏻ 16W 1.2.3.4 1.2.3.4 part123 2.0 1.1 1 1 rack-1 5s ago
`),
wantWideTable: pointer.Pointer(`
ID LAST EVENT STATUS POWER IP MAC BOARD PART NUMBER CHASSIS SERIAL PRODUCT SERIAL BIOS VERSION BMC VERSION SIZE PARTITION RACK UPDATED
1 Phoned Home ON 16W 1.2.3.4 1.2.3.4 part123 chassis123 product123 2.0 1.1 1 1 rack-1 5s ago
`),
template: pointer.Pointer("{{ .id }} {{ .name }}"),
wantTemplate: pointer.Pointer(`
1 machine-1
`),
wantMarkdown: pointer.Pointer(`
| ID | | POWER | IP | MAC | BOARD PART NUMBER | BIOS | BMC | SIZE | PARTITION | RACK | UPDATED |
|----|--|-------|---------|---------|-------------------|------|-----|------|-----------|--------|---------|
| 1 | | ⏻ 16W | 1.2.3.4 | 1.2.3.4 | part123 | 2.0 | 1.1 | 1 | 1 | rack-1 | 5s ago |
`),
},
{
name: "machine ipmi with broken powersupply",
cmd: func(want []*models.V1MachineIPMIResponse) []string {
return []string{"machine", "ipmi"}
},
mocks: &client.MetalMockFns{
Machine: func(mock *mock.Mock) {
mock.On("FindIPMIMachines", testcommon.MatchIgnoreContext(t, machine.NewFindIPMIMachinesParams().WithBody(&models.V1MachineFindRequest{
NicsMacAddresses: nil,
NetworkDestinationPrefixes: []string{},
NetworkIps: []string{},
NetworkIds: []string{},
Tags: []string{},
})), nil).Return(&machine.FindIPMIMachinesOK{
Payload: []*models.V1MachineIPMIResponse{
ipmiMachine2,
},
}, nil)
},
},
want: []*models.V1MachineIPMIResponse{
ipmiMachine2,
},
wantTable: pointer.Pointer(`
ID POWER IP MAC BOARD PART NUMBER BIOS BMC SIZE PARTITION RACK UPDATED
1 ⏻ 16W 1.2.3.4 1.2.3.4 part123 2.0 1.1 1 1 rack-1 5s ago
`),
wantWideTable: pointer.Pointer(`
ID LAST EVENT STATUS POWER IP MAC BOARD PART NUMBER CHASSIS SERIAL PRODUCT SERIAL BIOS VERSION BMC VERSION SIZE PARTITION RACK UPDATED
1 Phoned Home ON 16.00W 1.2.3.4 1.2.3.4 part123 chassis123 product123 2.0 1.1 1 1 rack-1 5s ago
ID LAST EVENT STATUS POWER IP MAC BOARD PART NUMBER CHASSIS SERIAL PRODUCT SERIAL BIOS VERSION BMC VERSION SIZE PARTITION RACK UPDATED
1 Phoned Home ON Power Supply NOT-OK 16W 1.2.3.4 1.2.3.4 part123 chassis123 product123 2.0 1.1 1 1 rack-1 5s ago
`),
template: pointer.Pointer("{{ .id }} {{ .name }}"),
wantTemplate: pointer.Pointer(`
1 machine-1
`),
wantMarkdown: pointer.Pointer(`
| ID | | POWER | IP | MAC | BOARD PART NUMBER | BIOS | BMC | SIZE | PARTITION | RACK | UPDATED |
|----|--|------------|---------|---------|-------------------|------|-----|------|-----------|--------|---------|
| 1 | | ●  (16.0W) | 1.2.3.4 | 1.2.3.4 | part123 | 2.0 | 1.1 | 1 | 1 | rack-1 | 5s ago |
| ID | | POWER | IP | MAC | BOARD PART NUMBER | BIOS | BMC | SIZE | PARTITION | RACK | UPDATED |
|----|--|-------|---------|---------|-------------------|------|-----|------|-----------|--------|---------|
| 1 | | ⏻ 16W | 1.2.3.4 | 1.2.3.4 | part123 | 2.0 | 1.1 | 1 | 1 | rack-1 | 5s ago |
`),
},
}
Expand Down Expand Up @@ -586,21 +666,21 @@ func Test_MachineIssuesCmd(t *testing.T) {
},
want: machineWithIssues,
wantTable: pointer.Pointer(`
ID POWER ALLOCATED LOCK REASON LAST EVENT WHEN ISSUES
1 ●  (16.0W) yes state Phoned Home 7d this is a test issue 1 (issue-1-id)
this is a test issue 2 (issue-2-id)
ID POWER ALLOCATED LOCK REASON LAST EVENT WHEN ISSUES
1 ⏻ 16W yes state Phoned Home 7d this is a test issue 1 (issue-1-id)
this is a test issue 2 (issue-2-id)
`),
wantWideTable: pointer.Pointer(`
ID NAME PARTITION PROJECT POWER STATE LOCK REASON LAST EVENT WHEN ISSUES REF URL DETAILS
1 machine-1 1 project-1 ON 16.00W state Phoned Home 7d this is a test issue 1 (issue-1-id) https://url-1 more details 1
ID NAME PARTITION PROJECT POWER STATE LOCK REASON LAST EVENT WHEN ISSUES REF URL DETAILS
1 machine-1 1 project-1 ON 16W state Phoned Home 7d this is a test issue 1 (issue-1-id) https://url-1 more details 1
this is a test issue 2 (issue-2-id) https://url-2 more details 2
`),
wantMarkdown: pointer.Pointer(`
| ID | POWER | ALLOCATED | | LOCK REASON | LAST EVENT | WHEN | ISSUES |
|----|------------|-----------|--|-------------|-------------|------|-------------------------------------|
| 1 | ●  (16.0W) | yes | | state | Phoned Home | 7d | this is a test issue 1 (issue-1-id) |
| | | | | | | | this is a test issue 2 (issue-2-id) |
| ID | POWER | ALLOCATED | | LOCK REASON | LAST EVENT | WHEN | ISSUES |
|----|-------|-----------|--|-------------|-------------|------|-------------------------------------|
| 1 | ⏻ 16W | yes | | state | Phoned Home | 7d | this is a test issue 1 (issue-1-id) |
| | | | | | | | this is a test issue 2 (issue-2-id) |
`),
},
}
Expand Down
6 changes: 4 additions & 2 deletions cmd/tableprinters/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
)

const (
dot = "●"
nbr = " "
dot = "●"
nbr = " "
poweron = "⏻"
powersleep = "⏾"
)

func depth(path string) uint {
Expand Down
25 changes: 19 additions & 6 deletions cmd/tableprinters/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,24 +225,37 @@ func (t *TablePrinter) MachineIPMITable(data []*models.V1MachineIPMIResponse, wi

func extractPowerState(ipmi *models.V1MachineIPMI) (short, wide string) {
if ipmi == nil || ipmi.Powerstate == nil {
return color.WhiteString(dot), wide
return color.WhiteString(poweron), wide
}

state := *ipmi.Powerstate
switch state {
case "ON":
short = color.GreenString(dot)
short = color.GreenString(poweron)
case "OFF":
short = color.RedString(dot)
short = color.GreenString(powersleep)
default:
short = color.WhiteString(dot)
short = color.WhiteString(poweron)
}

wide = state
for _, ps := range ipmi.Powersupplies {
if ps.Status == nil || ps.Status.Health == nil {
continue
}
if *ps.Status.Health != "OK" {
short = color.RedString(poweron)
wide = wide + nbr + "Power Supply" + nbr + *ps.Status.Health
}
if ps.Status.State != nil && *ps.Status.State != "Enabled" {
short = color.RedString(powersleep)
wide = wide + nbr + *ps.Status.State
}
}

if ipmi.Powermetric != nil {
short = fmt.Sprintf("%s"+nbr+nbr+"(%.1fW)", short, pointer.SafeDeref(ipmi.Powermetric.Averageconsumedwatts))
wide = fmt.Sprintf("%s %.2fW", wide, pointer.SafeDeref(ipmi.Powermetric.Averageconsumedwatts))
short = fmt.Sprintf("%s"+nbr+"%.0fW", short, pointer.SafeDeref(ipmi.Powermetric.Averageconsumedwatts))
wide = fmt.Sprintf("%s %.0fW", wide, pointer.SafeDeref(ipmi.Powermetric.Averageconsumedwatts))
}

return short, wide
Expand Down
39 changes: 19 additions & 20 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/go-openapi/strfmt v0.23.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/metal-stack/metal-go v0.36.0
github.com/metal-stack/metal-go v0.37.1
github.com/metal-stack/metal-lib v0.18.3
github.com/metal-stack/updater v1.2.2
github.com/metal-stack/v v1.0.3
Expand Down Expand Up @@ -91,7 +91,7 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hdevalence/ed25519consensus v0.2.0 // indirect
github.com/icza/dyno v0.0.0-20230330125955-09f820a8d9c0 // indirect
github.com/illarion/gonotify v1.0.1 // indirect
github.com/illarion/gonotify/v2 v2.0.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/insomniacslk/dhcp v0.0.0-20240227161007-c728f5dd21c8 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
Expand Down Expand Up @@ -140,34 +140,33 @@ require (
github.com/tailscale/golang-x-crypto v0.0.0-20240604161659-3fde5e568aa4 // indirect
github.com/tailscale/goupnp v1.0.1-0.20210804011211-c64d0f06ea05 // indirect
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a // indirect
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 // indirect
github.com/tailscale/netlink v1.1.1-0.20240822203006-4d49adab4de7 // indirect
github.com/tailscale/peercred v0.0.0-20240214030740-b535050b2aa4 // indirect
github.com/tailscale/web-client-prebuilt v0.0.0-20240226180453-5db17b287bf1 // indirect
github.com/tailscale/wireguard-go v0.0.0-20240731203015-71393c576b98 // indirect
github.com/tailscale/wireguard-go v0.0.0-20240905161824-799c1978fafc // indirect
github.com/tcnksm/go-httpstat v0.2.0 // indirect
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect
github.com/vishvananda/netlink v1.2.1-beta.2 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.mongodb.org/mongo-driver v1.16.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
go.mongodb.org/mongo-driver v1.17.0 // indirect
go.opentelemetry.io/otel v1.30.0 // indirect
go.opentelemetry.io/otel/metric v1.30.0 // indirect
go.opentelemetry.io/otel/trace v1.30.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go4.org/mem v0.0.0-20220726221520-4f986261bf13 // indirect
go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/net v0.28.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/term v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
golang.org/x/tools v0.25.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
google.golang.org/protobuf v1.34.2 // indirect
Expand All @@ -176,5 +175,5 @@ require (
gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
tailscale.com v1.72.1 // indirect
tailscale.com v1.74.1 // indirect
)
Loading

0 comments on commit 45c24e5

Please sign in to comment.