Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vc/incoming device api #38

Merged
merged 21 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
16960e5
update golang and golangci-lint
DoctorVin Mar 21, 2024
eb1da37
add a skeleton for incoming CIS data
DoctorVin Mar 21, 2024
b8dc43d
implement attribute upsert for incoming inventory
DoctorVin Mar 22, 2024
638183e
WIP: inventory updates
DoctorVin Mar 26, 2024
aaaf521
move component type initialization to FleetDB
DoctorVin Apr 3, 2024
cb2a829
refactor updateAnyAttribute so we can do component attributes too
DoctorVin Apr 4, 2024
70b5431
add real component initialization to setup and fix test fallout
DoctorVin Apr 5, 2024
bff98be
flesh out the incoming inventory API a bit
DoctorVin Apr 5, 2024
fd4e080
parallel tests are problematic with a big global database
DoctorVin Apr 5, 2024
c6935f7
generalize the routines for upserting attributes and versioned attrib…
DoctorVin Apr 5, 2024
9b2c286
implement bios and dimms
DoctorVin Apr 8, 2024
7ccad4f
implement bmc and mainboard
DoctorVin Apr 9, 2024
6cbaf7b
refactor the common parts out of the update functions
DoctorVin Apr 9, 2024
3128379
change the namespacing and fimware/status handling for vattr
DoctorVin Apr 12, 2024
f85fd81
implement generic deserialization routines
DoctorVin Apr 16, 2024
7a51fc3
update deps
DoctorVin Apr 16, 2024
7eeae19
convert to rivets.Server
DoctorVin Apr 18, 2024
48652ca
enforce a test timeout to catch hangs
DoctorVin Apr 18, 2024
6f7d7b0
update linter config and fix linting issues in code
DoctorVin Apr 18, 2024
1432f25
finish API and tests for inventory
DoctorVin Apr 19, 2024
60c4214
fix up some overly brittle tests
DoctorVin Apr 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/lint-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: '1.21.0'
go-version: '1.22.1'

DoctorVin marked this conversation as resolved.
Show resolved Hide resolved
- name: Install cockroach binary
run: curl https://binaries.cockroachdb.com/cockroach-v23.1.11.linux-amd64.tgz | tar -xz && sudo cp -i cockroach-v23.1.11.linux-amd64/cockroach /usr/local/bin/
Expand All @@ -32,12 +32,12 @@ jobs:
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.52.2
version: v1.57.1
args: --timeout=5m

- name: Run go tests and generate coverage report
run: FLEETDB_CRDB_URI="host=localhost port=26257 user=root sslmode=disable dbname=fleetdb_test" go test -race -coverprofile=coverage.txt -covermode=atomic -tags testtools -p 1 ./...

- name: Stop test database
run: cockroach node drain --insecure --host=localhost:26257

Expand Down
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ linters:
- govet
- misspell
- noctx
- revive
# - revive XXX: fix up old code caught here
- stylecheck
- whitespace

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ unit-test: | lint
## check test coverage
coverage: | test-database
@echo Generating coverage report...
@FLEETDB_CRDB_URI="${TEST_DB}" go test ./... -race -coverprofile=coverage.out -covermode=atomic -tags testtools -p 1
@FLEETDB_CRDB_URI="${TEST_DB}" go test ./... -race -coverprofile=coverage.out -covermode=atomic -tags testtools,integration -p 1
@go tool cover -func=coverage.out
@go tool cover -html=coverage.out

Expand Down
7 changes: 7 additions & 0 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"go.infratographer.com/x/crdbx"
"go.infratographer.com/x/otelx"
"go.infratographer.com/x/viperx"
"go.uber.org/zap"
"gocloud.dev/secrets"

