This repository has been archived by the owner on Jul 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
267 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package internalfleetdb | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"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" | ||
) | ||
|
||
func deviceVendorAttributes(cid *types.ComponentInventoryDevice) (map[string]string, *fleetdb.Attributes, error) { | ||
deviceVendorData := map[string]string{ | ||
constants.ServerSerialAttributeKey: "unknown", | ||
constants.ServerVendorAttributeKey: "unknown", | ||
constants.ServerModelAttributeKey: "unknown", | ||
} | ||
|
||
if cid.Inv != nil { | ||
if cid.Inv.Serial != "" { | ||
deviceVendorData[constants.ServerSerialAttributeKey] = cid.Inv.Serial | ||
} | ||
|
||
if cid.Inv.Model != "" { | ||
deviceVendorData[constants.ServerModelAttributeKey] = cid.Inv.Model | ||
} | ||
|
||
if cid.Inv.Vendor != "" { | ||
deviceVendorData[constants.ServerVendorAttributeKey] = cid.Inv.Vendor | ||
} | ||
} | ||
|
||
deviceVendorDataBytes, err := json.Marshal(deviceVendorData) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return deviceVendorData, &fleetdb.Attributes{ | ||
Namespace: constants.ServerVendorAttributeNS, | ||
Data: deviceVendorDataBytes, | ||
}, nil | ||
} | ||
|
||
// attributeByNamespace returns the attribute in the slice that matches the namespace | ||
func attributeByNamespace(ns string, attributes []fleetdb.Attributes) *fleetdb.Attributes { | ||
for _, attribute := range attributes { | ||
if attribute.Namespace == ns { | ||
return &attribute | ||
} | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package internalfleetdb | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
|
||
"github.com/google/uuid" | ||
"github.com/metal-toolbox/component-inventory/internal/app" | ||
"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" | ||
"go.uber.org/zap" | ||
) | ||
|
||
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 | ||
} | ||
|
||
// Creates a new Client, with reasonable defaults | ||
func NewFleetDBClient(cfg *app.Configuration) (Client, error) { | ||
client, err := fleetdb.NewClient(cfg.FleetDBAddress, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if cfg.FleetDBToken != "" { | ||
client.SetToken(cfg.FleetDBToken) | ||
} | ||
|
||
return &fleetDBClient{ | ||
client: client, | ||
}, nil | ||
} | ||
|
||
type fleetDBClient struct { | ||
client *fleetdb.Client | ||
} | ||
|
||
func (fc fleetDBClient) GetServer(ctx context.Context, id uuid.UUID) (*fleetdb.Server, *fleetdb.ServerResponse, error) { | ||
return fc.client.Get(ctx, id) | ||
} | ||
|
||
func (fc fleetDBClient) GetComponents(ctx context.Context, id uuid.UUID, params *fleetdb.PaginationParams) (fleetdb.ServerComponentSlice, *fleetdb.ServerResponse, error) { | ||
return fc.client.GetComponents(ctx, id, params) | ||
} | ||
|
||
func (fc fleetDBClient) UpdateAttributes(ctx context.Context, server *fleetdb.Server, dev *types.ComponentInventoryDevice, log *zap.Logger) error { | ||
return createUpdateServerAttributes(ctx, fc.client, server, dev, log) | ||
} | ||
|
||
// Functions below may be refactored in the near future. | ||
func createUpdateServerAttributes(ctx context.Context, c *fleetdb.Client, server *fleetdb.Server, dev *types.ComponentInventoryDevice, log *zap.Logger) error { | ||
newVendorData, newVendorAttrs, err := deviceVendorAttributes(dev) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// identify current vendor data in the inventory | ||
existingVendorAttrs := attributeByNamespace(constants.ServerVendorAttributeNS, server.Attributes) | ||
if existingVendorAttrs == nil { | ||
// create if none exists | ||
_, err = c.CreateAttributes(ctx, server.UUID, *newVendorAttrs) | ||
return err | ||
} | ||
|
||
// unpack vendor data from inventory | ||
existingVendorData := map[string]string{} | ||
if err := json.Unmarshal(existingVendorAttrs.Data, &existingVendorData); err != nil { | ||
// update vendor data since it seems to be invalid | ||
log.Warn("server vendor attributes data invalid, updating..") | ||
|
||
_, err = c.UpdateAttributes(ctx, server.UUID, constants.ServerVendorAttributeNS, newVendorAttrs.Data) | ||
|
||
return err | ||
} | ||
|
||
updatedVendorData := existingVendorData | ||
var changes bool | ||
for key := range newVendorData { | ||
if updatedVendorData[key] == "" || updatedVendorData[key] == "unknown" { | ||
if newVendorData[key] != "unknown" { | ||
changes = true | ||
updatedVendorData[key] = newVendorData[key] | ||
} | ||
} | ||
} | ||
|
||
if !changes { | ||
return nil | ||
} | ||
|
||
if len(updatedVendorData) > 0 { | ||
updateBytes, err := json.Marshal(updatedVendorData) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = c.UpdateAttributes(ctx, server.UUID, constants.ServerVendorAttributeNS, updateBytes) | ||
|
||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (fc fleetDBClient) UpdateServerBIOSConfig() error { | ||
return createUpdateServerBIOSConfig() | ||
} | ||
|
||
func createUpdateServerBIOSConfig() error { | ||
return fmt.Errorf("unimplemented") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package constants | ||
|
||
const ( | ||
LivenessEndpoint = "/_health/liveness" | ||
VersionEndpoint = "/api/version" | ||
ComponentsEndpoint = "/components" | ||
InbandInventoryEndpoint = "/inventory/in-band" | ||
OutofbandInventoryEndpoint = "/inventory/out-of-band" | ||
|
||
// server service attribute to look up the BMC IP Address in | ||
BmcAttributeNamespace = "sh.hollow.bmc_info" | ||
|
||
// 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" | ||
|
||
// server vendor, model attributes are stored in this namespace. | ||
ServerVendorAttributeNS = ServerServiceNSPrefix + ".server_vendor_attributes" | ||
|
||
// additional server metadata are stored in this namespace. | ||
ServerMetadataAttributeNS = ServerServiceNSPrefix + ".server_metadata_attributes" | ||
|
||
// errors that occurred when connecting/collecting inventory from the bmc are stored here. | ||
ServerBMCErrorsAttributeNS = ServerServiceNSPrefix + ".server_bmc_errors" | ||
|
||
// server service server serial attribute key | ||
ServerSerialAttributeKey = "serial" | ||
|
||
// server service server model attribute key | ||
ServerModelAttributeKey = "model" | ||
|
||
// server service server vendor attribute key | ||
ServerVendorAttributeKey = "vendor" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,24 @@ | ||
package routes | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
|
||
"github.com/bmc-toolbox/common" | ||
"github.com/google/uuid" | ||
internalfleetdb "github.com/metal-toolbox/component-inventory/internal/fleetdb" | ||
"github.com/metal-toolbox/component-inventory/pkg/api/types" | ||
fleetdb "github.com/metal-toolbox/fleetdb/pkg/api/v1" | ||
"go.uber.org/zap" | ||
) | ||
|
||
func processInband(c *fleetdb.Client, srvID uuid.UUID, dev *common.Device, log *zap.Logger) error { //nolint | ||
log.Info("processing", zap.String("server id", srvID.String()), zap.String("device", dev.Serial)) | ||
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)) | ||
if err := c.UpdateAttributes(ctx, server, dev, log); err != nil { | ||
return err | ||
} | ||
return errors.New("not implemented") | ||
} | ||
|
||
func processOutofband(c *fleetdb.Client, srvID uuid.UUID, dev *common.Device, log *zap.Logger) error { //nolint | ||
log.Info("processing", zap.String("server id", srvID.String()), zap.String("device", dev.Serial)) | ||
func processOutofband(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)) | ||
return errors.New("not implemented") | ||
} |
Oops, something went wrong.