Skip to content

Commit

Permalink
Fetch bmc details asynchronously (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sandro Koll authored Nov 23, 2020
1 parent 1d5762c commit 01a8328
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 184 deletions.
4 changes: 2 additions & 2 deletions domain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ type Config struct {
}

func (c Config) String() string {
return fmt.Sprintf("loglevel:%s partition:%s leasefile:%s debounce interval:%s report interval:%s metal-api url:%s ipmiport:%d ipmiuser:%s",
c.LogLevel, c.PartitionID, c.LeaseFile, c.DebounceInterval, c.ReportInterval, c.MetalAPIURL, c.IpmiPort, c.IpmiUser)
return fmt.Sprintf("loglevel:%s partition:%s leasefile:%s debounce interval:%s report interval:%s metal-api url:%s ipmiport:%d ipmiuser:%s, ignored-macs:%v",
c.LogLevel, c.PartitionID, c.LeaseFile, c.DebounceInterval, c.ReportInterval, c.MetalAPIURL, c.IpmiPort, c.IpmiUser, c.IgnoreMacs)
}
93 changes: 0 additions & 93 deletions internal/bmc/uuid.go

This file was deleted.

45 changes: 45 additions & 0 deletions internal/leases/bmc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package leases

import (
"github.com/metal-stack/go-hal/connect"
halzap "github.com/metal-stack/go-hal/pkg/logger/zap"
"github.com/metal-stack/metal-go/api/models"
)

func (i *ReportItem) EnrichWithBMCDetails(ipmiPort int, ipmiUser, ipmiPassword string) {
ob, err := connect.OutBand(i.Ip, ipmiPort, ipmiUser, ipmiPassword, halzap.New(i.Log))
if err != nil {
i.Log.Errorw("could not establish outband connection to device bmc", "mac", i.Mac, "ip", i.Ip, "err", err)
return
}

bmcDetails, err := ob.BMCConnection().BMC()
if err == nil {
i.BmcVersion = &bmcDetails.FirmwareRevision
i.FRU = &models.V1MachineFru{
BoardMfg: bmcDetails.BoardMfg,
BoardMfgSerial: bmcDetails.BoardMfgSerial,
BoardPartNumber: bmcDetails.BoardPartNumber,
ChassisPartNumber: bmcDetails.ChassisPartNumber,
ChassisPartSerial: bmcDetails.ChassisPartSerial,
ProductManufacturer: bmcDetails.ProductManufacturer,
ProductPartNumber: bmcDetails.ProductPartNumber,
ProductSerial: bmcDetails.ProductSerial,
}
} else {
i.Log.Warnw("could not retrieve bmc details of device", "mac", i.Mac, "ip", i.Ip, "err", err)
}

board := ob.Board()
if board != nil {
i.BiosVersion = &board.BiosVersion
}

u, err := ob.UUID()
if err == nil {
str := u.String()
i.UUID = &str
} else {
i.Log.Warnw("could not determine uuid of device", "mac", i.Mac, "ip", i.Ip, "err", err)
}
}
31 changes: 30 additions & 1 deletion internal/leases/types.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package leases

import "time"
import (
"github.com/metal-stack/metal-go/api/models"
"go.uber.org/zap"
"time"
)

type Lease struct {
Mac string
Expand All @@ -10,3 +14,28 @@ type Lease struct {
}

type Leases []Lease

type ReportItem struct {
Lease
Log *zap.SugaredLogger
UUID *string
BmcVersion *string
BiosVersion *string
FRU *models.V1MachineFru
}

func NewReportItem(l Lease, log *zap.SugaredLogger) *ReportItem {
return &ReportItem{
Lease: l,
Log: log,
}
}

func (i *ReportItem) MacContainedIn(macs []string) bool {
for _, m := range macs {
if m == i.Mac {
return true
}
}
return false
}
93 changes: 26 additions & 67 deletions internal/reporter/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,100 +2,57 @@ package reporter

import (
"github.com/metal-stack/bmc-catcher/domain"
"github.com/metal-stack/bmc-catcher/internal/bmc"
"github.com/metal-stack/bmc-catcher/internal/leases"
"github.com/metal-stack/go-hal/connect"
halzap "github.com/metal-stack/go-hal/pkg/logger/zap"
metalgo "github.com/metal-stack/metal-go"
"github.com/metal-stack/metal-go/api/models"
"go.uber.org/zap"
)

// Reporter reports information about bmc, bios and dhcp ip of bmc to metal-api
type Reporter struct {
cfg *domain.Config
log *zap.SugaredLogger
driver *metalgo.Driver
uuidCache *bmc.UUIDCache
ipmiPort int
ipmiUser string
ipmiPassword string
cfg *domain.Config
Log *zap.SugaredLogger
driver *metalgo.Driver
}

// NewReporter will create a reporter for MachineIpmiReports
func NewReporter(cfg *domain.Config, uuidCache *bmc.UUIDCache, log *zap.SugaredLogger, ipmiPort int, ipmiUser, ipmiPassword string) (*Reporter, error) {
func NewReporter(cfg *domain.Config, log *zap.SugaredLogger) (*Reporter, error) {
driver, err := metalgo.NewDriver(cfg.MetalAPIURL.String(), "", cfg.MetalAPIHMACKey, metalgo.AuthType("Metal-Edit"))
if err != nil {
return nil, err
}
return &Reporter{
cfg: cfg,
log: log,
driver: driver,
uuidCache: uuidCache,
ipmiPort: ipmiPort,
ipmiUser: ipmiUser,
ipmiPassword: ipmiPassword,
cfg: cfg,
Log: log,
driver: driver,
}, nil
}

// Report will send all gathered information about machines to the metal-api
func (r Reporter) Report(ls leases.Leases) error {
active := ls.FilterActive()
byMac := active.LatestByMac()
r.log.Infow("reporting leases to metal-api", "all", len(ls), "active", len(active), "uniqueActive", len(byMac))
func (r Reporter) Report(items []*leases.ReportItem) error {
partitionID := r.cfg.PartitionID
reports := make(map[string]models.V1MachineIpmiReport)

outer:
for mac, v := range byMac {
for _, m := range r.cfg.IgnoreMacs {
if m == mac {
continue outer
}
}

ip := v.Ip
uuid, err := r.uuidCache.Get(mac, ip)
if err != nil {
r.log.Errorw("could not determine uuid of device", "mac", mac, "ip", ip, "err", err)
continue
}
for _, item := range items {
mac := item.Mac

ob, err := connect.OutBand(v.Ip, r.ipmiPort, r.ipmiUser, r.ipmiPassword, halzap.New(r.log))
if err != nil {
r.log.Errorw("could not establish outband connection to device bmc", "mac", mac, "ip", ip, "err", err)
if item.MacContainedIn(r.cfg.IgnoreMacs) {
continue
}

biosversion := ""
board := ob.Board()
if board != nil {
biosversion = board.BiosVersion
}
bmcDetails, err := ob.BMCConnection().BMC()
if err != nil {
r.log.Errorw("could not retrieve bmc details of device", "mac", mac, "ip", ip, "err", err)
ip := item.Ip
if item.UUID == nil {
r.Log.Errorw("could not determine uuid of device", "mac", mac, "ip", ip)
continue
}

fru := &models.V1MachineFru{
BoardMfg: bmcDetails.BoardMfg,
BoardMfgSerial: bmcDetails.BoardMfgSerial,
BoardPartNumber: bmcDetails.BoardPartNumber,
ChassisPartNumber: bmcDetails.ChassisPartNumber,
ChassisPartSerial: bmcDetails.ChassisPartSerial,
ProductManufacturer: bmcDetails.ProductManufacturer,
ProductPartNumber: bmcDetails.ProductPartNumber,
ProductSerial: bmcDetails.ProductSerial,
}
report := models.V1MachineIpmiReport{
BMCIP: &ip,
BMCVersion: &bmcDetails.FirmwareRevision,
BIOSVersion: &biosversion,
FRU: fru,
BMCIP: &item.Ip,
BMCVersion: item.BmcVersion,
BIOSVersion: item.BiosVersion,
FRU: item.FRU,
}
reports[*uuid] = report
reports[*item.UUID] = report
}

mir := metalgo.MachineIPMIReports{
Expand All @@ -108,12 +65,14 @@ outer:
if err != nil {
return err
}
r.log.Infof("updated ipmi information of %d machines", len(ok.Response.Updated))
for _, uuid := range ok.Response.Updated {
r.log.Infow("ipmi information was updated for machine", "id", uuid)

r.Log.Infof("updated ipmi information of %d machines", len(ok.Response.Updated))
for _, u := range ok.Response.Updated {
r.Log.Infow("ipmi information was updated for machine", "uuid", u)
}
for _, uuid := range ok.Response.Created {
r.log.Infow("ipmi information was set and machine was created", "id", uuid)
for _, u := range ok.Response.Created {
r.Log.Infow("ipmi information was set and machine was created", "uuid", u)
}

return nil
}
Loading

0 comments on commit 01a8328

Please sign in to comment.