// import gocdk secret drivers
Expand Down Expand Up @@ -92,6 +93,12 @@ func serve(ctx context.Context) {

dbtools.RegisterHooks()

if err := dbtools.SetupComponentTypes(ctx, db); err != nil {
logger.With(
zap.Error(err),
).Fatal("set up component types")
}

keeper, err := secrets.OpenKeeper(ctx, viper.GetString("db.encryption_driver"))
if err != nil {
logger.Fatalw("failed to open secrets keeper", "error", err)
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/metal-toolbox/fleetdb

go 1.19
go 1.22

require (
github.com/XSAM/otelsql v0.23.0 // indirect
Expand Down Expand Up @@ -34,6 +34,7 @@ require (
)

require (
github.com/bmc-toolbox/common v0.0.0-20231204194243-7bcbccab7116
github.com/volatiletech/sqlboiler v3.7.1+incompatible
go.hollow.sh/toolbox v0.6.3
go.infratographer.com/x v0.3.7
Expand Down
38 changes: 38 additions & 0 deletions go.sum

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions internal/dbtools/component_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package dbtools

import (
"context"
"database/sql"

"github.com/bmc-toolbox/common"
"github.com/gosimple/slug"
"github.com/jmoiron/sqlx"
"github.com/pkg/errors"
"github.com/volatiletech/sqlboiler/v4/boil"

"github.com/metal-toolbox/fleetdb/internal/models"
)

var errAddTypes = errors.New("unable to add component types")

// XXX: if bmc-toolbox exported this as a list, we could just import it.
DoctorVin marked this conversation as resolved.
Show resolved Hide resolved
var knownComponentTypes = []string{
common.SlugBackplaneExpander,
common.SlugChassis,
common.SlugTPM,
common.SlugGPU,
common.SlugCPU,
common.SlugPhysicalMem,
common.SlugStorageController,
common.SlugBMC,
common.SlugBIOS,
common.SlugDrive,
common.SlugDriveTypePCIeNVMEeSSD,
common.SlugDriveTypeSATASSD,
common.SlugDriveTypeSATAHDD,
common.SlugNIC,
common.SlugPSU,
common.SlugCPLD,
common.SlugEnclosure,
common.SlugUnknown,
common.SlugMainboard,
}

// SetupComponentTypes upserts all known component types to the database.
// Despite the descriptor, in the database the Name field of the component type
// is the verbatim value of the string, and the Slug is computed as a lower-case
// english-localized variant.
func SetupComponentTypes(ctx context.Context, db *sqlx.DB) error {
txn := db.MustBeginTx(ctx, &sql.TxOptions{})
for _, typ := range knownComponentTypes {
sct := &models.ServerComponentType{
Name: typ,
Slug: slug.Make(typ),
}
if err := sct.Upsert(ctx, txn, false, []string{"slug"}, boil.None(), boil.Infer()); err != nil {
_ = txn.Rollback()
return errors.Wrap(errAddTypes, err.Error())
}
}
return txn.Commit()
}

// ComponentTypeIDFromName expects the name of the component (as defined in
// bmc-toolbox) and will return the internal database ID for that name.
func ComponentTypeIDFromName(ctx context.Context, exec boil.ContextExecutor, name string) (string, error) {
sct, err := models.ServerComponentTypes(
models.ServerComponentTypeWhere.Name.EQ(name),
).One(ctx, exec)
if err != nil {
return "", err
}
return sct.ID, nil
}

// MustComponentTypeID returns the component type id for the given component name or panics
func MustComponentTypeID(ctx context.Context, exec boil.ContextExecutor, name string) string {
id, err := ComponentTypeIDFromName(ctx, exec, name)
if err != nil {
panic(err)
}
return id
}
31 changes: 31 additions & 0 deletions internal/dbtools/component_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//go:build testtools && integration

package dbtools

import (
"context"
"testing"

"github.com/bmc-toolbox/common"
"github.com/stretchr/testify/require"
)

func TestServerComponentTypes(t *testing.T) {
db := DatabaseTest(t)
ctx := context.TODO()

err := SetupComponentTypes(ctx, db)
require.NoError(t, err)

for _, typ := range knownComponentTypes {
_, err := ComponentTypeIDFromName(ctx, db, typ)
require.NoError(t, err, "couldn't find %s", typ)
}

require.NotPanics(t, func() { _ = MustComponentTypeID(ctx, db, common.SlugBackplaneExpander) })

require.Panics(t, func() { _ = MustComponentTypeID(ctx, db, "bogus") })

_, err = ComponentTypeIDFromName(ctx, db, "bogus")
require.Error(t, err, "no error on bogus")
}
4 changes: 4 additions & 0 deletions internal/dbtools/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ func addFixtures(t *testing.T) error {
return err
}

if err := SetupComponentTypes(ctx, testDB); err != nil {
return err
}

// excluding Chuckles here since that server is deleted
FixtureServers = models.ServerSlice{FixtureNemo, FixtureDory, FixtureMarlin}
FixtureDeletedServers = models.ServerSlice{FixtureChuckles}
Expand Down
68 changes: 68 additions & 0 deletions internal/inventory/component_attributes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//nolint:all // XXX remove this!
package inventory

import (
"encoding/json"

"github.com/bmc-toolbox/common"
)

type attributes struct {
Architecture string `json:"architecture,omitempty"`
BlockSizeBytes int64 `json:"block_size_bytes,omitempty"`
BusInfo string `json:"bus_info,omitempty"`
Capabilities []*common.Capability `json:"capabilities,omitempty"`
CapableSpeedGbps int64 `json:"capable_speed_gbps,omitempty"`
CapacityBytes int64 `json:"capacity_bytes,omitempty" diff:"immutable"`
ChassisType string `json:"chassis_type,omitempty"`
ClockSpeedHz int64 `json:"clock_speed_hz,omitempty"`
Cores int `json:"cores,omitempty"`
Description string `json:"description,omitempty"`
DriveType string `json:"drive_type,omitempty"`
FormFactor string `json:"form_factor,omitempty"`
ID string `json:"id,omitempty"`
InterfaceType string `json:"interface_type,omitempty"`
MacAddress string `json:"macaddress,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
NegotiatedSpeedGbps int64 `json:"negotiated_speed_gbps,omitempty"`
Oem bool `json:"oem,omitempty"`
OemID string `json:"oem_id,omitempty"`
PartNumber string `json:"part_number,omitempty"`
PhysicalID string `json:"physid,omitempty"`
PowerCapacityWatts int64 `json:"power_capacity_watts,omitempty"`
ProductName string `json:"product_name,omitempty"`
Protocol string `json:"protocol,omitempty"`
SizeBytes int64 `json:"size_bytes,omitempty"`
Slot string `json:"slot,omitempty"`
SmartErrors []string `json:"smart_errors,omitempty"`
SmartStatus string `json:"smart_status,omitempty"`
SpeedBits int64 `json:"speed_bits,omitempty"`
SpeedGbps int64 `json:"speed_gbps,omitempty"`
StorageController string `json:"storage_controller,omitempty"`
SupportedControllerProtocols string `json:"supported_controller_protocol,omitempty"`
SupportedDeviceProtocols string `json:"supported_device_protocol,omitempty"`
SupportedRAIDTypes string `json:"supported_raid_types,omitempty"`
Threads int `json:"threads,omitempty"`
WWN string `json:"wwn,omitempty"`
}

func (a *attributes) MustJSON() []byte {
byt, err := json.Marshal(a)
if err != nil {
panic("bad attributes")
}
return byt
}

type versionedAttributes struct {
Firmware *common.Firmware `json:"firmware,omitempty"`
Status *common.Status `json:"status,omitempty"`
}

func (va *versionedAttributes) MustJSON() []byte {
byt, err := json.Marshal(va)
if err != nil {
panic("bad attributes")
}
return byt
}
Loading
Loading