From 782fd9d299bf8a1be8e0fdbd3f48981f81dbfecc Mon Sep 17 00:00:00 2001 From: Ulrich Schreiner Date: Tue, 7 May 2024 13:05:42 +0200 Subject: [PATCH] support for switch port toggle on/off (#119) --- cmd/internal/core/reconfigure-switch.go | 67 ++++++++++++-- cmd/internal/core/reconfigure-switch_test.go | 1 + cmd/internal/switcher/cumulus/cumulus.go | 5 +- cmd/internal/switcher/sonic/db/configdb.go | 9 +- cmd/internal/switcher/sonic/redis/applier.go | 27 +++--- cmd/internal/switcher/sonic/redis/port.go | 8 +- cmd/internal/switcher/sonic/sonic.go | 1 + .../switcher/templates/template_test.go | 9 +- .../conf_with_downports.yaml | 26 ++++++ .../interfaces_with_downports | 87 +++++++++++++++++++ cmd/internal/switcher/types/conf.go | 55 +++++++++++- cmd/internal/switcher/types/types.go | 5 +- go.mod | 38 ++++---- go.sum | 84 ++++++++++++------ 14 files changed, 345 insertions(+), 77 deletions(-) create mode 100644 cmd/internal/switcher/templates/test_down_interfaces/conf_with_downports.yaml create mode 100644 cmd/internal/switcher/templates/test_down_interfaces/interfaces_with_downports diff --git a/cmd/internal/core/reconfigure-switch.go b/cmd/internal/core/reconfigure-switch.go index 27fd446c..409d139f 100644 --- a/cmd/internal/core/reconfigure-switch.go +++ b/cmd/internal/core/reconfigure-switch.go @@ -2,6 +2,7 @@ package core import ( "fmt" + "net" "os" "slices" "strconv" @@ -23,7 +24,7 @@ func (c *Core) ReconfigureSwitch() { for range t.C { c.log.Info("trigger reconfiguration") start := time.Now() - err := c.reconfigureSwitch(host) + s, err := c.reconfigureSwitch(host) elapsed := time.Since(start) c.log.Info("reconfiguration took", "elapsed", elapsed) @@ -32,6 +33,7 @@ func (c *Core) ReconfigureSwitch() { ns := elapsed.Nanoseconds() nr := &models.V1SwitchNotifyRequest{ SyncDuration: &ns, + PortStates: make(map[string]string), } if err != nil { errStr := err.Error() @@ -42,6 +44,30 @@ func (c *Core) ReconfigureSwitch() { c.log.Info("reconfiguration succeeded") } + // fill the port states of the switch + for _, n := range s.Nics { + if n == nil || n.Name == nil { + // lets log the whole nic because the name could be empty; lets hope there is some useful information + // in the nic + c.log.Error("could not check if link is up", "nic", n) + c.metrics.CountError("switch-reconfiguration") + continue + } + isup, err := isLinkUp(*n.Name) + if err != nil { + c.log.Error("could not check if link is up", "error", err, "nicname", *n.Name) + nr.PortStates[*n.Name] = models.V1SwitchNicActualUNKNOWN + c.metrics.CountError("switch-reconfiguration") + continue + } + if isup { + nr.PortStates[*n.Name] = models.V1SwitchNicActualUP + } else { + nr.PortStates[*n.Name] = models.V1SwitchNicActualDOWN + } + + } + params.Body = nr _, err = c.driver.SwitchOperations().NotifySwitch(params, nil) if err != nil { @@ -51,37 +77,37 @@ func (c *Core) ReconfigureSwitch() { } } -func (c *Core) reconfigureSwitch(switchName string) error { +func (c *Core) reconfigureSwitch(switchName string) (*models.V1SwitchResponse, error) { params := sw.NewFindSwitchParams() params.ID = switchName fsr, err := c.driver.SwitchOperations().FindSwitch(params, nil) if err != nil { - return fmt.Errorf("could not fetch switch from metal-api: %w", err) + return nil, fmt.Errorf("could not fetch switch from metal-api: %w", err) } s := fsr.Payload switchConfig, err := c.buildSwitcherConfig(s) if err != nil { - return fmt.Errorf("could not build switcher config: %w", err) + return nil, fmt.Errorf("could not build switcher config: %w", err) } err = fillEth0Info(switchConfig, c.managementGateway) if err != nil { - return fmt.Errorf("could not gather information about eth0 nic: %w", err) + return nil, fmt.Errorf("could not gather information about eth0 nic: %w", err) } c.log.Info("assembled new config for switch", "config", switchConfig) if !c.enableReconfigureSwitch { c.log.Debug("skip config application because of environment setting") - return nil + return s, nil } err = c.nos.Apply(switchConfig) if err != nil { - return fmt.Errorf("could not apply switch config: %w", err) + return nil, fmt.Errorf("could not apply switch config: %w", err) } - return nil + return s, nil } func (c *Core) buildSwitcherConfig(s *models.V1SwitchResponse) (*types.Conf, error) { @@ -104,10 +130,18 @@ func (c *Core) buildSwitcherConfig(s *models.V1SwitchResponse) (*types.Conf, err Unprovisioned: []string{}, Vrfs: map[string]*types.Vrf{}, Firewalls: map[string]*types.Firewall{}, + DownPorts: map[string]bool{}, } p.BladePorts = c.additionalBridgePorts for _, nic := range s.Nics { port := *nic.Name + + if isPortStatusEqual(models.V1SwitchNicActualDOWN, nic.Actual) { + if has := p.DownPorts[port]; !has { + p.DownPorts[port] = true + } + } + if slices.Contains(p.Underlay, port) { continue } @@ -202,3 +236,20 @@ func fillEth0Info(c *types.Conf, gw string) error { c.Ports.Eth0.Gateway = gw return nil } + +// isLinkUp checks if the interface with the given name is up. +// It returns a boolean indicating if the interface is up, and an error if there was a problem checking the interface. +func isLinkUp(nicname string) (bool, error) { + nic, err := net.InterfaceByName(nicname) + if err != nil { + return false, fmt.Errorf("cannot query interface %q : %w", nicname, err) + } + return nic.Flags&net.FlagUp != 0, nil +} + +func isPortStatusEqual(stat string, other *string) bool { + if other == nil { + return false + } + return strings.EqualFold(stat, *other) +} diff --git a/cmd/internal/core/reconfigure-switch_test.go b/cmd/internal/core/reconfigure-switch_test.go index 93ef682e..8a89030e 100644 --- a/cmd/internal/core/reconfigure-switch_test.go +++ b/cmd/internal/core/reconfigure-switch_test.go @@ -58,6 +58,7 @@ func TestBuildSwitcherConfig(t *testing.T) { MetalCoreCIDR: "10.255.255.2/24", ASN: 420000001, Ports: types.Ports{ + DownPorts: map[string]bool{}, Underlay: []string{"swp31", "swp32"}, Unprovisioned: []string{"swp1"}, Firewalls: map[string]*types.Firewall{ diff --git a/cmd/internal/switcher/cumulus/cumulus.go b/cmd/internal/switcher/cumulus/cumulus.go index 1faaf19f..3a10bb81 100644 --- a/cmd/internal/switcher/cumulus/cumulus.go +++ b/cmd/internal/switcher/cumulus/cumulus.go @@ -29,12 +29,13 @@ func New(log *slog.Logger, frrTplFile, interfacesTplFile string) *Cumulus { } func (c *Cumulus) Apply(cfg *types.Conf) error { - err := c.interfacesApplier.Apply(cfg) + withoutDownPorts := cfg.NewWithoutDownPorts() + err := c.interfacesApplier.Apply(withoutDownPorts) if err != nil { return err } - return c.frrApplier.Apply(cfg) + return c.frrApplier.Apply(withoutDownPorts) } func (c *Cumulus) IsInitialized() (initialized bool, err error) { diff --git a/cmd/internal/switcher/sonic/db/configdb.go b/cmd/internal/switcher/sonic/db/configdb.go index d46d008f..f74107d4 100644 --- a/cmd/internal/switcher/sonic/db/configdb.go +++ b/cmd/internal/switcher/sonic/db/configdb.go @@ -16,6 +16,7 @@ const ( portTable = "PORT" adminStatus = "admin_status" adminStatusUp = "up" + adminStatusDown = "down" mtu = "mtu" fec = "fec" fecRS = "rs" @@ -204,8 +205,12 @@ func (d *ConfigDB) SetPortMtu(ctx context.Context, interfaceName string, val str return d.c.HSet(ctx, key, Val{mtu: val}) } -func (d *ConfigDB) SetAdminStatusUp(ctx context.Context, interfaceName string) error { +func (d *ConfigDB) SetAdminStatusUp(ctx context.Context, interfaceName string, up bool) error { key := Key{portTable, interfaceName} - return d.c.HSet(ctx, key, Val{adminStatus: adminStatusUp}) + status := adminStatusUp + if !up { + status = adminStatusDown + } + return d.c.HSet(ctx, key, Val{adminStatus: status}) } diff --git a/cmd/internal/switcher/sonic/redis/applier.go b/cmd/internal/switcher/sonic/redis/applier.go index 685f69b3..1c691524 100644 --- a/cmd/internal/switcher/sonic/redis/applier.go +++ b/cmd/internal/switcher/sonic/redis/applier.go @@ -49,19 +49,19 @@ func (a *Applier) Apply(cfg *types.Conf) error { } for _, interfaceName := range cfg.Ports.Underlay { - if err := a.configureUnderlayPort(interfaceName); err != nil { + if err := a.configureUnderlayPort(interfaceName, !cfg.Ports.DownPorts[interfaceName]); err != nil { errs = append(errs, err) } } for _, interfaceName := range cfg.Ports.Unprovisioned { - if err := a.configureUnprovisionedPort(interfaceName); err != nil { + if err := a.configureUnprovisionedPort(interfaceName, !cfg.Ports.DownPorts[interfaceName]); err != nil { errs = append(errs, err) } } for interfaceName := range cfg.Ports.Firewalls { - if err := a.configureFirewallPort(interfaceName); err != nil { + if err := a.configureFirewallPort(interfaceName, !cfg.Ports.DownPorts[interfaceName]); err != nil { errs = append(errs, err) } } @@ -71,7 +71,7 @@ func (a *Applier) Apply(cfg *types.Conf) error { errs = append(errs, err) } for _, interfaceName := range vrf.Neighbors { - if err := a.configureVrfNeighbor(interfaceName, vrfName); err != nil { + if err := a.configureVrfNeighbor(interfaceName, vrfName, !cfg.Ports.DownPorts[interfaceName]); err != nil { errs = append(errs, err) } } @@ -115,7 +115,7 @@ func (a *Applier) refreshOidMaps() error { return nil } -func (a *Applier) configureUnprovisionedPort(interfaceName string) error { +func (a *Applier) configureUnprovisionedPort(interfaceName string, isUp bool) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -124,14 +124,15 @@ func (a *Applier) configureUnprovisionedPort(interfaceName string) error { return err } - if err := a.ensurePortConfiguration(ctx, interfaceName, "9000", true); err != nil { + // unprovisioned ports should be up + if err := a.ensurePortConfiguration(ctx, interfaceName, "9000", true, isUp); err != nil { return fmt.Errorf("failed to update Port info for interface %s: %w", interfaceName, err) } return a.ensureInterfaceIsVlanMember(ctx, interfaceName, "Vlan4000") } -func (a *Applier) configureFirewallPort(interfaceName string) error { +func (a *Applier) configureFirewallPort(interfaceName string, isUp bool) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -140,24 +141,26 @@ func (a *Applier) configureFirewallPort(interfaceName string) error { return err } - if err := a.ensurePortConfiguration(ctx, interfaceName, "9216", true); err != nil { + // a firewall port should always be up + if err := a.ensurePortConfiguration(ctx, interfaceName, "9216", true, isUp); err != nil { return fmt.Errorf("failed to update Port info for interface %s: %w", interfaceName, err) } return a.ensureLinkLocalOnlyIsEnabled(ctx, interfaceName) } -func (a *Applier) configureUnderlayPort(interfaceName string) error { +func (a *Applier) configureUnderlayPort(interfaceName string, isUp bool) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - if err := a.ensurePortConfiguration(ctx, interfaceName, "9216", false); err != nil { + // underlay ports should be up + if err := a.ensurePortConfiguration(ctx, interfaceName, "9216", false, isUp); err != nil { return fmt.Errorf("failed to update Port info for interface %s: %w", interfaceName, err) } return a.ensureLinkLocalOnlyIsEnabled(ctx, interfaceName) } -func (a *Applier) configureVrfNeighbor(interfaceName, vrfName string) error { +func (a *Applier) configureVrfNeighbor(interfaceName, vrfName string, isUp bool) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -171,7 +174,7 @@ func (a *Applier) configureVrfNeighbor(interfaceName, vrfName string) error { return err } - if err := a.ensurePortConfiguration(ctx, interfaceName, "9000", true); err != nil { + if err := a.ensurePortConfiguration(ctx, interfaceName, "9000", true, isUp); err != nil { return fmt.Errorf("failed to update Port info for interface %s: %w", interfaceName, err) } diff --git a/cmd/internal/switcher/sonic/redis/port.go b/cmd/internal/switcher/sonic/redis/port.go index 03b6b796..894d75aa 100644 --- a/cmd/internal/switcher/sonic/redis/port.go +++ b/cmd/internal/switcher/sonic/redis/port.go @@ -7,7 +7,7 @@ import ( "github.com/avast/retry-go/v4" ) -func (a *Applier) ensurePortConfiguration(ctx context.Context, portName, mtu string, isFecRs bool) error { +func (a *Applier) ensurePortConfiguration(ctx context.Context, portName, mtu string, isFecRs, isUp bool) error { p, err := a.db.Config.GetPort(ctx, portName) if err != nil { return fmt.Errorf("could not retrieve port info for %s from redis: %w", portName, err) @@ -29,9 +29,9 @@ func (a *Applier) ensurePortConfiguration(ctx context.Context, portName, mtu str } } - if !p.AdminStatus { - a.log.Debug("set admin status to", "port", portName, "admin_status", "up") - return a.db.Config.SetAdminStatusUp(ctx, portName) + if p.AdminStatus != isUp { + a.log.Debug("set admin status to", "port", portName, "admin_status_up", isUp) + return a.db.Config.SetAdminStatusUp(ctx, portName, isUp) } return nil diff --git a/cmd/internal/switcher/sonic/sonic.go b/cmd/internal/switcher/sonic/sonic.go index 6b2bb439..c2c4c532 100644 --- a/cmd/internal/switcher/sonic/sonic.go +++ b/cmd/internal/switcher/sonic/sonic.go @@ -154,6 +154,7 @@ func getPortsConfig(filepath string) (map[string]PortInfo, error) { config := struct { Ports map[string]PortInfo `json:"PORT"` }{} + //nolint:musttag err = json.Unmarshal(byteValue, &config) return config.Ports, err diff --git a/cmd/internal/switcher/templates/template_test.go b/cmd/internal/switcher/templates/template_test.go index c16ed84e..4bf6b162 100644 --- a/cmd/internal/switcher/templates/template_test.go +++ b/cmd/internal/switcher/templates/template_test.go @@ -26,6 +26,13 @@ func TestInterfacesTemplate(t *testing.T) { } } +func TestInterfacesTemplateWithDownPorts(t *testing.T) { + c := readConf(t, path.Join("test_down_interfaces", "conf_with_downports.yaml")) + c = *c.NewWithoutDownPorts() + tpl := InterfacesTemplate("") + verifyTemplate(t, tpl, &c, path.Join("test_down_interfaces", "interfaces_with_downports")) +} + func TestCumulusFrrTemplate(t *testing.T) { tests := listTestCases() for i := range tests { @@ -76,7 +83,7 @@ func TestCustomSonicFrrTemplate(t *testing.T) { func verifyTemplate(t *testing.T, tpl *template.Template, c *types.Conf, expectedFilename string) { actual := renderToString(t, tpl, c) expected := readExpected(t, expectedFilename) - require.Equal(t, expected, actual, "Wanted: %s, Got: %s", expected, actual) + require.Equal(t, expected, actual, "Wanted: %s\nGot: %s", expected, actual) } func renderToString(t *testing.T, tpl *template.Template, c *types.Conf) string { diff --git a/cmd/internal/switcher/templates/test_down_interfaces/conf_with_downports.yaml b/cmd/internal/switcher/templates/test_down_interfaces/conf_with_downports.yaml new file mode 100644 index 00000000..54de56d6 --- /dev/null +++ b/cmd/internal/switcher/templates/test_down_interfaces/conf_with_downports.yaml @@ -0,0 +1,26 @@ +--- +name: leaf01 +loglevel: warnings +loopback: 10.0.0.10 +asn: 4200000010 +metalcorecidr: 10.255.255.2/24 +ports: + vrfs: + vrf1: + vni: 1 + vlanid: 2 + neighbors: + - swp3 + cidrs: + - 10.255.255.1/28 + eth0: + addresscidr: 192.168.0.11 + gateway: 192.168.0.254 + underlay: + - swp31 + - swp32 + unprovisioned: + - swp1 + - swp2 + downports: + swp3: True diff --git a/cmd/internal/switcher/templates/test_down_interfaces/interfaces_with_downports b/cmd/internal/switcher/templates/test_down_interfaces/interfaces_with_downports new file mode 100644 index 00000000..67c75bfb --- /dev/null +++ b/cmd/internal/switcher/templates/test_down_interfaces/interfaces_with_downports @@ -0,0 +1,87 @@ +# This file describes the network interfaces available on your system +# and how to activate them. For more information, see interfaces(5). + +source /etc/network/interfaces.d/*.intf + +# The loopback network interface +auto lo +iface lo inet loopback + address 10.0.0.10/32 + +# The primary network interface +auto eth0 +iface eth0 + address 192.168.0.11 + gateway 192.168.0.254 + vrf mgmt + +auto mgmt +iface mgmt + address 127.0.0.1/8 + vrf-table auto + +auto swp31 +iface swp31 + mtu 9216 + +auto swp32 +iface swp32 + mtu 9216 + +auto bridge +iface bridge + bridge-ports vni104000 swp1 swp2 vni1 + bridge-vids 4000 2 + bridge-vlan-aware yes + +# Tenants + +auto vrf1 +iface vrf1 + vrf-table auto + +auto vlan2 +iface vlan2 + mtu 9000 + vlan-id 2 + vlan-raw-device bridge + vrf vrf1 + +auto vni1 +iface vni1 + mtu 9000 + bridge-access 2 + bridge-arp-nd-suppress on + bridge-learning off + mstpctl-bpduguard yes + mstpctl-portbpdufilter yes + vxlan-id 1 + vxlan-local-tunnelip 10.0.0.10 + +# PXE-Config +auto vlan4000 +iface vlan4000 + mtu 9000 + address 10.255.255.2/24 + vlan-id 4000 + vlan-raw-device bridge + +auto vni104000 +iface vni104000 + mtu 9000 + bridge-access 4000 + bridge-learning off + mstpctl-bpduguard yes + mstpctl-portbpdufilter yes + vxlan-id 104000 + vxlan-local-tunnelip 10.0.0.10 + +auto swp1 +iface swp1 + mtu 9000 + bridge-access 4000 + +auto swp2 +iface swp2 + mtu 9000 + bridge-access 4000 diff --git a/cmd/internal/switcher/types/conf.go b/cmd/internal/switcher/types/conf.go index 5ceda8db..58ba991d 100644 --- a/cmd/internal/switcher/types/conf.go +++ b/cmd/internal/switcher/types/conf.go @@ -50,5 +50,58 @@ func (c *Conf) CapitalizeVrfName() { } c.Ports.Vrfs = capitalizedVRFs - return +} + +func (c *Conf) NewWithoutDownPorts() *Conf { + if len(c.Ports.DownPorts) < 1 { + return c + } + newConf := *c + newConf.Ports.Vrfs = make(map[string]*Vrf) + + // create a copy of the VRFs and filter out the interfaces which should be down + for vrf, vrfConf := range c.Ports.Vrfs { + newVrfConf := *vrfConf + newVrfConf.Neighbors = []string{} + for _, port := range vrfConf.Neighbors { + if _, isdown := c.Ports.DownPorts[port]; !isdown { + newVrfConf.Neighbors = append(newVrfConf.Neighbors, port) + } + } + newConf.Ports.Vrfs[vrf] = &newVrfConf + } + newConf.Ports.Underlay = []string{} + newConf.Ports.Unprovisioned = []string{} + newConf.Ports.BladePorts = []string{} + newConf.Ports.Firewalls = make(map[string]*Firewall) + + // create a copy of the firewalls and filter out the interfaces which should be down + for port, fwConf := range c.Ports.Firewalls { + if _, isdown := c.Ports.DownPorts[port]; !isdown { + newConf.Ports.Firewalls[port] = fwConf + } + } + + // create a copy of the underlay ports without the downports + for _, port := range c.Ports.Underlay { + if _, isdown := c.Ports.DownPorts[port]; !isdown { + newConf.Ports.Underlay = append(newConf.Ports.Underlay, port) + } + } + + // create a copy of the unprovisioned ports without the downports + for _, port := range c.Ports.Unprovisioned { + if _, isdown := c.Ports.DownPorts[port]; !isdown { + newConf.Ports.Unprovisioned = append(newConf.Ports.Unprovisioned, port) + } + } + + // create a copy of the blade ports without the downports + for _, port := range c.Ports.BladePorts { + if _, isdown := c.Ports.DownPorts[port]; !isdown { + newConf.Ports.BladePorts = append(newConf.Ports.BladePorts, port) + } + } + + return &newConf } diff --git a/cmd/internal/switcher/types/types.go b/cmd/internal/switcher/types/types.go index f3329358..21c4fd27 100644 --- a/cmd/internal/switcher/types/types.go +++ b/cmd/internal/switcher/types/types.go @@ -1,6 +1,8 @@ package types -import "fmt" +import ( + "fmt" +) // Conf holds the switch configuration type Conf struct { @@ -18,6 +20,7 @@ type Ports struct { Underlay []string Unprovisioned []string BladePorts []string + DownPorts map[string]bool Vrfs map[string]*Vrf Firewalls map[string]*Firewall } diff --git a/go.mod b/go.mod index 05b8f05e..bb7caa3c 100644 --- a/go.mod +++ b/go.mod @@ -5,23 +5,19 @@ go 1.22 require ( github.com/avast/retry-go/v4 v4.5.1 github.com/coreos/go-systemd/v22 v22.5.0 - github.com/go-openapi/errors v0.22.0 - github.com/go-openapi/strfmt v0.23.0 - github.com/go-openapi/swag v0.23.0 - github.com/go-openapi/validate v0.24.0 - github.com/go-redis/redismock/v9 v9.2.0 + github.com/go-redis/redismock/v9 v9.0.3 github.com/google/go-cmp v0.6.0 github.com/kelseyhightower/envconfig v1.4.0 - github.com/metal-stack/go-lldpd v0.4.7 - github.com/metal-stack/metal-api v0.28.4 - github.com/metal-stack/metal-go v0.28.4 + github.com/metal-stack/go-lldpd v0.4.5 + github.com/metal-stack/metal-api v0.23.2 + github.com/metal-stack/metal-go v0.29.0 github.com/metal-stack/v v1.0.3 github.com/prometheus/client_golang v1.19.0 github.com/redis/go-redis/v9 v9.5.1 github.com/stretchr/testify v1.9.0 github.com/vishvananda/netlink v1.2.1-beta.2 golang.org/x/text v0.14.0 - google.golang.org/grpc v1.63.2 + google.golang.org/grpc v1.61.1 google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -38,14 +34,19 @@ require ( github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.23.0 // indirect + github.com/go-openapi/errors v0.22.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/loads v0.22.0 // indirect github.com/go-openapi/runtime v0.28.0 // indirect github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/strfmt v0.23.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-openapi/validate v0.24.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.1 // indirect @@ -59,25 +60,26 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mdlayher/ethernet v0.0.0-20220221185849-529eae5b6118 // indirect github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5 // indirect - github.com/metal-stack/metal-lib v0.16.2 // indirect + github.com/metal-stack/metal-lib v0.15.1 // indirect github.com/metal-stack/security v0.8.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.50.0 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/vishvananda/netns v0.0.4 // indirect go.mongodb.org/mongo-driver v1.14.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/metric v1.24.0 // indirect go.opentelemetry.io/otel/trace v1.24.0 // indirect - golang.org/x/crypto v0.22.0 // indirect - golang.org/x/net v0.24.0 // indirect - golang.org/x/oauth2 v0.19.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.19.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + golang.org/x/sys v0.18.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect ) diff --git a/go.sum b/go.sum index eff93cec..266450fb 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,8 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= -github.com/go-redis/redismock/v9 v9.2.0 h1:ZrMYQeKPECZPjOj5u9eyOjg8Nnb0BS9lkVIZ6IpsKLw= -github.com/go-redis/redismock/v9 v9.2.0/go.mod h1:18KHfGDK4Y6c2R0H38EUGWAdc7ZQS9gfYxc94k7rWT0= +github.com/go-redis/redismock/v9 v9.0.3 h1:mtHQi2l51lCmXIbTRTqb1EiHYe9tL5Yk5oorlSJJqR0= +github.com/go-redis/redismock/v9 v9.0.3/go.mod h1:F6tJRfnU8R/NZ0E+Gjvoluk14MqMC5ueSZX6vVQypc0= 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/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -61,6 +61,11 @@ github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -100,14 +105,14 @@ github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5 h1:i4JJtLb5iDVsncU7s github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5/go.mod h1:IZAsRpRUv/4B6NhGzofHK/+I+N31NTUz/hrEm4ssUwA= github.com/mdlayher/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU= github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E= -github.com/metal-stack/go-lldpd v0.4.7 h1:Y3FALidODscleqJCS6sGgBunxyLX1scNT7cMoKn6b1Q= -github.com/metal-stack/go-lldpd v0.4.7/go.mod h1:CYKuwnjSZ6zYmAMKLy45/QAQJKj5xZnkfv2zyi+B33o= -github.com/metal-stack/metal-api v0.28.4 h1:/0Tn5+H4//dfHo/ZjjDafGs3q38Fg93GolZVBOWmRY0= -github.com/metal-stack/metal-api v0.28.4/go.mod h1:7UgO0RRW36nARCs/8dfuAvq9B4r7Iq3LIDf4lo2XDaM= -github.com/metal-stack/metal-go v0.28.4 h1:cTI2jZqn59FNw0RkPAD7TYeK5YKJjj94YFJiuRl8eDo= -github.com/metal-stack/metal-go v0.28.4/go.mod h1:gYLZX3umsoZLWZ5d4MJdVbnR8eFXUTlLTK7tyx638As= -github.com/metal-stack/metal-lib v0.16.2 h1:RJls/Spai4h5xr3BEmQt9UdWNN4RB9+SOINoZcjYaA8= -github.com/metal-stack/metal-lib v0.16.2/go.mod h1:nyNGI4DZFOcWbSoq2Y6V3SHpFxuXBIqYBZHTb6cy//s= +github.com/metal-stack/go-lldpd v0.4.5 h1:VeWsPN6wSWMslnuFtF1ebvS4fCk6VPZmqracsoXqic8= +github.com/metal-stack/go-lldpd v0.4.5/go.mod h1:aCVI7lCka0uRo6dkrh2ET97WBpN7M5yZqK8NX0vGpho= +github.com/metal-stack/metal-api v0.23.2 h1:5l5m4jszrLURotjgmGoJywMaHZ4oDIyaK8ks5p45+/w= +github.com/metal-stack/metal-api v0.23.2/go.mod h1:1404/Y2/x/98I6DTGKYS34J8awFmmU/zPdCRuezLEdE= +github.com/metal-stack/metal-go v0.29.0 h1:EuJ7u/L+3lsby+kzrE0aF6gBIBDKPENqvOO2idGhMqw= +github.com/metal-stack/metal-go v0.29.0/go.mod h1:gYLZX3umsoZLWZ5d4MJdVbnR8eFXUTlLTK7tyx638As= +github.com/metal-stack/metal-lib v0.15.1 h1:QCmtZ6ci6pHsf3RQnSDbbvYshpyRaxCSeXghVvbDFuA= +github.com/metal-stack/metal-lib v0.15.1/go.mod h1:x1nyPRi+b/WeK7N41cm4R8w4pScnhOYv8hos2UM4lXY= github.com/metal-stack/security v0.8.0 h1:tVaSDB9m5clwYrnLyaXfPy7mQlJTnmeoHscG+RUy/xo= github.com/metal-stack/security v0.8.0/go.mod h1:7GAcQb+pOgflW30ohJygxpqc3i0dQ2ahGJK1CU5tqa0= github.com/metal-stack/v v1.0.3 h1:Sh2oBlnxrCUD+mVpzfC8HiqL045YWkxs0gpTvkjppqs= @@ -129,12 +134,12 @@ 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/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_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.50.0 h1:YSZE6aa9+luNa2da6/Tik0q0A5AbR+U003TItK57CPQ= -github.com/prometheus/common v0.50.0/go.mod h1:wHFBCEVWVmHMUpg7pYcOm2QUR/ocQdYSJVQJKnHc3xQ= -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/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8= github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= @@ -152,6 +157,7 @@ github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhg github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= @@ -164,41 +170,63 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -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/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= +google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=