From 8c1d56240fb1423b704b28bf5d56b8fcf6e1227c Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 11:14:30 +0200 Subject: [PATCH 01/11] worker: rename file --- internal/worker/{worker.go => outofband.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename internal/worker/{worker.go => outofband.go} (100%) diff --git a/internal/worker/worker.go b/internal/worker/outofband.go similarity index 100% rename from internal/worker/worker.go rename to internal/worker/outofband.go From f6c28bfe63ed8402f0644ea127d6a2fb8b7ea73a Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 14:20:22 +0200 Subject: [PATCH 02/11] model: switch to rivets.Server, Component types As a prerequisite to using the rivets.Task type --- internal/model/asset.go | 33 ------- internal/model/component.go | 143 +++++++++++-------------------- internal/model/component_test.go | 114 ------------------------ 3 files changed, 48 insertions(+), 242 deletions(-) delete mode 100644 internal/model/asset.go delete mode 100644 internal/model/component_test.go diff --git a/internal/model/asset.go b/internal/model/asset.go deleted file mode 100644 index 2868ef83..00000000 --- a/internal/model/asset.go +++ /dev/null @@ -1,33 +0,0 @@ -package model - -import ( - "net" - - "github.com/google/uuid" -) - -// Asset holds attributes of a server retrieved from the inventory store. -// -// nolint:govet // fieldalignment struct is easier to read in the current format -type Asset struct { - ID uuid.UUID - - // Device BMC attributes - BmcAddress net.IP - BmcUsername string - BmcPassword string - - // Inventory status attribute - State string - - // Manufacturer attributes - Vendor string - Model string - Serial string - - // Facility this Asset is hosted in. - FacilityCode string - - // Device components - Components Components -} diff --git a/internal/model/component.go b/internal/model/component.go index a2ec1ec1..6d88d2b4 100644 --- a/internal/model/component.go +++ b/internal/model/component.go @@ -6,57 +6,9 @@ import ( "github.com/bmc-toolbox/common" "github.com/pkg/errors" -) - -// Component is a device component -type Component struct { - Slug string - Serial string - Vendor string - Model string - FirmwareInstalled string -} - -// Components is a slice of Component on which one or more methods may be available. -type Components []*Component - -// BySlug returns a component that matches the slug value. -func (c Components) BySlugModel(cSlug string, cModels []string) *Component { - // identify components that match the slug - slugsMatch := []*Component{} - for _, component := range c { - component := component - // skip non matching component slug - if !strings.EqualFold(cSlug, component.Slug) { - continue - } - - // since theres a single BIOS, BMC (:fingers_crossed) component on a machine - // we look for further and return the found component - if strings.EqualFold(common.SlugBIOS, cSlug) || strings.EqualFold(common.SlugBMC, cSlug) { - return component - } - - slugsMatch = append(slugsMatch, component) - } - // none found - if len(slugsMatch) == 0 { - return nil - } - - // multiple components identified, match component by model - for _, find := range cModels { - for _, component := range slugsMatch { - find = strings.ToLower(strings.TrimSpace(find)) - if strings.Contains(strings.ToLower(component.Model), find) { - return component - } - } - } - - return nil -} + rtypes "github.com/metal-toolbox/rivets/types" +) // ComponentConvertor provides methods to convert a common.Device to its Component equivalents. type ComponentConverter struct { @@ -77,7 +29,7 @@ func NewComponentConverter() *ComponentConverter { return &ComponentConverter{} // TODO(joel): the bmc-toolbox/common Device component types could implement an interface with // methods to retrieve component - firmware installed, vendor, model, serial, slug attributes // this method can then call the interface methods instead of multiple small methods for each device component type. -func (cc *ComponentConverter) CommonDeviceToComponents(device *common.Device) (Components, error) { +func (cc *ComponentConverter) CommonDeviceToComponents(device *common.Device) (rtypes.Components, error) { if device == nil { return nil, errors.Wrap(ErrComponentConverter, "device object is nil") } @@ -85,7 +37,7 @@ func (cc *ComponentConverter) CommonDeviceToComponents(device *common.Device) (C cc.deviceModel = common.FormatProductName(device.Model) cc.deviceVendor = device.Vendor - componentsTmp := []*Component{} + componentsTmp := []*rtypes.Component{} componentsTmp = append(componentsTmp, cc.bios(device.BIOS), cc.bmc(device.BMC), @@ -103,7 +55,7 @@ func (cc *ComponentConverter) CommonDeviceToComponents(device *common.Device) (C componentsTmp = append(componentsTmp, cc.storageControllers(device.StorageControllers)...) componentsTmp = append(componentsTmp, cc.enclosures(device.Enclosures)...) - components := []*Component{} + components := []*rtypes.Component{} for _, component := range componentsTmp { if component == nil { @@ -116,7 +68,7 @@ func (cc *ComponentConverter) CommonDeviceToComponents(device *common.Device) (C return components, nil } -func (cc *ComponentConverter) newComponent(slug, cvendor, cmodel, cserial string) (*Component, error) { +func (cc *ComponentConverter) newComponent(slug, cvendor, cmodel, cserial string) (*rtypes.Component, error) { slug = strings.ToLower(slug) if cvendor == "" { @@ -127,11 +79,12 @@ func (cc *ComponentConverter) newComponent(slug, cvendor, cmodel, cserial string cmodel = cc.deviceModel } - return &Component{ - Vendor: common.FormatVendorName(cvendor), - Model: common.FormatProductName(cmodel), - Serial: cserial, - Slug: slug, + return &rtypes.Component{ + Vendor: common.FormatVendorName(cvendor), + Model: common.FormatProductName(cmodel), + Serial: cserial, + Name: slug, + Firmware: &common.Firmware{}, }, nil } @@ -143,12 +96,12 @@ func (cc *ComponentConverter) firmwareInstalled(firmware *common.Firmware) strin return strings.TrimSpace(firmware.Installed) } -func (cc *ComponentConverter) gpus(gpus []*common.GPU) []*Component { +func (cc *ComponentConverter) gpus(gpus []*common.GPU) []*rtypes.Component { if gpus == nil { return nil } - components := make([]*Component, 0, len(gpus)) + components := make([]*rtypes.Component, 0, len(gpus)) for idx, c := range gpus { if strings.TrimSpace(c.Serial) == "" { @@ -160,19 +113,19 @@ func (cc *ComponentConverter) gpus(gpus []*common.GPU) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) cplds(cplds []*common.CPLD) []*Component { +func (cc *ComponentConverter) cplds(cplds []*common.CPLD) []*rtypes.Component { if cplds == nil { return nil } - components := make([]*Component, 0, len(cplds)) + components := make([]*rtypes.Component, 0, len(cplds)) for idx, c := range cplds { if strings.TrimSpace(c.Serial) == "" { @@ -184,19 +137,19 @@ func (cc *ComponentConverter) cplds(cplds []*common.CPLD) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) tpms(tpms []*common.TPM) []*Component { +func (cc *ComponentConverter) tpms(tpms []*common.TPM) []*rtypes.Component { if tpms == nil { return nil } - components := make([]*Component, 0, len(tpms)) + components := make([]*rtypes.Component, 0, len(tpms)) for idx, c := range tpms { if strings.TrimSpace(c.Serial) == "" { @@ -208,19 +161,19 @@ func (cc *ComponentConverter) tpms(tpms []*common.TPM) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) cpus(cpus []*common.CPU) []*Component { +func (cc *ComponentConverter) cpus(cpus []*common.CPU) []*rtypes.Component { if cpus == nil { return nil } - components := make([]*Component, 0, len(cpus)) + components := make([]*rtypes.Component, 0, len(cpus)) for idx, c := range cpus { if strings.TrimSpace(c.Serial) == "" { @@ -232,19 +185,19 @@ func (cc *ComponentConverter) cpus(cpus []*common.CPU) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) storageControllers(controllers []*common.StorageController) []*Component { +func (cc *ComponentConverter) storageControllers(controllers []*common.StorageController) []*rtypes.Component { if controllers == nil { return nil } - components := make([]*Component, 0, len(controllers)) + components := make([]*rtypes.Component, 0, len(controllers)) for idx, c := range controllers { if strings.TrimSpace(c.Serial) == "" { @@ -256,19 +209,19 @@ func (cc *ComponentConverter) storageControllers(controllers []*common.StorageCo return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) psus(psus []*common.PSU) []*Component { +func (cc *ComponentConverter) psus(psus []*common.PSU) []*rtypes.Component { if psus == nil { return nil } - components := make([]*Component, 0, len(psus)) + components := make([]*rtypes.Component, 0, len(psus)) for idx, c := range psus { if strings.TrimSpace(c.Serial) == "" { @@ -280,19 +233,19 @@ func (cc *ComponentConverter) psus(psus []*common.PSU) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) drives(drives []*common.Drive) []*Component { +func (cc *ComponentConverter) drives(drives []*common.Drive) []*rtypes.Component { if drives == nil { return nil } - components := make([]*Component, 0, len(drives)) + components := make([]*rtypes.Component, 0, len(drives)) for idx, c := range drives { if strings.TrimSpace(c.Serial) == "" { @@ -304,19 +257,19 @@ func (cc *ComponentConverter) drives(drives []*common.Drive) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) nics(nics []*common.NIC) []*Component { +func (cc *ComponentConverter) nics(nics []*common.NIC) []*rtypes.Component { if nics == nil { return nil } - components := make([]*Component, 0, len(nics)) + components := make([]*rtypes.Component, 0, len(nics)) for idx, c := range nics { if strings.TrimSpace(c.Serial) == "" { @@ -328,19 +281,19 @@ func (cc *ComponentConverter) nics(nics []*common.NIC) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) dimms(dimms []*common.Memory) []*Component { +func (cc *ComponentConverter) dimms(dimms []*common.Memory) []*rtypes.Component { if dimms == nil { return nil } - components := make([]*Component, 0, len(dimms)) + components := make([]*rtypes.Component, 0, len(dimms)) for idx, c := range dimms { // skip empty dimm slots @@ -361,19 +314,19 @@ func (cc *ComponentConverter) dimms(dimms []*common.Memory) []*Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) enclosures(enclosures []*common.Enclosure) []*Component { +func (cc *ComponentConverter) enclosures(enclosures []*common.Enclosure) []*rtypes.Component { if enclosures == nil { return nil } - components := make([]*Component, 0, len(enclosures)) + components := make([]*rtypes.Component, 0, len(enclosures)) for idx, c := range enclosures { if strings.TrimSpace(c.Serial) == "" { @@ -385,14 +338,14 @@ func (cc *ComponentConverter) enclosures(enclosures []*common.Enclosure) []*Comp return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) components = append(components, sc) } return components } -func (cc *ComponentConverter) bmc(c *common.BMC) *Component { +func (cc *ComponentConverter) bmc(c *common.BMC) *rtypes.Component { if c == nil { return nil } @@ -406,12 +359,12 @@ func (cc *ComponentConverter) bmc(c *common.BMC) *Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) return sc } -func (cc *ComponentConverter) bios(c *common.BIOS) *Component { +func (cc *ComponentConverter) bios(c *common.BIOS) *rtypes.Component { if c == nil { return nil } @@ -425,12 +378,12 @@ func (cc *ComponentConverter) bios(c *common.BIOS) *Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) return sc } -func (cc *ComponentConverter) mainboard(c *common.Mainboard) *Component { +func (cc *ComponentConverter) mainboard(c *common.Mainboard) *rtypes.Component { if c == nil { return nil } @@ -444,7 +397,7 @@ func (cc *ComponentConverter) mainboard(c *common.Mainboard) *Component { return nil } - sc.FirmwareInstalled = cc.firmwareInstalled(c.Firmware) + sc.Firmware.Installed = cc.firmwareInstalled(c.Firmware) return sc } diff --git a/internal/model/component_test.go b/internal/model/component_test.go deleted file mode 100644 index b8f97b48..00000000 --- a/internal/model/component_test.go +++ /dev/null @@ -1,114 +0,0 @@ -package model - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestComponentBySlugModel(t *testing.T) { - component1 := &Component{ - Slug: "cpu", - Serial: "123", - Vendor: "Intel", - Model: "Core i7", - FirmwareInstalled: "v1.0", - } - - component2 := &Component{ - Slug: "gpu", - Serial: "456", - Vendor: "NVIDIA", - Model: "GeForce RTX 3080", - FirmwareInstalled: "v2.0", - } - - component3 := &Component{ - Slug: "cpu", - Serial: "789", - Vendor: "AMD", - Model: "Ryzen 9", - FirmwareInstalled: "v1.5", - } - - biosComponent := &Component{ - Slug: "bios", - Serial: "111", - Vendor: "AMI", - Model: "BIOS Model", - FirmwareInstalled: "v1.2", - } - - bmcComponent := &Component{ - Slug: "bmc", - Serial: "222", - Vendor: "Supermicro", - Model: "BMC Model", - FirmwareInstalled: "v3.0", - } - - components := Components{component1, component2, component3, biosComponent, bmcComponent} - - testCases := []struct { - name string - slug string - models []string - expected *Component - }{ - { - name: "Single Match", - slug: "gpu", - models: []string{"RTX 3080"}, - expected: component2, - }, - { - name: "No Match", - slug: "memory", - models: []string{"DDR4"}, - expected: nil, - }, - { - name: "Multiple Matches", - slug: "cpu", - models: []string{"Ryzen 9"}, - expected: component3, - }, - { - name: "Slug Match", - slug: "cpu", - models: []string{}, - expected: nil, - }, - { - name: "Slug BIOS", - slug: "bios", - models: []string{}, - expected: biosComponent, - }, - { - name: "Slug upper case BIOS", - slug: "BIOS", - models: []string{}, - expected: biosComponent, - }, - { - name: "Slug BMC", - slug: "bmc", - models: []string{}, - expected: bmcComponent, - }, - { - name: "Slug BMC with Models", - slug: "bmc", - models: []string{"BMC Model"}, - expected: bmcComponent, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - result := components.BySlugModel(tc.slug, tc.models) - assert.Equal(t, tc.expected, result) - }) - } -} From 8bf284dbe7aadbf81ee97b54fe1059ee47b7501b Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 14:22:29 +0200 Subject: [PATCH 03/11] store/fleetdb: return asset data as the rivets.Server,Component type since we're transitioning to use the rivets.Task type --- internal/store/fleetdb.go | 19 ++++---- internal/store/fleetdb_attrs.go | 80 +++++---------------------------- 2 files changed, 19 insertions(+), 80 deletions(-) diff --git a/internal/store/fleetdb.go b/internal/store/fleetdb.go index 360a1e57..6ac748ac 100644 --- a/internal/store/fleetdb.go +++ b/internal/store/fleetdb.go @@ -9,6 +9,7 @@ import ( fleetdbapi "github.com/metal-toolbox/fleetdb/pkg/api/v1" rfleetdb "github.com/metal-toolbox/rivets/fleetdb" + rtypes "github.com/metal-toolbox/rivets/types" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" @@ -153,7 +154,7 @@ func (s *FleetDBAPI) registerMetric(queryKind string) { } // AssetByID returns an Asset object with various attributes populated. -func (s *FleetDBAPI) AssetByID(ctx context.Context, id string) (*model.Asset, error) { +func (s *FleetDBAPI) AssetByID(ctx context.Context, id string) (*rtypes.Server, error) { ctx, span := otel.Tracer(pkgName).Start(ctx, "FleetDBAPI.AssetByID") defer span.End() @@ -162,7 +163,7 @@ func (s *FleetDBAPI) AssetByID(ctx context.Context, id string) (*model.Asset, er return nil, errors.Wrap(ErrDeviceID, err.Error()+id) } - asset := &model.Asset{ID: deviceUUID} + asset := &rtypes.Server{ID: deviceUUID.String()} // query credentials credential, _, err := s.client.GetCredential(ctx, deviceUUID, fleetdbapi.ServerCredentialTypeBMC) @@ -172,8 +173,8 @@ func (s *FleetDBAPI) AssetByID(ctx context.Context, id string) (*model.Asset, er return nil, errors.Wrap(ErrServerserviceQuery, "GetCredential: "+err.Error()) } - asset.BmcUsername = credential.Username - asset.BmcPassword = credential.Password + asset.BMCUser = credential.Username + asset.BMCPassword = credential.Password // query the server object srv, _, err := s.client.Get(ctx, deviceUUID) @@ -183,19 +184,15 @@ func (s *FleetDBAPI) AssetByID(ctx context.Context, id string) (*model.Asset, er return nil, errors.Wrap(ErrServerserviceQuery, "GetServer: "+err.Error()) } - asset.FacilityCode = srv.FacilityCode + asset.Facility = srv.FacilityCode // set bmc address - asset.BmcAddress, err = s.bmcAddressFromAttributes(srv.Attributes) + bmcAddress, err := s.bmcAddressFromAttributes(srv.Attributes) if err != nil { return nil, err } - // set device state attribute - asset.State, err = s.assetStateAttribute(srv.Attributes) - if err != nil { - return nil, err - } + asset.BMCAddress = bmcAddress.String() // set asset vendor attributes asset.Vendor, asset.Model, asset.Serial, err = s.vendorModelFromAttributes(srv.Attributes) diff --git a/internal/store/fleetdb_attrs.go b/internal/store/fleetdb_attrs.go index f729768c..5985928c 100644 --- a/internal/store/fleetdb_attrs.go +++ b/internal/store/fleetdb_attrs.go @@ -7,16 +7,12 @@ import ( fleetdbapi "github.com/metal-toolbox/fleetdb/pkg/api/v1" rfleetdb "github.com/metal-toolbox/rivets/fleetdb" + rtypes "github.com/metal-toolbox/rivets/types" + "github.com/bmc-toolbox/common" - "github.com/metal-toolbox/flasher/internal/model" "github.com/pkg/errors" ) -// versionedAttributeFirmware is the format in which the firmware data is present in fleetdb API. -type versionedAttributeFirmware struct { - Firmware *common.Firmware `json:"firmware,omitempty"` -} - func findAttribute(ns string, attributes []fleetdbapi.Attributes) *fleetdbapi.Attributes { for _, attribute := range attributes { if attribute.Namespace == ns { @@ -27,37 +23,6 @@ func findAttribute(ns string, attributes []fleetdbapi.Attributes) *fleetdbapi.At return nil } -func findVersionedAttribute(ns string, attributes []fleetdbapi.VersionedAttributes) *fleetdbapi.VersionedAttributes { - for _, attribute := range attributes { - if attribute.Namespace == ns { - return &attribute - } - } - - return nil -} - -// assetState returns the asset state attribute value from the configured AssetStateAttributeNS -func (s *FleetDBAPI) assetStateAttribute(attributes []fleetdbapi.Attributes) (string, error) { - var assetState string - - assetStateAttribute := findAttribute(s.config.AssetStateAttributeNS, attributes) - if assetStateAttribute == nil { - return assetState, nil - } - - data := map[string]string{} - if err := json.Unmarshal(assetStateAttribute.Data, &data); err != nil { - return assetState, errors.Wrap(ErrDeviceState, err.Error()) - } - - if data[s.config.AssetStateAttributeKey] == "" { - return assetState, errors.Wrap(ErrDeviceState, "device state attribute is not set") - } - - return data[s.config.AssetStateAttributeKey], nil -} - func (s *FleetDBAPI) bmcAddressFromAttributes(attributes []fleetdbapi.Attributes) (net.IP, error) { ip := net.IP{} @@ -116,42 +81,19 @@ func (s *FleetDBAPI) vendorModelFromAttributes(attributes []fleetdbapi.Attribute return } -func (s *FleetDBAPI) fromServerserviceComponents(scomponents fleetdbapi.ServerComponentSlice) model.Components { - components := make(model.Components, 0, len(scomponents)) +func (s *FleetDBAPI) fromServerserviceComponents(scomponents fleetdbapi.ServerComponentSlice) []*rtypes.Component { + components := make([]*rtypes.Component, 0, len(scomponents)) // nolint:gocritic // rangeValCopy - this type is returned in the current form by fleetdb API. for _, sc := range scomponents { - components = append(components, &model.Component{ - Slug: sc.ComponentTypeSlug, - Serial: sc.Serial, - Vendor: sc.Vendor, - Model: sc.Model, - FirmwareInstalled: s.firmwareFromVersionedAttributes(sc.VersionedAttributes), - }) - } - - return components -} - -func (s *FleetDBAPI) firmwareFromVersionedAttributes(va []fleetdbapi.VersionedAttributes) string { - if len(va) == 0 { - return "" - } - - found := findVersionedAttribute(s.config.OutofbandFirmwareNS, va) - if found == nil { - return "" - } - - vaData := &versionedAttributeFirmware{} - if err := json.Unmarshal(found.Data, vaData); err != nil { - s.logger.Warn("failed to unmarshal firmware data") - return "" - } + sc := sc + c, err := rfleetdb.RecordToComponent(&sc) + if err != nil { + s.logger.WithError(err).Warn("failed to convert component from fleetdb record: " + sc.Name) + } - if vaData.Firmware == nil { - return "" + components = append(components, c) } - return vaData.Firmware.Installed + return components } From 92add88bd7540f85ff441c5b60e46877363ea6a0 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 14:33:48 +0200 Subject: [PATCH 04/11] outofband: use rivets.Server instead of model.Asset This is based on the changes in the previous commit --- internal/outofband/action_handlers.go | 38 +++++++++++----------- internal/outofband/action_handlers_test.go | 1 + internal/outofband/actions.go | 2 +- internal/outofband/actions_test.go | 5 +-- internal/outofband/bmc.go | 9 ++--- internal/outofband/bmc_helpers.go | 10 +++--- internal/outofband/graph.go | 5 +-- 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/internal/outofband/action_handlers.go b/internal/outofband/action_handlers.go index ed2cfa54..e7c33bf8 100644 --- a/internal/outofband/action_handlers.go +++ b/internal/outofband/action_handlers.go @@ -109,7 +109,7 @@ func (h *handler) serverPoweredOff(ctx context.Context) (bool, error) { // init out of band device queryor - if one isn't already initialized // this is done conditionally to enable tests to pass in a device queryor if h.deviceQueryor == nil { - h.deviceQueryor = NewDeviceQueryor(ctx, h.task.Asset, h.logger) + h.deviceQueryor = NewDeviceQueryor(ctx, h.task.Server, h.logger) } if err := h.deviceQueryor.Open(ctx); err != nil { @@ -181,7 +181,7 @@ func (h *handler) installedEqualsExpected(ctx context.Context, component, expect return err } - found := components.BySlugModel(component, models) + found := components.ByNameModel(component, models) if found == nil { h.logger.WithFields( logrus.Fields{ @@ -201,22 +201,22 @@ func (h *handler) installedEqualsExpected(ctx context.Context, component, expect h.logger.WithFields( logrus.Fields{ - "component": found.Slug, + "component": found.Name, "vendor": found.Vendor, "model": found.Model, "serial": found.Serial, - "current": found.FirmwareInstalled, + "current": found.Firmware.Installed, "expected": expectedFirmware, }).Debug("component version check") - if strings.TrimSpace(found.FirmwareInstalled) == "" { + if strings.TrimSpace(found.Firmware.Installed) == "" { return ErrInstalledVersionUnknown } - if !strings.EqualFold(expectedFirmware, found.FirmwareInstalled) { + if !strings.EqualFold(expectedFirmware, found.Firmware.Installed) { return errors.Wrap( ErrInstalledFirmwareNotEqual, - fmt.Sprintf("expected: %s, current: %s", expectedFirmware, found.FirmwareInstalled), + fmt.Sprintf("expected: %s, current: %s", expectedFirmware, found.Firmware.Installed), ) } @@ -500,7 +500,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { logrus.Fields{ "component": h.action.Firmware.Component, "version": h.action.Firmware.Version, - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "step": h.action.FirmwareInstallStep, "installTask": installTask, }).Info("polling BMC for firmware task status") @@ -548,7 +548,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { case nil: h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "component": h.firmware.Component, }).Debug("Installed firmware matches expected.") @@ -567,7 +567,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { attemptErrors = multierror.Append(attemptErrors, err) h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "component": h.firmware.Component, "elapsed": time.Since(startTS).String(), "attempts": fmt.Sprintf("attempt %d/%d", attempts, maxPollStatusAttempts), @@ -592,7 +592,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { "component": h.firmware.Component, "update": h.firmware.FileName, "version": h.firmware.Version, - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "elapsed": time.Since(startTS).String(), "attempts": fmt.Sprintf("attempt %d/%d", attempts, maxPollStatusAttempts), "taskState": state, @@ -625,7 +625,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { if componentIsBMC(h.action.Firmware.Component) && installTask { h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "delay": delayBMCReset.String(), "taskState": state, "bmcTaskID": h.action.BMCTaskID, @@ -691,7 +691,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { if err := h.powerCycleBMC(ctx); err != nil { h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "component": h.firmware.Component, "err": err.Error(), }).Debug("install failure required a BMC reset, reset returned error") @@ -699,7 +699,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "component": h.firmware.Component, }).Debug("BMC reset for failed BMC firmware install") } @@ -719,7 +719,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { if errBmcReset := h.powerCycleBMC(ctx); errBmcReset != nil { h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "component": h.firmware.Component, "err": errBmcReset.Error(), }).Debug("install success required a BMC reset, reset returned error") @@ -727,7 +727,7 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { h.logger.WithFields( logrus.Fields{ - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, "component": h.firmware.Component, }).Debug("BMC reset for successful BMC firmware install") } @@ -747,7 +747,7 @@ func (h *handler) resetBMC(ctx context.Context) error { h.logger.WithFields( logrus.Fields{ "component": h.firmware.Component, - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, }).Info("resetting BMC, delay introduced: " + delayBMCReset.String()) err := h.powerCycleBMC(ctx) @@ -778,7 +778,7 @@ func (h *handler) powerCycleServer(ctx context.Context) error { h.logger.WithFields( logrus.Fields{ "component": h.firmware.Component, - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, }).Info("resetting host for firmware install") return h.deviceQueryor.SetPowerState(ctx, "cycle") @@ -822,7 +822,7 @@ func (h *handler) powerOffServer(ctx context.Context) error { h.logger.WithFields( logrus.Fields{ "component": h.firmware.Component, - "bmc": h.task.Asset.BmcAddress, + "bmc": h.task.Server.BMCAddress, }).Debug("powering off device") if err := h.deviceQueryor.SetPowerState(ctx, "off"); err != nil { diff --git a/internal/outofband/action_handlers_test.go b/internal/outofband/action_handlers_test.go index b7c36e65..9d756b8d 100644 --- a/internal/outofband/action_handlers_test.go +++ b/internal/outofband/action_handlers_test.go @@ -11,6 +11,7 @@ import ( "github.com/metal-toolbox/flasher/internal/model" "github.com/metal-toolbox/flasher/internal/runner" rctypes "github.com/metal-toolbox/rivets/condition" + rtypes "github.com/metal-toolbox/rivets/types" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" diff --git a/internal/outofband/actions.go b/internal/outofband/actions.go index c2f30745..d432e4df 100644 --- a/internal/outofband/actions.go +++ b/internal/outofband/actions.go @@ -55,7 +55,7 @@ func initHandler(actionCtx *runner.ActionHandlerContext, queryor device.Queryor) func (o *ActionHandler) ComposeAction(ctx context.Context, actionCtx *runner.ActionHandlerContext) (*model.Action, error) { var deviceQueryor device.Queryor if actionCtx.DeviceQueryor == nil { - deviceQueryor = NewDeviceQueryor(ctx, actionCtx.Task.Asset, actionCtx.Logger) + deviceQueryor = NewDeviceQueryor(ctx, actionCtx.Task.Server, actionCtx.Logger) } else { deviceQueryor = actionCtx.DeviceQueryor } diff --git a/internal/outofband/actions_test.go b/internal/outofband/actions_test.go index 1035ba09..7af00c45 100644 --- a/internal/outofband/actions_test.go +++ b/internal/outofband/actions_test.go @@ -9,6 +9,7 @@ import ( "github.com/metal-toolbox/flasher/internal/model" "github.com/metal-toolbox/flasher/internal/runner" rctypes "github.com/metal-toolbox/rivets/condition" + rtypes "github.com/metal-toolbox/rivets/types" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -19,8 +20,8 @@ func TestComposeAction(t *testing.T) { return &runner.ActionHandlerContext{ TaskHandlerContext: &runner.TaskHandlerContext{ Task: &model.Task{ - Parameters: rctypes.FirmwareInstallTaskParameters{}, - Asset: &model.Asset{}, + Parameters: &rctypes.FirmwareInstallTaskParameters{}, + Server: &rtypes.Server{}, }, Logger: logrus.NewEntry(logrus.New()), }, diff --git a/internal/outofband/bmc.go b/internal/outofband/bmc.go index be5fd6d5..8c36366e 100644 --- a/internal/outofband/bmc.go +++ b/internal/outofband/bmc.go @@ -15,8 +15,9 @@ import ( "github.com/bmc-toolbox/common" "github.com/metal-toolbox/flasher/internal/device" - "github.com/metal-toolbox/flasher/internal/model" "github.com/sirupsen/logrus" + + rtypes "github.com/metal-toolbox/rivets/types" ) var ( @@ -48,17 +49,17 @@ var ( ErrFirmwareInstallProvider = errors.New("firmware install provider not identified") ) -// bmc wraps the bmclib client and implements the bmcQueryor interface +// bmc wraps the bmclib client and implements the device.Queryor interface type bmc struct { client *bmclib.Client logger *logrus.Entry - asset *model.Asset + asset *rtypes.Server installProvider string availableProviders []string } // NewDeviceQueryor returns a bmc queryor that implements the DeviceQueryor interface -func NewDeviceQueryor(ctx context.Context, asset *model.Asset, logger *logrus.Entry) device.Queryor { +func NewDeviceQueryor(ctx context.Context, asset *rtypes.Server, logger *logrus.Entry) device.Queryor { return &bmc{ client: newBmclibv2Client(ctx, asset, logger), logger: logger, diff --git a/internal/outofband/bmc_helpers.go b/internal/outofband/bmc_helpers.go index 1199b616..92726946 100644 --- a/internal/outofband/bmc_helpers.go +++ b/internal/outofband/bmc_helpers.go @@ -19,12 +19,12 @@ import ( logrusrv2 "github.com/bombsimon/logrusr/v2" "github.com/hashicorp/go-multierror" "github.com/jpillora/backoff" + rtypes "github.com/metal-toolbox/rivets/types" "github.com/pkg/errors" "go.opentelemetry.io/otel" "golang.org/x/exp/slices" "golang.org/x/net/publicsuffix" - "github.com/metal-toolbox/flasher/internal/model" "github.com/sirupsen/logrus" ) @@ -73,7 +73,7 @@ func newHTTPClient() *http.Client { } // newBmclibv2Client initializes a bmclib client with the given credentials -func newBmclibv2Client(_ context.Context, asset *model.Asset, l *logrus.Entry) *bmclib.Client { +func newBmclibv2Client(_ context.Context, asset *rtypes.Server, l *logrus.Entry) *bmclib.Client { logger := logrus.New() if l != nil { logger.Formatter = l.Logger.Formatter @@ -93,9 +93,9 @@ func newBmclibv2Client(_ context.Context, asset *model.Asset, l *logrus.Entry) * logruslogr := logrusrv2.New(logger) bmcClient := bmclib.NewClient( - asset.BmcAddress.String(), - asset.BmcUsername, - asset.BmcPassword, + asset.BMCAddress, + asset.BMCAddress, + asset.BMCPassword, bmclib.WithLogger(logruslogr), bmclib.WithHTTPClient(newHTTPClient()), bmclib.WithPerProviderTimeout(loginTimeout), diff --git a/internal/outofband/graph.go b/internal/outofband/graph.go index 9168a755..82937dd8 100644 --- a/internal/outofband/graph.go +++ b/internal/outofband/graph.go @@ -12,6 +12,7 @@ import ( bconsts "github.com/bmc-toolbox/bmclib/v2/constants" rctypes "github.com/metal-toolbox/rivets/condition" + rtypes "github.com/metal-toolbox/rivets/types" ) func GraphSteps(ctx context.Context, g *dot.Graph) error { @@ -28,10 +29,10 @@ func GraphSteps(ctx context.Context, g *dot.Graph) error { testActionCtx := &runner.ActionHandlerContext{ TaskHandlerContext: &runner.TaskHandlerContext{ Task: &model.Task{ - Parameters: rctypes.FirmwareInstallTaskParameters{ + Parameters: &rctypes.FirmwareInstallTaskParameters{ ResetBMCBeforeInstall: true, }, - Asset: &model.Asset{}, + Server: &rtypes.Server{}, }, Logger: logrus.NewEntry(logrus.New()), DeviceQueryor: m, From d7a183fc98e647b3dedcefdfb14cc0afc008d45a Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 14:59:22 +0200 Subject: [PATCH 05/11] misc: switch to rivets.{Server,Task} types --- internal/install/install.go | 20 ++++---- internal/install/task_handler.go | 20 ++++---- internal/outofband/action_handlers.go | 6 +-- internal/outofband/action_handlers_test.go | 4 +- internal/runner/runner.go | 12 ++--- internal/runner/runner_test.go | 4 +- internal/store/interface.go | 3 +- internal/worker/outofband.go | 10 ++-- internal/worker/task_handler.go | 22 ++++----- internal/worker/task_handler_test.go | 56 +++++++++++----------- 10 files changed, 83 insertions(+), 74 deletions(-) diff --git a/internal/install/install.go b/internal/install/install.go index c844bad9..a4ddd319 100644 --- a/internal/install/install.go +++ b/internal/install/install.go @@ -10,9 +10,11 @@ import ( "github.com/google/uuid" "github.com/metal-toolbox/flasher/internal/model" "github.com/metal-toolbox/flasher/internal/runner" - rctypes "github.com/metal-toolbox/rivets/condition" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + rctypes "github.com/metal-toolbox/rivets/condition" + rtypes "github.com/metal-toolbox/rivets/types" ) type Installer struct { @@ -56,21 +58,21 @@ func (i *Installer) Install(ctx context.Context, params *Params) { }, } - task, err := model.NewTask(uuid.New(), taskParams) + task, err := model.NewTask(uuid.New(), rctypes.FirmwareInstall, taskParams) if err != nil { i.logger.Fatal(err) } task.Parameters.DryRun = params.DryRun - task.Asset = &model.Asset{ - BmcAddress: net.ParseIP(params.BmcAddr), - BmcUsername: params.User, - BmcPassword: params.Pass, + task.Server = &rtypes.Server{ + BMCAddress: net.ParseIP(params.BmcAddr).String(), + BMCUser: params.User, + BMCPassword: params.Pass, Model: params.Model, Vendor: params.Vendor, } - task.Status = model.NewTaskStatusRecord("initialized task") + task.Status = rctypes.NewTaskStatusRecord("initialized task") le := i.logger.WithFields( logrus.Fields{ @@ -102,7 +104,7 @@ func (i *Installer) runTask(ctx context.Context, params *Params, task *model.Tas if err := r.RunTask(ctx, task, h); err != nil { i.logger.WithFields( logrus.Fields{ - "bmc-ip": task.Asset.BmcAddress.String(), + "bmc-ip": task.Server.BMCAddress, "err": err.Error(), }, ).Warn("task for device failed") @@ -111,7 +113,7 @@ func (i *Installer) runTask(ctx context.Context, params *Params, task *model.Tas } i.logger.WithFields(logrus.Fields{ - "bmc-ip": task.Asset.BmcAddress.String(), + "bmc-ip": task.Server.BMCAddress, "elapsed": time.Since(startTS).String(), }).Info("task for device completed") } diff --git a/internal/install/task_handler.go b/internal/install/task_handler.go index 1aa1850d..3c4c8cb5 100644 --- a/internal/install/task_handler.go +++ b/internal/install/task_handler.go @@ -9,6 +9,8 @@ import ( "github.com/metal-toolbox/flasher/internal/runner" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + rtypes "github.com/metal-toolbox/rivets/types" ) var ( @@ -33,7 +35,7 @@ func (t *handler) Initialize(ctx context.Context) error { // so this DeviceQueryor would have to be extended // // For this to work with both inband and out of band, the firmware set data should include the install method. - t.taskCtx.DeviceQueryor = outofband.NewDeviceQueryor(ctx, t.taskCtx.Task.Asset, t.taskCtx.Logger) + t.taskCtx.DeviceQueryor = outofband.NewDeviceQueryor(ctx, t.taskCtx.Task.Server, t.taskCtx.Logger) } return nil @@ -51,7 +53,7 @@ func (t *handler) Query(ctx context.Context) error { // component inventory was identified if len(components) > 0 { - t.taskCtx.Task.Asset.Components = components + t.taskCtx.Task.Server.Components = components return nil } @@ -89,7 +91,7 @@ func (t *handler) PlanActions(ctx context.Context) error { //nolint:errcheck // SetState never returns an error action.SetState(model.StatePending) - t.taskCtx.Task.ActionsPlanned = []*model.Action{action} + t.taskCtx.Task.Data.ActionsPlanned = []*model.Action{action} return nil } @@ -97,14 +99,14 @@ func (t *handler) PlanActions(ctx context.Context) error { func (t *handler) Publish(context.Context) {} // query device components inventory from the device itself. -func (t *handler) queryFromDevice(ctx context.Context) (model.Components, error) { +func (t *handler) queryFromDevice(ctx context.Context) ([]*rtypes.Component, error) { if t.taskCtx.DeviceQueryor == nil { // TODO(joel): DeviceQueryor is to be instantiated based on the method(s) for the firmwares to be installed // if its a mix of inband, out of band firmware to be installed, then both are to be queried and // so this DeviceQueryor would have to be extended // // For this to work with both inband and out of band, the firmware set data should include the install method. - t.taskCtx.DeviceQueryor = outofband.NewDeviceQueryor(ctx, t.taskCtx.Task.Asset, t.taskCtx.Logger) + t.taskCtx.DeviceQueryor = outofband.NewDeviceQueryor(ctx, t.taskCtx.Task.Server, t.taskCtx.Logger) } t.taskCtx.Task.Status.Append("connecting to device BMC") @@ -120,12 +122,12 @@ func (t *handler) queryFromDevice(ctx context.Context) (model.Components, error) return nil, err } - if t.taskCtx.Task.Asset.Vendor == "" { - t.taskCtx.Task.Asset.Vendor = deviceCommon.Vendor + if t.taskCtx.Task.Server.Vendor == "" { + t.taskCtx.Task.Server.Vendor = deviceCommon.Vendor } - if t.taskCtx.Task.Asset.Model == "" { - t.taskCtx.Task.Asset.Model = common.FormatProductName(deviceCommon.Model) + if t.taskCtx.Task.Server.Model == "" { + t.taskCtx.Task.Server.Model = common.FormatProductName(deviceCommon.Model) } return model.NewComponentConverter().CommonDeviceToComponents(deviceCommon) diff --git a/internal/outofband/action_handlers.go b/internal/outofband/action_handlers.go index e7c33bf8..4bb018a0 100644 --- a/internal/outofband/action_handlers.go +++ b/internal/outofband/action_handlers.go @@ -136,7 +136,7 @@ func (h *handler) powerOnServer(ctx context.Context) error { } // server is currently powered on and it wasn't powered on by flasher - if !serverIsPoweredOff && h.task.Data[devicePoweredOn] != "true" { + if !serverIsPoweredOff && h.task.Data.Scratch[devicePoweredOn] != "true" { if h.task.Parameters.RequireHostPoweredOff { return ErrRequireHostPoweredOff } @@ -160,7 +160,7 @@ func (h *handler) powerOnServer(ctx context.Context) error { } } - h.task.Data[devicePoweredOn] = "true" + h.task.Data.Scratch[devicePoweredOn] = "true" return nil } @@ -795,7 +795,7 @@ func (h *handler) conditionalPowerOffDevice(_ context.Context) (bool, error) { return false, nil } - wasPoweredOn, keyExists := h.task.Data[devicePoweredOn] + wasPoweredOn, keyExists := h.task.Data.Scratch[devicePoweredOn] if !keyExists { return false, nil } diff --git a/internal/outofband/action_handlers_test.go b/internal/outofband/action_handlers_test.go index 9d756b8d..f53d3393 100644 --- a/internal/outofband/action_handlers_test.go +++ b/internal/outofband/action_handlers_test.go @@ -23,8 +23,8 @@ func newTestActionCtx() *runner.ActionHandlerContext { return &runner.ActionHandlerContext{ TaskHandlerContext: &runner.TaskHandlerContext{ Task: &model.Task{ - Parameters: rctypes.FirmwareInstallTaskParameters{}, - Asset: &model.Asset{}, + Parameters: &rctypes.FirmwareInstallTaskParameters{}, + Server: &rtypes.Server{}, State: model.StateActive, }, Logger: logrus.NewEntry(logrus.New()), diff --git a/internal/runner/runner.go b/internal/runner/runner.go index 1533ba6e..52ef068c 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -86,7 +86,7 @@ func (r *Runner) RunTask(ctx context.Context, task *model.Task, handler TaskHand taskFailed := func(err error) error { // no error returned - _ = task.SetState(model.StateFailed) + task.SetState(model.StateFailed) task.Status.Append("task failed") task.Status.Append(err.Error()) handler.Publish(ctx) @@ -98,7 +98,7 @@ func (r *Runner) RunTask(ctx context.Context, task *model.Task, handler TaskHand taskSuccess := func() error { // no error returned - _ = task.SetState(model.StateSucceeded) + task.SetState(model.StateSucceeded) task.Status.Append("task completed successfully") handler.Publish(ctx) @@ -117,7 +117,7 @@ func (r *Runner) RunTask(ctx context.Context, task *model.Task, handler TaskHand }() // nolint:errcheck // nope // no error returned - _ = task.SetState(model.StateActive) + task.SetState(model.StateActive) handler.Publish(ctx) // initialize, plan actions @@ -131,13 +131,13 @@ func (r *Runner) RunTask(ctx context.Context, task *model.Task, handler TaskHand } } - r.logger.WithField("planned.actions", len(task.ActionsPlanned)).Debug("start running planned actions") + r.logger.WithField("planned.actions", len(task.Data.ActionsPlanned)).Debug("start running planned actions") if err := r.runActions(ctx, task, handler); err != nil { return taskFailed(err) } - r.logger.WithField("planned.actions", len(task.ActionsPlanned)).Debug("finished running planned actions") + r.logger.WithField("planned.actions", len(task.Data.ActionsPlanned)).Debug("finished running planned actions") return taskSuccess() } @@ -163,7 +163,7 @@ func (r *Runner) runActions(ctx context.Context, task *model.Task, handler TaskH } // each action corresponds to a firmware to be installed - for _, action := range task.ActionsPlanned { + for _, action := range task.Data.ActionsPlanned { startTS := time.Now() actionLogger := r.logger.WithFields(logrus.Fields{ diff --git a/internal/runner/runner_test.go b/internal/runner/runner_test.go index e6603252..1e544456 100644 --- a/internal/runner/runner_test.go +++ b/internal/runner/runner_test.go @@ -48,7 +48,9 @@ func TestRunTask(t *testing.T) { tt.mockSetup(mockHandler) // Set up the mock expectations r := New(logrus.NewEntry(logrus.New())) - task := &model.Task{} + task := &model.Task{ + Data: &model.TaskData{}, + } err := r.RunTask(context.Background(), task, mockHandler) diff --git a/internal/store/interface.go b/internal/store/interface.go index 4474df91..01bfd3aa 100644 --- a/internal/store/interface.go +++ b/internal/store/interface.go @@ -5,11 +5,12 @@ import ( "github.com/google/uuid" "github.com/metal-toolbox/flasher/internal/model" + rtypes "github.com/metal-toolbox/rivets/types" ) type Repository interface { // AssetByID returns asset. - AssetByID(ctx context.Context, id string) (*model.Asset, error) + AssetByID(ctx context.Context, id string) (*rtypes.Server, error) FirmwareSetByID(ctx context.Context, id uuid.UUID) ([]*model.Firmware, error) diff --git a/internal/worker/outofband.go b/internal/worker/outofband.go index 33fc82c9..9f39d107 100644 --- a/internal/worker/outofband.go +++ b/internal/worker/outofband.go @@ -87,7 +87,7 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co if err != nil { h.logger.WithFields(logrus.Fields{ "assetID": task.Parameters.AssetID.String(), - "conditionID": condition.ID, + "conditionID": task.ID, "controllerID": h.controllerID, "err": err.Error(), }).Error("asset lookup error") @@ -95,7 +95,7 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co return controller.ErrRetryHandler } - task.Asset = asset + task.Server = asset task.FacilityCode = h.facilityCode task.WorkerID = h.controllerID @@ -105,10 +105,10 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co l.Level = h.logger.Level hLogger := l.WithFields( logrus.Fields{ - "conditionID": condition.ID.String(), + "conditionID": task.ID.String(), "controllerID": h.controllerID, - "assetID": asset.ID.String(), - "bmc": asset.BmcAddress.String(), + "assetID": asset.ID, + "bmc": asset.BMCAddress, }, ) diff --git a/internal/worker/task_handler.go b/internal/worker/task_handler.go index e39b3dd3..11f3c4ff 100644 --- a/internal/worker/task_handler.go +++ b/internal/worker/task_handler.go @@ -52,7 +52,7 @@ func (t *handler) Initialize(ctx context.Context) error { // so this DeviceQueryor would have to be extended // // For this to work with both inband and out of band, the firmware set data should include the install method. - t.DeviceQueryor = outofband.NewDeviceQueryor(ctx, t.Task.Asset, t.Logger) + t.DeviceQueryor = outofband.NewDeviceQueryor(ctx, t.Task.Server, t.Logger) } return nil @@ -76,12 +76,12 @@ func (t *handler) Query(ctx context.Context) error { return errors.Wrap(errTaskQueryInventory, err.Error()) } - if t.Task.Asset.Vendor == "" { - t.Task.Asset.Vendor = deviceCommon.Vendor + if t.Task.Server.Vendor == "" { + t.Task.Server.Vendor = deviceCommon.Vendor } - if t.Task.Asset.Model == "" { - t.Task.Asset.Model = common.FormatProductName(deviceCommon.Model) + if t.Task.Server.Model == "" { + t.Task.Server.Model = common.FormatProductName(deviceCommon.Model) } components, err := model.NewComponentConverter().CommonDeviceToComponents(deviceCommon) @@ -91,7 +91,7 @@ func (t *handler) Query(ctx context.Context) error { // component inventory was identified if len(components) > 0 { - t.Task.Asset.Components = components + t.Task.Server.Components = components return nil } @@ -100,13 +100,13 @@ func (t *handler) Query(ctx context.Context) error { } func (t *handler) PlanActions(ctx context.Context) error { - switch t.Task.FirmwarePlanMethod { + switch t.Task.Data.FirmwarePlanMethod { case model.FromFirmwareSet: return t.planFromFirmwareSet(ctx) case model.FromRequestedFirmware: return errors.Wrap(errTaskPlanActions, "firmware plan method not implemented"+string(model.FromRequestedFirmware)) default: - return errors.Wrap(errTaskPlanActions, "firmware plan method invalid: "+string(t.Task.FirmwarePlanMethod)) + return errors.Wrap(errTaskPlanActions, "firmware plan method invalid: "+string(t.Task.Data.FirmwarePlanMethod)) } } @@ -123,7 +123,7 @@ func (t *handler) planFromFirmwareSet(ctx context.Context) error { } // plan actions based and update task action list - t.Task.ActionsPlanned, err = t.planInstall(ctx, applicable) + t.Task.Data.ActionsPlanned, err = t.planInstall(ctx, applicable) if err != nil { return err } @@ -213,8 +213,8 @@ func (t *handler) removeFirmwareAlreadyAtDesiredVersion(fws []*model.Firmware) [ var toInstall []*model.Firmware invMap := make(map[string]string) - for _, cmp := range t.Task.Asset.Components { - invMap[strings.ToLower(cmp.Slug)] = cmp.FirmwareInstalled + for _, cmp := range t.Task.Server.Components { + invMap[strings.ToLower(cmp.Name)] = cmp.Firmware.Installed } fmtCause := func(component, cause, currentV, requestedV string) string { diff --git a/internal/worker/task_handler_test.go b/internal/worker/task_handler_test.go index d2bd7f55..1753011e 100644 --- a/internal/worker/task_handler_test.go +++ b/internal/worker/task_handler_test.go @@ -15,7 +15,9 @@ import ( "github.com/stretchr/testify/require" bconsts "github.com/bmc-toolbox/bmclib/v2/constants" + "github.com/bmc-toolbox/common" rctypes "github.com/metal-toolbox/rivets/condition" + rtypes "github.com/metal-toolbox/rivets/types" ) func TestSortFirmwareByInstallOrder(t *testing.T) { @@ -114,16 +116,16 @@ func TestRemoveFirmwareAlreadyAtDesiredVersion(t *testing.T) { Task: &model.Task{ ID: serverID, // it just needs to be a UUID WorkerID: registry.GetID("test-app").String(), - Asset: &model.Asset{ - ID: serverID, - Components: model.Components{ + Server: &rtypes.Server{ + ID: serverID.String(), + Components: rtypes.Components{ { - Slug: "BiOs", - FirmwareInstalled: "2.6.6", + Name: "BiOs", + Firmware: &common.Firmware{Installed: "2.6.6"}, }, { - Slug: "nic", - FirmwareInstalled: "some-different-version", + Name: "nic", + Firmware: &common.Firmware{Installed: "some-different-version"}, }, }, }, @@ -189,24 +191,24 @@ func TestPlanInstall(t *testing.T) { Task: &model.Task{ ID: taskID, WorkerID: registry.GetID("test-app").String(), - Parameters: rctypes.FirmwareInstallTaskParameters{ + Parameters: &rctypes.FirmwareInstallTaskParameters{ AssetID: serverID, ResetBMCBeforeInstall: true, }, - Asset: &model.Asset{ - ID: serverID, - Components: model.Components{ + Server: &rtypes.Server{ + ID: serverID.String(), + Components: rtypes.Components{ { - Slug: "BiOs", - FirmwareInstalled: "2.6.6", + Name: "BiOs", + Firmware: &common.Firmware{Installed: "2.6.6"}, }, { - Slug: "bmc", - FirmwareInstalled: "5.10.00.00", + Name: "bmc", + Firmware: &common.Firmware{Installed: "5.10.00.00"}, }, { - Slug: "nic", - FirmwareInstalled: "1.2.2", + Name: "nic", + Firmware: &common.Firmware{Installed: "1.2.2"}, }, }, }, @@ -273,24 +275,24 @@ func TestPlanInstall2(t *testing.T) { Task: &model.Task{ ID: taskID, WorkerID: registry.GetID("test-app").String(), - Parameters: rctypes.FirmwareInstallTaskParameters{ + Parameters: &rctypes.FirmwareInstallTaskParameters{ AssetID: serverID, ForceInstall: true, }, - Asset: &model.Asset{ - ID: serverID, - Components: model.Components{ + Server: &rtypes.Server{ + ID: serverID.String(), + Components: rtypes.Components{ { - Slug: "BiOs", - FirmwareInstalled: "2.6.6", + Name: "BiOs", + Firmware: &common.Firmware{Installed: "2.6.6"}, }, { - Slug: "bmc", - FirmwareInstalled: "5.10.00.00", + Name: "bmc", + Firmware: &common.Firmware{Installed: "5.10.00.00"}, }, { - Slug: "nic", - FirmwareInstalled: "1.2.2", + Name: "nic", + Firmware: &common.Firmware{Installed: "1.2.2"}, }, }, }, From df3a5fd2f82e247dacb6cc58b604ef75b063ae43 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 14:54:42 +0200 Subject: [PATCH 06/11] model/task: use Task type from rivets The rivets.Task type is to be used by all controllers to execute work recieved as conditions --- internal/model/task.go | 244 +++++++++++++++++++++++------------- internal/model/task_test.go | 98 --------------- 2 files changed, 159 insertions(+), 183 deletions(-) delete mode 100644 internal/model/task_test.go diff --git a/internal/model/task.go b/internal/model/task.go index 993cdc2c..318c7a10 100644 --- a/internal/model/task.go +++ b/internal/model/task.go @@ -2,12 +2,14 @@ package model import ( "encoding/json" - "time" + "reflect" "github.com/google/uuid" + "github.com/mitchellh/copystructure" "github.com/pkg/errors" rctypes "github.com/metal-toolbox/rivets/condition" + rtypes "github.com/metal-toolbox/rivets/types" ) // InstallMethod is one of 'outofband' OR 'inband' @@ -40,87 +42,80 @@ const ( StateSucceeded = rctypes.Succeeded StateFailed = rctypes.Failed - TaskVersion = "1.0" + TaskDataStructVersion = "1.0" ) var ( errTaskFirmwareParam = errors.New("firmware task parameters error") ) -// Task is a top level unit of work handled by flasher. -// -// A task performs one or more actions, each of the action corresponds to a Firmware planned for install. -// -// nolint:govet // fieldalignment - struct is better readable in its current form. -type Task struct { - // StructVersion indicates the Task object version and is used to determine Task compatibility. - StructVersion string `json:"task_version"` +// Alias parameterized model.Task +type Task rctypes.Task[*rctypes.FirmwareInstallTaskParameters, *TaskData] - // Task unique identifier, this is set to the Condition identifier. - ID uuid.UUID `json:"id"` +func (t *Task) SetState(s rctypes.State) { + t.State = s +} - // state is the state of the install - State rctypes.State `json:"state"` +func (t *Task) MustMarshal() json.RawMessage { + b, err := json.Marshal(t) + if err != nil { + panic(err) + } - // status holds informational data on the state - Status StatusRecord `json:"status"` + return b +} +type TaskData struct { + StructVersion string `json:"struct_version"` // Flasher determines the firmware to be installed for each component based on the firmware plan method. FirmwarePlanMethod FirmwarePlanMethod `json:"firmware_plan_method,omitempty"` // ActionsPlanned to be executed for each firmware to be installed. ActionsPlanned Actions `json:"actions_planned,omitempty"` - // Parameters for this task - Parameters rctypes.FirmwareInstallTaskParameters `json:"parameters,omitempty"` - - // Fault is a field to inject failures into a flasher task execution, - // this is set from the Condition only when the worker is run with fault-injection enabled. - Fault *rctypes.Fault `json:"fault,omitempty"` - - // FacilityCode identifies the facility this task is to be executed in. - FacilityCode string `json:"facility_code"` - - // Data is an arbitrary key values map available to all task, action handler methods. - Data map[string]string `json:"data,omitempty"` + // Scratch is an arbitrary key values map available to all task, action handler methods. + Scratch map[string]string `json:"data,omitempty"` +} - // Asset holds attributes about the device under firmware install. - Asset *Asset `json:"asset,omitempty"` +func (td *TaskData) MapStringInterfaceToStruct(m map[string]interface{}) error { + jsonData, err := json.Marshal(m) + if err != nil { + return err + } - // WorkerID is the identifier for the worker executing this task. - WorkerID string `json:"worker_id,omitempty"` + return json.Unmarshal(jsonData, td) +} - CreatedAt time.Time `json:"created_at,omitempty"` - UpdatedAt time.Time `json:"updated_at,omitempty"` - CompletedAt time.Time `json:"completed_at,omitempty"` +func (td *TaskData) Marshal() (json.RawMessage, error) { + return json.Marshal(td) } -// SetState implements the Task runner interface -func (t *Task) SetState(state rctypes.State) error { - t.State = state - return nil +func (td *TaskData) Unmarshal(r json.RawMessage) error { + return json.Unmarshal(r, td) } -func NewTask(conditionID uuid.UUID, params *rctypes.FirmwareInstallTaskParameters) (Task, error) { +func NewTask(conditionID uuid.UUID, kind rctypes.Kind, params *rctypes.FirmwareInstallTaskParameters) (Task, error) { t := Task{ - StructVersion: TaskVersion, + StructVersion: rctypes.TaskVersion1, ID: conditionID, - Status: NewTaskStatusRecord("initialized task"), + Kind: kind, + Data: &TaskData{}, + Status: rctypes.NewTaskStatusRecord("initialized task"), State: StatePending, - Parameters: *params, - Data: make(map[string]string), + Parameters: params, } + t.Data.Scratch = make(map[string]string) if len(params.Firmwares) > 0 { t.Parameters.Firmwares = params.Firmwares - t.FirmwarePlanMethod = FromRequestedFirmware + t.Data.FirmwarePlanMethod = FromRequestedFirmware return t, nil } if params.FirmwareSetID != uuid.Nil { t.Parameters.FirmwareSetID = params.FirmwareSetID - t.FirmwarePlanMethod = FromFirmwareSet + t.Data.FirmwarePlanMethod = FromFirmwareSet return t, nil } @@ -128,67 +123,146 @@ func NewTask(conditionID uuid.UUID, params *rctypes.FirmwareInstallTaskParameter return t, errors.Wrap(errTaskFirmwareParam, "no firmware list or firmwareSetID specified") } -func NewTaskStatusRecord(s string) StatusRecord { - sr := StatusRecord{} - if s == "" { - return sr - } +func convTaskParams(params any) (*rctypes.FirmwareInstallTaskParameters, error) { + errParamsConv := errors.New("error in Task.Parameters conversion") - sr.Append(s) + fwInstallParams := &rctypes.FirmwareInstallTaskParameters{} + switch v := params.(type) { + // When unpacked from a http request by the condition orc client, + // Parameters are of this type. + case map[string]interface{}: + if err := fwInstallParams.MapStringInterfaceToStruct(v); err != nil { + return nil, errors.Wrap(errParamsConv, err.Error()) + } + // When received over NATS its of this type. + case json.RawMessage: + if err := fwInstallParams.Unmarshal(v); err != nil { + return nil, errors.Wrap(errParamsConv, err.Error()) + } + default: + msg := "Task.Parameters expected to be one of map[string]interface{} or json.RawMessage, current type: " + reflect.TypeOf(params).String() + return nil, errors.Wrap(errParamsConv, msg) + } - return sr + return fwInstallParams, nil } -type StatusRecord struct { - StatusMsgs []StatusMsg `json:"records"` -} +func convTaskData(data any) (*TaskData, error) { + errDataConv := errors.New("error in Task.Data conversion") -type StatusMsg struct { - Timestamp time.Time `json:"ts,omitempty"` - Msg string `json:"msg,omitempty"` + taskData := &TaskData{} + switch v := data.(type) { + // When unpacked from a http request by the condition orc client, + // Parameters are of this type. + case map[string]interface{}: + if err := taskData.MapStringInterfaceToStruct(v); err != nil { + return nil, errors.Wrap(errDataConv, err.Error()) + } + // When received over NATS its of this type. + case json.RawMessage: + if err := taskData.Unmarshal(v); err != nil { + return nil, errors.Wrap(errDataConv, err.Error()) + } + default: + msg := "Task.Data expected to be one of map[string]interface{} or json.RawMessage, current type: " + reflect.TypeOf(data).String() + return nil, errors.Wrap(errDataConv, msg) + } + + return taskData, nil } -func (sr *StatusRecord) Append(s string) { - if s == "" { - return +func CopyAsFwInstallTask(task *rctypes.Task[any, any]) (*Task, error) { + errTaskConv := errors.New("error in generic Task conversion") + + params, err := convTaskParams(task.Parameters) + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()) } - for _, r := range sr.StatusMsgs { - if r.Msg == s { - return - } + data, err := convTaskData(task.Data) + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()) } - if len(sr.StatusMsgs) > 4 { - sr.StatusMsgs = sr.StatusMsgs[1:] + // deep copy fields referenced by pointer + asset, err := copystructure.Copy(task.Server) + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()+": Task.Server") } - n := StatusMsg{Timestamp: time.Now(), Msg: s} + fault, err := copystructure.Copy(task.Fault) + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()+": Task.Fault") + } - sr.StatusMsgs = append(sr.StatusMsgs, n) -} + if len(params.Firmwares) > 0 { + data.FirmwarePlanMethod = FromRequestedFirmware + } -func (sr *StatusRecord) Last() string { - if len(sr.StatusMsgs) == 0 { - return "" + if params.FirmwareSetID != uuid.Nil { + data.FirmwarePlanMethod = FromFirmwareSet } - return sr.StatusMsgs[len(sr.StatusMsgs)-1].Msg + return &Task{ + StructVersion: task.StructVersion, + ID: task.ID, + Kind: task.Kind, + State: task.State, + Status: task.Status, + Data: data, + Parameters: params, + Fault: fault.(*rctypes.Fault), + FacilityCode: task.FacilityCode, + Server: asset.(*rtypes.Server), + WorkerID: task.WorkerID, + TraceID: task.TraceID, + SpanID: task.SpanID, + CreatedAt: task.CreatedAt, + UpdatedAt: task.UpdatedAt, + CompletedAt: task.CompletedAt, + }, nil } -func (sr *StatusRecord) Update(currentMsg, newMsg string) { - for idx, r := range sr.StatusMsgs { - if r.Msg == currentMsg { - sr.StatusMsgs[idx].Msg = newMsg - } +func CopyAsGenericTask(task *Task) (*rctypes.Task[any, any], error) { + errTaskConv := errors.New("error in firmware install Task conversion") + + paramsJSON, err := task.Parameters.Marshal() + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()+": Task.Parameters") } -} -func (sr *StatusRecord) MustMarshal() json.RawMessage { - b, err := json.Marshal(sr) + dataJSON, err := task.Data.Marshal() if err != nil { - panic(err) + return nil, errors.Wrap(errTaskConv, err.Error()+": Task.Data") } - return b + // deep copy fields referenced by pointer + asset, err := copystructure.Copy(task.Server) + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()+": Task.Server") + } + + fault, err := copystructure.Copy(task.Fault) + if err != nil { + return nil, errors.Wrap(errTaskConv, err.Error()+": Task.Fault") + } + + return &rctypes.Task[any, any]{ + StructVersion: task.StructVersion, + ID: task.ID, + Kind: task.Kind, + State: task.State, + Status: task.Status, + Data: dataJSON, + Parameters: paramsJSON, + Fault: fault.(*rctypes.Fault), + FacilityCode: task.FacilityCode, + Server: asset.(*rtypes.Server), + WorkerID: task.WorkerID, + TraceID: task.TraceID, + SpanID: task.SpanID, + CreatedAt: task.CreatedAt, + UpdatedAt: task.UpdatedAt, + CompletedAt: task.CompletedAt, + }, nil } diff --git a/internal/model/task_test.go b/internal/model/task_test.go deleted file mode 100644 index 3309c1be..00000000 --- a/internal/model/task_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package model - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestTaskStatusRecord(t *testing.T) { - tests := []struct { - name string - appendStatus string - updateStatus map[string]string - appendStatuses []string - wantStatuses []string - }{ - { - "single status record appended", - "works", - nil, - nil, - []string{"works"}, - }, - { - "multiple status record appended", - "", - nil, - []string{"a", "b", "c"}, - []string{"a", "b", "c"}, - }, - { - "dup status excluded", - "", - nil, - []string{"a", "a", "b", "c"}, - []string{"a", "b", "c"}, - }, - { - "empty status excluded", - "", - nil, - []string{"a", "", "", "c"}, - []string{"a", "c"}, - }, - { - "truncates long set of statuses", - "", - nil, - []string{"a", "b", "c", "d", "e", "f"}, - []string{"b", "c", "d", "e", "f"}, - }, - { - "update a status record", - "", - map[string]string{"b": "updated", "d": "also updated"}, - []string{"a", "b", "c", "d", "e"}, - []string{"a", "updated", "c", "also updated", "e"}, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - sr := NewTaskStatusRecord("") - - if tc.appendStatus != "" { - sr.Append(tc.appendStatus) - - assert.Equal(t, tc.appendStatus, sr.StatusMsgs[0].Msg) - assert.False(t, sr.StatusMsgs[0].Timestamp.IsZero()) - } - - // continue with other tests when theres no appendStatuses - if tc.appendStatuses == nil { - return - } - - for _, s := range tc.appendStatuses { - sr.Append(s) - } - - // append statuses - to test Update() - if tc.updateStatus != nil { - for k, v := range tc.updateStatus { - sr.Update(k, v) - } - } - - assert.Equal(t, len(tc.wantStatuses), len(sr.StatusMsgs)) - for idx, w := range tc.wantStatuses { - assert.Equal(t, w, sr.StatusMsgs[idx].Msg) - assert.False(t, sr.StatusMsgs[idx].Timestamp.IsZero()) - } - - // test Last() method - assert.Equal(t, tc.appendStatuses[len(tc.appendStatuses)-1], sr.Last()) - }) - } -} From cad83f9344cbc3bbefa1b9f2e3a6e17ecbd7d992 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 15:05:37 +0200 Subject: [PATCH 07/11] RunMode identifies the mode the application was executed in This prepares the way to add inband fimware update support --- internal/model/model.go | 4 ++++ internal/worker/outofband.go | 3 ++- internal/worker/task_handler.go | 5 ++++- internal/worker/task_handler_test.go | 6 +++--- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/internal/model/model.go b/internal/model/model.go index efa63170..2f143205 100644 --- a/internal/model/model.go +++ b/internal/model/model.go @@ -5,6 +5,7 @@ type ( StoreKind string // LogLevel is the logging level string. LogLevel string + RunMode string ) const ( @@ -12,6 +13,9 @@ const ( AppKindWorker AppKind = "worker" AppKindCLI AppKind = "cli" + RunInband RunMode = "inband" + RunOutofband RunMode = "outofband" + InventoryStoreYAML StoreKind = "yaml" InventoryStoreServerservice StoreKind = "serverservice" diff --git a/internal/worker/outofband.go b/internal/worker/outofband.go index 9f39d107..7fd7882c 100644 --- a/internal/worker/outofband.go +++ b/internal/worker/outofband.go @@ -114,6 +114,7 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co // init handler handler := newHandler( + model.RunOutofband, task, h.store, model.NewNatsTaskStatusPublisher(publisher), @@ -123,7 +124,7 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co // init runner r := runner.New(hLogger) - hLogger.Info("running task for device") + hLogger.WithField("mode", model.RunOutofband).Info("running task for device") if err := r.RunTask(ctx, task, handler); err != nil { hLogger.WithError(err).Error("task for device failed") return err diff --git a/internal/worker/task_handler.go b/internal/worker/task_handler.go index 11f3c4ff..6015e38a 100644 --- a/internal/worker/task_handler.go +++ b/internal/worker/task_handler.go @@ -26,17 +26,20 @@ var ( // // The handler is instantiated to run a single task type handler struct { + mode model.RunMode *runner.TaskHandlerContext } func newHandler( + mode model.RunMode, task *model.Task, storage store.Repository, publisher model.Publisher, logger *logrus.Entry, ) runner.TaskHandler { return &handler{ - &runner.TaskHandlerContext{ + mode: mode, + TaskHandlerContext: &runner.TaskHandlerContext{ Task: task, Publisher: publisher, Store: storage, diff --git a/internal/worker/task_handler_test.go b/internal/worker/task_handler_test.go index 1753011e..93dd0274 100644 --- a/internal/worker/task_handler_test.go +++ b/internal/worker/task_handler_test.go @@ -143,7 +143,7 @@ func TestRemoveFirmwareAlreadyAtDesiredVersion(t *testing.T) { }, } - h := handler{taskHandlerCtx} + h := handler{mode: model.RunOutofband, TaskHandlerContext: taskHandlerCtx} got := h.removeFirmwareAlreadyAtDesiredVersion(fwSet) require.Equal(t, 3, len(h.Task.Status.StatusMsgs)) require.Equal(t, 1, len(got)) @@ -224,7 +224,7 @@ func TestPlanInstall(t *testing.T) { bconsts.FirmwareInstallStepInstallStatus, }, nil) - h := &handler{taskHandlerCtx} + h := handler{mode: model.RunOutofband, TaskHandlerContext: taskHandlerCtx} actions, err := h.planInstall(context.Background(), fwSet) require.NoError(t, err, "no errors returned") require.Equal(t, 2, len(actions), "expect two actions to be performed") @@ -308,7 +308,7 @@ func TestPlanInstall2(t *testing.T) { bconsts.FirmwareInstallStepInstallStatus, }, nil) - h := &handler{taskHandlerCtx} + h := handler{mode: model.RunOutofband, TaskHandlerContext: taskHandlerCtx} actions, err := h.planInstall(context.Background(), fwSet) require.NoError(t, err, "no errors returned") require.Equal(t, 3, len(actions), "expect three actions to be performed") From 482cbde9fb6342bbb5a1fb61c793a7040c2fa8f6 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 15:10:00 +0200 Subject: [PATCH 08/11] publisher: use ctrl.Publisher which publishes both the Task, StatusValue --- internal/model/publisher.go | 52 ++++++++++++++++++++------- internal/outofband/action_handlers.go | 3 +- internal/worker/outofband.go | 2 +- internal/worker/task_handler.go | 3 +- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/internal/model/publisher.go b/internal/model/publisher.go index ccdcfd08..58348fc7 100644 --- a/internal/model/publisher.go +++ b/internal/model/publisher.go @@ -3,30 +3,56 @@ package model import ( "context" - "github.com/metal-toolbox/rivets/events/controller" + "github.com/metal-toolbox/ctrl" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +var ( + ErrPublishStatus = errors.New("error in publish Condition status") + ErrPublishTask = errors.New("error in publish Condition Task") ) // Publisher defines methods to publish task information. type Publisher interface { - Publish(ctx context.Context, task *Task) + Publish(ctx context.Context, task *Task) error } // StatusPublisher implements the Publisher interface // to wrap the condition controller publish method type StatusPublisher struct { - cp controller.ConditionStatusPublisher + logger *logrus.Entry + cp ctrl.Publisher } -// TODO: this needs to publish the whole task to the KV -func NewNatsTaskStatusPublisher(cp controller.ConditionStatusPublisher) Publisher { - return &StatusPublisher{cp} +func NewTaskStatusPublisher(logger *logrus.Entry, cp ctrl.Publisher) Publisher { + return &StatusPublisher{ + logger, + cp, + } } -func (s *StatusPublisher) Publish(ctx context.Context, task *Task) { - s.cp.Publish( - ctx, - task.Asset.ID.String(), - task.State, - task.Status.MustMarshal(), - ) +func (s *StatusPublisher) Publish(ctx context.Context, task *Task) error { + genericTask, err := CopyAsGenericTask(task) + if err != nil { + err = errors.Wrap(ErrPublishTask, err.Error()) + s.logger.WithError(err).Warn("Task publish error") + + return err + } + + // overwrite credentials before this gets written back to the repository + genericTask.Server.BMCAddress = "" + genericTask.Server.BMCPassword = "" + genericTask.Server.BMCUser = "" + + if err := s.cp.Publish(ctx, genericTask, false); err != nil { + err = errors.Wrap(ErrPublishStatus, err.Error()) + s.logger.WithError(err).Error("Condition status publish error") + + return err + } + + s.logger.Trace("Condition Status publish successful") + return nil } diff --git a/internal/outofband/action_handlers.go b/internal/outofband/action_handlers.go index 4bb018a0..e0faa5b7 100644 --- a/internal/outofband/action_handlers.go +++ b/internal/outofband/action_handlers.go @@ -602,7 +602,8 @@ func (h *handler) pollFirmwareTaskStatus(ctx context.Context) error { if h.publisher != nil && status != "" { h.task.Status.Update(h.task.Status.Last(), statusPrefix+" -- "+status) - h.publisher.Publish(ctx, h.task) + //nolint:errcheck // method called logs errors if any + _ = h.publisher.Publish(ctx, h.task) } // error check returns when maxPollStatusAttempts have been reached diff --git a/internal/worker/outofband.go b/internal/worker/outofband.go index 7fd7882c..0ffd5031 100644 --- a/internal/worker/outofband.go +++ b/internal/worker/outofband.go @@ -117,7 +117,7 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co model.RunOutofband, task, h.store, - model.NewNatsTaskStatusPublisher(publisher), + model.NewTaskStatusPublisher(hLogger, statusPublisher), hLogger, ) diff --git a/internal/worker/task_handler.go b/internal/worker/task_handler.go index 6015e38a..f03654dc 100644 --- a/internal/worker/task_handler.go +++ b/internal/worker/task_handler.go @@ -292,5 +292,6 @@ func (t *handler) OnFailure(ctx context.Context, _ *model.Task) { } func (t *handler) Publish(ctx context.Context) { - t.Publisher.Publish(ctx, t.Task) + //nolint:errcheck // method called logs errors if any + _ = t.Publisher.Publish(ctx, t.Task) } From bf8cc34c230803154415ebd330667eb4816930bb Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 15:14:16 +0200 Subject: [PATCH 09/11] cmd/run, worker: switch to ctrl.NatsController The ctrl.NatsController deals with the Condition and passes a Task object to the controller handler. This way the controller itself does not have to deal with the Condition type and works with the Task type. --- cmd/run.go | 15 +++++++-------- internal/worker/outofband.go | 32 +++++++++++++++++++------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/cmd/run.go b/cmd/run.go index 7b762fa1..8c812094 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -3,15 +3,14 @@ package cmd import ( "context" "log" - "strings" "github.com/equinix-labs/otel-init-go/otelinit" + "github.com/metal-toolbox/ctrl" "github.com/metal-toolbox/flasher/internal/app" "github.com/metal-toolbox/flasher/internal/metrics" "github.com/metal-toolbox/flasher/internal/model" "github.com/metal-toolbox/flasher/internal/store" "github.com/metal-toolbox/flasher/internal/worker" - "github.com/metal-toolbox/rivets/events/controller" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -82,24 +81,24 @@ func runWorker(ctx context.Context) { flasher.Logger.Fatal(err) } - nc := controller.NewNatsController( + nc := ctrl.NewNatsController( model.AppName, facilityCode, "firmwareInstall", natsCfg.NatsURL, natsCfg.CredsFile, "firmwareInstall", - controller.WithConcurrency(flasher.Config.Concurrency), - controller.WithKVReplicas(natsCfg.KVReplicas), - controller.WithLogger(flasher.Logger), - controller.WithConnectionTimeout(natsCfg.ConnectTimeout), + ctrl.WithConcurrency(flasher.Config.Concurrency), + ctrl.WithKVReplicas(natsCfg.KVReplicas), + ctrl.WithLogger(flasher.Logger), + ctrl.WithConnectionTimeout(natsCfg.ConnectTimeout), ) if err := nc.Connect(ctx); err != nil { flasher.Logger.Fatal(err) } - worker.Run( + worker.RunOutofband( ctx, dryrun, faultInjection, diff --git a/internal/worker/outofband.go b/internal/worker/outofband.go index 0ffd5031..c75c1a12 100644 --- a/internal/worker/outofband.go +++ b/internal/worker/outofband.go @@ -2,7 +2,7 @@ package worker import ( "context" - "encoding/json" + "sync" "github.com/metal-toolbox/flasher/internal/model" "github.com/metal-toolbox/flasher/internal/runner" @@ -12,8 +12,8 @@ import ( "github.com/sirupsen/logrus" "go.opentelemetry.io/otel" + "github.com/metal-toolbox/ctrl" rctypes "github.com/metal-toolbox/rivets/condition" - "github.com/metal-toolbox/rivets/events/controller" ) const ( @@ -24,8 +24,9 @@ var ( errInitTask = errors.New("error initializing new task from condition") ) -type ConditionTaskHandler struct { +type OobConditionTaskHandler struct { store store.Repository + syncWG *sync.WaitGroup logger *logrus.Logger facilityCode string controllerID string @@ -33,13 +34,13 @@ type ConditionTaskHandler struct { faultInjection bool } -// NewOutofbandWorker returns a out of band firmware install worker instance -func Run( +// RunOutofband initializes the Out of band Condition handler and listens for events +func RunOutofband( ctx context.Context, dryrun, faultInjection bool, repository store.Repository, - nc *controller.NatsController, + nc *ctrl.NatsController, logger *logrus.Logger, ) { ctx, span := otel.Tracer(pkgName).Start( @@ -57,11 +58,12 @@ func Run( "dry-run": dryrun, "faultInjection": faultInjection, }, - ).Info("flasher worker running") + ).Info("flasher out-of-band installer running") - handlerFactory := func() controller.ConditionHandler { - return &ConditionTaskHandler{ + handlerFactory := func() ctrl.TaskHandler { + return &OobConditionTaskHandler{ store: repository, + syncWG: &sync.WaitGroup{}, logger: logger, dryrun: dryrun, faultInjection: faultInjection, @@ -75,9 +77,13 @@ func Run( } } -// Handle implements the controller.ConditionHandler interface -func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Condition, publisher controller.ConditionStatusPublisher) error { - task, err := newTaskFromCondition(condition, h.dryrun, h.faultInjection) +// HandleTask implements the ctrl.TaskHandler interface +func (h *OobConditionTaskHandler) HandleTask( + ctx context.Context, + genericTask *rctypes.Task[any, any], + statusPublisher ctrl.Publisher, +) error { + task, err := model.CopyAsFwInstallTask(genericTask) if err != nil { return errors.Wrap(errInitTask, err.Error()) } @@ -92,7 +98,7 @@ func (h *ConditionTaskHandler) Handle(ctx context.Context, condition *rctypes.Co "err": err.Error(), }).Error("asset lookup error") - return controller.ErrRetryHandler + return ctrl.ErrRetryHandler } task.Server = asset From 00f4fa8a9ee027ebf7ce02bea767447c5bc734e1 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 15:17:11 +0200 Subject: [PATCH 10/11] purge unused code --- cmd/run.go | 6 +--- internal/store/yaml.go | 42 ------------------------ internal/worker/outofband.go | 23 ------------- internal/worker/worker_test.go | 59 ---------------------------------- 4 files changed, 1 insertion(+), 129 deletions(-) delete mode 100644 internal/store/yaml.go delete mode 100644 internal/worker/worker_test.go diff --git a/cmd/run.go b/cmd/run.go index 8c812094..0314a4e4 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -109,11 +109,7 @@ func runWorker(ctx context.Context) { } func initStore(ctx context.Context, config *app.Configuration, logger *logrus.Logger) (store.Repository, error) { - switch { - // from CLI flags - case strings.HasSuffix(storeKind, ".yml"), strings.HasSuffix(storeKind, ".yaml"): - return store.NewYamlInventory(storeKind) - case storeKind == string(model.InventoryStoreServerservice): + if storeKind == string(model.InventoryStoreServerservice) { return store.NewServerserviceStore(ctx, config.FleetDBAPIOptions, logger) } diff --git a/internal/store/yaml.go b/internal/store/yaml.go deleted file mode 100644 index 863bcfce..00000000 --- a/internal/store/yaml.go +++ /dev/null @@ -1,42 +0,0 @@ -package store - -import ( - "context" - "errors" - - "github.com/google/uuid" - "github.com/metal-toolbox/flasher/internal/model" -) - -const ( - InventorySourceYAML = "inventoryStoreYAML" -) - -var ( - ErrYamlSource = errors.New("error in Yaml inventory") -) - -// Yaml type implements the inventory interface -type Yaml struct { - YamlFile string -} - -// NewYamlInventory returns a Yaml type that implements the inventory interface. -func NewYamlInventory(yamlFile string) (Repository, error) { - return &Yaml{YamlFile: yamlFile}, nil -} - -// AssetByID returns device attributes by its identifier -func (c *Yaml) AssetByID(_ context.Context, _ string) (*model.Asset, error) { - return nil, nil -} - -// FirmwareByDeviceVendorModel returns the firmware for the device vendor, model. -func (c *Yaml) FirmwareByDeviceVendorModel(_ context.Context, _, _ string) ([]*model.Firmware, error) { - return nil, nil -} - -// FirmwareSetByID returns a list of firmwares part of a firmware set identified by the given id. -func (c *Yaml) FirmwareSetByID(_ context.Context, _ uuid.UUID) ([]*model.Firmware, error) { - return nil, nil -} diff --git a/internal/worker/outofband.go b/internal/worker/outofband.go index c75c1a12..1852c43b 100644 --- a/internal/worker/outofband.go +++ b/internal/worker/outofband.go @@ -139,26 +139,3 @@ func (h *OobConditionTaskHandler) HandleTask( hLogger.Info("task for device completed") return nil } - -// newTaskFromMsg returns a new task object with the given parameters -func newTaskFromCondition(condition *rctypes.Condition, dryRun, faultInjection bool) (*model.Task, error) { - parameters := &rctypes.FirmwareInstallTaskParameters{} - if err := json.Unmarshal(condition.Parameters, parameters); err != nil { - return nil, errors.Wrap(errInitTask, "Firmware install task parameters error: "+err.Error()) - } - - t, err := model.NewTask(condition.ID, parameters) - if err != nil { - return nil, err - } - - if faultInjection && condition.Fault != nil { - t.Fault = condition.Fault - } - - if dryRun { - t.Parameters.DryRun = true - } - - return &t, nil -} diff --git a/internal/worker/worker_test.go b/internal/worker/worker_test.go deleted file mode 100644 index 32c89dd6..00000000 --- a/internal/worker/worker_test.go +++ /dev/null @@ -1,59 +0,0 @@ -// nolint -package worker - -import ( - "testing" - - "github.com/google/uuid" - "github.com/metal-toolbox/flasher/internal/model" - "github.com/stretchr/testify/assert" - - rctypes "github.com/metal-toolbox/rivets/condition" -) - -func TestNewTaskFromCondition(t *testing.T) { - tests := []struct { - name string - condition *rctypes.Condition - want *model.Task - wantErr bool - }{ - { - "condition parameters parsed into task parameters", - &rctypes.Condition{ - ID: uuid.MustParse("abc81024-f62a-4288-8730-3fab8ccea777"), - Kind: rctypes.FirmwareInstall, - Version: "1", - Parameters: []byte(`{"asset_id":"ede81024-f62a-4288-8730-3fab8cceab78","firmware_set_id":"9d70c28c-5f65-4088-b014-205c54ad4ac7", "force_install": true, "reset_bmc_before_install": true}`), - }, - func() *model.Task { - t, _ := model.NewTask( - uuid.MustParse("abc81024-f62a-4288-8730-3fab8ccea777"), - &rctypes.FirmwareInstallTaskParameters{ - AssetID: uuid.MustParse("ede81024-f62a-4288-8730-3fab8cceab78"), - FirmwareSetID: uuid.MustParse("9d70c28c-5f65-4088-b014-205c54ad4ac7"), - ForceInstall: true, - ResetBMCBeforeInstall: true, - }, - ) - return &t - }(), - false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := newTaskFromCondition(tt.condition, false, false) - if (err != nil) != tt.wantErr { - t.Errorf("newTaskFromCondition() error = %v, wantErr %v", err, tt.wantErr) - return - } - - assert.Equal(t, tt.want.ID, got.ID) - assert.Equal(t, tt.want.State, got.State) - assert.Equal(t, tt.want.Parameters, got.Parameters) - assert.Contains(t, string(got.Status.MustMarshal()), "initialized task") - }) - } -} From ae2d8050ad590823911df12383b9f27b164f1a06 Mon Sep 17 00:00:00 2001 From: Joel Rebello Date: Fri, 9 Aug 2024 15:17:45 +0200 Subject: [PATCH 11/11] go: updated deps --- go.mod | 107 +++++++++++++--------- go.sum | 283 ++++++++++++++++++++++++++++++++------------------------- 2 files changed, 224 insertions(+), 166 deletions(-) diff --git a/go.mod b/go.mod index f8bbb36e..8fd6bd38 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22 require ( github.com/banzaicloud/logrus-runtime-formatter v0.0.0-20190729070250-5ae5475bae5e github.com/bmc-toolbox/bmclib/v2 v2.2.6 - github.com/bmc-toolbox/common v0.0.0-20240416132216-a56a09c16f4e + github.com/bmc-toolbox/common v0.0.0-20240723142833-87832458b53b github.com/bombsimon/logrusr/v2 v2.0.1 github.com/coreos/go-oidc/v3 v3.11.0 github.com/emicklei/dot v1.6.2 @@ -15,21 +15,24 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.7 github.com/jeremywohl/flatten v1.0.1 github.com/jpillora/backoff v1.0.0 - github.com/metal-toolbox/fleetdb v0.17.1 - github.com/metal-toolbox/rivets v1.0.4 + github.com/metal-toolbox/ctrl v0.2.1 + github.com/metal-toolbox/fleetdb v1.19.3 + github.com/metal-toolbox/ironlib v0.4.1 + github.com/metal-toolbox/rivets v1.2.1-0.20240809101507-f574730a9963 + github.com/mitchellh/copystructure v1.2.0 github.com/mitchellh/mapstructure v1.5.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 - go.opentelemetry.io/otel v1.25.0 - go.opentelemetry.io/otel/trace v1.25.0 - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 + go.opentelemetry.io/otel v1.28.0 + go.opentelemetry.io/otel/trace v1.28.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/net v0.27.0 - golang.org/x/oauth2 v0.21.0 + golang.org/x/oauth2 v0.22.0 ) require ( @@ -37,71 +40,83 @@ require ( github.com/Jeffail/gabs/v2 v2.7.0 // indirect github.com/VictorLowther/simplexml v0.0.0-20180716164440-0bff93621230 // indirect github.com/VictorLowther/soap v0.0.0-20150314151524-8e36fca84b22 // indirect + github.com/beevik/etree v1.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bytedance/sonic v1.11.4 // indirect + github.com/bytedance/sonic v1.12.0 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudwego/base64x v0.1.0 // indirect - github.com/cloudwego/iasm v0.1.1 // indirect - github.com/cockroachdb/cockroach-go/v2 v2.3.7 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cockroachdb/cockroach-go/v2 v2.3.8 // indirect + github.com/coreos/go-oidc v2.2.1+incompatible // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910 // indirect github.com/ericlagergren/decimal v0.0.0-20240411145413-00de7ca16731 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/friendsofgo/errors v0.9.2 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/gin-gonic/gin v1.9.1 // indirect + github.com/gin-gonic/gin v1.10.0 // indirect github.com/go-jose/go-jose/v4 v4.0.2 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.19.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/googleapis/gax-go/v2 v2.12.3 // indirect + github.com/googleapis/gax-go/v2 v2.13.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/gosimple/slug v1.14.0 // indirect github.com/gosimple/unidecode v1.0.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hetiansu5/urlquery v1.2.7 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.14.3 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgproto3/v2 v2.3.3 // indirect - github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgtype v1.14.3 // indirect github.com/jackc/pgx/v4 v4.18.3 // indirect github.com/jacobweinstock/iamt v0.0.0-20230502042727-d7cdbe67d9ef // indirect github.com/jacobweinstock/registrar v0.4.7 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/jmoiron/sqlx v1.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.8 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect + github.com/metal-toolbox/conditionorc v1.1.1-0.20240805163108-b1c018c91b87 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/nats-io/nats.go v1.34.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nats-io/nats.go v1.36.0 // indirect github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect - github.com/pelletier/go-toml/v2 v2.2.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/pquerna/cachecontrol v0.2.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.52.3 // indirect - github.com/prometheus/procfs v0.13.0 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/r3labs/diff/v3 v3.0.1 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect + github.com/slack-go/slack v0.13.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect @@ -109,8 +124,13 @@ require ( github.com/stmcginnis/gofish v0.15.1-0.20231121142100-22a60a77be91 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/tidwall/gjson v1.17.1 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/volatiletech/inflect v0.0.1 // indirect github.com/volatiletech/null v8.0.0+incompatible // indirect github.com/volatiletech/null/v8 v8.1.2 // indirect @@ -120,25 +140,26 @@ require ( github.com/volatiletech/strmangle v0.0.6 // indirect go.hollow.sh/toolbox v0.6.3 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 // indirect - go.opentelemetry.io/otel/metric v1.25.0 // indirect - go.opentelemetry.io/otel/sdk v1.25.0 // indirect - go.opentelemetry.io/proto/otlp v1.2.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - gocloud.dev v0.37.0 // indirect - golang.org/x/arch v0.7.0 // indirect + gocloud.dev v0.38.0 // indirect + golang.org/x/arch v0.8.0 // indirect golang.org/x/crypto v0.25.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/api v0.173.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect + google.golang.org/api v0.189.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect + google.golang.org/grpc v1.65.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9f7d9041..bf172eb2 100644 --- a/go.sum +++ b/go.sum @@ -29,7 +29,11 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= +cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE= +cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= +cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= +cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -41,16 +45,16 @@ cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJW cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM= -cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= +cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= +cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= +cloud.google.com/go/kms v1.15.8 h1:szIeDCowID8th2i8XE4uRev5PMxQFqW+JjwYxL9h6xs= +cloud.google.com/go/kms v1.15.8/go.mod h1:WoUHcDjD9pluCg7pNds131awnH429QGvRM3N/4MyoVs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -99,6 +103,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/banzaicloud/logrus-runtime-formatter v0.0.0-20190729070250-5ae5475bae5e h1:ZOnKnYG1LLgq4W7wZUYj9ntn3RxQ65EZyYqdtFpP2Dw= github.com/banzaicloud/logrus-runtime-formatter v0.0.0-20190729070250-5ae5475bae5e/go.mod h1:hEvEpPmuwKO+0TbrDQKIkmX0gW2s2waZHF8pIhEEmpM= +github.com/beevik/etree v1.4.0 h1:oz1UedHRepuY3p4N5OjE0nK1WLCqtzHf25bxplKOHLs= +github.com/beevik/etree v1.4.0/go.mod h1:cyWiXwGoasx60gHvtnEh5x8+uIjUVnjWqBvEnhnqKDA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -106,14 +112,15 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmc-toolbox/bmclib/v2 v2.2.6 h1:ol2jVa1ERfBFZS5Ye1chORai+nkzt9J1LgTTMxjZ0mw= github.com/bmc-toolbox/bmclib/v2 v2.2.6/go.mod h1:V2XVg0Scpm16+0gE7WnI+5bU/M0c/o/nPZKHKzyVjAo= -github.com/bmc-toolbox/common v0.0.0-20240416132216-a56a09c16f4e h1:MepqMSwXZPngO7KWD0MyaUKuQkZD/yNfpRJhYZszbr4= -github.com/bmc-toolbox/common v0.0.0-20240416132216-a56a09c16f4e/go.mod h1:SY//n1PJjZfbFbmAsB6GvEKbc7UXz3d30s3kWxfJQ/c= +github.com/bmc-toolbox/common v0.0.0-20240723142833-87832458b53b h1:0LHjikaGWlqEMczrCEZ6w1N/ZqcYlx6WRHkhabRUQEk= +github.com/bmc-toolbox/common v0.0.0-20240723142833-87832458b53b/go.mod h1:Cdnkm+edb6C0pVkyCrwh3JTXAe0iUF9diDG/DztPI9I= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.11.4 h1:8+OMLSSDDm2/qJc6ld5K5Sm62NK9VHcUKk0NzBoMAM4= -github.com/bytedance/sonic v1.11.4/go.mod h1:YrWEqYtlBPS6LUA0vpuG79a1trsh4Ae41uWUWUreHhE= +github.com/bytedance/sonic v1.12.0 h1:YGPgxF9xzaCNvd/ZKdQ28yRovhfMFZQjuk6fKBzZ3ls= +github.com/bytedance/sonic v1.12.0/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -121,20 +128,16 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudwego/base64x v0.1.0 h1:Tg5q9tq1khq9Y9UwfoC6zkHK0FypN2GLDvhqFceOL8U= -github.com/cloudwego/base64x v0.1.0/go.mod h1:lM8nFiNbg74QgesNo6EAtv8N9tlRjBWExmHoNDa3PkU= -github.com/cloudwego/iasm v0.0.9/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= -github.com/cloudwego/iasm v0.1.1 h1:Py/XoYVR3xFd2pXmvmOnoS5vHTlYT9SnGK28ES8JOIk= -github.com/cloudwego/iasm v0.1.1/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -146,8 +149,10 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/cockroach-go/v2 v2.3.7 h1:nq5GYDuA2zIR/kdLkVLTg7oHTw0UbGU9RWpC+OZVYYU= -github.com/cockroachdb/cockroach-go/v2 v2.3.7/go.mod h1:1wNJ45eSXW9AnOc3skntW9ZUZz6gxrQK3cOj3rK+BC8= +github.com/cockroachdb/cockroach-go/v2 v2.3.8 h1:53yoUo4+EtrC1NrAEgnnad4AS3ntNvGup1PAXZ7UmpE= +github.com/cockroachdb/cockroach-go/v2 v2.3.8/go.mod h1:9uH5jK4yQ3ZQUT9IXe4I2fHzMIF5+JC/oOdzTRgJYJk= +github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= +github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -164,6 +169,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910 h1:w9T/rS5VP0SPXqYr7BpUeqf6ukp/GEWm6nXhziWzBY4= +github.com/dselans/dmidecode v0.0.0-20180814053009-65c3f9d81910/go.mod h1:yGxJ4za56u74+F00gmg9RJoyXLzvrOrIat4b/Dgw9Lo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= @@ -197,18 +204,18 @@ github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= -github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-contrib/zap v1.1.0 h1:GWzL9+zmK8OJdiycaK2SK1/D3SZIYpieJDD0QCNAU1o= -github.com/gin-contrib/zap v1.1.0/go.mod h1:KzROP9rAL7ofFd1P8lx7Oo2lerwPWNL5vv4f6U/mAk8= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-contrib/zap v1.1.3 h1:9e/U9fYd4/OBfmSEBs5hHZq114uACn7bpuzvCkcJySA= +github.com/gin-contrib/zap v1.1.3/go.mod h1:+BD/6NYZKJyUpqVoJEvgeq9GLz8pINEQvak9LHNOTSE= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -222,8 +229,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zerologr v1.2.3 h1:up5N9vcH9Xck3jJkXzgyOxozT14R47IyDODz8LM1KSs= @@ -234,14 +241,16 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4= -github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= -github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho= +github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= @@ -350,17 +359,20 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= +github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es= github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ= github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o= github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 h1:CWyXh/jylQWp2dtiV33mY4iSSp6yf4lmn+c7/tN+ObI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0/go.mod h1:nCLIt0w3Ept2NwF8ThLmrppXsfT07oC8k0XNDxd8sVU= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -399,6 +411,8 @@ github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hetiansu5/urlquery v1.2.7 h1:jn0h+9pIRqUziSPnRdK/gJK8S5TCnk+HZZx5fRHf8K0= +github.com/hetiansu5/urlquery v1.2.7/go.mod h1:wFpZdTHRdwt7mk0EM/DdZEWtEN4xf8HJoH/BLXm/PG0= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -440,8 +454,8 @@ github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUO github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= @@ -467,8 +481,8 @@ github.com/jacobweinstock/registrar v0.4.7 h1:s4dOExccgD+Pc7rJC+f3Mc3D+NXHcXUaOi github.com/jacobweinstock/registrar v0.4.7/go.mod h1:PWmkdGFG5/ZdCqgMo7pvB3pXABOLHc5l8oQ0sgmBNDU= github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs= github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO0nAlMHgfLQ= -github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= -github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -485,11 +499,11 @@ github.com/kat-co/vala v0.0.0-20170210184112-42e1d8b61f12/go.mod h1:u9MdXq/QageO github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= -github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -539,15 +553,21 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw= github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/metal-toolbox/fleetdb v0.17.1 h1:eyaCg4yGQnbXIjiBMZPsLqmEpxbltlEUNDG+Mn27Fsc= -github.com/metal-toolbox/fleetdb v0.17.1/go.mod h1:TbRbU+ppHIknqiAONR7JDQfzKij30uiPkehgxlA1Hv0= -github.com/metal-toolbox/rivets v1.0.4 h1:BFvlYWsN+5Zb2JS+oJJBDtaQ94M5x2Llf6kmwi+Byjo= -github.com/metal-toolbox/rivets v1.0.4/go.mod h1:EMQJRT1mjIyFRXxvKNaBlz7Z4Sp88rTaGO8W18olN2I= +github.com/metal-toolbox/conditionorc v1.1.1-0.20240805163108-b1c018c91b87 h1:C3Gkj7+bV18HgXJuzeJ6RAttzqsO6sDBF7I20x5JvWM= +github.com/metal-toolbox/conditionorc v1.1.1-0.20240805163108-b1c018c91b87/go.mod h1:0Rh7BPun3VcJzxsBfbZ94lxxxSUNLtugAeZPRWPcD3c= +github.com/metal-toolbox/ctrl v0.2.1 h1:CYOOsmX7SNBFJjxDIWWW76imGXlIfxO8KEKlUffXAak= +github.com/metal-toolbox/ctrl v0.2.1/go.mod h1:VfYYvY7SAvHjN+PTPsaahaazM7gKWq5s37aS3kX4KKo= +github.com/metal-toolbox/fleetdb v1.19.3 h1:Dk7MVi5rS42a4OI46Ye/etg8R5hm1iajaI4U0k1GSec= +github.com/metal-toolbox/fleetdb v1.19.3/go.mod h1:v9agAzF7BhBBjA4rY+H2eZzQaBTEXO4b/Qikn4jmA7A= +github.com/metal-toolbox/ironlib v0.4.1 h1:AL9xYNjViIdR7xEGxu8KHZb92uzSISYEFkU094s+21A= +github.com/metal-toolbox/ironlib v0.4.1/go.mod h1:YNS/N5Q61awwVEXJ20V04AzLrgSsT/Xrh8bHD6Iwi7M= +github.com/metal-toolbox/rivets v1.2.1-0.20240809101507-f574730a9963 h1:VtVyh556iekeYNrxUiD5Q3L5rY4F4O7X3ZULnKWNHvk= +github.com/metal-toolbox/rivets v1.2.1-0.20240809101507-f574730a9963/go.mod h1:i78a1x0w2uNyMlvUgyO6ST552u9wV2Xa4+A73oA4WJY= github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -555,6 +575,7 @@ github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= @@ -564,6 +585,7 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -574,14 +596,16 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt/v2 v2.5.5 h1:ROfXb50elFq5c9+1ztaUbdlrArNFl2+fQWP6B8HGEq4= github.com/nats-io/jwt/v2 v2.5.5/go.mod h1:ZdWS1nZa6WMZfFwwgpEaqBV8EPGVgOTDHN/wTbz0Y5A= -github.com/nats-io/nats-server/v2 v2.10.11 h1:yKUiLVincZISpo3A4YljJQ+HfLltGAgoNNJl99KL8I0= -github.com/nats-io/nats-server/v2 v2.10.11/go.mod h1:dXtOqVWzbMTEj+tUyC/itXjJhW37xh0tUBrTAlqAfx8= -github.com/nats-io/nats.go v1.34.1 h1:syWey5xaNHZgicYBemv0nohUPPmaLteiBEUT6Q5+F/4= -github.com/nats-io/nats.go v1.34.1/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= +github.com/nats-io/nats-server/v2 v2.10.12 h1:G6u+RDrHkw4bkwn7I911O5jqys7jJVRY6MwgndyUsnE= +github.com/nats-io/nats-server/v2 v2.10.12/go.mod h1:H1n6zXtYLFCgXcf/SF8QNTSIFuS8tyZQMN9NguUHdEs= +github.com/nats-io/nats.go v1.36.0 h1:suEUPuWzTSse/XhESwqLxXGuj8vGRuPRoG7MoRN/qyU= +github.com/nats-io/nats.go v1.36.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= @@ -591,8 +615,8 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= -github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -605,13 +629,15 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k= +github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -622,21 +648,23 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA= -github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg= +github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -645,8 +673,8 @@ github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWR github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= -github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= -github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= +github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= @@ -663,6 +691,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slack-go/slack v0.13.1 h1:6UkM3U1OnbhPsYeb1IMkQ6HSNOSikWluwOncJt4Tz/o= +github.com/slack-go/slack v0.13.1/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -681,8 +711,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stmcginnis/gofish v0.15.1-0.20231121142100-22a60a77be91 h1:WmABtU8y6kTgzoVUn3FWCQGAfyodve3uz3xno28BrRs= github.com/stmcginnis/gofish v0.15.1-0.20231121142100-22a60a77be91/go.mod h1:BLDSFTp8pDlf/xDbLZa+F7f7eW0E/CHCboggsu8CznI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -709,11 +739,22 @@ github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU= github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA= github.com/volatiletech/null v8.0.0+incompatible h1:7wP8m5d/gZ6kW/9GnrLtMCRre2dlEnaQ9Km5OXlK4zg= @@ -736,16 +777,14 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/zsais/go-gin-prometheus v0.1.0 h1:bkLv1XCdzqVgQ36ScgRi09MA2UC1t3tAB6nsfErsGO4= -github.com/zsais/go-gin-prometheus v0.1.0/go.mod h1:Slirjzuz8uM8Cw0jmPNqbneoqcUtY2GGjn2bEd4NRLY= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.hollow.sh/toolbox v0.6.3 h1:IJOjiGdiwWwXJ2QfOkJuSucSIqrdXJbUBFst3u6T6z4= go.hollow.sh/toolbox v0.6.3/go.mod h1:nl+5RDDyYY/+wukOUzHHX2mOyWKRjlTOXUcGxny+tns= -go.infratographer.com/x v0.3.9 h1:fsfF/w5zHgiNAHvYmvsWlICNha2X53WNLVSKOkyPnWo= -go.infratographer.com/x v0.3.9/go.mod h1:n/61MZRKFbGlS8xUwAhTyDhqcL2Wk6uPsXADC2n5t1I= +go.infratographer.com/x v0.5.3 h1:Ul50kwszNWPSf9Tds7RKmSQx+QHZbE8Jy9J38cEztP8= +go.infratographer.com/x v0.5.3/go.mod h1:IyZALpwaaviUIN8bGp9cU0hnn1mn0A/6zi70XES4+iE= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -755,27 +794,27 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0 h1:1f31+6grJmV3X4lxcEvUy13i5/kfDw1nJZwhd8mA4tg= -go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.49.0/go.mod h1:1P/02zM3OwkX9uki+Wmxw3a5GVb6KUXRsa7m7bOC9Fg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= -go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= -go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= -go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= -go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= -go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= -go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= -go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= -go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.53.0 h1:ktt8061VV/UU5pdPF6AcEFyuPxMizf/vU6eD1l+13LI= +go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin v0.53.0/go.mod h1:JSRiHPV7E3dbOAP0N6SRPg2nC/cugJnVXRqP018ejtY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0/go.mod h1:27iA5uvhuRNmalO+iEUdVn5ZMj2qy10Mm+XRIpRmyuU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.2.0 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94= -go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -796,11 +835,10 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= -gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= -golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= -golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +gocloud.dev v0.38.0 h1:SpxfaOc/Fp4PeO8ui7wRcCZV0EgXZ+IWcVSLn6ZMSw0= +gocloud.dev v0.38.0/go.mod h1:3XjKvd2E5iVNu/xFImRzjN0d/fkNHe4s0RiKidpEUMQ= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -834,8 +872,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -938,8 +976,8 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1146,8 +1184,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= +golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1187,8 +1225,8 @@ google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRR google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= -google.golang.org/api v0.173.0 h1:fz6B7GWYWLS/HfruiTsRYVKQQApJ6vasTYWAK6+Qo8g= -google.golang.org/api v0.173.0/go.mod h1:ins7pTzjeBPQ3SdC/plzki6d/dQWwAWy8qVZ4Vgkzl8= +google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= +google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1274,12 +1312,12 @@ google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s= -google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7/go.mod h1:/3XmxOjePkvmKrHuBy4zNFw7IzxJXtAgdpXi8Ll990U= -google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= -google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg= +google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= +google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf h1:GillM0Ef0pkZPIB+5iO6SDK+4T9pf6TpaYR6ICD5rVE= +google.golang.org/genproto/googleapis/api v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:OFMYQFHJ4TM3JRlWDZhJbZfra2uqc3WLBZiaaqP4DtU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1310,8 +1348,8 @@ google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5 google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1327,8 +1365,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1403,7 +1441,6 @@ modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=