Skip to content

Commit 35db8dd

Browse files
authored
fix metadata updates (#182)
1 parent 07ffab2 commit 35db8dd

File tree

7 files changed

+46
-70
lines changed

7 files changed

+46
-70
lines changed

internal/collector/collector.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ var (
2525
ErrInventoryCollect = errors.New("error collecting inventory data")
2626
)
2727

28-
func init() {
29-
30-
}
31-
3228
// DeviceCollector holds attributes to collect inventory, bios configuration data from a single device.
3329
type DeviceCollector struct {
3430
queryor device.Queryor

internal/collector/collector_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"go.uber.org/goleak"
1414
)
1515

16+
// XXX: Warning, this test might be flaky.
1617
func Test_Collect_Concurrent(t *testing.T) {
1718
ignorefunc := "go.opencensus.io/stats/view.(*worker).start"
1819
defer goleak.VerifyNone(t, goleak.IgnoreTopFunction(ignorefunc))

internal/store/serverservice/attributes.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import (
1818
)
1919

2020
const (
21-
uefiVariablesKey = "uefi-variables"
21+
uefiVariablesKey = "uefi-variables"
22+
ssMetadataAttributeFound = "__ss_found"
2223
)
2324

2425
// createUpdateServerAttributes creates/updates the server serial, vendor, model attributes
@@ -174,11 +175,7 @@ func mustFilterAssetMetadata(inventory map[string]string) json.RawMessage {
174175
func (r *Store) createUpdateServerMetadataAttributes(ctx context.Context, serverID uuid.UUID, asset *model.Asset) error {
175176
// no metadata reported in inventory from device
176177
if asset.Inventory == nil || len(asset.Inventory.Metadata) == 0 {
177-
return nil
178-
}
179-
180-
// update when metadata differs
181-
if helpers.MapsAreEqual(asset.Metadata, asset.Inventory.Metadata) {
178+
// XXX: should delete the metadata on the server-service record!
182179
return nil
183180
}
184181

@@ -190,12 +187,15 @@ func (r *Store) createUpdateServerMetadataAttributes(ctx context.Context, server
190187
Data: metadata,
191188
}
192189

193-
// current asset metadata has no attributes set, create
194-
if len(asset.Metadata) == 0 {
190+
// XXX: This would be much easier if serverservice/fleetdb supported upsert
191+
// current asset metadata has no attributes set and no metadata attribute, create one
192+
if _, ok := asset.Metadata[ssMetadataAttributeFound]; !ok {
193+
r.logger.WithField("server.id", serverID.String()).Debug("creating metadata attributes")
195194
_, err := r.CreateAttributes(ctx, serverID, attribute)
196195
return err
197196
}
198197

198+
r.logger.WithField("server.id", serverID.String()).Debug("updating metadata attributes")
199199
// update vendor, model attributes
200200
_, err := r.UpdateAttributes(ctx, serverID, serverMetadataAttributeNS, metadata)
201201

@@ -498,6 +498,10 @@ func serverMetadataAttributes(attributes []serverserviceapi.Attributes) (map[str
498498
if err := json.Unmarshal(attribute.Data, &metadata); err != nil {
499499
return nil, errors.Wrap(ErrServerServiceObject, "server metadata attribute: "+err.Error())
500500
}
501+
// XXX: it is possible for there to be a metadata attribute with an empty Data field
502+
// Add an entry here so that when we test for doing a create vs. an update we make the
503+
// right decision.
504+
metadata[ssMetadataAttributeFound] = "true"
501505
}
502506
}
503507

internal/store/serverservice/attributes_test.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/bmc-toolbox/common"
1616
"github.com/google/uuid"
1717
"github.com/hashicorp/go-retryablehttp"
18-
"github.com/metal-toolbox/alloy/internal/app"
1918
"github.com/metal-toolbox/alloy/internal/fixtures"
2019
"github.com/metal-toolbox/alloy/internal/model"
2120
"github.com/sirupsen/logrus"
@@ -44,7 +43,7 @@ func testStoreInstance(t *testing.T, mockURL string) *Store {
4443
}
4544

4645
return &Store{
47-
logger: app.NewLogrusEntryFromLogger(logrus.Fields{"component": "publisher"}, logrus.New()),
46+
logger: logrus.New(),
4847
slugs: fixtures.ServerServiceSlugMap(),
4948
Client: mockClient,
5049
attributeNS: serverComponentAttributeNS(model.AppKindOutOfBand),
@@ -676,11 +675,17 @@ func Test_ServerService_CreateUpdateServerMetadataAttributes_Update(t *testing.T
676675
serverID, _ := uuid.Parse(fixtures.TestserverID_Dell_fc167440)
677676

678677
device := &model.Asset{
679-
Metadata: map[string]string{"foo": "bar"},
680-
Vendor: "foobar",
678+
Metadata: map[string]string{
679+
"foo": "bar",
680+
"__ss_found": "true",
681+
},
682+
Vendor: "foobar",
681683
Inventory: &common.Device{
682684
Common: common.Common{
683-
Metadata: map[string]string{"foo": "bar", "test": "lala"},
685+
Metadata: map[string]string{
686+
"foo": "bar",
687+
"test": "lala",
688+
},
684689
},
685690
},
686691
}
@@ -693,23 +698,19 @@ func Test_ServerService_CreateUpdateServerMetadataAttributes_Update(t *testing.T
693698
switch r.Method {
694699
case http.MethodPut:
695700
b, err := io.ReadAll(r.Body)
696-
if err != nil {
697-
t.Fatal(err)
698-
}
701+
require.NoError(t, err)
699702

700703
// unpack attributes posted by method
701704
attributes := &serverserviceapi.Attributes{}
702-
if err = json.Unmarshal(b, attributes); err != nil {
703-
t.Fatal(err)
704-
}
705+
err = json.Unmarshal(b, attributes)
706+
require.NoError(t, err)
705707

706708
// unpack attributes data
707709
data := map[string]string{}
708-
if err = json.Unmarshal(attributes.Data, &data); err != nil {
709-
t.Fatal(err)
710-
}
710+
err = json.Unmarshal(attributes.Data, &data)
711+
require.NoError(t, err)
711712

712-
assert.Equal(t, device.Inventory.Metadata, data)
713+
require.Equal(t, device.Inventory.Metadata, data)
713714

714715
w.Header().Set("Content-Type", "application/json")
715716
_, _ = w.Write(fixtures.ServerServiceR6515Components_fc167440_JSON())
@@ -719,13 +720,17 @@ func Test_ServerService_CreateUpdateServerMetadataAttributes_Update(t *testing.T
719720
},
720721
)
721722

723+
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
724+
t.Logf("unhandled URL: %s", r.URL)
725+
w.WriteHeader(404)
726+
})
727+
722728
mock := httptest.NewServer(handler)
729+
t.Logf("mock URL: %s", mock.URL)
723730
p := testStoreInstance(t, mock.URL)
724731

725732
err := p.createUpdateServerMetadataAttributes(context.TODO(), serverID, device)
726-
if err != nil {
727-
t.Fatal(err)
728-
}
733+
require.NoError(t, err)
729734
}
730735

731736
func Test_ServerService_CreateUpdateServerBMCErrorAttributes_NoErrorsNoChanges(t *testing.T) {

internal/store/serverservice/components_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func Test_ToComponentSlice(t *testing.T) {
4141

4242
mock := httptest.NewServer(handler)
4343
p := testStoreInstance(t, mock.URL)
44-
p.logger = logrus.NewEntry(logrus.New())
44+
p.logger = logrus.New()
4545
p.slugs = fixtures.ServerServiceSlugMap()
4646
p.attributeNS = serverComponentAttributeNS(model.AppKindOutOfBand)
4747
p.firmwareVersionedAttributeNS = serverComponentFirmwareNS(model.AppKindOutOfBand)

internal/store/serverservice/helpers.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ var (
3030
// TODO move this under an interface
3131

3232
// NewServerServiceClient instantiates and returns a serverService client
33-
func NewServerServiceClient(ctx context.Context, cfg *app.ServerserviceOptions, logger *logrus.Entry) (*serverserviceapi.Client, error) {
33+
func NewServerServiceClient(ctx context.Context, cfg *app.ServerserviceOptions, logger *logrus.Logger) (*serverserviceapi.Client, error) {
3434
if cfg == nil {
3535
return nil, errors.Wrap(ErrConfig, "configuration is nil")
3636
}
@@ -43,7 +43,7 @@ func NewServerServiceClient(ctx context.Context, cfg *app.ServerserviceOptions,
4343
}
4444

4545
// returns a serverservice retryable client with Otel
46-
func newServerserviceClientWithOtel(cfg *app.ServerserviceOptions, endpoint string, logger *logrus.Entry) (*serverserviceapi.Client, error) {
46+
func newServerserviceClientWithOtel(cfg *app.ServerserviceOptions, endpoint string, logger *logrus.Logger) (*serverserviceapi.Client, error) {
4747
if cfg == nil {
4848
return nil, errors.Wrap(ErrConfig, "configuration is nil")
4949
}
@@ -69,13 +69,6 @@ func newServerserviceClientWithOtel(cfg *app.ServerserviceOptions, endpoint stri
6969
// set retryable HTTP client to be the otel http client to collect telemetry
7070
retryableClient.HTTPClient = otelhttp.DefaultClient
7171

72-
// disable default debug logging on the retryable client
73-
if logger.Level < logrus.DebugLevel {
74-
retryableClient.Logger = nil
75-
} else {
76-
retryableClient.Logger = logger
77-
}
78-
7972
// requests taking longer than timeout value should be canceled.
8073
client := retryableClient.StandardClient()
8174
client.Timeout = timeout
@@ -88,24 +81,19 @@ func newServerserviceClientWithOtel(cfg *app.ServerserviceOptions, endpoint stri
8881
}
8982

9083
// returns a serverservice retryable http client with Otel and Oauth wrapped in
91-
func newServerserviceClientWithOAuthOtel(ctx context.Context, cfg *app.ServerserviceOptions, endpoint string, logger *logrus.Entry) (*serverserviceapi.Client, error) {
84+
func newServerserviceClientWithOAuthOtel(ctx context.Context, cfg *app.ServerserviceOptions, endpoint string, logger *logrus.Logger) (*serverserviceapi.Client, error) {
9285
if cfg == nil {
9386
return nil, errors.Wrap(ErrConfig, "configuration is nil")
9487
}
9588

89+
logger.Info("serverservice client ctor")
90+
9691
// init retryable http client
9792
retryableClient := retryablehttp.NewClient()
9893

9994
// set retryable HTTP client to be the otel http client to collect telemetry
10095
retryableClient.HTTPClient = otelhttp.DefaultClient
10196

102-
// disable default debug logging on the retryable client
103-
if logger.Level < logrus.DebugLevel {
104-
retryableClient.Logger = nil
105-
} else {
106-
retryableClient.Logger = logger
107-
}
108-
10997
// setup oidc provider
11098
provider, err := oidc.NewProvider(ctx, cfg.OidcIssuerEndpoint)
11199
if err != nil {

internal/store/serverservice/serverservice.go

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const (
3131
// Store is an asset inventory store
3232
type Store struct {
3333
*serverserviceapi.Client
34-
logger *logrus.Entry
34+
logger *logrus.Logger
3535
config *app.ServerserviceOptions
3636
slugs map[string]*serverserviceapi.ServerComponentType
3737
firmwares map[string][]*serverserviceapi.ComponentFirmwareVersion
@@ -44,20 +44,17 @@ type Store struct {
4444

4545
// NewStore returns a serverservice store queryor to lookup and publish assets to, from the store.
4646
func New(ctx context.Context, appKind model.AppKind, cfg *app.ServerserviceOptions, logger *logrus.Logger) (*Store, error) {
47-
loggerEntry := app.NewLogrusEntryFromLogger(
48-
logrus.Fields{"component": "store.serverservice"},
49-
logger,
50-
)
47+
logger.Info("serverservice store ctor")
5148

52-
apiclient, err := NewServerServiceClient(ctx, cfg, loggerEntry)
49+
apiclient, err := NewServerServiceClient(ctx, cfg, logger)
5350
if err != nil {
5451
return nil, err
5552
}
5653

5754
s := &Store{
5855
Client: apiclient,
5956
appKind: appKind,
60-
logger: loggerEntry,
57+
logger: logger,
6158
config: cfg,
6259
slugs: make(map[string]*serverserviceapi.ServerComponentType),
6360
firmwares: make(map[string][]*serverserviceapi.ComponentFirmwareVersion),
@@ -347,21 +344,6 @@ func (r *Store) createUpdateServerComponents(ctx context.Context, serverID uuid.
347344
return errors.Wrap(model.ErrInventoryQuery, err.Error())
348345
}
349346

350-
// For debugging and to capture test fixtures data.
351-
if os.Getenv(model.EnvVarDumpFixtures) == "true" {
352-
current := serverID.String() + ".current.components.fixture"
353-
r.logger.Info("components current fixture dumped as file: " + current)
354-
355-
// nolint:gomnd // file permissions are clearer in this form.
356-
_ = os.WriteFile(current, []byte(litter.Sdump(currentInventory)), 0o600)
357-
358-
newc := serverID.String() + ".new.components.fixture"
359-
r.logger.Info("components new fixture dumped as file: " + newc)
360-
361-
// nolint:gomnd // file permissions are clearer in this form.
362-
_ = os.WriteFile(newc, []byte(litter.Sdump(newInventory)), 0o600)
363-
}
364-
365347
// convert to a pointer slice since this data is passed around
366348
currentInventoryPtrSlice := componentPtrSlice(currentInventory)
367349

0 commit comments

Comments
 (0)