Skip to content
This repository has been archived by the owner on Jul 18, 2024. It is now read-only.

Commit

Permalink
implement metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
Alva8756 committed Mar 19, 2024
1 parent 8b5d2ef commit 009e62b
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 18 deletions.
39 changes: 39 additions & 0 deletions internal/fleetdb/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ package internalfleetdb

import (
"encoding/json"
"fmt"
"os"

"github.com/metal-toolbox/component-inventory/pkg/api/constants"
"github.com/metal-toolbox/component-inventory/pkg/api/types"
fleetdb "github.com/metal-toolbox/fleetdb/pkg/api/v1"
)

const (
uefiVariablesKey = "uefi-variables"
ssMetadataAttributeFound = "__ss_found"
)

func deviceVendorAttributes(cid *types.ComponentInventoryDevice) (map[string]string, *fleetdb.Attributes, error) {
deviceVendorData := map[string]string{
constants.ServerSerialAttributeKey: "unknown",
Expand Down Expand Up @@ -50,3 +57,35 @@ func attributeByNamespace(ns string, attributes []fleetdb.Attributes) *fleetdb.A

return nil
}

// mustFilterAssetMetadata processes the asset inventory metadata to filter out fields we'll turn into versioned attributes (e.g. UEFIVariables)
func mustFilterAssetMetadata(inventory map[string]string) json.RawMessage {
excludedKeys := map[string]struct{}{
uefiVariablesKey: {},
}

filtered := make(map[string]string)

for k, v := range inventory {
if _, ok := excludedKeys[k]; ok {
continue
}
filtered[k] = v
}

byt, err := json.Marshal(filtered)
if err != nil {
panic("serializing metadata string map")
}

return byt
}

// serverBIOSConfigNS returns the namespace server bios configuration are stored in.
func serverBIOSConfigNS(appKind types.AppKind) string {
if biosConfigNS := os.Getenv("CIS_FLEETDB_BIOS_CONFIG_NS"); biosConfigNS != "" {
return biosConfigNS
}

return fmt.Sprintf("%s.%s.bios_configuration", constants.FleetDBNSPrefix, appKind)
}
70 changes: 58 additions & 12 deletions internal/fleetdb/fleetdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package internalfleetdb
import (
"context"
"encoding/json"
"fmt"

"github.com/google/uuid"
"github.com/metal-toolbox/component-inventory/internal/app"
Expand All @@ -17,7 +16,8 @@ type Client interface {
GetServer(context.Context, uuid.UUID) (*fleetdb.Server, *fleetdb.ServerResponse, error)
GetComponents(context.Context, uuid.UUID, *fleetdb.PaginationParams) (fleetdb.ServerComponentSlice, *fleetdb.ServerResponse, error)
UpdateAttributes(context.Context, *fleetdb.Server, *types.ComponentInventoryDevice, *zap.Logger) error
UpdateServerBIOSConfig() error
UpdateServerBIOSConfig(context.Context, *fleetdb.Server, *types.ComponentInventoryDevice, *zap.Logger) error
UpdateServerMetadataAttributes(context.Context, uuid.UUID, *types.ComponentInventoryDevice, *zap.Logger) error
}

// Creates a new Client, with reasonable defaults
Expand All @@ -37,7 +37,8 @@ func NewFleetDBClient(cfg *app.Configuration) (Client, error) {
}

type fleetDBClient struct {
client *fleetdb.Client
client *fleetdb.Client
appKind types.AppKind
}

func (fc fleetDBClient) GetServer(ctx context.Context, id uuid.UUID) (*fleetdb.Server, *fleetdb.ServerResponse, error) {
Expand Down Expand Up @@ -78,13 +79,12 @@ func createUpdateServerAttributes(ctx context.Context, c *fleetdb.Client, server
return err
}

updatedVendorData := existingVendorData
var changes bool
for key := range newVendorData {
if updatedVendorData[key] == "" || updatedVendorData[key] == "unknown" {
if existingVendorData[key] == "" || existingVendorData[key] == "unknown" {
if newVendorData[key] != "unknown" {
changes = true
updatedVendorData[key] = newVendorData[key]
existingVendorData[key] = newVendorData[key]
}
}
}
Expand All @@ -93,8 +93,8 @@ func createUpdateServerAttributes(ctx context.Context, c *fleetdb.Client, server
return nil
}

if len(updatedVendorData) > 0 {
updateBytes, err := json.Marshal(updatedVendorData)
if len(existingVendorData) > 0 {
updateBytes, err := json.Marshal(existingVendorData)
if err != nil {
return err
}
Expand All @@ -107,10 +107,56 @@ func createUpdateServerAttributes(ctx context.Context, c *fleetdb.Client, server
return nil
}

func (fc fleetDBClient) UpdateServerBIOSConfig() error {
return createUpdateServerBIOSConfig()
func (fc fleetDBClient) UpdateServerBIOSConfig(ctx context.Context, server *fleetdb.Server, dev *types.ComponentInventoryDevice, log *zap.Logger) error {
// Nothing to publish
if len(*dev.BiosCfg) == 0 {
log.Info("no bios configuration collected")
return nil
}

// marshal metadata from device
bc, err := json.Marshal(dev.BiosCfg)
if err != nil {
log.Error("invalid biosConfig")
return err
}

va := fleetdb.VersionedAttributes{
Namespace: serverBIOSConfigNS(fc.appKind),
Data: bc,
}

_, err = fc.client.CreateVersionedAttributes(ctx, server.UUID, va)

return err
}

func createUpdateServerBIOSConfig() error {
return fmt.Errorf("unimplemented")
func (fc fleetDBClient) UpdateServerMetadataAttributes(ctx context.Context, serverID uuid.UUID, dev *types.ComponentInventoryDevice, log *zap.Logger) error {
// no metadata reported in inventory from device
if dev.Inv == nil || len(dev.Inv.Metadata) == 0 {
// XXX: should delete the metadata on the server-service record!
return nil
}

// marshal metadata from device
metadata := mustFilterAssetMetadata(dev.Inv.Metadata)

attribute := fleetdb.Attributes{
Namespace: constants.ServerMetadataAttributeNS,
Data: metadata,
}

// XXX: This would be much easier if serverservice/fleetdb supported upsert
// current asset metadata has no attributes set and no metadata attribute, create one
if _, ok := dev.Inv.Metadata[ssMetadataAttributeFound]; !ok {
_, err := fc.client.CreateAttributes(ctx, serverID, attribute)
log.Info("creating server attributes")
return err
}

// update vendor, model attributes
_, err := fc.client.UpdateAttributes(ctx, serverID, constants.ServerMetadataAttributeNS, metadata)

return err

}
10 changes: 5 additions & 5 deletions pkg/api/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ const (
// server server service BMC address attribute key found under the bmcAttributeNamespace
BmcIPAddressAttributeKey = "address"

// serverservice namespace prefix the data is stored in.
ServerServiceNSPrefix = "sh.hollow.alloy"
// fleetdb namespace prefix the data is stored in.
FleetDBNSPrefix = "sh.hollow.alloy"

// server vendor, model attributes are stored in this namespace.
ServerVendorAttributeNS = ServerServiceNSPrefix + ".server_vendor_attributes"
ServerVendorAttributeNS = FleetDBNSPrefix + ".server_vendor_attributes"

// additional server metadata are stored in this namespace.
ServerMetadataAttributeNS = ServerServiceNSPrefix + ".server_metadata_attributes"
ServerMetadataAttributeNS = FleetDBNSPrefix + ".server_metadata_attributes"

// errors that occurred when connecting/collecting inventory from the bmc are stored here.
ServerBMCErrorsAttributeNS = ServerServiceNSPrefix + ".server_bmc_errors"
ServerBMCErrorsAttributeNS = FleetDBNSPrefix + ".server_bmc_errors"

// server service server serial attribute key
ServerSerialAttributeKey = "serial"
Expand Down
12 changes: 12 additions & 0 deletions pkg/api/routes/inventory.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,21 @@ import (

func processInband(ctx context.Context, c internalfleetdb.Client, server *fleetdb.Server, dev *types.ComponentInventoryDevice, log *zap.Logger) error { //nolint
log.Info("processing", zap.String("server", server.Name), zap.String("device", dev.Inv.Serial))
// update bisconfig
if err := c.UpdateServerBIOSConfig(ctx, server, dev, log); err != nil {
return err
}

// create/update server serial, vendor, model attributes
if err := c.UpdateAttributes(ctx, server, dev, log); err != nil {
return err
}

// create update server metadata attributes
if err := c.UpdateServerMetadataAttributes(ctx, server.UUID, dev, log); err != nil {
return err
}

return errors.New("not implemented")
}

Expand Down
5 changes: 4 additions & 1 deletion pkg/api/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"github.com/bmc-toolbox/common"
)

type BiosConfig map[string]string
type (
BiosConfig map[string]string
AppKind string
)

type ComponentInventoryDevice struct {
ID string `json:"id,omitempty"`
Expand Down

0 comments on commit 009e62b

Please sign in to comment.