From 1c87017378224728c5d1890b40ef313aaa73c626 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Fri, 29 Nov 2024 20:08:04 +0100 Subject: [PATCH 01/14] feat: add process scheduling options This commit adds runner options for priority, IO priority, scheduling policy. It also cleans up previously developed code for capabilities. This is useful to launch background tasks such as xfs_scrub to not reduce system performance. We set nice 10 for dashboard so that it gives priority to more important system services. Signed-off-by: Dmitry Sharshakov (cherry picked from commit 9081506d6cde26d60a29f08a090e28da501e4bd1) --- .../pkg/system/runner/process/process.go | 95 ++++++++--- .../pkg/system/runner/process/process_test.go | 150 ++++++++++++++++++ .../app/machined/pkg/system/runner/runner.go | 64 ++++++++ .../machined/pkg/system/services/dashboard.go | 1 + pkg/machinery/constants/constants.go | 4 + 5 files changed, 295 insertions(+), 19 deletions(-) diff --git a/internal/app/machined/pkg/system/runner/process/process.go b/internal/app/machined/pkg/system/runner/process/process.go index 4de88e216b..8849bdc6a8 100644 --- a/internal/app/machined/pkg/system/runner/process/process.go +++ b/internal/app/machined/pkg/system/runner/process/process.go @@ -13,9 +13,9 @@ import ( "os" "path" "slices" - "strings" "syscall" "time" + "unsafe" "github.com/containerd/cgroups/v3" "github.com/containerd/cgroups/v3/cgroup1" @@ -104,27 +104,22 @@ type commandWrapper struct { } func dropCaps(droppedCapabilities []string, launcher *cap.Launcher) error { - droppedCaps := strings.Join(droppedCapabilities, ",") - - if droppedCaps != "" { - caps := strings.Split(droppedCaps, ",") - dropCaps := xslices.Map(caps, func(c string) cap.Value { - capability, capErr := cap.FromName(c) - if capErr != nil { - panic(fmt.Errorf("failed to parse capability: %s", capErr)) - } - - return capability - }) - - iab := cap.IABGetProc() - if err := iab.SetVector(cap.Bound, true, dropCaps...); err != nil { - return fmt.Errorf("failed to set capabilities: %w", err) + dropCaps := xslices.Map(droppedCapabilities, func(c string) cap.Value { + capability, capErr := cap.FromName(c) + if capErr != nil { + panic(fmt.Errorf("failed to parse capability: %s", capErr)) } - launcher.SetIAB(iab) + return capability + }) + + iab := cap.IABGetProc() + if err := iab.SetVector(cap.Bound, true, dropCaps...); err != nil { + return fmt.Errorf("failed to set capabilities: %w", err) } + launcher.SetIAB(iab) + return nil } @@ -309,7 +304,7 @@ func (p *processRunner) build() (commandWrapper, error) { // Apply cgroup and OOM score after the process is launched. // -//nolint:gocyclo +//nolint:gocyclo,cyclop func applyProperties(p *processRunner, pid int) error { if p.opts.CgroupPath != "" { path := cgroup.Path(p.opts.CgroupPath) @@ -353,6 +348,68 @@ func applyProperties(p *processRunner, pid int) error { } } + if p.opts.Priority != 0 { + if err := syscall.Setpriority(syscall.PRIO_PROCESS, pid, p.opts.Priority); err != nil { + return fmt.Errorf("failed to set priority of process %s to %d: %w", p, p.opts.Priority, err) + } + } + + if ioPriority, ioPrioritySet := p.opts.IOPriority.Get(); ioPrioritySet { + err := setIOPriority(p, pid, ioPriority) + if err != nil { + return err + } + } + + if schedulingPolicy, schedulingPolicySet := p.opts.SchedulingPolicy.Get(); schedulingPolicySet { + err := setSchedulingPolicy(p, pid, schedulingPolicy) + if err != nil { + return err + } + } + + return nil +} + +func setIOPriority(p *processRunner, pid int, ioPriority runner.IOPriorityParam) error { + if ioPriority.Class > runner.IoprioClassIdle { + return fmt.Errorf("failed to set IO priority of process %s: class %d is not valid", p, ioPriority.Class) + } + + if ioPriority.Priority > 7 { + return fmt.Errorf("failed to set IO priority of process %s: priority %d is not valid", p, ioPriority.Priority) + } + + classPos := 13 // IOPRIO_CLASS_SHIFT + priorityValue := ioPriority.Class< runner.SchedulingPolicyDeadline { + return fmt.Errorf("failed to set scheduling policy of process %s: policy %d is not valid", p, schedulingPolicy) + } + + options := struct{ Priority int32 }{ + Priority: int32(0), + } + + if _, _, syscallError := syscall.Syscall( + syscall.SYS_SCHED_SETSCHEDULER, + uintptr(pid), + uintptr(schedulingPolicy), + uintptr(unsafe.Pointer(&options)), + ); syscallError != 0 { + return fmt.Errorf("failed to set scheduling policy of process %s to %d: syscall failed with %s", p, schedulingPolicy, syscallError.Error()) + } + return nil } diff --git a/internal/app/machined/pkg/system/runner/process/process_test.go b/internal/app/machined/pkg/system/runner/process/process_test.go index 5deed27bd9..1714efa0f4 100644 --- a/internal/app/machined/pkg/system/runner/process/process_test.go +++ b/internal/app/machined/pkg/system/runner/process/process_test.go @@ -10,7 +10,10 @@ import ( "log" "os" "path/filepath" + "strconv" + "strings" "sync" + "syscall" "testing" "time" @@ -219,6 +222,153 @@ func (suite *ProcessSuite) TestStopSigKill() { <-done } +func (suite *ProcessSuite) TestPriority() { + pidFile := filepath.Join(suite.tmpDir, "talos-test-pid-prio") + //nolint:errcheck + _ = os.Remove(pidFile) + + currentPriority, err := syscall.Getpriority(syscall.PRIO_PROCESS, os.Getpid()) + suite.Assert().NoError(err) + + if currentPriority <= 3 { + suite.T().Skipf("skipping test, we already have low priority %d", currentPriority) + } + + r := process.NewRunner(false, &runner.Args{ + ID: "nokill", + ProcessArgs: []string{"/bin/sh", "-c", "echo $BASHPID >> " + pidFile + "; trap -- '' SIGTERM; while :; do :; done"}, + }, + runner.WithLoggingManager(suite.loggingManager), + runner.WithGracefulShutdownTimeout(10*time.Millisecond), + runner.WithPriority(17), + ) + suite.Assert().NoError(r.Open()) + + defer func() { suite.Assert().NoError(r.Close()) }() + + done := make(chan error, 1) + + go func() { + done <- r.Run(MockEventSink) + }() + + time.Sleep(10 * time.Millisecond) + + pidString, err := os.ReadFile(pidFile) + suite.Assert().NoError(err) + + pid, err := strconv.ParseUint(strings.Trim(string(pidString), "\r\n"), 10, 32) + suite.Assert().NoError(err) + + currentPriority, err = syscall.Getpriority(syscall.PRIO_PROCESS, int(pid)) + suite.Assert().NoError(err) + // 40..1 corresponds to -20..19 since system call interface must reserve -1 for error + suite.Assert().Equalf(3, currentPriority, "process priority should be 3 (nice 17), got %d", currentPriority) + + time.Sleep(1000 * time.Millisecond) + + suite.Assert().NoError(r.Stop()) + <-done +} + +func (suite *ProcessSuite) TestIOPriority() { + pidFile := filepath.Join(suite.tmpDir, "talos-test-pid-ionice") + //nolint:errcheck + _ = os.Remove(pidFile) + + //nolint:errcheck + ioprio, _, _ := syscall.Syscall(syscall.SYS_IOPRIO_GET, uintptr(1), uintptr(os.Getpid()), 0) + suite.Assert().NotEqual(-1, int(ioprio)) + + if ioprio>>13 == runner.IoprioClassIdle { + suite.T().Skipf("skipping test, we already have idle IO priority %d", ioprio) + } + + r := process.NewRunner(false, &runner.Args{ + ID: "nokill", + ProcessArgs: []string{"/bin/sh", "-c", "echo $BASHPID >> " + pidFile + "; trap -- '' SIGTERM; while :; do :; done"}, + }, + runner.WithLoggingManager(suite.loggingManager), + runner.WithGracefulShutdownTimeout(10*time.Millisecond), + runner.WithIOPriority(runner.IoprioClassIdle, 6), + ) + suite.Assert().NoError(r.Open()) + + defer func() { suite.Assert().NoError(r.Close()) }() + + done := make(chan error, 1) + + go func() { + done <- r.Run(MockEventSink) + }() + + time.Sleep(10 * time.Millisecond) + + pidString, err := os.ReadFile(pidFile) + suite.Assert().NoError(err) + + pid, err := strconv.ParseUint(strings.Trim(string(pidString), "\r\n"), 10, 32) + suite.Assert().NoError(err) + + //nolint:errcheck + ioprio, _, _ = syscall.Syscall(syscall.SYS_IOPRIO_GET, uintptr(1), uintptr(pid), 0) + suite.Assert().NotEqual(-1, int(ioprio)) + suite.Assert().Equal(runner.IoprioClassIdle<<13+6, int(ioprio)) + + time.Sleep(10 * time.Millisecond) + + suite.Assert().NoError(r.Stop()) + <-done +} + +func (suite *ProcessSuite) TestSchedulingPolicy() { + pidFile := filepath.Join(suite.tmpDir, "talos-test-pid-sched") + //nolint:errcheck + _ = os.Remove(pidFile) + + pol, _, errno := syscall.Syscall(syscall.SYS_SCHED_GETSCHEDULER, uintptr(os.Getpid()), 0, 0) + suite.Assert().Equal(0, int(errno)) + + if pol == runner.SchedulingPolicyIdle { + suite.T().Skipf("skipping test, we already have idle scheduling policy") + } + + r := process.NewRunner(false, &runner.Args{ + ID: "nokill", + ProcessArgs: []string{"/bin/sh", "-c", "echo $BASHPID >> " + pidFile + "; trap -- '' SIGTERM; while :; do :; done"}, + }, + runner.WithLoggingManager(suite.loggingManager), + runner.WithGracefulShutdownTimeout(10*time.Millisecond), + runner.WithSchedulingPolicy(runner.SchedulingPolicyIdle), + ) + suite.Assert().NoError(r.Open()) + + defer func() { suite.Assert().NoError(r.Close()) }() + + done := make(chan error, 1) + + go func() { + done <- r.Run(MockEventSink) + }() + + time.Sleep(10 * time.Millisecond) + + pidString, err := os.ReadFile(pidFile) + suite.Assert().NoError(err) + + pid, err := strconv.ParseUint(strings.Trim(string(pidString), "\r\n"), 10, 32) + suite.Assert().NoError(err) + + pol, _, errno = syscall.Syscall(syscall.SYS_SCHED_GETSCHEDULER, uintptr(pid), 0, 0) + suite.Assert().Equal(0, int(errno)) + suite.Assert().Equal(runner.SchedulingPolicyIdle, int(pol)) + + time.Sleep(10 * time.Millisecond) + + suite.Assert().NoError(r.Stop()) + <-done +} + func TestProcessSuite(t *testing.T) { for _, runReaper := range []bool{true, false} { func(runReaper bool) { diff --git a/internal/app/machined/pkg/system/runner/runner.go b/internal/app/machined/pkg/system/runner/runner.go index 9efeed1b0a..05fcc17bb1 100644 --- a/internal/app/machined/pkg/system/runner/runner.go +++ b/internal/app/machined/pkg/system/runner/runner.go @@ -40,6 +40,12 @@ type Args struct { ProcessArgs []string } +// IOPriorityParam represents the combination of IO scheduling class and priority. +type IOPriorityParam struct { + Class uint + Priority uint +} + // Options is the functional options struct. type Options struct { // LoggingManager provides service log handling. @@ -82,6 +88,12 @@ type Options struct { Ctty optional.Optional[int] // UID is the user id of the process. UID uint32 + // Priority is the niceness value of the process. + Priority int + // IOPriority is the IO priority value and class of the process. + IOPriority optional.Optional[IOPriorityParam] + // SchedulingPolicy is the scheduling policy of the process. + SchedulingPolicy optional.Optional[uint] } // Option is the functional option func. @@ -249,3 +261,55 @@ func WithMemoryReservation(limit uint64) oci.SpecOpts { return nil } } + +// WithPriority sets the priority of the process. +func WithPriority(priority int) Option { + return func(args *Options) { + args.Priority = priority + } +} + +const ( + // IoprioClassNone represents IOPRIO_CLASS_NONE. + IoprioClassNone = iota + // IoprioClassRt represents IOPRIO_CLASS_RT. + IoprioClassRt + // IoprioClassBe represents IOPRIO_CLASS_BE. + IoprioClassBe + // IoprioClassIdle represents IOPRIO_CLASS_IDLE. + IoprioClassIdle +) + +// WithIOPriority sets the IO priority and class of the process. +func WithIOPriority(class, priority uint) Option { + return func(args *Options) { + args.IOPriority = optional.Some(IOPriorityParam{ + Class: class, + Priority: priority, + }) + } +} + +const ( + // SchedulingPolicyNormal represents SCHED_NORMAL. + SchedulingPolicyNormal = iota + // SchedulingPolicyFIFO represents SCHED_FIFO. + SchedulingPolicyFIFO + // SchedulingPolicyRR represents SCHED_RR. + SchedulingPolicyRR + // SchedulingPolicyBatch represents SCHED_BATCH. + SchedulingPolicyBatch + // SchedulingPolicyIsoUnimplemented represents SCHED_ISO. + SchedulingPolicyIsoUnimplemented + // SchedulingPolicyIdle represents SCHED_IDLE. + SchedulingPolicyIdle + // SchedulingPolicyDeadline represents SCHED_DEADLINE. + SchedulingPolicyDeadline +) + +// WithSchedulingPolicy sets the scheduling policy of the process. +func WithSchedulingPolicy(policy uint) Option { + return func(args *Options) { + args.SchedulingPolicy = optional.Some(policy) + } +} diff --git a/internal/app/machined/pkg/system/services/dashboard.go b/internal/app/machined/pkg/system/services/dashboard.go index 74133eef14..921bd287bf 100644 --- a/internal/app/machined/pkg/system/services/dashboard.go +++ b/internal/app/machined/pkg/system/services/dashboard.go @@ -72,6 +72,7 @@ func (d *Dashboard) Runner(r runtime.Runtime) (runner.Runner, error) { runner.WithSelinuxLabel(constants.SelinuxLabelDashboard), runner.WithCgroupPath(constants.CgroupDashboard), runner.WithUID(constants.DashboardUserID), + runner.WithPriority(constants.DashboardPriority), ), restart.WithType(restart.Forever), ), nil diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 08c7a969c9..87b95e0ef1 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -530,6 +530,10 @@ const ( // We use the same user ID as apid so that the dashboard can write to the machined unix socket. DashboardUserID = ApidUserID + // DashboardPriority is the priority for the dashboard service. + // Higher nice value for the dashboard to give more CPU time to other services when under load. + DashboardPriority = 10 + // TrustdPort is the port for the trustd service. TrustdPort = 50001 From 24f9875e49acd47ef0a955076b6db6fe62e569ec Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 2 Dec 2024 21:18:16 +0400 Subject: [PATCH 02/14] feat: support vlan/bond in v1, vlan in v2 for nocloud Fixes #9753 Signed-off-by: Andrey Smirnov (cherry picked from commit 852baf819d453a3d8d58ae9f029e280ae75e0cb1) --- .../platform/internal/netutils/netutils.go | 41 -- .../v1alpha1/platform/nocloud/metadata.go | 436 +++++++++++++----- .../v1alpha1/platform/nocloud/nocloud.go | 70 ++- .../v1alpha1/platform/nocloud/nocloud_test.go | 86 +++- .../nocloud/testdata/expected-v1-pnap.yaml | 105 +++++ .../testdata/expected-v2-serverscom.yaml | 158 +++++++ .../nocloud/testdata/expected-v2.yaml | 18 +- .../nocloud/testdata/metadata-v1-pnap.yaml | 53 +++ .../testdata/metadata-v2-cloud-init.yaml | 8 + .../nocloud/testdata/metadata-v2-nocloud.yaml | 8 + .../testdata/metadata-v2-serverscom.yaml | 49 ++ .../nocloud/testdata/metadata-v2.yaml | 49 -- .../nocloud/testdata/metadata-v3.yaml | 49 -- 13 files changed, 833 insertions(+), 297 deletions(-) create mode 100644 internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v1-pnap.yaml create mode 100644 internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2-serverscom.yaml create mode 100644 internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v1-pnap.yaml create mode 100644 internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-serverscom.yaml delete mode 100644 internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2.yaml delete mode 100644 internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v3.yaml diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/internal/netutils/netutils.go b/internal/app/machined/pkg/runtime/v1alpha1/platform/internal/netutils/netutils.go index 42895c58be..90f3a9653e 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/internal/netutils/netutils.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/internal/netutils/netutils.go @@ -7,12 +7,9 @@ package netutils import ( "context" - "fmt" "log" "time" - "github.com/cenkalti/backoff/v4" - "github.com/cosi-project/runtime/pkg/safe" "github.com/cosi-project/runtime/pkg/state" "github.com/siderolabs/go-retry/retry" @@ -28,44 +25,6 @@ func Wait(ctx context.Context, r state.State) error { return network.NewReadyCondition(r, network.AddressReady).Wait(ctx) } -// WaitInterfaces for the interfaces to be up to interact with platform metadata services. -func WaitInterfaces(ctx context.Context, r state.State) error { - backoff := backoff.NewExponentialBackOff() - backoff.MaxInterval = 2 * time.Second - backoff.MaxElapsedTime = 30 * time.Second - - for ctx.Err() == nil { - hostInterfaces, err := safe.StateListAll[*network.LinkStatus](ctx, r) - if err != nil { - return fmt.Errorf("error listing host interfaces: %w", err) - } - - numPhysical := 0 - - for iface := range hostInterfaces.All() { - if iface.TypedSpec().Physical() { - numPhysical++ - } - } - - if numPhysical > 0 { - return nil - } - - log.Printf("waiting for physical network interfaces to appear...") - - interval := backoff.NextBackOff() - - select { - case <-ctx.Done(): - return nil - case <-time.After(interval): - } - } - - return nil -} - // WaitForDevicesReady waits for devices to be ready. func WaitForDevicesReady(ctx context.Context, r state.State) error { log.Printf("waiting for devices to be ready...") diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/metadata.go b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/metadata.go index ff5c920399..4fc6d56ecc 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/metadata.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/metadata.go @@ -50,22 +50,30 @@ type NetworkCloudInitConfig struct { // NetworkConfig holds network-config info. type NetworkConfig struct { - Version int `yaml:"version"` - Config []struct { - Mac string `yaml:"mac_address,omitempty"` - Interfaces string `yaml:"name,omitempty"` - MTU uint32 `yaml:"mtu,omitempty"` - Subnets []struct { - Address string `yaml:"address,omitempty"` - Netmask string `yaml:"netmask,omitempty"` - Gateway string `yaml:"gateway,omitempty"` - Type string `yaml:"type"` - } `yaml:"subnets,omitempty"` - Address []string `yaml:"address,omitempty"` - Type string `yaml:"type"` - } `yaml:"config,omitempty"` + Version int `yaml:"version"` + Config []ConfigV1 `yaml:"config,omitempty"` Ethernets map[string]Ethernet `yaml:"ethernets,omitempty"` - Bonds map[string]Bonds `yaml:"bonds,omitempty"` + Bonds map[string]Bond `yaml:"bonds,omitempty"` + VLANs map[string]VLAN `yaml:"vlans,omitempty"` +} + +// ConfigV1 holds nocloud v1 config. +type ConfigV1 struct { + Mac string `yaml:"mac_address,omitempty"` + Interfaces string `yaml:"name,omitempty"` + MTU uint32 `yaml:"mtu,omitempty"` + Subnets []struct { + Address string `yaml:"address,omitempty"` + Netmask string `yaml:"netmask,omitempty"` + Gateway string `yaml:"gateway,omitempty"` + Type string `yaml:"type"` + } `yaml:"subnets,omitempty"` + Address []string `yaml:"address,omitempty"` + Type string `yaml:"type"` + BondInterfaces []string `yaml:"bond_interfaces,omitempty"` + VlanID uint16 `yaml:"vlan_id,omitempty"` + VlanLink string `yaml:"vlan_link,omitempty"` + Params NetworkParams `yaml:"params,omitempty"` } // Ethernet holds network interface info. @@ -97,8 +105,8 @@ type Ethernet struct { } `yaml:"routing-policy,omitempty"` } -// Bonds holds bonding interface info. -type Bonds struct { +// Bond holds bonding interface info. +type Bond struct { Ethernet `yaml:",inline"` Interfaces []string `yaml:"interfaces,omitempty"` Params struct { @@ -111,6 +119,13 @@ type Bonds struct { } `yaml:"parameters,omitempty"` } +// VLAN holds vlan interface info. +type VLAN struct { + Ethernet `yaml:",inline"` + ID uint16 `yaml:"id,omitempty"` + Link string `yaml:"link,omitempty"` +} + // MetadataConfig holds meta info. type MetadataConfig struct { Hostname string `yaml:"hostname,omitempty"` @@ -123,6 +138,16 @@ type MetadataConfig struct { Zone string `yaml:"zone,omitempty"` } +// NetworkParams holds network parameters (mostly bond for v1 network-config). +type NetworkParams struct { + BondLACPRate string `yaml:"bond-lacp-rate,omitempty"` + BondMiimon uint32 `yaml:"bond-miimon,omitempty"` + BondMode string `yaml:"bond-mode,omitempty"` + BondXmitHashPolicy string `yaml:"bond-xmit-hash-policy,omitempty"` + UpDelay uint32 `yaml:"up-delay,omitempty"` + DownDelay uint32 `yaml:"down-delay,omitempty"` +} + func (n *Nocloud) configFromNetwork(ctx context.Context, metaBaseURL string, r state.State) (metaConfig []byte, networkConfig []byte, machineConfig []byte, err error) { log.Printf("fetching meta config from: %q", metaBaseURL+configMetaDataPath) @@ -284,18 +309,112 @@ func (n *Nocloud) acquireConfig(ctx context.Context, r state.State) (metadataNet } //nolint:gocyclo,cyclop -func (n *Nocloud) applyNetworkConfigV1(config *NetworkConfig, st state.State, networkConfig *runtime.PlatformNetworkConfig) error { - ctx := context.TODO() +func (n *Nocloud) applyNetworkConfigV1(ctx context.Context, config *NetworkConfig, st state.State, networkConfig *runtime.PlatformNetworkConfig) (bool, error) { + hostInterfaces, err := safe.StateListAll[*network.LinkStatus](ctx, st) + if err != nil { + return false, fmt.Errorf("error listing host interfaces: %w", err) + } + + var needsReconcile bool + + parseSubnets := func(ntwrk ConfigV1, name string) error { + for _, subnet := range ntwrk.Subnets { + switch subnet.Type { + case "dhcp", "dhcp4": + networkConfig.Operators = append(networkConfig.Operators, network.OperatorSpecSpec{ + Operator: network.OperatorDHCP4, + LinkName: name, + RequireUp: true, + DHCP4: network.DHCP4OperatorSpec{ + RouteMetric: network.DefaultRouteMetric, + }, + ConfigLayer: network.ConfigPlatform, + }) + case "static", "static6": + family := nethelpers.FamilyInet4 + + if subnet.Type == "static6" { + family = nethelpers.FamilyInet6 + } + + ipPrefix, err := netip.ParsePrefix(subnet.Address) + if err != nil { + ip, err := netip.ParseAddr(subnet.Address) + if err != nil { + return err + } + + netmask, err := netip.ParseAddr(subnet.Netmask) + if err != nil { + return err + } - if err := netutils.WaitInterfaces(ctx, st); err != nil { - return err + mask, _ := netmask.MarshalBinary() //nolint:errcheck // never fails + ones, _ := net.IPMask(mask).Size() + ipPrefix = netip.PrefixFrom(ip, ones) + } + + networkConfig.Addresses = append(networkConfig.Addresses, + network.AddressSpecSpec{ + ConfigLayer: network.ConfigPlatform, + LinkName: name, + Address: ipPrefix, + Scope: nethelpers.ScopeGlobal, + Flags: nethelpers.AddressFlags(nethelpers.AddressPermanent), + Family: family, + }, + ) + + if subnet.Gateway != "" { + gw, err := netip.ParseAddr(subnet.Gateway) + if err != nil { + return err + } + + route := network.RouteSpecSpec{ + ConfigLayer: network.ConfigPlatform, + Gateway: gw, + OutLinkName: name, + Table: nethelpers.TableMain, + Protocol: nethelpers.ProtocolStatic, + Type: nethelpers.TypeUnicast, + Family: family, + Priority: network.DefaultRouteMetric, + } + + if family == nethelpers.FamilyInet6 { + route.Priority = 2 * network.DefaultRouteMetric + } + + route.Normalize() + + networkConfig.Routes = append(networkConfig.Routes, route) + } + case "ipv6_dhcpv6-stateful": + networkConfig.Operators = append(networkConfig.Operators, network.OperatorSpecSpec{ + Operator: network.OperatorDHCP6, + LinkName: name, + RequireUp: true, + DHCP6: network.DHCP6OperatorSpec{ + RouteMetric: 2 * network.DefaultRouteMetric, + }, + ConfigLayer: network.ConfigPlatform, + }) + } + } + + return nil } - hostInterfaces, err := safe.StateListAll[*network.LinkStatus](ctx, st) - if err != nil { - return fmt.Errorf("error listing host interfaces: %w", err) + physicalNameMap := map[string]string{} + + type enslavedLink struct { + bondName string + slaveIndex int } + enslavedLinks := map[string]enslavedLink{} + for _, ntwrk := range config.Config { switch ntwrk.Type { case "nameserver": @@ -305,7 +424,7 @@ func (n *Nocloud) applyNetworkConfigV1(config *NetworkConfig, st state.State, ne if ip, err := netip.ParseAddr(ntwrk.Address[i]); err == nil { dnsIPs = append(dnsIPs, ip) } else { - return err + return false, err } } @@ -313,6 +432,89 @@ func (n *Nocloud) applyNetworkConfigV1(config *NetworkConfig, st state.State, ne DNSServers: dnsIPs, ConfigLayer: network.ConfigPlatform, }) + case "bond": + name := ntwrk.Interfaces + + mode, err := nethelpers.BondModeByName(ntwrk.Params.BondMode) + if err != nil { + return false, fmt.Errorf("invalid mode: %w", err) + } + + hashPolicy, err := nethelpers.BondXmitHashPolicyByName(ntwrk.Params.BondXmitHashPolicy) + if err != nil { + return false, fmt.Errorf("invalid transmit-hash-policy: %w", err) + } + + lacpRate, err := nethelpers.LACPRateByName(ntwrk.Params.BondLACPRate) + if err != nil { + return false, fmt.Errorf("invalid lacp-rate: %w", err) + } + + bondLink := network.LinkSpecSpec{ + ConfigLayer: network.ConfigPlatform, + Name: name, + Logical: true, + Up: true, + Kind: network.LinkKindBond, + Type: nethelpers.LinkEther, + BondMaster: network.BondMasterSpec{ + Mode: mode, + HashPolicy: hashPolicy, + MIIMon: ntwrk.Params.BondMiimon, + UpDelay: ntwrk.Params.UpDelay, + DownDelay: ntwrk.Params.DownDelay, + LACPRate: lacpRate, + }, + } + + if ntwrk.MTU != 0 { + bondLink.MTU = ntwrk.MTU + } + + networkadapter.BondMasterSpec(&bondLink.BondMaster).FillDefaults() + networkConfig.Links = append(networkConfig.Links, bondLink) + + for idx, slave := range ntwrk.BondInterfaces { + enslavedLinks[slave] = enslavedLink{ + bondName: name, + slaveIndex: idx, + } + } + + if err = parseSubnets(ntwrk, name); err != nil { + return false, err + } + case "vlan": + name := ntwrk.Interfaces + + parentName, ok := physicalNameMap[ntwrk.VlanLink] + if !ok { + parentName = ntwrk.VlanLink + } + + linkSpec := network.LinkSpecSpec{ + ConfigLayer: network.ConfigPlatform, + Name: name, + Logical: true, + Up: true, + Kind: network.LinkKindVLAN, + Type: nethelpers.LinkEther, + ParentName: parentName, + VLAN: network.VLANSpec{ + VID: ntwrk.VlanID, + Protocol: nethelpers.VLANProtocol8021Q, + }, + } + + if ntwrk.MTU != 0 { + linkSpec.MTU = ntwrk.MTU + } + + networkConfig.Links = append(networkConfig.Links, linkSpec) + + if err = parseSubnets(ntwrk, name); err != nil { + return false, err + } case "physical": name := ntwrk.Interfaces @@ -339,103 +541,50 @@ func (n *Nocloud) applyNetworkConfigV1(config *NetworkConfig, st state.State, ne if !macAddressMatched { log.Printf("nocloud: no link with matching MAC address %q, defaulted to use name %s instead", ntwrk.Mac, name) + + needsReconcile = true } } - networkConfig.Links = append(networkConfig.Links, network.LinkSpecSpec{ + physicalNameMap[ntwrk.Interfaces] = name + + linkSpec := network.LinkSpecSpec{ Name: name, Up: true, ConfigLayer: network.ConfigPlatform, - }) + } - for _, subnet := range ntwrk.Subnets { - switch subnet.Type { - case "dhcp", "dhcp4": - networkConfig.Operators = append(networkConfig.Operators, network.OperatorSpecSpec{ - Operator: network.OperatorDHCP4, - LinkName: name, - RequireUp: true, - DHCP4: network.DHCP4OperatorSpec{ - RouteMetric: network.DefaultRouteMetric, - }, - ConfigLayer: network.ConfigPlatform, - }) - case "static", "static6": - family := nethelpers.FamilyInet4 + if ntwrk.MTU != 0 { + linkSpec.MTU = ntwrk.MTU + } - if subnet.Type == "static6" { - family = nethelpers.FamilyInet6 - } + networkConfig.Links = append(networkConfig.Links, linkSpec) - ipPrefix, err := netip.ParsePrefix(subnet.Address) - if err != nil { - ip, err := netip.ParseAddr(subnet.Address) - if err != nil { - return err - } - - netmask, err := netip.ParseAddr(subnet.Netmask) - if err != nil { - return err - } - - mask, _ := netmask.MarshalBinary() //nolint:errcheck // never fails - ones, _ := net.IPMask(mask).Size() - ipPrefix = netip.PrefixFrom(ip, ones) - } + if err = parseSubnets(ntwrk, name); err != nil { + return false, err + } + } + } - networkConfig.Addresses = append(networkConfig.Addresses, - network.AddressSpecSpec{ - ConfigLayer: network.ConfigPlatform, - LinkName: name, - Address: ipPrefix, - Scope: nethelpers.ScopeGlobal, - Flags: nethelpers.AddressFlags(nethelpers.AddressPermanent), - Family: family, - }, - ) - - if subnet.Gateway != "" { - gw, err := netip.ParseAddr(subnet.Gateway) - if err != nil { - return err - } - - route := network.RouteSpecSpec{ - ConfigLayer: network.ConfigPlatform, - Gateway: gw, - OutLinkName: name, - Table: nethelpers.TableMain, - Protocol: nethelpers.ProtocolStatic, - Type: nethelpers.TypeUnicast, - Family: family, - Priority: network.DefaultRouteMetric, - } - - if family == nethelpers.FamilyInet6 { - route.Priority = 2 * network.DefaultRouteMetric - } - - route.Normalize() - - networkConfig.Routes = append(networkConfig.Routes, route) - } - case "ipv6_dhcpv6-stateful": - networkConfig.Operators = append(networkConfig.Operators, network.OperatorSpecSpec{ - Operator: network.OperatorDHCP6, - LinkName: name, - RequireUp: true, - DHCP6: network.DHCP6OperatorSpec{ - RouteMetric: 2 * network.DefaultRouteMetric, - }, - ConfigLayer: network.ConfigPlatform, - }) - } + for slaveName, enslavedLink := range enslavedLinks { + physicalName, ok := physicalNameMap[slaveName] + if !ok { + physicalName = slaveName + } + + for idx := range networkConfig.Links { + if networkConfig.Links[idx].Name != physicalName { + continue + } + + networkConfig.Links[idx].BondSlave = network.BondSlave{ + MasterName: enslavedLink.bondName, + SlaveIndex: enslavedLink.slaveIndex, } } } - return nil + return needsReconcile, nil } //nolint:gocyclo @@ -602,13 +751,16 @@ func applyNetworkConfigV2Ethernet(name string, eth Ethernet, networkConfig *runt return nil } -//nolint:gocyclo -func (n *Nocloud) applyNetworkConfigV2(config *NetworkConfig, st state.State, networkConfig *runtime.PlatformNetworkConfig) error { - var dnsIPs []netip.Addr +//nolint:gocyclo,cyclop +func (n *Nocloud) applyNetworkConfigV2(ctx context.Context, config *NetworkConfig, st state.State, networkConfig *runtime.PlatformNetworkConfig) (bool, error) { + var ( + dnsIPs []netip.Addr + needsReconcile bool + ) - hostInterfaces, err := safe.StateListAll[*network.LinkStatus](context.TODO(), st) + hostInterfaces, err := safe.StateListAll[*network.LinkStatus](ctx, st) if err != nil { - return fmt.Errorf("error listing host interfaces: %w", err) + return false, fmt.Errorf("error listing host interfaces: %w", err) } ethernetNames := maps.Keys(config.Ethernets) @@ -620,10 +772,10 @@ func (n *Nocloud) applyNetworkConfigV2(config *NetworkConfig, st state.State, ne var bondSlave network.BondSlave for bondName, bond := range config.Bonds { - for _, iface := range bond.Interfaces { + for idx, iface := range bond.Interfaces { if iface == name { bondSlave.MasterName = bondName - bondSlave.SlaveIndex = 1 + bondSlave.SlaveIndex = idx } } } @@ -655,6 +807,8 @@ func (n *Nocloud) applyNetworkConfigV2(config *NetworkConfig, st state.State, ne if !macAddressMatched { log.Printf("nocloud: no link with matching MAC address %q (available %v), defaulted to use name %s instead", eth.Match.HWAddr, availableMACAddresses, name) + + needsReconcile = true } } @@ -668,29 +822,34 @@ func (n *Nocloud) applyNetworkConfigV2(config *NetworkConfig, st state.State, ne err := applyNetworkConfigV2Ethernet(name, eth, networkConfig, &dnsIPs) if err != nil { - return err + return false, err } } - for name, bond := range config.Bonds { + bondNames := maps.Keys(config.Bonds) + slices.Sort(bondNames) + + for _, bondName := range bondNames { + bond := config.Bonds[bondName] + mode, err := nethelpers.BondModeByName(bond.Params.Mode) if err != nil { - return fmt.Errorf("invalid mode: %w", err) + return false, fmt.Errorf("invalid mode: %w", err) } hashPolicy, err := nethelpers.BondXmitHashPolicyByName(bond.Params.HashPolicy) if err != nil { - return fmt.Errorf("invalid transmit-hash-policy: %w", err) + return false, fmt.Errorf("invalid transmit-hash-policy: %w", err) } lacpRate, err := nethelpers.LACPRateByName(bond.Params.LACPRate) if err != nil { - return fmt.Errorf("invalid lacp-rate: %w", err) + return false, fmt.Errorf("invalid lacp-rate: %w", err) } bondLink := network.LinkSpecSpec{ ConfigLayer: network.ConfigPlatform, - Name: name, + Name: bondName, Logical: true, Up: true, MTU: bond.Ethernet.MTU, @@ -709,9 +868,38 @@ func (n *Nocloud) applyNetworkConfigV2(config *NetworkConfig, st state.State, ne networkadapter.BondMasterSpec(&bondLink.BondMaster).FillDefaults() networkConfig.Links = append(networkConfig.Links, bondLink) - err = applyNetworkConfigV2Ethernet(name, bond.Ethernet, networkConfig, &dnsIPs) + err = applyNetworkConfigV2Ethernet(bondName, bond.Ethernet, networkConfig, &dnsIPs) if err != nil { - return err + return false, err + } + } + + vlanNames := maps.Keys(config.VLANs) + slices.Sort(vlanNames) + + for _, vlanName := range vlanNames { + vlan := config.VLANs[vlanName] + + vlanLink := network.LinkSpecSpec{ + ConfigLayer: network.ConfigPlatform, + Name: vlanName, + Logical: true, + Up: true, + MTU: vlan.Ethernet.MTU, + Kind: network.LinkKindVLAN, + Type: nethelpers.LinkEther, + ParentName: vlan.Link, + VLAN: network.VLANSpec{ + VID: vlan.ID, + Protocol: nethelpers.VLANProtocol8021Q, + }, + } + + networkConfig.Links = append(networkConfig.Links, vlanLink) + + err = applyNetworkConfigV2Ethernet(vlanName, vlan.Ethernet, networkConfig, &dnsIPs) + if err != nil { + return false, err } } @@ -722,7 +910,7 @@ func (n *Nocloud) applyNetworkConfigV2(config *NetworkConfig, st state.State, ne }) } - return nil + return needsReconcile, nil } func withDefault[T comparable](v T, defaultValue T) T { diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud.go b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud.go index e05519174d..21947f44b9 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud.go @@ -9,14 +9,18 @@ import ( "context" stderrors "errors" "fmt" + "time" + "github.com/cenkalti/backoff/v4" "github.com/cosi-project/runtime/pkg/state" + "github.com/siderolabs/gen/channel" "github.com/siderolabs/gen/maps" "github.com/siderolabs/go-procfs/procfs" yaml "gopkg.in/yaml.v3" "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" "github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/errors" + "github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/internal/netutils" "github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/resources/network" runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" @@ -31,7 +35,7 @@ func (n *Nocloud) Name() string { } // ParseMetadata converts nocloud metadata to platform network config. -func (n *Nocloud) ParseMetadata(unmarshalledNetworkConfig *NetworkConfig, st state.State, metadata *MetadataConfig) (*runtime.PlatformNetworkConfig, error) { +func (n *Nocloud) ParseMetadata(ctx context.Context, unmarshalledNetworkConfig *NetworkConfig, st state.State, metadata *MetadataConfig) (*runtime.PlatformNetworkConfig, bool, error) { networkConfig := &runtime.PlatformNetworkConfig{} hostname := metadata.Hostname @@ -45,23 +49,28 @@ func (n *Nocloud) ParseMetadata(unmarshalledNetworkConfig *NetworkConfig, st sta } if err := hostnameSpec.ParseFQDN(hostname); err != nil { - return nil, err + return nil, false, err } networkConfig.Hostnames = append(networkConfig.Hostnames, hostnameSpec) } + var ( + needsReconcile bool + err error + ) + switch unmarshalledNetworkConfig.Version { case 1: - if err := n.applyNetworkConfigV1(unmarshalledNetworkConfig, st, networkConfig); err != nil { - return nil, err + if needsReconcile, err = n.applyNetworkConfigV1(ctx, unmarshalledNetworkConfig, st, networkConfig); err != nil { + return nil, false, err } case 2: - if err := n.applyNetworkConfigV2(unmarshalledNetworkConfig, st, networkConfig); err != nil { - return nil, err + if needsReconcile, err = n.applyNetworkConfigV2(ctx, unmarshalledNetworkConfig, st, networkConfig); err != nil { + return nil, false, err } default: - return nil, fmt.Errorf("network-config metadata version=%d is not supported", unmarshalledNetworkConfig.Version) + return nil, false, fmt.Errorf("network-config metadata version=%d is not supported", unmarshalledNetworkConfig.Version) } networkConfig.Metadata = &runtimeres.PlatformMetadataSpec{ @@ -76,7 +85,7 @@ func (n *Nocloud) ParseMetadata(unmarshalledNetworkConfig *NetworkConfig, st sta ExternalDNS: metadata.ExternalDNS, } - return networkConfig, nil + return networkConfig, needsReconcile, nil } // Configuration implements the runtime.Platform interface. @@ -107,7 +116,14 @@ func (n *Nocloud) KernelArgs(string) procfs.Parameters { } // NetworkConfiguration implements the runtime.Platform interface. +// +//nolint:gocyclo func (n *Nocloud) NetworkConfiguration(ctx context.Context, st state.State, ch chan<- *runtime.PlatformNetworkConfig) error { + // wait for devices to be ready before proceeding + if err := netutils.WaitForDevicesReady(ctx, st); err != nil { + return fmt.Errorf("error waiting for devices to be ready: %w", err) + } + metadataNetworkConfigDl, _, metadata, err := n.acquireConfig(ctx, st) if stderrors.Is(err, errors.ErrNoConfigSource) { err = nil @@ -127,18 +143,36 @@ func (n *Nocloud) NetworkConfiguration(ctx context.Context, st state.State, ch c return err } - networkConfig, err := n.ParseMetadata(unmarshalledNetworkConfig, st, metadata) - if err != nil { - return err - } + // do a loop to retry network config remap in case of missing links + // on each try, export the configuration as it is, and if the network is reconciled next time, export the reconciled configuration + for { + bckoff := backoff.NewExponentialBackOff() - select { - case ch <- networkConfig: - case <-ctx.Done(): - return ctx.Err() - } + networkConfig, needsReconcile, err := n.ParseMetadata(ctx, unmarshalledNetworkConfig, st, metadata) + if err != nil { + return err + } + + if !channel.SendWithContext(ctx, ch, networkConfig) { + return ctx.Err() + } + + if !needsReconcile { + return nil + } + + // wait for for backoff to retry network config remap + nextBackoff := bckoff.NextBackOff() + if nextBackoff == backoff.Stop { + return nil + } - return nil + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(nextBackoff): + } + } } // DecodeNetworkConfig decodes the network configuration guessing the format from the content. diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud_test.go b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud_test.go index f96735d6a6..b6aea9f28e 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud_test.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/nocloud_test.go @@ -7,11 +7,14 @@ package nocloud_test import ( "context" _ "embed" + "net" "testing" + "time" "github.com/cosi-project/runtime/pkg/state" "github.com/cosi-project/runtime/pkg/state/impl/inmem" "github.com/cosi-project/runtime/pkg/state/impl/namespaced" + "github.com/siderolabs/gen/xtesting/must" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" @@ -19,28 +22,45 @@ import ( "github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/network" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) //go:embed testdata/metadata-v1.yaml var rawMetadataV1 []byte +//go:embed testdata/metadata-v1-pnap.yaml +var rawMetadataV1Pnap []byte + //go:embed testdata/metadata-v2-nocloud.yaml var rawMetadataV2Nocloud []byte //go:embed testdata/metadata-v2-cloud-init.yaml var rawMetadataV2CloudInit []byte +//go:embed testdata/metadata-v2-serverscom.yaml +var rawMetadataV2Serverscom []byte + //go:embed testdata/expected-v1.yaml var expectedNetworkConfigV1 string +//go:embed testdata/expected-v1-pnap.yaml +var expectedNetworkConfigV1Pnap string + //go:embed testdata/expected-v2.yaml var expectedNetworkConfigV2 string +//go:embed testdata/expected-v2-serverscom.yaml +var expectedNetworkConfigV2Serverscom string + func TestParseMetadata(t *testing.T) { + t.Parallel() + for _, tt := range []struct { - name string - raw []byte - expected string + name string + raw []byte + + expected string + expectedNeedsRecocile bool }{ { name: "V1", @@ -48,45 +68,78 @@ func TestParseMetadata(t *testing.T) { expected: expectedNetworkConfigV1, }, { - name: "V2-nocloud", - raw: rawMetadataV2Nocloud, - expected: expectedNetworkConfigV2, + name: "V1-pnap", + raw: rawMetadataV1Pnap, + expected: expectedNetworkConfigV1Pnap, + }, + { + name: "V2-nocloud", + raw: rawMetadataV2Nocloud, + expected: expectedNetworkConfigV2, + expectedNeedsRecocile: true, }, { - name: "V2-cloud-init", - raw: rawMetadataV2CloudInit, - expected: expectedNetworkConfigV2, + name: "V2-cloud-init", + raw: rawMetadataV2CloudInit, + expected: expectedNetworkConfigV2, + expectedNeedsRecocile: true, + }, + { + name: "V2-servers.com", + raw: rawMetadataV2Serverscom, + expected: expectedNetworkConfigV2Serverscom, }, } { t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + t.Cleanup(cancel) + n := &nocloud.Nocloud{} st := state.WrapCore(namespaced.NewState(inmem.Build)) + devicesReady := runtime.NewDevicesStatus(runtime.NamespaceName, runtime.DevicesID) + devicesReady.TypedSpec().Ready = true + require.NoError(t, st.Create(ctx, devicesReady)) + bond0 := network.NewLinkStatus(network.NamespaceName, "bond0") bond0.TypedSpec().PermanentAddr = nethelpers.HardwareAddr{0x68, 0x05, 0xca, 0xb8, 0xf1, 0xf7} // this link is not a physical one, so it should be ignored bond0.TypedSpec().Type = nethelpers.LinkEther bond0.TypedSpec().Kind = "bond" - require.NoError(t, st.Create(context.TODO(), bond0)) + require.NoError(t, st.Create(ctx, bond0)) eth0 := network.NewLinkStatus(network.NamespaceName, "eth0") eth0.TypedSpec().PermanentAddr = nethelpers.HardwareAddr{0x68, 0x05, 0xca, 0xb8, 0xf1, 0xf7} eth0.TypedSpec().Type = nethelpers.LinkEther eth0.TypedSpec().Kind = "" - require.NoError(t, st.Create(context.TODO(), eth0)) + require.NoError(t, st.Create(ctx, eth0)) eth1 := network.NewLinkStatus(network.NamespaceName, "eth1") eth1.TypedSpec().HardwareAddr = nethelpers.HardwareAddr{0x68, 0x05, 0xca, 0xb8, 0xf1, 0xf9} // this link has a permanent address, so hardware addr should be ignored eth1.TypedSpec().PermanentAddr = nethelpers.HardwareAddr{0x68, 0x05, 0xca, 0xb8, 0xf1, 0xf8} eth1.TypedSpec().Type = nethelpers.LinkEther eth1.TypedSpec().Kind = "" - require.NoError(t, st.Create(context.TODO(), eth1)) + require.NoError(t, st.Create(ctx, eth1)) eth2 := network.NewLinkStatus(network.NamespaceName, "eth2") eth2.TypedSpec().HardwareAddr = nethelpers.HardwareAddr{0x68, 0x05, 0xca, 0xb8, 0xf1, 0xf9} // this link doesn't have a permanent address, but only a hardware address eth2.TypedSpec().Type = nethelpers.LinkEther eth2.TypedSpec().Kind = "" - require.NoError(t, st.Create(context.TODO(), eth2)) + require.NoError(t, st.Create(ctx, eth2)) + + eno1np0 := network.NewLinkStatus(network.NamespaceName, "eno1np0") + eno1np0.TypedSpec().PermanentAddr = nethelpers.HardwareAddr(must.Value(net.ParseMAC("3c:ec:ef:e0:45:28"))(t)) + eno1np0.TypedSpec().Type = nethelpers.LinkEther + eno1np0.TypedSpec().Kind = "" + require.NoError(t, st.Create(ctx, eno1np0)) + + eno2np1 := network.NewLinkStatus(network.NamespaceName, "eno2np1") + eno2np1.TypedSpec().PermanentAddr = nethelpers.HardwareAddr(must.Value(net.ParseMAC("3c:ec:ef:e0:45:29"))(t)) + eno2np1.TypedSpec().Type = nethelpers.LinkEther + eno2np1.TypedSpec().Kind = "" + require.NoError(t, st.Create(ctx, eno2np1)) m, err := nocloud.DecodeNetworkConfig(tt.raw) require.NoError(t, err) @@ -101,11 +154,14 @@ func TestParseMetadata(t *testing.T) { InstanceID: "0", } - networkConfig, err := n.ParseMetadata(m, st, &mc) + networkConfig, needsReconcile, err := n.ParseMetadata(ctx, m, st, &mc) require.NoError(t, err) - networkConfig2, err := n.ParseMetadata(m, st, &mc2) + networkConfig2, needsReconcile2, err := n.ParseMetadata(ctx, m, st, &mc2) require.NoError(t, err) + assert.Equal(t, needsReconcile, needsReconcile2) + assert.Equal(t, tt.expectedNeedsRecocile, needsReconcile) + marshaled, err := yaml.Marshal(networkConfig) require.NoError(t, err) marshaled2, err := yaml.Marshal(networkConfig2) diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v1-pnap.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v1-pnap.yaml new file mode 100644 index 0000000000..e8aee81a87 --- /dev/null +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v1-pnap.yaml @@ -0,0 +1,105 @@ +addresses: + - address: 1.2.3.4/29 + linkName: bond0.2 + family: inet4 + scope: global + flags: permanent + layer: platform + - address: 10.0.0.11/24 + linkName: bond0.4 + family: inet4 + scope: global + flags: permanent + layer: platform +links: + - name: eno1np0 + logical: false + up: true + mtu: 9000 + kind: "" + type: netrom + masterName: bond0 + layer: platform + - name: eno2np1 + logical: false + up: true + mtu: 9000 + kind: "" + type: netrom + masterName: bond0 + slaveIndex: 1 + layer: platform + - name: bond0 + logical: true + up: true + mtu: 9000 + kind: bond + type: ether + bondMaster: + mode: 802.3ad + xmitHashPolicy: layer3+4 + lacpRate: fast + arpValidate: none + arpAllTargets: any + primaryReselect: always + failOverMac: 0 + miimon: 100 + resendIgmp: 1 + lpInterval: 1 + packetsPerSlave: 1 + numPeerNotif: 1 + tlbLogicalLb: 1 + adActorSysPrio: 65535 + layer: platform + - name: bond0.2 + logical: true + up: true + mtu: 9000 + kind: vlan + type: ether + parentName: bond0 + vlan: + vlanID: 2 + vlanProtocol: 802.1q + layer: platform + - name: bond0.4 + logical: true + up: true + mtu: 9000 + kind: vlan + type: ether + parentName: bond0 + vlan: + vlanID: 4 + vlanProtocol: 802.1q + layer: platform +routes: + - family: inet4 + dst: "" + src: "" + gateway: 1.2.3.5 + outLinkName: bond0.2 + table: main + priority: 1024 + scope: global + type: unicast + flags: "" + protocol: static + layer: platform +hostnames: + - hostname: talos + domainname: fqdn + layer: platform +resolvers: + - dnsServers: + - 8.8.8.8 + - 8.8.4.4 + layer: platform +timeServers: [] +operators: [] +externalIPs: [] +metadata: + platform: nocloud + hostname: talos.fqdn + instanceId: "0" + internalDNS: talos.fqdn diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2-serverscom.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2-serverscom.yaml new file mode 100644 index 0000000000..c8a4e19ddb --- /dev/null +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2-serverscom.yaml @@ -0,0 +1,158 @@ +addresses: + - address: 188.42.48.188/29 + linkName: agge + family: inet4 + scope: global + flags: permanent + layer: platform + - address: 10.26.98.92/29 + linkName: aggi + family: inet4 + scope: global + flags: permanent + layer: platform +links: + - name: eno1np0 + logical: false + up: true + mtu: 0 + kind: "" + type: netrom + masterName: agge + layer: platform + - name: eno2np1 + logical: false + up: true + mtu: 0 + kind: "" + type: netrom + masterName: agge + slaveIndex: 1 + layer: platform + - name: eth1 + logical: false + up: true + mtu: 0 + kind: "" + type: netrom + masterName: aggi + layer: platform + - name: eth2 + logical: false + up: true + mtu: 0 + kind: "" + type: netrom + masterName: aggi + slaveIndex: 1 + layer: platform + - name: agge + logical: true + up: true + mtu: 0 + kind: bond + type: ether + bondMaster: + mode: 802.3ad + xmitHashPolicy: layer3+4 + lacpRate: slow + arpValidate: none + arpAllTargets: any + primaryReselect: always + failOverMac: 0 + miimon: 100 + updelay: 200 + downdelay: 200 + resendIgmp: 1 + lpInterval: 1 + packetsPerSlave: 1 + numPeerNotif: 1 + tlbLogicalLb: 1 + adActorSysPrio: 65535 + layer: platform + - name: aggi + logical: true + up: true + mtu: 0 + kind: bond + type: ether + bondMaster: + mode: 802.3ad + xmitHashPolicy: layer3+4 + lacpRate: slow + arpValidate: none + arpAllTargets: any + primaryReselect: always + failOverMac: 0 + miimon: 100 + updelay: 200 + downdelay: 200 + resendIgmp: 1 + lpInterval: 1 + packetsPerSlave: 1 + numPeerNotif: 1 + tlbLogicalLb: 1 + adActorSysPrio: 65535 + layer: platform +routes: + - family: inet4 + dst: "" + src: "" + gateway: 188.42.48.187 + outLinkName: agge + table: main + priority: 1024 + scope: global + type: unicast + flags: "" + protocol: static + layer: platform + - family: inet4 + dst: 10.0.0.0/8 + src: "" + gateway: 10.26.98.91 + outLinkName: aggi + table: main + priority: 1024 + scope: global + type: unicast + flags: "" + protocol: static + layer: platform + - family: inet4 + dst: 192.168.0.0/16 + src: "" + gateway: 10.26.98.91 + outLinkName: aggi + table: main + priority: 1024 + scope: global + type: unicast + flags: "" + protocol: static + layer: platform + - family: inet4 + dst: 188.42.208.0/21 + src: "" + gateway: 10.26.98.91 + outLinkName: aggi + table: main + priority: 1024 + scope: global + type: unicast + flags: "" + protocol: static + layer: platform +hostnames: + - hostname: talos + domainname: fqdn + layer: platform +resolvers: [] +timeServers: [] +operators: [] +externalIPs: [] +metadata: + platform: nocloud + hostname: talos.fqdn + instanceId: "0" + internalDNS: talos.fqdn diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2.yaml index afd24fa23e..3a90656333 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2.yaml +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/expected-v2.yaml @@ -23,6 +23,12 @@ addresses: scope: global flags: permanent layer: platform + - address: 192.34.34.34/32 + linkName: bond0.4 + family: inet4 + scope: global + flags: permanent + layer: platform links: - name: eth0 logical: false @@ -45,7 +51,6 @@ links: kind: "" type: netrom masterName: bond0 - slaveIndex: 1 layer: platform - name: eth2 logical: false @@ -80,6 +85,17 @@ links: tlbLogicalLb: 1 adActorSysPrio: 65535 layer: platform + - name: bond0.4 + logical: true + up: true + mtu: 1500 + kind: vlan + type: ether + parentName: bond0 + vlan: + vlanID: 4 + vlanProtocol: 802.1q + layer: platform routes: - family: inet4 dst: "" diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v1-pnap.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v1-pnap.yaml new file mode 100644 index 0000000000..bafdf6f7e2 --- /dev/null +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v1-pnap.yaml @@ -0,0 +1,53 @@ +version: 1 +config: + +- type: physical + name: eno1np0 + mac_address: "3c:ec:ef:e0:45:28" + mtu: 9000 + +- type: physical + name: eno2np1 + mac_address: "3c:ec:ef:e0:45:29" + mtu: 9000 + +- type: bond + name: bond0 + mac_address: "3c:ec:ef:e0:45:28" + mtu: 9000 + bond_interfaces: + - eno1np0 + - eno2np1 + params: + bond-lacp-rate: fast + bond-miimon: 100 + bond-mode: 802.3ad + bond-xmit-hash-policy: layer3+4 + up-delay: 0 + down-delay: 0 + +# public frontend MERGED_FRONTEND vlan 2 +- type: vlan + name: bond0.2 + mtu: 9000 + vlan_id: 2 + vlan_link: bond0 + subnets: + - address: 1.2.3.4/29 + gateway: 1.2.3.5 + type: static + +# private backend vlan 4 +- type: vlan + mtu: 9000 + name: bond0.4 + vlan_id: 4 + vlan_link: bond0 + subnets: + - type: static + address: 10.0.0.11/24 + +- type: nameserver + address: + - 8.8.8.8 + - 8.8.4.4 diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-cloud-init.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-cloud-init.yaml index f01cee2d11..1e1735a1a1 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-cloud-init.yaml +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-cloud-init.yaml @@ -60,3 +60,11 @@ network: via: 10.10.4.147 - to: 188.42.208.0/21 via: 10.10.4.147 + + vlans: + bond0.4: + id: 4 + link: bond0 + mtu: 1500 + addresses: + - 192.34.34.34/32 diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-nocloud.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-nocloud.yaml index 43739eb089..51f5659b2d 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-nocloud.yaml +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-nocloud.yaml @@ -59,3 +59,11 @@ bonds: via: 10.10.4.147 - to: 188.42.208.0/21 via: 10.10.4.147 + +vlans: + bond0.4: + id: 4 + link: bond0 + mtu: 1500 + addresses: + - 192.34.34.34/32 diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-serverscom.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-serverscom.yaml new file mode 100644 index 0000000000..52846ce94e --- /dev/null +++ b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2-serverscom.yaml @@ -0,0 +1,49 @@ +version: 2 +bonds: + aggi: + interfaces: + - int0 + - int1 + addresses: + - 10.26.98.92/29 + parameters: + mode: 802.3ad + lacp-rate: slow + mii-monitor-interval: 100 + up-delay: 200 + down-delay: 200 + transmit-hash-policy: layer3+4 + routes: + - to: 10.0.0.0/8 + via: 10.26.98.91 + - to: 192.168.0.0/16 + via: 10.26.98.91 + - to: 188.42.208.0/21 + via: 10.26.98.91 + agge: + interfaces: + - ext0 + - ext1 + addresses: + - 188.42.48.188/29 + parameters: + mode: 802.3ad + lacp-rate: slow + mii-monitor-interval: 100 + up-delay: 200 + down-delay: 200 + transmit-hash-policy: layer3+4 + gateway4: 188.42.48.187 +ethernets: + int0: + match: + macaddress: 68:05:ca:b8:f1:f8 + int1: + match: + macaddress: 68:05:ca:b8:f1:f9 + ext0: + match: + macaddress: 3c:ec:ef:e0:45:28 + ext1: + match: + macaddress: 3c:ec:ef:e0:45:29 diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2.yaml deleted file mode 100644 index 5d7b0d0435..0000000000 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v2.yaml +++ /dev/null @@ -1,49 +0,0 @@ -version: 2 -ethernets: - eth0: - match: - macaddress: '00:20:6e:1f:f9:a8' - dhcp4: true - addresses: - - 192.168.14.2/24 - - 2001:1::1/64 - gateway4: 192.168.14.1 - gateway6: 2001:1::2 - nameservers: - search: [foo.local, bar.local] - addresses: [8.8.8.8] - - ext1: - match: - macaddress: 68:05:ca:b8:f1:f8 - ext2: - match: - macaddress: 68:05:ca:b8:f1:f9 - -bonds: - bond0: - interfaces: - - ext1 - - ext2 - macaddress: e4:3d:1a:4d:6a:28 - mtu: 1500 - parameters: - mode: 802.3ad - mii-monitor-interval: 100 - down-delay: 200 - up-delay: 200 - lacp-rate: fast - transmit-hash-policy: layer3+4 - addresses: - - 10.10.4.140/29 - nameservers: - addresses: - - 1.1.1.1 - - 2.2.2.2 - routes: - - to: 10.0.0.0/8 - via: 10.10.4.147 - - to: 192.168.0.0/16 - via: 10.10.4.147 - - to: 188.42.208.0/21 - via: 10.10.4.147 diff --git a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v3.yaml b/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v3.yaml deleted file mode 100644 index b6fe782617..0000000000 --- a/internal/app/machined/pkg/runtime/v1alpha1/platform/nocloud/testdata/metadata-v3.yaml +++ /dev/null @@ -1,49 +0,0 @@ -version: 2 -ethernets: - eth0: - match: - macaddress: '00:20:6e:1f:f9:a8' - dhcp4: true - addresses: - - 192.168.14.2/24 - - 2001:1::1/64 - gateway4: 192.168.14.1 - gateway6: 2001:1::2 - nameservers: - search: [foo.local, bar.local] - addresses: [8.8.8.8] - - ext1: - match: - macaddress: f4:33:01:16:3d:90 - ext2: - match: - macaddress: 50:a5:1b:e8:7b:db - -bonds: - bond0: - interfaces: - - ext1 - - ext2 - macaddress: e4:3d:1a:4d:6a:28 - mtu: 1500 - parameters: - mode: 802.3ad - mii-monitor-interval: 100 - down-delay: 200 - up-delay: 200 - lacp-rate: fast - transmit-hash-policy: layer3+4 - addresses: - - 10.10.4.140/29 - nameservers: - addresses: - - 1.1.1.1 - - 2.2.2.2 - routes: - - to: 10.0.0.0/8 - via: 10.10.4.147 - - to: 192.168.0.0/16 - via: 10.10.4.147 - - to: 188.42.208.0/21 - via: 10.10.4.147 From 246180febf6e2c557483f93c2609a4d8f8873d1b Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 4 Dec 2024 15:21:46 +0400 Subject: [PATCH 03/14] feat: update Kubernetes to 1.32.0-rc.1 See https://github.com/kubernetes/kubernetes/releases/tag/v1.32.0-rc.1 Signed-off-by: Andrey Smirnov (cherry picked from commit 5a4bdf62a9bf1387b6489eaf2c9cc0770aa0b68c) --- Makefile | 2 +- go.mod | 22 +++++----- go.sum | 44 +++++++++---------- hack/release.toml | 2 +- hack/test/e2e.sh | 2 +- pkg/machinery/constants/constants.go | 2 +- website/content/v1.9/reference/cli.md | 8 ++-- .../configuration/v1alpha1/config.md | 30 ++++++------- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Makefile b/Makefile index 43ab363e33..d5fb64a256 100644 --- a/Makefile +++ b/Makefile @@ -105,7 +105,7 @@ INTEGRATION_TEST := integration-test INTEGRATION_TEST_DEFAULT_TARGET := $(INTEGRATION_TEST)-$(OPERATING_SYSTEM) INTEGRATION_TEST_PROVISION_DEFAULT_TARGET := integration-test-provision-$(OPERATING_SYSTEM) # renovate: datasource=github-releases depName=kubernetes/kubernetes -KUBECTL_VERSION ?= v1.32.0-rc.0 +KUBECTL_VERSION ?= v1.32.0-rc.1 # renovate: datasource=github-releases depName=kastenhq/kubestr KUBESTR_VERSION ?= v0.4.46 # renovate: datasource=github-releases depName=helm/helm diff --git a/go.mod b/go.mod index 45cb1a2290..908cb27cd8 100644 --- a/go.mod +++ b/go.mod @@ -32,16 +32,16 @@ replace github.com/insomniacslk/dhcp => github.com/smira/dhcp v0.0.0-20241001122 // Kubernetes dependencies sharing the same version. require ( - k8s.io/api v0.32.0-rc.0 - k8s.io/apimachinery v0.32.0-rc.0 - k8s.io/apiserver v0.32.0-rc.0 - k8s.io/client-go v0.32.0-rc.0 - k8s.io/component-base v0.32.0-rc.0 - k8s.io/cri-api v0.32.0-rc.0 - k8s.io/kube-scheduler v0.32.0-rc.0 - k8s.io/kubectl v0.32.0-rc.0 - k8s.io/kubelet v0.32.0-rc.0 - k8s.io/pod-security-admission v0.32.0-rc.0 + k8s.io/api v0.32.0-rc.1 + k8s.io/apimachinery v0.32.0-rc.1 + k8s.io/apiserver v0.32.0-rc.1 + k8s.io/client-go v0.32.0-rc.1 + k8s.io/component-base v0.32.0-rc.1 + k8s.io/cri-api v0.32.0-rc.1 + k8s.io/kube-scheduler v0.32.0-rc.1 + k8s.io/kubectl v0.32.0-rc.1 + k8s.io/kubelet v0.32.0-rc.1 + k8s.io/pod-security-admission v0.32.0-rc.1 ) require ( @@ -362,7 +362,7 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/cli-runtime v0.32.0-rc.0 // indirect + k8s.io/cli-runtime v0.32.0-rc.1 // indirect k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect kernel.org/pub/linux/libs/security/libcap/psx v1.2.72 // indirect diff --git a/go.sum b/go.sum index 2a543d917d..a461d0fc3a 100644 --- a/go.sum +++ b/go.sum @@ -1097,32 +1097,32 @@ gvisor.dev/gvisor v0.0.0-20240331093104-8c9cbf0d9090/go.mod h1:NQHVAzMwvZ+Qe3ElS honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.32.0-rc.0 h1:/JeK0EoDPuDmV4YhcojORdB38o3tfSJlEXx6zBIFVBE= -k8s.io/api v0.32.0-rc.0/go.mod h1:cWKDBZRmf22qbGbFb7nTF1Bgyft9Y8/2Ems4nfonwsU= -k8s.io/apimachinery v0.32.0-rc.0 h1:u+1irgylqNowg1vQFJJqw0UASsb07LhSpFvIX+EnI5A= -k8s.io/apimachinery v0.32.0-rc.0/go.mod h1:HqhdaJUgQqky29T1V0o2yFkt/pZqLFIDyn9Zi/8rxoY= -k8s.io/apiserver v0.32.0-rc.0 h1:Djr9zFBIgWctxuO9pOYPFG3VSraachj9QU2V6uUdgBw= -k8s.io/apiserver v0.32.0-rc.0/go.mod h1:S1L6AHxdnAMUR1oq0srAq15veddvijAYP1hcMiPkM6I= -k8s.io/cli-runtime v0.32.0-rc.0 h1:POoxV3AK6+WnHIN0tjMQRh74jSZZ3n8u5FYFnqrKp9s= -k8s.io/cli-runtime v0.32.0-rc.0/go.mod h1:KCLZk3bkknEmF2xBM/poDEU25IatAUfPsA0JvjwBjH0= -k8s.io/client-go v0.32.0-rc.0 h1:8QFsKiUSQsERKRnfEyfw2TV37f/mdR8BEEzFqJqg6y0= -k8s.io/client-go v0.32.0-rc.0/go.mod h1:ke1QuLYLBZ/4oUqsb2emcPoDcdSGE1jYL9IQnD8wByU= -k8s.io/component-base v0.32.0-rc.0 h1:x/z6A18GeEsTQjfIuoeauFoWL7IDKCJNxE6yQuqQ12g= -k8s.io/component-base v0.32.0-rc.0/go.mod h1:L8fl5Xqwi2XF3gkj8+Z92h2Hg8O9gGiV2rCCYYSDj6Q= -k8s.io/cri-api v0.32.0-rc.0 h1:tqVelzAGCb/2t9yFKEsYI6Om3IOrwDEzIe6rmdzu33Q= -k8s.io/cri-api v0.32.0-rc.0/go.mod h1:5WOp91NVV2mzTQRp732avavhFFItsWsQy8jO7DPv8d8= +k8s.io/api v0.32.0-rc.1 h1:dxXiVjLYq4JmlXFgctsK9zJaXhPA1hJLO772lHk4wKw= +k8s.io/api v0.32.0-rc.1/go.mod h1:3TNYUV1WB3ZF2yOeY4qlr9FDb1GVzO+OucsXW2BOi5o= +k8s.io/apimachinery v0.32.0-rc.1 h1:jeLQr/Dqcq0kGU/yjEmievDMHTJzzwQctlysW0Kb70U= +k8s.io/apimachinery v0.32.0-rc.1/go.mod h1:HqhdaJUgQqky29T1V0o2yFkt/pZqLFIDyn9Zi/8rxoY= +k8s.io/apiserver v0.32.0-rc.1 h1:zlrmW4wO1JYXlu4mHzQ/bQajC7OP/sgCRFF8abOWhEQ= +k8s.io/apiserver v0.32.0-rc.1/go.mod h1:kzVgA1c3Ig7wDnDF99bOz/dY4iEY/OWzayCY1gZPzDI= +k8s.io/cli-runtime v0.32.0-rc.1 h1:rQDtu2ihnv/ItkawGIewwqhgb6C6skVwNFWCxBx7loI= +k8s.io/cli-runtime v0.32.0-rc.1/go.mod h1:ifV1UrGAvsFhohEfFLkxoAAZPAXnp92ROioZvFG4be4= +k8s.io/client-go v0.32.0-rc.1 h1:ZW27sbQZ06FnkFTNqlfa9HTIW01RGoLoiOmdiLbWYK0= +k8s.io/client-go v0.32.0-rc.1/go.mod h1:Nlv9GR11bKYSlCcxY3B1RpVbcsfasSAwminv42knDHk= +k8s.io/component-base v0.32.0-rc.1 h1:c3EG8QuyozbalRmbsUxXW/ZmF2bev3Zq9PbpU3oIHT4= +k8s.io/component-base v0.32.0-rc.1/go.mod h1:xIvfPkeLsQbd2fkDNWezG20WQwrabBetTUxp67eycbI= +k8s.io/cri-api v0.32.0-rc.1 h1:e7+u84qR9Nychp2imSIIDeQSNBZut/1alF7vcskZbik= +k8s.io/cri-api v0.32.0-rc.1/go.mod h1:5WOp91NVV2mzTQRp732avavhFFItsWsQy8jO7DPv8d8= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= -k8s.io/kube-scheduler v0.32.0-rc.0 h1:ZkdCF11CmxAxXsSU/DtT+cr7N+5V/B6Oqc+i3tvTGmg= -k8s.io/kube-scheduler v0.32.0-rc.0/go.mod h1:E+sESpgNo21ffzrRlrFk5MaWGr7BFha1q98cNTmfcWE= -k8s.io/kubectl v0.32.0-rc.0 h1:xlP1o8Y9YLQG2mBS1snB4ruI62TNKxpYUugfbkqlnhI= -k8s.io/kubectl v0.32.0-rc.0/go.mod h1:OyY/YZRSU3urKX376mgSS1qCHFuz9jDNTeY1LytgWuU= -k8s.io/kubelet v0.32.0-rc.0 h1:hXpLanUvHYnfUvbajgBWOh2a0eX4T4bXwSLvfXVeXFI= -k8s.io/kubelet v0.32.0-rc.0/go.mod h1:rU3iw03AeaAoNTkbEIdlh4feBS3i7heKMrsIYONjwdQ= -k8s.io/pod-security-admission v0.32.0-rc.0 h1:ufhIe+HjC1+lA/CjJtp8dT3UShzXVcgzvE/2SF3Bbcw= -k8s.io/pod-security-admission v0.32.0-rc.0/go.mod h1:MD7IMDTajPEzRADmg1bO8PSzLVkanv9KSS0/ESxFU3Y= +k8s.io/kube-scheduler v0.32.0-rc.1 h1:TrCQMuOZthP7POY+wQgPZoXQ9+wJeHZNsCbeqO26jGw= +k8s.io/kube-scheduler v0.32.0-rc.1/go.mod h1:SjsaRjg/7iyItYvxkKaSaTvSQNnIbXwBMYSjrp+8ZhY= +k8s.io/kubectl v0.32.0-rc.1 h1:hkZ9bqMyOySj8Ky8d6/Yjxa7WQBJKijaMTcGkYmYYKE= +k8s.io/kubectl v0.32.0-rc.1/go.mod h1:+N+xgO48ssPu8eJMm2rymUuMIDy2UgqY67Xj/p5eO0Y= +k8s.io/kubelet v0.32.0-rc.1 h1:vgQavYPMnDlOAECm3ApeKWrU3m7Oo2lQuGtviJ00jSA= +k8s.io/kubelet v0.32.0-rc.1/go.mod h1:lkKQv20UU5m23z4DKYOUbe+j3BMnhRpALR2rqDtduBo= +k8s.io/pod-security-admission v0.32.0-rc.1 h1:hinSdeNwLTmuyQpUaZjAPgQjSzIKfu8vo4MFPwV2uKE= +k8s.io/pod-security-admission v0.32.0-rc.1/go.mod h1:kMQk2qV2sdGCXMRITdPNy4dAZ9qqcbLgdkzgj/C+niM= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= kernel.org/pub/linux/libs/security/libcap/cap v1.2.72 h1:SqLZbTqwcNxctcdM5yb6OcO3lFJNtRgDJoFeca+5hP0= diff --git a/hack/release.toml b/hack/release.toml index fdff906fbe..0e05bc23f6 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -21,7 +21,7 @@ preface = """ * Linux: 6.12.1 * containerd: 2.0.0 * Flannel: 0.26.1 -* Kubernetes: 1.32.0-rc.0 +* Kubernetes: 1.32.0-rc.1 * runc: 1.2.1 * CoreDNS: 1.12.0 diff --git a/hack/test/e2e.sh b/hack/test/e2e.sh index 2b108ce8dc..4a8241dd11 100755 --- a/hack/test/e2e.sh +++ b/hack/test/e2e.sh @@ -33,7 +33,7 @@ export TALOS_VERSION # Kubernetes export KUBECONFIG="${TMP}/kubeconfig" -export KUBERNETES_VERSION=${KUBERNETES_VERSION:-1.32.0-rc.0} +export KUBERNETES_VERSION=${KUBERNETES_VERSION:-1.32.0-rc.1} export NAME_PREFIX="talos-e2e-${SHA}-${PLATFORM}" export TIMEOUT=1200 diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 87b95e0ef1..8b43867201 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -390,7 +390,7 @@ const ( // DefaultKubernetesVersion is the default target version of the control plane. // renovate: datasource=github-releases depName=kubernetes/kubernetes - DefaultKubernetesVersion = "1.32.0-rc.0" + DefaultKubernetesVersion = "1.32.0-rc.1" // SupportedKubernetesVersions is the number of Kubernetes versions supported by Talos starting from DefaultKubernesVersion going backwards. SupportedKubernetesVersions = 6 diff --git a/website/content/v1.9/reference/cli.md b/website/content/v1.9/reference/cli.md index 4bb53c9826..426cda88b0 100644 --- a/website/content/v1.9/reference/cli.md +++ b/website/content/v1.9/reference/cli.md @@ -184,7 +184,7 @@ talosctl cluster create [flags] --ipxe-boot-script string iPXE boot script (URL) to use --iso-path string the ISO path to use for the initial boot (VM only) --kubeprism-port int KubePrism port (set to 0 to disable) (default 7445) - --kubernetes-version string desired kubernetes version to run (default "1.32.0-rc.0") + --kubernetes-version string desired kubernetes version to run (default "1.32.0-rc.1") --memory int the limit on memory usage in MB (each control plane/VM) (default 2048) --memory-workers int the limit on memory usage in MB (each worker/VM) (default 2048) --mount mount attach a mount to the container (Docker only) @@ -1358,7 +1358,7 @@ talosctl gen config [flags] -h, --help help for config --install-disk string the disk to install to (default "/dev/sda") --install-image string the image used to perform an installation (default "ghcr.io/siderolabs/installer:latest") - --kubernetes-version string desired kubernetes version to run (default "1.32.0-rc.0") + --kubernetes-version string desired kubernetes version to run (default "1.32.0-rc.1") -o, --output string destination to output generated files. when multiple output types are specified, it must be a directory. for a single output type, it must either be a file path, or "-" for stdout -t, --output-types strings types of outputs to be generated. valid types are: ["controlplane" "worker" "talosconfig"] (default [controlplane,worker,talosconfig]) -p, --persist the desired persist value for configs (default true) @@ -1791,7 +1791,7 @@ talosctl image cache-create [flags] ### Examples ``` -talosctl images cache-create --images=ghcr.io/siderolabs/kubelet:1.32.0-rc.0 --image-cache-path=/tmp/talos-image-cache +talosctl images cache-create --images=ghcr.io/siderolabs/kubelet:1.32.0-rc.1 --image-cache-path=/tmp/talos-image-cache Alternatively, stdin can be piped to the command: talosctl images default | talosctl images cache-create --image-cache-path=/tmp/talos-image-cache --images=- @@ -3021,7 +3021,7 @@ talosctl upgrade-k8s [flags] --pre-pull-images pre-pull images before upgrade (default true) --proxy-image string kube-proxy image to use (default "registry.k8s.io/kube-proxy") --scheduler-image string kube-scheduler image to use (default "registry.k8s.io/kube-scheduler") - --to string the Kubernetes control plane version to upgrade to (default "1.32.0-rc.0") + --to string the Kubernetes control plane version to upgrade to (default "1.32.0-rc.1") --upgrade-kubelet upgrade kubelet service (default true) --with-docs patch all machine configs adding the documentation for each field (default true) --with-examples patch all machine configs with the commented examples (default true) diff --git a/website/content/v1.9/reference/configuration/v1alpha1/config.md b/website/content/v1.9/reference/configuration/v1alpha1/config.md index d7698831dd..0830a5963a 100644 --- a/website/content/v1.9/reference/configuration/v1alpha1/config.md +++ b/website/content/v1.9/reference/configuration/v1alpha1/config.md @@ -90,7 +90,7 @@ controlPlane: {{< /highlight >}} | | |`kubelet` |KubeletConfig |Used to provide additional options to the kubelet.
Show example(s){{< highlight yaml >}} kubelet: - image: ghcr.io/siderolabs/kubelet:v1.32.0-rc.0 # The `image` field is an optional reference to an alternative kubelet image. + image: ghcr.io/siderolabs/kubelet:v1.32.0-rc.1 # The `image` field is an optional reference to an alternative kubelet image. # The `extraArgs` field is used to provide additional flags to the kubelet. extraArgs: feature-gates: ServerSideApply=true @@ -519,7 +519,7 @@ KubeletConfig represents the kubelet config values. {{< highlight yaml >}} machine: kubelet: - image: ghcr.io/siderolabs/kubelet:v1.32.0-rc.0 # The `image` field is an optional reference to an alternative kubelet image. + image: ghcr.io/siderolabs/kubelet:v1.32.0-rc.1 # The `image` field is an optional reference to an alternative kubelet image. # The `extraArgs` field is used to provide additional flags to the kubelet. extraArgs: feature-gates: ServerSideApply=true @@ -572,7 +572,7 @@ machine: | Field | Type | Description | Value(s) | |-------|------|-------------|----------| |`image` |string |The `image` field is an optional reference to an alternative kubelet image.
Show example(s){{< highlight yaml >}} -image: ghcr.io/siderolabs/kubelet:v1.32.0-rc.0 +image: ghcr.io/siderolabs/kubelet:v1.32.0-rc.1 {{< /highlight >}}
| | |`clusterDNS` |[]string |The `ClusterDNS` field is an optional reference to an alternative kubelet clusterDNS ip list.
Show example(s){{< highlight yaml >}} clusterDNS: @@ -2997,7 +2997,7 @@ serviceAccount: {{< /highlight >}}
| | |`apiServer` |APIServerConfig |API server specific configuration options.
Show example(s){{< highlight yaml >}} apiServer: - image: registry.k8s.io/kube-apiserver:v1.32.0-rc.0 # The container image used in the API server manifest. + image: registry.k8s.io/kube-apiserver:v1.32.0-rc.1 # The container image used in the API server manifest. # Extra arguments to supply to the API server. extraArgs: feature-gates: ServerSideApply=true @@ -3062,14 +3062,14 @@ apiServer: {{< /highlight >}}
| | |`controllerManager` |ControllerManagerConfig |Controller manager server specific configuration options.
Show example(s){{< highlight yaml >}} controllerManager: - image: registry.k8s.io/kube-controller-manager:v1.32.0-rc.0 # The container image used in the controller manager manifest. + image: registry.k8s.io/kube-controller-manager:v1.32.0-rc.1 # The container image used in the controller manager manifest. # Extra arguments to supply to the controller manager. extraArgs: feature-gates: ServerSideApply=true {{< /highlight >}}
| | |`proxy` |ProxyConfig |Kube-proxy server-specific configuration options
Show example(s){{< highlight yaml >}} proxy: - image: registry.k8s.io/kube-proxy:v1.32.0-rc.0 # The container image used in the kube-proxy manifest. + image: registry.k8s.io/kube-proxy:v1.32.0-rc.1 # The container image used in the kube-proxy manifest. mode: ipvs # proxy mode of kube-proxy. # Extra arguments to supply to kube-proxy. extraArgs: @@ -3080,7 +3080,7 @@ proxy: {{< /highlight >}}
| | |`scheduler` |SchedulerConfig |Scheduler server specific configuration options.
Show example(s){{< highlight yaml >}} scheduler: - image: registry.k8s.io/kube-scheduler:v1.32.0-rc.0 # The container image used in the scheduler manifest. + image: registry.k8s.io/kube-scheduler:v1.32.0-rc.1 # The container image used in the scheduler manifest. # Extra arguments to supply to the scheduler. extraArgs: feature-gates: AllBeta=true @@ -3324,7 +3324,7 @@ APIServerConfig represents the kube apiserver configuration options. {{< highlight yaml >}} cluster: apiServer: - image: registry.k8s.io/kube-apiserver:v1.32.0-rc.0 # The container image used in the API server manifest. + image: registry.k8s.io/kube-apiserver:v1.32.0-rc.1 # The container image used in the API server manifest. # Extra arguments to supply to the API server. extraArgs: feature-gates: ServerSideApply=true @@ -3392,7 +3392,7 @@ cluster: | Field | Type | Description | Value(s) | |-------|------|-------------|----------| |`image` |string |The container image used in the API server manifest.
Show example(s){{< highlight yaml >}} -image: registry.k8s.io/kube-apiserver:v1.32.0-rc.0 +image: registry.k8s.io/kube-apiserver:v1.32.0-rc.1 {{< /highlight >}}
| | |`extraArgs` |map[string]string |Extra arguments to supply to the API server. | | |`extraVolumes` |[]VolumeMountConfig |Extra volumes to mount to the API server static pod. | | @@ -3604,7 +3604,7 @@ ControllerManagerConfig represents the kube controller manager configuration opt {{< highlight yaml >}} cluster: controllerManager: - image: registry.k8s.io/kube-controller-manager:v1.32.0-rc.0 # The container image used in the controller manager manifest. + image: registry.k8s.io/kube-controller-manager:v1.32.0-rc.1 # The container image used in the controller manager manifest. # Extra arguments to supply to the controller manager. extraArgs: feature-gates: ServerSideApply=true @@ -3614,7 +3614,7 @@ cluster: | Field | Type | Description | Value(s) | |-------|------|-------------|----------| |`image` |string |The container image used in the controller manager manifest.
Show example(s){{< highlight yaml >}} -image: registry.k8s.io/kube-controller-manager:v1.32.0-rc.0 +image: registry.k8s.io/kube-controller-manager:v1.32.0-rc.1 {{< /highlight >}}
| | |`extraArgs` |map[string]string |Extra arguments to supply to the controller manager. | | |`extraVolumes` |[]VolumeMountConfig |Extra volumes to mount to the controller manager static pod. | | @@ -3684,7 +3684,7 @@ ProxyConfig represents the kube proxy configuration options. {{< highlight yaml >}} cluster: proxy: - image: registry.k8s.io/kube-proxy:v1.32.0-rc.0 # The container image used in the kube-proxy manifest. + image: registry.k8s.io/kube-proxy:v1.32.0-rc.1 # The container image used in the kube-proxy manifest. mode: ipvs # proxy mode of kube-proxy. # Extra arguments to supply to kube-proxy. extraArgs: @@ -3701,7 +3701,7 @@ cluster: disabled: false {{< /highlight >}}
| | |`image` |string |The container image used in the kube-proxy manifest.
Show example(s){{< highlight yaml >}} -image: registry.k8s.io/kube-proxy:v1.32.0-rc.0 +image: registry.k8s.io/kube-proxy:v1.32.0-rc.1 {{< /highlight >}}
| | |`mode` |string |
proxy mode of kube-proxy.The default is 'iptables'.
| | |`extraArgs` |map[string]string |Extra arguments to supply to kube-proxy. | | @@ -3720,7 +3720,7 @@ SchedulerConfig represents the kube scheduler configuration options. {{< highlight yaml >}} cluster: scheduler: - image: registry.k8s.io/kube-scheduler:v1.32.0-rc.0 # The container image used in the scheduler manifest. + image: registry.k8s.io/kube-scheduler:v1.32.0-rc.1 # The container image used in the scheduler manifest. # Extra arguments to supply to the scheduler. extraArgs: feature-gates: AllBeta=true @@ -3730,7 +3730,7 @@ cluster: | Field | Type | Description | Value(s) | |-------|------|-------------|----------| |`image` |string |The container image used in the scheduler manifest.
Show example(s){{< highlight yaml >}} -image: registry.k8s.io/kube-scheduler:v1.32.0-rc.0 +image: registry.k8s.io/kube-scheduler:v1.32.0-rc.1 {{< /highlight >}}
| | |`extraArgs` |map[string]string |Extra arguments to supply to the scheduler. | | |`extraVolumes` |[]VolumeMountConfig |Extra volumes to mount to the scheduler static pod. | | From 1343773e6e8db28f5912dc1811b1f8fa9645d7e7 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 4 Dec 2024 15:25:20 +0400 Subject: [PATCH 04/14] test: use two workers in qemu tests by default Fixes #9870 Signed-off-by: Andrey Smirnov (cherry picked from commit 77e9db4abf9c9b694d60c8803b436121dfe30ccd) --- .github/workflows/ci.yaml | 7 ++----- .github/workflows/integration-cilium-cron.yaml | 5 +---- .github/workflows/integration-conformance-cron.yaml | 3 +-- .github/workflows/integration-extensions-cron.yaml | 3 ++- .kres.yaml | 5 +---- hack/test/e2e-qemu.sh | 2 +- 6 files changed, 8 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bc375bc963..d3a3f06423 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-11-28T14:18:12Z by kres 232fe63. +# Generated on 2024-12-04T12:34:25Z by kres 232fe63. name: default concurrency: @@ -1014,7 +1014,6 @@ jobs: env: GITHUB_STEP_NAME: ${{ github.job}}-e2e-cilium IMAGE_REGISTRY: registry.dev.siderolabs.io - QEMU_WORKERS: "2" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH: '@hack/test/patches/cilium-no-kubeproxy.yaml' WITH_CUSTOM_CNI: cilium @@ -1027,7 +1026,6 @@ jobs: CILIUM_INSTALL_TYPE: strict GITHUB_STEP_NAME: ${{ github.job}}-e2e-cilium-strict IMAGE_REGISTRY: registry.dev.siderolabs.io - QEMU_WORKERS: "2" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH: '@hack/test/patches/cilium-kubeproxy.yaml' WITH_CUSTOM_CNI: cilium @@ -1040,7 +1038,6 @@ jobs: CILIUM_INSTALL_TYPE: strict GITHUB_STEP_NAME: ${{ github.job}}-e2e-cilium-strict-kubespan IMAGE_REGISTRY: registry.dev.siderolabs.io - QEMU_WORKERS: "2" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH: '@hack/test/patches/cilium-kubeproxy.yaml' WITH_CUSTOM_CNI: cilium @@ -1228,7 +1225,6 @@ jobs: GITHUB_STEP_NAME: ${{ github.job}}-conformance-qemu IMAGE_REGISTRY: registry.dev.siderolabs.io QEMU_CPUS: "4" - QEMU_WORKERS: "2" TEST_MODE: fast-conformance run: | sudo -E make e2e-qemu @@ -1469,6 +1465,7 @@ jobs: IMAGE_REGISTRY: registry.dev.siderolabs.io QEMU_EXTRA_DISKS: "3" QEMU_MEMORY_WORKERS: "4096" + QEMU_WORKERS: "1" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH_WORKER: '@_out/installer-extensions-patch.yaml:@hack/test/patches/extensions.yaml:@hack/test/patches/dm-raid-module.yaml' run: | diff --git a/.github/workflows/integration-cilium-cron.yaml b/.github/workflows/integration-cilium-cron.yaml index 2d286705b1..2169ca6862 100644 --- a/.github/workflows/integration-cilium-cron.yaml +++ b/.github/workflows/integration-cilium-cron.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-11-28T13:53:18Z by kres 232fe63. +# Generated on 2024-12-04T11:25:05Z by kres 232fe63. name: integration-cilium-cron concurrency: @@ -82,7 +82,6 @@ jobs: env: GITHUB_STEP_NAME: ${{ github.job}}-e2e-cilium IMAGE_REGISTRY: registry.dev.siderolabs.io - QEMU_WORKERS: "2" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH: '@hack/test/patches/cilium-no-kubeproxy.yaml' WITH_CUSTOM_CNI: cilium @@ -95,7 +94,6 @@ jobs: CILIUM_INSTALL_TYPE: strict GITHUB_STEP_NAME: ${{ github.job}}-e2e-cilium-strict IMAGE_REGISTRY: registry.dev.siderolabs.io - QEMU_WORKERS: "2" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH: '@hack/test/patches/cilium-kubeproxy.yaml' WITH_CUSTOM_CNI: cilium @@ -108,7 +106,6 @@ jobs: CILIUM_INSTALL_TYPE: strict GITHUB_STEP_NAME: ${{ github.job}}-e2e-cilium-strict-kubespan IMAGE_REGISTRY: registry.dev.siderolabs.io - QEMU_WORKERS: "2" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH: '@hack/test/patches/cilium-kubeproxy.yaml' WITH_CUSTOM_CNI: cilium diff --git a/.github/workflows/integration-conformance-cron.yaml b/.github/workflows/integration-conformance-cron.yaml index 9a9d4a4b6f..0f5922eaee 100644 --- a/.github/workflows/integration-conformance-cron.yaml +++ b/.github/workflows/integration-conformance-cron.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-11-28T13:48:17Z by kres 232fe63. +# Generated on 2024-12-04T11:25:05Z by kres 232fe63. name: integration-conformance-cron concurrency: @@ -83,7 +83,6 @@ jobs: GITHUB_STEP_NAME: ${{ github.job}}-conformance-qemu IMAGE_REGISTRY: registry.dev.siderolabs.io QEMU_CPUS: "4" - QEMU_WORKERS: "2" TEST_MODE: fast-conformance run: | sudo -E make e2e-qemu diff --git a/.github/workflows/integration-extensions-cron.yaml b/.github/workflows/integration-extensions-cron.yaml index 43f3529b2e..15b871f42d 100644 --- a/.github/workflows/integration-extensions-cron.yaml +++ b/.github/workflows/integration-extensions-cron.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-11-28T13:53:18Z by kres 232fe63. +# Generated on 2024-12-04T12:34:25Z by kres 232fe63. name: integration-extensions-cron concurrency: @@ -113,6 +113,7 @@ jobs: IMAGE_REGISTRY: registry.dev.siderolabs.io QEMU_EXTRA_DISKS: "3" QEMU_MEMORY_WORKERS: "4096" + QEMU_WORKERS: "1" SHORT_INTEGRATION_TEST: "yes" WITH_CONFIG_PATCH_WORKER: '@_out/installer-extensions-patch.yaml:@hack/test/patches/extensions.yaml:@hack/test/patches/dm-raid-module.yaml' run: | diff --git a/.kres.yaml b/.kres.yaml index 3e82eebbfc..be179ba066 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -385,7 +385,6 @@ spec: withSudo: true environment: GITHUB_STEP_NAME: ${{ github.job}}-conformance-qemu - QEMU_WORKERS: 2 QEMU_CPUS: 4 TEST_MODE: fast-conformance IMAGE_REGISTRY: registry.dev.siderolabs.io @@ -1054,6 +1053,7 @@ spec: withSudo: true environment: GITHUB_STEP_NAME: ${{ github.job}}-e2e-extensions + QEMU_WORKERS: 1 QEMU_MEMORY_WORKERS: 4096 WITH_CONFIG_PATCH_WORKER: "@_out/installer-extensions-patch.yaml:@hack/test/patches/extensions.yaml:@hack/test/patches/dm-raid-module.yaml" QEMU_EXTRA_DISKS: 3 @@ -1113,7 +1113,6 @@ spec: WITH_SKIP_K8S_NODE_READINESS_CHECK: yes WITH_CUSTOM_CNI: cilium WITH_FIREWALL: accept - QEMU_WORKERS: 2 WITH_CONFIG_PATCH: "@hack/test/patches/cilium-no-kubeproxy.yaml" IMAGE_REGISTRY: registry.dev.siderolabs.io - name: e2e-cilium-strict @@ -1125,7 +1124,6 @@ spec: WITH_SKIP_K8S_NODE_READINESS_CHECK: yes WITH_CUSTOM_CNI: cilium WITH_FIREWALL: accept - QEMU_WORKERS: 2 CILIUM_INSTALL_TYPE: strict WITH_CONFIG_PATCH: "@hack/test/patches/cilium-kubeproxy.yaml" IMAGE_REGISTRY: registry.dev.siderolabs.io @@ -1139,7 +1137,6 @@ spec: WITH_CUSTOM_CNI: cilium WITH_FIREWALL: accept WITH_KUBESPAN: true - QEMU_WORKERS: 2 CILIUM_INSTALL_TYPE: strict WITH_CONFIG_PATCH: "@hack/test/patches/cilium-kubeproxy.yaml" IMAGE_REGISTRY: registry.dev.siderolabs.io diff --git a/hack/test/e2e-qemu.sh b/hack/test/e2e-qemu.sh index bed3f2987d..51e6c0aef4 100755 --- a/hack/test/e2e-qemu.sh +++ b/hack/test/e2e-qemu.sh @@ -209,7 +209,7 @@ function create_cluster { --name="${CLUSTER_NAME}" \ --kubernetes-version="${KUBERNETES_VERSION}" \ --controlplanes=3 \ - --workers="${QEMU_WORKERS:-1}" \ + --workers="${QEMU_WORKERS:-2}" \ --disk=15360 \ --extra-disks="${QEMU_EXTRA_DISKS:-0}" \ --extra-disks-size="${QEMU_EXTRA_DISKS_SIZE:-5120}" \ From 1c26aad5642f1726a90ab0f1c65822717d7a8461 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 29 Nov 2024 22:08:04 +0400 Subject: [PATCH 05/14] feat: implement new address sorting algorithm Fixes #9725 See #9749 Signed-off-by: Andrey Smirnov (cherry picked from commit 7d6507189ff9a99b3b05ee9528701b65af4ad147) --- .github/workflows/ci.yaml | 10 +- .../workflows/integration-misc-2-cron.yaml | 10 +- .kres.yaml | 8 + api/resource/definitions/enums/enums.proto | 6 + .../definitions/network/network.proto | 6 + hack/release.toml | 13 + hack/test/patches/node-address-v2.yaml | 3 + .../pkg/controllers/k8s/nodeip_test.go | 22 + .../internal/addressutil/addressutil.go | 67 ++ .../internal/addressutil/addressutil_test.go | 105 ++ .../network/internal/addressutil/compare.go | 89 ++ .../internal/addressutil/compare_test.go | 81 ++ .../pkg/controllers/network/node_address.go | 161 ++- .../network/node_address_sort_algorithm.go | 82 ++ .../controllers/network/node_address_test.go | 268 +++-- .../pkg/runtime/v1alpha1/v1alpha1_runtime.go | 2 + .../runtime/v1alpha2/v1alpha2_controller.go | 1 + .../pkg/runtime/v1alpha2/v1alpha2_state.go | 1 + .../resource/definitions/enums/enums.pb.go | 348 +++--- .../definitions/network/network.pb.go | 1007 +++++++++-------- .../definitions/network/network_vtproto.pb.go | 148 +++ pkg/machinery/config/config/machine.go | 2 + .../config/schemas/config.schema.json | 7 + .../types/v1alpha1/v1alpha1_features.go | 15 + .../config/types/v1alpha1/v1alpha1_types.go | 6 + .../types/v1alpha1/v1alpha1_types_doc.go | 7 + .../types/v1alpha1/v1alpha1_validation.go | 6 + .../v1alpha1/v1alpha1_validation_test.go | 24 + .../nethelpers/addresssortalgorithm.go | 16 + .../nethelpers/arpalltargets_enumer.go | 84 +- pkg/machinery/nethelpers/nethelpers.go | 2 +- .../resources/network/address_spec.go | 2 +- .../resources/network/deep_copy.generated.go | 8 +- .../resources/network/network_test.go | 1 + .../resources/network/node_address.go | 8 +- .../network/node_address_sort_algorithm.go | 66 ++ website/content/v1.9/reference/api.md | 30 + .../configuration/v1alpha1/config.md | 1 + .../content/v1.9/schemas/config.schema.json | 7 + .../editing-machine-configuration.md | 1 + 40 files changed, 1911 insertions(+), 820 deletions(-) create mode 100644 hack/test/patches/node-address-v2.yaml create mode 100644 internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil.go create mode 100644 internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil_test.go create mode 100644 internal/app/machined/pkg/controllers/network/internal/addressutil/compare.go create mode 100644 internal/app/machined/pkg/controllers/network/internal/addressutil/compare_test.go create mode 100644 internal/app/machined/pkg/controllers/network/node_address_sort_algorithm.go create mode 100644 pkg/machinery/nethelpers/addresssortalgorithm.go create mode 100644 pkg/machinery/resources/network/node_address_sort_algorithm.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d3a3f06423..9dbef22c77 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-12-04T12:34:25Z by kres 232fe63. +# Generated on 2024-12-04T15:25:22Z by kres 232fe63. name: default concurrency: @@ -2208,6 +2208,14 @@ jobs: WITH_DISK_ENCRYPTION: "true" run: | sudo -E make e2e-qemu + - name: e2e-node-address-v2 + env: + GITHUB_STEP_NAME: ${{ github.job}}-e2e-disk-image + IMAGE_REGISTRY: registry.dev.siderolabs.io + SHORT_INTEGRATION_TEST: "yes" + WITH_CONFIG_PATCH: '@hack/test/patches/node-address-v2.yaml' + run: | + sudo -E make e2e-qemu - name: save artifacts if: always() uses: actions/upload-artifact@v4 diff --git a/.github/workflows/integration-misc-2-cron.yaml b/.github/workflows/integration-misc-2-cron.yaml index 47711487c8..e6ab6a45e4 100644 --- a/.github/workflows/integration-misc-2-cron.yaml +++ b/.github/workflows/integration-misc-2-cron.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-11-28T13:53:18Z by kres 232fe63. +# Generated on 2024-12-04T15:25:22Z by kres 232fe63. name: integration-misc-2-cron concurrency: @@ -110,6 +110,14 @@ jobs: WITH_DISK_ENCRYPTION: "true" run: | sudo -E make e2e-qemu + - name: e2e-node-address-v2 + env: + GITHUB_STEP_NAME: ${{ github.job}}-e2e-disk-image + IMAGE_REGISTRY: registry.dev.siderolabs.io + SHORT_INTEGRATION_TEST: "yes" + WITH_CONFIG_PATCH: '@hack/test/patches/node-address-v2.yaml' + run: | + sudo -E make e2e-qemu - name: save artifacts if: always() uses: actions/upload-artifact@v4 diff --git a/.kres.yaml b/.kres.yaml index be179ba066..9f9308ca4b 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -828,6 +828,14 @@ spec: VIA_MAINTENANCE_MODE: true WITH_DISK_ENCRYPTION: true IMAGE_REGISTRY: registry.dev.siderolabs.io + - name: e2e-node-address-v2 + command: e2e-qemu + withSudo: true + environment: + GITHUB_STEP_NAME: ${{ github.job}}-e2e-disk-image + SHORT_INTEGRATION_TEST: yes + WITH_CONFIG_PATCH: "@hack/test/patches/node-address-v2.yaml" + IMAGE_REGISTRY: registry.dev.siderolabs.io - name: save-talos-logs conditions: - always diff --git a/api/resource/definitions/enums/enums.proto b/api/resource/definitions/enums/enums.proto index 90287b97f1..8d5658ddde 100755 --- a/api/resource/definitions/enums/enums.proto +++ b/api/resource/definitions/enums/enums.proto @@ -37,6 +37,12 @@ enum NethelpersAddressFlag { ADDRESS_STABLE_PRIVACY = 2048; } +// NethelpersAddressSortAlgorithm is an internal address sorting algorithm. +enum NethelpersAddressSortAlgorithm { + ADDRESS_SORT_ALGORITHM_V1 = 0; + ADDRESS_SORT_ALGORITHM_V2 = 1; +} + // NethelpersADSelect is ADSelect. enum NethelpersADSelect { AD_SELECT_STABLE = 0; diff --git a/api/resource/definitions/network/network.proto b/api/resource/definitions/network/network.proto index 270b7f017f..9d8d3a3c36 100755 --- a/api/resource/definitions/network/network.proto +++ b/api/resource/definitions/network/network.proto @@ -274,9 +274,15 @@ message NodeAddressFilterSpec { repeated common.NetIPPrefix exclude_subnets = 2; } +// NodeAddressSortAlgorithmSpec describes a filter for NodeAddresses. +message NodeAddressSortAlgorithmSpec { + talos.resource.definitions.enums.NethelpersAddressSortAlgorithm algorithm = 1; +} + // NodeAddressSpec describes a set of node addresses. message NodeAddressSpec { repeated common.NetIPPrefix addresses = 1; + talos.resource.definitions.enums.NethelpersAddressSortAlgorithm sort_algorithm = 2; } // OperatorSpecSpec describes DNS resolvers. diff --git a/hack/release.toml b/hack/release.toml index 0e05bc23f6..e4c24705f8 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -163,6 +163,19 @@ options ndots:5 Talos now supports providing a local [Image Cache](https://www.talos.dev/v1.9/talos-guides/configuration/image-cache/) for container images. """ + [notes.node-address-sort] + title = "Node Address Sort" + description = """\ +Talos supports new experimental address sort algorithm for `NodeAddress` which are used to pick up default addresses for kubelet, etcd, etc. + +It can be enabled with the following config patch: + +```yaml +machine: + features: + nodeAddressSortAlgorithm: v2 +""" + [make_deps] [make_deps.tools] diff --git a/hack/test/patches/node-address-v2.yaml b/hack/test/patches/node-address-v2.yaml new file mode 100644 index 0000000000..f6ca9c72d6 --- /dev/null +++ b/hack/test/patches/node-address-v2.yaml @@ -0,0 +1,3 @@ +machine: + features: + nodeAddressSortAlgorithm: v2 diff --git a/internal/app/machined/pkg/controllers/k8s/nodeip_test.go b/internal/app/machined/pkg/controllers/k8s/nodeip_test.go index 2c412aae32..522787c25a 100644 --- a/internal/app/machined/pkg/controllers/k8s/nodeip_test.go +++ b/internal/app/machined/pkg/controllers/k8s/nodeip_test.go @@ -99,6 +99,28 @@ func (suite *NodeIPSuite) TestReconcileNoMatch() { }) } +func (suite *NodeIPSuite) TestReconcileIPv6Denies() { + cfg := k8s.NewNodeIPConfig(k8s.NamespaceName, k8s.KubeletID) + cfg.TypedSpec().ValidSubnets = []string{"::/0", "!fd01:cafe::f14c:9fa1:8496:557f/128"} + suite.Require().NoError(suite.State().Create(suite.Ctx(), cfg)) + + addresses := network.NewNodeAddress( + network.NamespaceName, + network.FilteredNodeAddressID(network.NodeAddressRoutedID, k8s.NodeAddressFilterNoK8s), + ) + + addresses.TypedSpec().Addresses = []netip.Prefix{ + netip.MustParsePrefix("fd01:cafe::f14c:9fa1:8496:557f/128"), + netip.MustParsePrefix("fd01:cafe::5054:ff:fe1f:c7bd/64"), + } + + suite.Require().NoError(suite.State().Create(suite.Ctx(), addresses)) + + rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{k8s.KubeletID}, func(nodeIP *k8s.NodeIP, asrt *assert.Assertions) { + asrt.Equal("[fd01:cafe::5054:ff:fe1f:c7bd]", fmt.Sprintf("%s", nodeIP.TypedSpec().Addresses)) + }) +} + func TestNodeIPSuite(t *testing.T) { t.Parallel() diff --git a/internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil.go b/internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil.go new file mode 100644 index 0000000000..92784c3488 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil.go @@ -0,0 +1,67 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package addressutil contains helpers working with addresses. +package addressutil + +import "net/netip" + +// DeduplicateIPPrefixes removes duplicates from the given list of prefixes. +// +// The input list must be sorted. +// DeduplicateIPPrefixes performs in-place deduplication. +func DeduplicateIPPrefixes(in []netip.Prefix) []netip.Prefix { + // assumes that current is sorted + n := 0 + + var prev netip.Prefix + + for _, x := range in { + if prev != x { + in[n] = x + n++ + } + + prev = x + } + + return in[:n] +} + +// FilterIPs filters the given list of IP prefixes based on the given include and exclude subnets. +// +// If includeSubnets is not empty, only IPs that are in one of the subnets are included. +// If excludeSubnets is not empty, IPs that are in one of the subnets are excluded. +func FilterIPs(addrs []netip.Prefix, includeSubnets, excludeSubnets []netip.Prefix) []netip.Prefix { + result := make([]netip.Prefix, 0, len(addrs)) + +outer: + for _, ip := range addrs { + if len(includeSubnets) > 0 { + matchesAny := false + + for _, subnet := range includeSubnets { + if subnet.Contains(ip.Addr()) { + matchesAny = true + + break + } + } + + if !matchesAny { + continue outer + } + } + + for _, subnet := range excludeSubnets { + if subnet.Contains(ip.Addr()) { + continue outer + } + } + + result = append(result, ip) + } + + return result +} diff --git a/internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil_test.go b/internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil_test.go new file mode 100644 index 0000000000..70d1a55f92 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/internal/addressutil/addressutil_test.go @@ -0,0 +1,105 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package addressutil_test + +import ( + "net/netip" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network/internal/addressutil" +) + +func TestDeduplicateIPPrefixes(t *testing.T) { + t.Parallel() + + for _, test := range []struct { + name string + in []netip.Prefix + + out []netip.Prefix + }{ + { + name: "empty", + }, + { + name: "single", + in: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("1.2.3.4/32")}, + + out: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32")}, + }, + { + name: "many", + in: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("1.2.3.4/24"), netip.MustParsePrefix("2000::aebc/64"), netip.MustParsePrefix("2000::aebc/64")}, + + out: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("1.2.3.4/24"), netip.MustParsePrefix("2000::aebc/64")}, + }, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + got := addressutil.DeduplicateIPPrefixes(test.in) + + assert.Equal(t, test.out, got) + }) + } +} + +// TestFilterIPs tests the FilterIPs function. +func TestFilterIPs(t *testing.T) { + t.Parallel() + + for _, test := range []struct { + name string + + in []netip.Prefix + include []netip.Prefix + exclude []netip.Prefix + + out []netip.Prefix + }{ + { + name: "empty filters", + + in: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("2000::aebc/64")}, + + out: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("2000::aebc/64")}, + }, + { + name: "v4 only", + + in: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("2000::aebc/64")}, + include: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")}, + + out: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32")}, + }, + { + name: "v6 only", + + in: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("2000::aebc/64")}, + exclude: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")}, + + out: []netip.Prefix{netip.MustParsePrefix("2000::aebc/64")}, + }, + { + name: "include and exclude", + + in: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32"), netip.MustParsePrefix("3.4.5.6/24"), netip.MustParsePrefix("2000::aebc/64")}, + include: []netip.Prefix{netip.MustParsePrefix("0.0.0.0/0")}, + exclude: []netip.Prefix{netip.MustParsePrefix("3.0.0.0/8")}, + + out: []netip.Prefix{netip.MustParsePrefix("1.2.3.4/32")}, + }, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + got := addressutil.FilterIPs(test.in, test.include, test.exclude) + + assert.Equal(t, test.out, got) + }) + } +} diff --git a/internal/app/machined/pkg/controllers/network/internal/addressutil/compare.go b/internal/app/machined/pkg/controllers/network/internal/addressutil/compare.go new file mode 100644 index 0000000000..6482195a25 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/internal/addressutil/compare.go @@ -0,0 +1,89 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package addressutil + +import ( + "cmp" + "fmt" + "net/netip" + + "github.com/siderolabs/talos/pkg/machinery/nethelpers" + "github.com/siderolabs/talos/pkg/machinery/resources/network" +) + +// CompareByAlgorithm returns a comparison function based on the given algorithm. +func CompareByAlgorithm(algorithm nethelpers.AddressSortAlgorithm) func(a, b netip.Prefix) int { + switch algorithm { + case nethelpers.AddressSortAlgorithmV1: + return ComparePrefixesLegacy + case nethelpers.AddressSortAlgorithmV2: + return ComparePrefixNew + } + + panic(fmt.Sprintf("unknown address sort algorithm: %s", algorithm)) +} + +// ComparePrefixesLegacy is the old way to sort prefixes. +// +// It only compares addresses and does not take prefix length into account. +func ComparePrefixesLegacy(a, b netip.Prefix) int { + if c := a.Addr().Compare(b.Addr()); c != 0 { + return c + } + + // note: this was missing in the previous implementation, but this makes sorting stable + return cmp.Compare(a.Bits(), b.Bits()) +} + +func family(a netip.Prefix) int { + if a.Addr().Is4() { + return 4 + } + + return 6 +} + +// ComparePrefixNew compares two prefixes by address family, address, and prefix length. +// +// It prefers more specific prefixes. +func ComparePrefixNew(a, b netip.Prefix) int { + // (1): first, compare address families + if c := cmp.Compare(family(a), family(b)); c != 0 { + return c + } + + // (2): if addresses are equal, Contains will report that one prefix contains the other, so compare prefix lengths + if a.Addr() == b.Addr() { + return -cmp.Compare(a.Bits(), b.Bits()) + } + + // (3): if one prefix contains another, the more specific one should come first + // but if both prefixes contain each other, proceed to compare addresses + aContainsB := a.Contains(b.Addr()) + bContainsA := b.Contains(a.Addr()) + + switch { + case aContainsB && !bContainsA: + return 1 + case !aContainsB && bContainsA: + return -1 + } + + // (4): compare addresses, they are not equal at this point (see (2)) + return a.Addr().Compare(b.Addr()) +} + +// CompareAddressStatuses compares two address statuses with the prefix comparison func. +// +// The comparison of AddressStatuses sorts by link name and then by address. +func CompareAddressStatuses(comparePrefixes func(a, b netip.Prefix) int) func(a, b *network.AddressStatus) int { + return func(a, b *network.AddressStatus) int { + if c := cmp.Compare(a.TypedSpec().LinkName, b.TypedSpec().LinkName); c != 0 { + return c + } + + return comparePrefixes(a.TypedSpec().Address, b.TypedSpec().Address) + } +} diff --git a/internal/app/machined/pkg/controllers/network/internal/addressutil/compare_test.go b/internal/app/machined/pkg/controllers/network/internal/addressutil/compare_test.go new file mode 100644 index 0000000000..60e4ebc5e0 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/internal/addressutil/compare_test.go @@ -0,0 +1,81 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package addressutil_test + +import ( + "math/rand/v2" + "net/netip" + "slices" + "testing" + + "github.com/siderolabs/gen/xslices" + "github.com/stretchr/testify/assert" + + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network/internal/addressutil" +) + +func toNetip(prefixes ...string) []netip.Prefix { + return xslices.Map(prefixes, netip.MustParsePrefix) +} + +func toString(prefixes []netip.Prefix) []string { + return xslices.Map(prefixes, netip.Prefix.String) +} + +func TestCompare(t *testing.T) { + t.Parallel() + + for _, test := range []struct { + name string + + in []netip.Prefix + + outLegacy []netip.Prefix + outNew []netip.Prefix + }{ + { + name: "ipv4", + + in: toNetip("10.3.4.1/24", "10.3.4.5/24", "10.3.4.5/32", "1.2.3.4/26", "192.168.35.11/24", "192.168.36.10/24"), + + outLegacy: toNetip("1.2.3.4/26", "10.3.4.1/24", "10.3.4.5/24", "10.3.4.5/32", "192.168.35.11/24", "192.168.36.10/24"), + outNew: toNetip("1.2.3.4/26", "10.3.4.5/32", "10.3.4.1/24", "10.3.4.5/24", "192.168.35.11/24", "192.168.36.10/24"), + }, + { + name: "ipv6", + + in: toNetip("2001:db8::1/64", "2001:db8::1/128", "2001:db8::2/64", "2001:db8::2/128", "2001:db8::3/64", "2001:db8::3/128"), + + outLegacy: toNetip("2001:db8::1/64", "2001:db8::1/128", "2001:db8::2/64", "2001:db8::2/128", "2001:db8::3/64", "2001:db8::3/128"), + outNew: toNetip("2001:db8::1/128", "2001:db8::2/128", "2001:db8::3/128", "2001:db8::1/64", "2001:db8::2/64", "2001:db8::3/64"), + }, + { + name: "mixed", + + in: toNetip("fd01:cafe::5054:ff:fe1f:c7bd/64", "fd01:cafe::f14c:9fa1:8496:557f/128", "192.168.3.4/24", "10.5.0.0/16"), + + outLegacy: toNetip("10.5.0.0/16", "192.168.3.4/24", "fd01:cafe::5054:ff:fe1f:c7bd/64", "fd01:cafe::f14c:9fa1:8496:557f/128"), + outNew: toNetip("10.5.0.0/16", "192.168.3.4/24", "fd01:cafe::f14c:9fa1:8496:557f/128", "fd01:cafe::5054:ff:fe1f:c7bd/64"), + }, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + // add more randomness to ensure the sorting is stable + in := slices.Clone(test.in) + rand.Shuffle(len(in), func(i, j int) { in[i], in[j] = in[j], in[i] }) + + legacy := slices.Clone(in) + slices.SortFunc(legacy, addressutil.ComparePrefixesLegacy) + + assert.Equal(t, test.outLegacy, legacy, "expected %q but got %q", toString(test.outLegacy), toString(legacy)) + + newer := slices.Clone(in) + slices.SortFunc(newer, addressutil.ComparePrefixNew) + + assert.Equal(t, test.outNew, newer, "expected %q but got %q", toString(test.outNew), toString(newer)) + }) + } +} diff --git a/internal/app/machined/pkg/controllers/network/node_address.go b/internal/app/machined/pkg/controllers/network/node_address.go index e4bbe9ed4c..b1950e500b 100644 --- a/internal/app/machined/pkg/controllers/network/node_address.go +++ b/internal/app/machined/pkg/controllers/network/node_address.go @@ -9,14 +9,16 @@ import ( "fmt" "net/netip" "slices" - "sort" "github.com/cosi-project/runtime/pkg/controller" "github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/safe" + "github.com/cosi-project/runtime/pkg/state" "github.com/siderolabs/gen/value" + "github.com/siderolabs/gen/xslices" "go.uber.org/zap" + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network/internal/addressutil" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/network" ) @@ -47,6 +49,11 @@ func (ctrl *NodeAddressController) Inputs() []controller.Input { Type: network.NodeAddressFilterType, Kind: controller.InputWeak, }, + { + Namespace: network.NamespaceName, + Type: network.NodeAddressSortAlgorithmType, + Kind: controller.InputWeak, + }, } } @@ -75,8 +82,21 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime case <-r.EventCh(): } + // get algorithm to use + algoRes, err := safe.ReaderGetByID[*network.NodeAddressSortAlgorithm](ctx, r, network.NodeAddressSortAlgorithmID) + if err != nil { + if state.IsNotFoundError(err) { + // wait for the resource to appear + continue + } + + return fmt.Errorf("error getting sort algorithm: %w", err) + } + + algo := algoRes.TypedSpec().Algorithm + // fetch link and address status resources - links, err := r.List(ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined)) + links, err := safe.ReaderListAll[*network.LinkStatus](ctx, r) if err != nil { return fmt.Errorf("error listing links: %w", err) } @@ -84,9 +104,7 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime // build "link up" lookup table linksUp := make(map[uint32]struct{}) - for _, r := range links.Items { - link := r.(*network.LinkStatus) //nolint:forcetypeassert - + for link := range links.All() { if link.TypedSpec().OperationalState == nethelpers.OperStateUp || link.TypedSpec().OperationalState == nethelpers.OperStateUnknown { // skip physical interfaces without carrier if !link.TypedSpec().Physical() || link.TypedSpec().LinkState { @@ -96,42 +114,51 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime } // fetch list of filters - filters, err := r.List(ctx, resource.NewMetadata(network.NamespaceName, network.NodeAddressFilterType, "", resource.VersionUndefined)) + filters, err := safe.ReaderListAll[*network.NodeAddressFilter](ctx, r) if err != nil { return fmt.Errorf("error listing address filters: %w", err) } - addresses, err := r.List(ctx, resource.NewMetadata(network.NamespaceName, network.AddressStatusType, "", resource.VersionUndefined)) + addressesList, err := safe.ReaderListAll[*network.AddressStatus](ctx, r) if err != nil { return fmt.Errorf("error listing links: %w", err) } - var ( - defaultAddress netip.Prefix - defaultAddrLinkName string - current []netip.Prefix - routed []netip.Prefix - accumulative []netip.Prefix - ) + addresses := safe.ToSlice(addressesList, func(a *network.AddressStatus) *network.AddressStatus { return a }) - for _, r := range addresses.Items { - addr := r.(*network.AddressStatus) //nolint:forcetypeassert + compareFunc := addressutil.CompareByAlgorithm(algo) + // filter out addresses which should be ignored + addresses = xslices.FilterInPlace(addresses, func(addr *network.AddressStatus) bool { if addr.TypedSpec().Scope >= nethelpers.ScopeLink { - continue + return false } ip := addr.TypedSpec().Address if ip.Addr().IsLoopback() || ip.Addr().IsMulticast() || ip.Addr().IsLinkLocalUnicast() { - continue + return false } + return true + }) + + slices.SortFunc(addresses, addressutil.CompareAddressStatuses(compareFunc)) + + var ( + defaultAddress netip.Prefix + current []netip.Prefix + routed []netip.Prefix + accumulative []netip.Prefix + ) + + for _, addr := range addresses { + ip := addr.TypedSpec().Address + // set defaultAddress to the smallest IP from the alphabetically first link if addr.Metadata().Owner() == addressStatusControllerName { - if value.IsZero(defaultAddress) || addr.TypedSpec().LinkName < defaultAddrLinkName || (addr.TypedSpec().LinkName == defaultAddrLinkName && ip.Addr().Compare(defaultAddress.Addr()) < 0) { + if value.IsZero(defaultAddress) { defaultAddress = ip - defaultAddrLinkName = addr.TypedSpec().LinkName } } @@ -151,12 +178,12 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime } // sort current addresses - sort.Slice(current, func(i, j int) bool { return current[i].Addr().Compare(current[j].Addr()) < 0 }) - sort.Slice(routed, func(i, j int) bool { return routed[i].Addr().Compare(routed[j].Addr()) < 0 }) + slices.SortFunc(current, compareFunc) + slices.SortFunc(routed, compareFunc) // remove duplicates from current addresses - current = deduplicateIPPrefixes(current) - routed = deduplicateIPPrefixes(routed) + current = addressutil.DeduplicateIPPrefixes(current) + routed = addressutil.DeduplicateIPPrefixes(routed) touchedIDs := make(map[resource.ID]struct{}) @@ -169,11 +196,13 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime // we should start handing default address updates, but for now we're not ready // // at the same time check that recorded default address is still on the host, if it's not => replace it - if len(spec.Addresses) > 0 && slices.ContainsFunc(current, func(addr netip.Prefix) bool { return spec.Addresses[0] == addr }) { + // also replace default address on algorithm change + if spec.SortAlgorithm == algo && len(spec.Addresses) > 0 && slices.ContainsFunc(current, func(addr netip.Prefix) bool { return spec.Addresses[0] == addr }) { return nil } spec.Addresses = []netip.Prefix{defaultAddress} + spec.SortAlgorithm = algo return nil }); err != nil { @@ -183,42 +212,42 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime touchedIDs[network.NodeAddressDefaultID] = struct{}{} } - if err = updateCurrentAddresses(ctx, r, network.NodeAddressCurrentID, current); err != nil { + if err = ctrl.updateCurrentAddresses(ctx, r, network.NodeAddressCurrentID, current, algo); err != nil { return err } touchedIDs[network.NodeAddressCurrentID] = struct{}{} - if err = updateCurrentAddresses(ctx, r, network.NodeAddressRoutedID, routed); err != nil { + if err = ctrl.updateCurrentAddresses(ctx, r, network.NodeAddressRoutedID, routed, algo); err != nil { return err } touchedIDs[network.NodeAddressRoutedID] = struct{}{} - if err = updateAccumulativeAddresses(ctx, r, network.NodeAddressAccumulativeID, accumulative); err != nil { + if err = ctrl.updateAccumulativeAddresses(ctx, r, network.NodeAddressAccumulativeID, accumulative, algo); err != nil { return err } touchedIDs[network.NodeAddressAccumulativeID] = struct{}{} // update filtered resources - for _, res := range filters.Items { - filterID := res.Metadata().ID() - filter := res.(*network.NodeAddressFilter).TypedSpec() + for filterRes := range filters.All() { + filterID := filterRes.Metadata().ID() + filter := filterRes.TypedSpec() - filteredCurrent := filterIPs(current, filter.IncludeSubnets, filter.ExcludeSubnets) - filteredRouted := filterIPs(routed, filter.IncludeSubnets, filter.ExcludeSubnets) - filteredAccumulative := filterIPs(accumulative, filter.IncludeSubnets, filter.ExcludeSubnets) + filteredCurrent := addressutil.FilterIPs(current, filter.IncludeSubnets, filter.ExcludeSubnets) + filteredRouted := addressutil.FilterIPs(routed, filter.IncludeSubnets, filter.ExcludeSubnets) + filteredAccumulative := addressutil.FilterIPs(accumulative, filter.IncludeSubnets, filter.ExcludeSubnets) - if err = updateCurrentAddresses(ctx, r, network.FilteredNodeAddressID(network.NodeAddressCurrentID, filterID), filteredCurrent); err != nil { + if err = ctrl.updateCurrentAddresses(ctx, r, network.FilteredNodeAddressID(network.NodeAddressCurrentID, filterID), filteredCurrent, algo); err != nil { return err } - if err = updateCurrentAddresses(ctx, r, network.FilteredNodeAddressID(network.NodeAddressRoutedID, filterID), filteredRouted); err != nil { + if err = ctrl.updateCurrentAddresses(ctx, r, network.FilteredNodeAddressID(network.NodeAddressRoutedID, filterID), filteredRouted, algo); err != nil { return err } - if err = updateAccumulativeAddresses(ctx, r, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filterID), filteredAccumulative); err != nil { + if err = ctrl.updateAccumulativeAddresses(ctx, r, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filterID), filteredAccumulative, algo); err != nil { return err } @@ -249,62 +278,12 @@ func (ctrl *NodeAddressController) Run(ctx context.Context, r controller.Runtime } } -func deduplicateIPPrefixes(current []netip.Prefix) []netip.Prefix { - // assumes that current is sorted - n := 0 - - var prev netip.Prefix - - for _, x := range current { - if prev != x { - current[n] = x - n++ - } - - prev = x - } - - return current[:n] -} - -func filterIPs(addrs []netip.Prefix, includeSubnets, excludeSubnets []netip.Prefix) []netip.Prefix { - result := make([]netip.Prefix, 0, len(addrs)) - -outer: - for _, ip := range addrs { - if len(includeSubnets) > 0 { - matchesAny := false - - for _, subnet := range includeSubnets { - if subnet.Contains(ip.Addr()) { - matchesAny = true - - break - } - } - - if !matchesAny { - continue outer - } - } - - for _, subnet := range excludeSubnets { - if subnet.Contains(ip.Addr()) { - continue outer - } - } - - result = append(result, ip) - } - - return result -} - -func updateCurrentAddresses(ctx context.Context, r controller.Runtime, id resource.ID, current []netip.Prefix) error { +func (ctrl *NodeAddressController) updateCurrentAddresses(ctx context.Context, r controller.Runtime, id resource.ID, current []netip.Prefix, algo nethelpers.AddressSortAlgorithm) error { if err := safe.WriterModify(ctx, r, network.NewNodeAddress(network.NamespaceName, id), func(r *network.NodeAddress) error { spec := r.TypedSpec() spec.Addresses = current + spec.SortAlgorithm = algo return nil }); err != nil { @@ -314,7 +293,7 @@ func updateCurrentAddresses(ctx context.Context, r controller.Runtime, id resour return nil } -func updateAccumulativeAddresses(ctx context.Context, r controller.Runtime, id resource.ID, accumulative []netip.Prefix) error { +func (ctrl *NodeAddressController) updateAccumulativeAddresses(ctx context.Context, r controller.Runtime, id resource.ID, accumulative []netip.Prefix, algo nethelpers.AddressSortAlgorithm) error { if err := safe.WriterModify(ctx, r, network.NewNodeAddress(network.NamespaceName, id), func(r *network.NodeAddress) error { spec := r.TypedSpec() @@ -332,6 +311,8 @@ func updateAccumulativeAddresses(ctx context.Context, r controller.Runtime, id r spec.Addresses = slices.Insert(spec.Addresses, pos, ip) } + spec.SortAlgorithm = algo + return nil }); err != nil { return fmt.Errorf("error updating output resource: %w", err) diff --git a/internal/app/machined/pkg/controllers/network/node_address_sort_algorithm.go b/internal/app/machined/pkg/controllers/network/node_address_sort_algorithm.go new file mode 100644 index 0000000000..0d07ec41a4 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/node_address_sort_algorithm.go @@ -0,0 +1,82 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package network + +import ( + "context" + "fmt" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "github.com/cosi-project/runtime/pkg/state" + "github.com/siderolabs/gen/optional" + "go.uber.org/zap" + + "github.com/siderolabs/talos/pkg/machinery/nethelpers" + "github.com/siderolabs/talos/pkg/machinery/resources/config" + "github.com/siderolabs/talos/pkg/machinery/resources/network" +) + +// NodeAddressSortAlgorithmController manages NodeAddressSortAlgorithm based on configuration. +type NodeAddressSortAlgorithmController struct{} + +// Name implements controller.Controller interface. +func (ctrl *NodeAddressSortAlgorithmController) Name() string { + return "network.NodeAddressSortAlgorithmController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *NodeAddressSortAlgorithmController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: config.NamespaceName, + Type: config.MachineConfigType, + ID: optional.Some(config.V1Alpha1ID), + Kind: controller.InputWeak, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *NodeAddressSortAlgorithmController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: network.NodeAddressSortAlgorithmType, + Kind: controller.OutputExclusive, + }, + } +} + +// Run implements controller.Controller interface. +func (ctrl *NodeAddressSortAlgorithmController) Run(ctx context.Context, r controller.Runtime, _ *zap.Logger) error { + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID) + if err != nil && !state.IsNotFoundError(err) { + return fmt.Errorf("failed to get %s: %w", config.MachineConfigType, err) + } + + algorithm := nethelpers.AddressSortAlgorithmV1 + + if cfg != nil && cfg.Config().Machine() != nil { + algorithm = cfg.Provider().Machine().Features().NodeAddressSortAlgorithm() + } + + if err = safe.WriterModify(ctx, r, network.NewNodeAddressSortAlgorithm(network.NamespaceName, network.NodeAddressSortAlgorithmID), func(res *network.NodeAddressSortAlgorithm) error { + res.TypedSpec().Algorithm = algorithm + + return nil + }); err != nil { + return fmt.Errorf("failed to update %s: %w", network.NodeAddressSortAlgorithmType, err) + } + + r.ResetRestartBackoff() + } +} diff --git a/internal/app/machined/pkg/controllers/network/node_address_test.go b/internal/app/machined/pkg/controllers/network/node_address_test.go index bc0435acb3..7fbea879ae 100644 --- a/internal/app/machined/pkg/controllers/network/node_address_test.go +++ b/internal/app/machined/pkg/controllers/network/node_address_test.go @@ -15,11 +15,13 @@ import ( "github.com/cosi-project/runtime/pkg/resource" "github.com/cosi-project/runtime/pkg/resource/rtestutils" "github.com/cosi-project/runtime/pkg/state" + "github.com/siderolabs/gen/xslices" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest" netctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network" + "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network/internal/addressutil" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/network" runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" @@ -35,6 +37,10 @@ func (suite *NodeAddressSuite) TestDefaults() { deviceStatus.TypedSpec().Ready = true suite.Require().NoError(suite.State().Create(suite.Ctx(), deviceStatus)) + sortAlgorithm := network.NewNodeAddressSortAlgorithm(network.NamespaceName, network.NodeAddressSortAlgorithmID) + sortAlgorithm.TypedSpec().Algorithm = nethelpers.AddressSortAlgorithmV1 + suite.Require().NoError(suite.State().Create(suite.Ctx(), sortAlgorithm)) + suite.Require().NoError(suite.Runtime().RegisterController(&netctrl.AddressStatusController{})) suite.Require().NoError(suite.Runtime().RegisterController(&netctrl.LinkStatusController{})) @@ -53,9 +59,7 @@ func (suite *NodeAddressSuite) TestDefaults() { asrt.True( slices.IsSortedFunc( addrs, - func(a, b netip.Prefix) int { - return a.Addr().Compare(b.Addr()) - }, + addressutil.ComparePrefixesLegacy, ), "addresses %s", addrs, ) @@ -68,13 +72,39 @@ func (suite *NodeAddressSuite) TestDefaults() { ) } -//nolint:gocyclo -func (suite *NodeAddressSuite) TestFilters() { - var ( - addressStatusController netctrl.AddressStatusController - platformConfigController netctrl.PlatformConfigController +func (suite *NodeAddressSuite) newAddress(addr netip.Prefix, link *network.LinkStatus) { + var addressStatusController netctrl.AddressStatusController + + addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID(link.Metadata().ID(), addr)) + addressStatus.TypedSpec().Address = addr + addressStatus.TypedSpec().LinkName = link.Metadata().ID() + addressStatus.TypedSpec().LinkIndex = link.TypedSpec().Index + suite.Require().NoError( + suite.State().Create( + suite.Ctx(), + addressStatus, + state.WithCreateOwner(addressStatusController.Name()), + ), ) +} +func (suite *NodeAddressSuite) newExternalAddress(addr netip.Prefix) { + var platformConfigController netctrl.PlatformConfigController + + addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID("external", addr)) + addressStatus.TypedSpec().Address = addr + addressStatus.TypedSpec().LinkName = "external" + suite.Require().NoError( + suite.State().Create( + suite.Ctx(), + addressStatus, + state.WithCreateOwner(platformConfigController.Name()), + ), + ) +} + +//nolint:gocyclo +func (suite *NodeAddressSuite) TestFilters() { linkUp := network.NewLinkStatus(network.NamespaceName, "eth0") linkUp.TypedSpec().Type = nethelpers.LinkEther linkUp.TypedSpec().LinkState = true @@ -87,32 +117,9 @@ func (suite *NodeAddressSuite) TestFilters() { linkDown.TypedSpec().Index = 2 suite.Require().NoError(suite.State().Create(suite.Ctx(), linkDown)) - newAddress := func(addr netip.Prefix, link *network.LinkStatus) { - addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID(link.Metadata().ID(), addr)) - addressStatus.TypedSpec().Address = addr - addressStatus.TypedSpec().LinkName = link.Metadata().ID() - addressStatus.TypedSpec().LinkIndex = link.TypedSpec().Index - suite.Require().NoError( - suite.State().Create( - suite.Ctx(), - addressStatus, - state.WithCreateOwner(addressStatusController.Name()), - ), - ) - } - - newExternalAddress := func(addr netip.Prefix) { - addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID("external", addr)) - addressStatus.TypedSpec().Address = addr - addressStatus.TypedSpec().LinkName = "external" - suite.Require().NoError( - suite.State().Create( - suite.Ctx(), - addressStatus, - state.WithCreateOwner(platformConfigController.Name()), - ), - ) - } + sortAlgorithm := network.NewNodeAddressSortAlgorithm(network.NamespaceName, network.NodeAddressSortAlgorithmID) + sortAlgorithm.TypedSpec().Algorithm = nethelpers.AddressSortAlgorithmV1 + suite.Require().NoError(suite.State().Create(suite.Ctx(), sortAlgorithm)) for _, addr := range []string{ "10.0.0.1/8", @@ -121,15 +128,15 @@ func (suite *NodeAddressSuite) TestFilters() { "127.0.0.1/8", "fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128", } { - newAddress(netip.MustParsePrefix(addr), linkUp) + suite.newAddress(netip.MustParsePrefix(addr), linkUp) } for _, addr := range []string{"10.0.0.2/8", "192.168.3.7/24"} { - newAddress(netip.MustParsePrefix(addr), linkDown) + suite.newAddress(netip.MustParsePrefix(addr), linkDown) } for _, addr := range []string{"1.2.3.4/32", "25.3.7.9/32"} { // duplicate with link address: 25.3.7.9 - newExternalAddress(netip.MustParsePrefix(addr)) + suite.newExternalAddress(netip.MustParsePrefix(addr)) } filter1 := network.NewNodeAddressFilter(network.NamespaceName, "no-k8s") @@ -161,73 +168,132 @@ func (suite *NodeAddressSuite) TestFilters() { switch r.Metadata().ID() { case network.NodeAddressDefaultID: - asrt.Equal(addrs, ipList("10.0.0.1/8")) + asrt.Equal("10.0.0.1/8", stringifyIPs(addrs)) case network.NodeAddressCurrentID: asrt.Equal( - ipList("1.2.3.4/32 10.0.0.1/8 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128"), - addrs, + "1.2.3.4/32 10.0.0.1/8 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128", + stringifyIPs(addrs), ) case network.NodeAddressRoutedID: asrt.Equal( - ipList("10.0.0.1/8 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64"), - addrs, + "10.0.0.1/8 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64", + stringifyIPs(addrs), ) case network.NodeAddressAccumulativeID: asrt.Equal( - ipList("1.2.3.4/32 10.0.0.1/8 10.0.0.2/8 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128"), - addrs, + "1.2.3.4/32 10.0.0.1/8 10.0.0.2/8 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128", + stringifyIPs(addrs), ) case network.FilteredNodeAddressID(network.NodeAddressCurrentID, filter1.Metadata().ID()): asrt.Equal( - ipList("1.2.3.4/32 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128"), - addrs, + "1.2.3.4/32 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128", + stringifyIPs(addrs), ) case network.FilteredNodeAddressID(network.NodeAddressRoutedID, filter1.Metadata().ID()): asrt.Equal( - ipList("25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64"), - addrs, + "25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64", + stringifyIPs(addrs), ) case network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filter1.Metadata().ID()): asrt.Equal( - ipList("1.2.3.4/32 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128"), - addrs, + "1.2.3.4/32 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64 fdae:41e4:649b:9303:7886:731d:1ce9:4d4/128", + stringifyIPs(addrs), ) case network.FilteredNodeAddressID(network.NodeAddressCurrentID, filter2.Metadata().ID()), network.FilteredNodeAddressID(network.NodeAddressRoutedID, filter2.Metadata().ID()): - asrt.Equal(addrs, ipList("10.0.0.1/8")) + asrt.Equal("10.0.0.1/8", stringifyIPs(addrs)) case network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filter2.Metadata().ID()): - asrt.Equal(addrs, ipList("10.0.0.1/8 10.0.0.2/8 192.168.3.7/24")) + asrt.Equal("10.0.0.1/8 10.0.0.2/8 192.168.3.7/24", stringifyIPs(addrs)) } }, ) } -func (suite *NodeAddressSuite) TestFilterOverlappingSubnets() { +func (suite *NodeAddressSuite) TestSortAlgorithmV2() { linkUp := network.NewLinkStatus(network.NamespaceName, "eth0") linkUp.TypedSpec().Type = nethelpers.LinkEther linkUp.TypedSpec().LinkState = true linkUp.TypedSpec().Index = 1 suite.Require().NoError(suite.State().Create(suite.Ctx(), linkUp)) - newAddress := func(addr netip.Prefix, link *network.LinkStatus) { - addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID(link.Metadata().ID(), addr)) - addressStatus.TypedSpec().Address = addr - addressStatus.TypedSpec().LinkName = link.Metadata().ID() - addressStatus.TypedSpec().LinkIndex = link.TypedSpec().Index - suite.Require().NoError( - suite.State().Create( - suite.Ctx(), - addressStatus, - ), - ) + linkDown := network.NewLinkStatus(network.NamespaceName, "eth1") + linkDown.TypedSpec().Type = nethelpers.LinkEther + linkDown.TypedSpec().LinkState = false + linkDown.TypedSpec().Index = 2 + suite.Require().NoError(suite.State().Create(suite.Ctx(), linkDown)) + + sortAlgorithm := network.NewNodeAddressSortAlgorithm(network.NamespaceName, network.NodeAddressSortAlgorithmID) + sortAlgorithm.TypedSpec().Algorithm = nethelpers.AddressSortAlgorithmV2 + suite.Require().NoError(suite.State().Create(suite.Ctx(), sortAlgorithm)) + + for _, addr := range []string{ + "10.3.4.1/24", + "10.3.4.5/24", + "10.3.4.5/32", + "1.2.3.4/26", + "192.168.35.11/24", + "192.168.36.10/24", + "127.0.0.1/8", + "::1/128", + "fd01:cafe::5054:ff:fe1f:c7bd/64", + "fd01:cafe::f14c:9fa1:8496:557f/128", + } { + suite.newAddress(netip.MustParsePrefix(addr), linkUp) + } + + for _, addr := range []string{"10.0.0.2/8", "192.168.3.7/24"} { + suite.newAddress(netip.MustParsePrefix(addr), linkDown) + } + + for _, addr := range []string{"1.2.3.4/26"} { // duplicate with link address: 1.2.3.4 + suite.newExternalAddress(netip.MustParsePrefix(addr)) } + rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), + []resource.ID{ + network.NodeAddressDefaultID, + network.NodeAddressCurrentID, + network.NodeAddressRoutedID, + network.NodeAddressAccumulativeID, + }, + func(r *network.NodeAddress, asrt *assert.Assertions) { + addrs := r.TypedSpec().Addresses + + switch r.Metadata().ID() { + case network.NodeAddressDefaultID: + asrt.Equal("1.2.3.4/26", stringifyIPs(addrs)) + case network.NodeAddressCurrentID, network.NodeAddressRoutedID: + asrt.Equal( + "1.2.3.4/26 10.3.4.5/32 10.3.4.1/24 10.3.4.5/24 192.168.35.11/24 192.168.36.10/24 fd01:cafe::f14c:9fa1:8496:557f/128 fd01:cafe::5054:ff:fe1f:c7bd/64", + stringifyIPs(addrs), + ) + case network.NodeAddressAccumulativeID: + asrt.Equal( + "1.2.3.4/26 10.0.0.2/8 10.3.4.1/24 10.3.4.5/32 192.168.3.7/24 192.168.35.11/24 192.168.36.10/24 fd01:cafe::5054:ff:fe1f:c7bd/64 fd01:cafe::f14c:9fa1:8496:557f/128", + stringifyIPs(addrs), + ) + } + }, + ) +} + +func (suite *NodeAddressSuite) TestFilterOverlappingSubnets() { + linkUp := network.NewLinkStatus(network.NamespaceName, "eth0") + linkUp.TypedSpec().Type = nethelpers.LinkEther + linkUp.TypedSpec().LinkState = true + linkUp.TypedSpec().Index = 1 + suite.Require().NoError(suite.State().Create(suite.Ctx(), linkUp)) + + sortAlgorithm := network.NewNodeAddressSortAlgorithm(network.NamespaceName, network.NodeAddressSortAlgorithmID) + sortAlgorithm.TypedSpec().Algorithm = nethelpers.AddressSortAlgorithmV1 + suite.Require().NoError(suite.State().Create(suite.Ctx(), sortAlgorithm)) + for _, addr := range []string{ "10.0.0.1/8", "10.96.0.2/32", "25.3.7.9/32", } { - newAddress(netip.MustParsePrefix(addr), linkUp) + suite.newAddress(netip.MustParsePrefix(addr), linkUp) } filter1 := network.NewNodeAddressFilter(network.NamespaceName, "no-k8s") @@ -256,22 +322,22 @@ func (suite *NodeAddressSuite) TestFilterOverlappingSubnets() { switch r.Metadata().ID() { case network.NodeAddressCurrentID, network.NodeAddressRoutedID, network.NodeAddressAccumulativeID: asrt.Equal( - ipList("10.0.0.1/8 10.96.0.2/32 25.3.7.9/32"), - addrs, + "10.0.0.1/8 10.96.0.2/32 25.3.7.9/32", + stringifyIPs(addrs), ) case network.FilteredNodeAddressID(network.NodeAddressCurrentID, filter1.Metadata().ID()), network.FilteredNodeAddressID(network.NodeAddressRoutedID, filter1.Metadata().ID()), network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filter1.Metadata().ID()): asrt.Equal( - ipList("10.0.0.1/8 25.3.7.9/32"), - addrs, + "10.0.0.1/8 25.3.7.9/32", + stringifyIPs(addrs), ) case network.FilteredNodeAddressID(network.NodeAddressCurrentID, filter2.Metadata().ID()), network.FilteredNodeAddressID(network.NodeAddressRoutedID, filter2.Metadata().ID()), network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filter2.Metadata().ID()): asrt.Equal( - ipList("10.96.0.2/32"), - addrs, + "10.96.0.2/32", + stringifyIPs(addrs), ) } }, @@ -288,26 +354,16 @@ func (suite *NodeAddressSuite) TestDefaultAddressChange() { linkUp.TypedSpec().Index = 1 suite.Require().NoError(suite.State().Create(suite.Ctx(), linkUp)) - newAddress := func(addr netip.Prefix, link *network.LinkStatus) { - addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID(link.Metadata().ID(), addr)) - addressStatus.TypedSpec().Address = addr - addressStatus.TypedSpec().LinkName = link.Metadata().ID() - addressStatus.TypedSpec().LinkIndex = link.TypedSpec().Index - suite.Require().NoError( - suite.State().Create( - suite.Ctx(), - addressStatus, - state.WithCreateOwner(addressStatusController.Name()), - ), - ) - } + sortAlgorithm := network.NewNodeAddressSortAlgorithm(network.NamespaceName, network.NodeAddressSortAlgorithmID) + sortAlgorithm.TypedSpec().Algorithm = nethelpers.AddressSortAlgorithmV1 + suite.Require().NoError(suite.State().Create(suite.Ctx(), sortAlgorithm)) for _, addr := range []string{ "10.0.0.5/8", "25.3.7.9/32", "127.0.0.1/8", } { - newAddress(netip.MustParsePrefix(addr), linkUp) + suite.newAddress(netip.MustParsePrefix(addr), linkUp) } rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), @@ -320,23 +376,23 @@ func (suite *NodeAddressSuite) TestDefaultAddressChange() { switch r.Metadata().ID() { case network.NodeAddressDefaultID: - asrt.Equal(addrs, ipList("10.0.0.5/8")) + asrt.Equal("10.0.0.5/8", stringifyIPs(addrs)) case network.NodeAddressCurrentID: asrt.Equal( - addrs, - ipList("10.0.0.5/8 25.3.7.9/32"), + "10.0.0.5/8 25.3.7.9/32", + stringifyIPs(addrs), ) case network.NodeAddressAccumulativeID: asrt.Equal( - addrs, - ipList("10.0.0.5/8 25.3.7.9/32"), + "10.0.0.5/8 25.3.7.9/32", + stringifyIPs(addrs), ) } }, ) // add another address which is "smaller", but default address shouldn't change - newAddress(netip.MustParsePrefix("1.1.1.1/32"), linkUp) + suite.newAddress(netip.MustParsePrefix("1.1.1.1/32"), linkUp) rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{ @@ -348,16 +404,16 @@ func (suite *NodeAddressSuite) TestDefaultAddressChange() { switch r.Metadata().ID() { case network.NodeAddressDefaultID: - asrt.Equal(addrs, ipList("10.0.0.5/8")) + asrt.Equal("10.0.0.5/8", stringifyIPs(addrs)) case network.NodeAddressCurrentID: asrt.Equal( - addrs, - ipList("1.1.1.1/32 10.0.0.5/8 25.3.7.9/32"), + "1.1.1.1/32 10.0.0.5/8 25.3.7.9/32", + stringifyIPs(addrs), ) case network.NodeAddressAccumulativeID: asrt.Equal( - addrs, - ipList("1.1.1.1/32 10.0.0.5/8 25.3.7.9/32"), + "1.1.1.1/32 10.0.0.5/8 25.3.7.9/32", + stringifyIPs(addrs), ) } }, @@ -379,16 +435,16 @@ func (suite *NodeAddressSuite) TestDefaultAddressChange() { switch r.Metadata().ID() { case network.NodeAddressDefaultID: - asrt.Equal(addrs, ipList("1.1.1.1/32")) + asrt.Equal("1.1.1.1/32", stringifyIPs(addrs)) case network.NodeAddressCurrentID: asrt.Equal( - addrs, - ipList("1.1.1.1/32 25.3.7.9/32"), + "1.1.1.1/32 25.3.7.9/32", + stringifyIPs(addrs), ) case network.NodeAddressAccumulativeID: asrt.Equal( - addrs, - ipList("1.1.1.1/32 10.0.0.5/8 25.3.7.9/32"), + "1.1.1.1/32 10.0.0.5/8 25.3.7.9/32", + stringifyIPs(addrs), ) } }, @@ -408,12 +464,6 @@ func TestNodeAddressSuite(t *testing.T) { }) } -func ipList(ips string) []netip.Prefix { - var result []netip.Prefix //nolint:prealloc - - for _, ip := range strings.Split(ips, " ") { - result = append(result, netip.MustParsePrefix(ip)) - } - - return result +func stringifyIPs(ips []netip.Prefix) string { + return strings.Join(xslices.Map(ips, netip.Prefix.String), " ") } diff --git a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go index 1a7ddae5ab..a0e23a72a8 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_runtime.go @@ -137,6 +137,7 @@ func (r *Runtime) CanApplyImmediate(cfg config.Provider) error { // * .machine.features.kubePrism // * .machine.features.hostDNS // * .machine.features.imageCache + // * .machine.features.nodeAddressSortAlgorithm newConfig.ConfigDebug = currentConfig.ConfigDebug newConfig.ClusterConfig = currentConfig.ClusterConfig @@ -165,6 +166,7 @@ func (r *Runtime) CanApplyImmediate(cfg config.Provider) error { newConfig.MachineConfig.MachineFeatures.KubePrismSupport = currentConfig.MachineConfig.MachineFeatures.KubePrismSupport newConfig.MachineConfig.MachineFeatures.HostDNSSupport = currentConfig.MachineConfig.MachineFeatures.HostDNSSupport newConfig.MachineConfig.MachineFeatures.ImageCacheSupport = currentConfig.MachineConfig.MachineFeatures.ImageCacheSupport + newConfig.MachineConfig.MachineFeatures.FeatureNodeAddressSortAlgorithm = currentConfig.MachineConfig.MachineFeatures.FeatureNodeAddressSortAlgorithm } } diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go index c910de37f8..fa9e01ae07 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go @@ -244,6 +244,7 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error &network.NfTablesChainConfigController{}, &network.NfTablesChainController{}, &network.NodeAddressController{}, + &network.NodeAddressSortAlgorithmController{}, &network.OperatorConfigController{ Cmdline: procfs.ProcCmdline(), }, diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go index 031046fa58..1694530013 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go @@ -175,6 +175,7 @@ func NewState() (*State, error) { &network.NfTablesChain{}, &network.NodeAddress{}, &network.NodeAddressFilter{}, + &network.NodeAddressSortAlgorithm{}, &network.OperatorSpec{}, &network.ProbeSpec{}, &network.ProbeStatus{}, diff --git a/pkg/machinery/api/resource/definitions/enums/enums.pb.go b/pkg/machinery/api/resource/definitions/enums/enums.pb.go index ef8b0faf62..e05c30d8fd 100644 --- a/pkg/machinery/api/resource/definitions/enums/enums.pb.go +++ b/pkg/machinery/api/resource/definitions/enums/enums.pb.go @@ -161,6 +161,53 @@ func (NethelpersAddressFlag) EnumDescriptor() ([]byte, []int) { return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{1} } +// NethelpersAddressSortAlgorithm is an internal address sorting algorithm. +type NethelpersAddressSortAlgorithm int32 + +const ( + NethelpersAddressSortAlgorithm_ADDRESS_SORT_ALGORITHM_V1 NethelpersAddressSortAlgorithm = 0 + NethelpersAddressSortAlgorithm_ADDRESS_SORT_ALGORITHM_V2 NethelpersAddressSortAlgorithm = 1 +) + +// Enum value maps for NethelpersAddressSortAlgorithm. +var ( + NethelpersAddressSortAlgorithm_name = map[int32]string{ + 0: "ADDRESS_SORT_ALGORITHM_V1", + 1: "ADDRESS_SORT_ALGORITHM_V2", + } + NethelpersAddressSortAlgorithm_value = map[string]int32{ + "ADDRESS_SORT_ALGORITHM_V1": 0, + "ADDRESS_SORT_ALGORITHM_V2": 1, + } +) + +func (x NethelpersAddressSortAlgorithm) Enum() *NethelpersAddressSortAlgorithm { + p := new(NethelpersAddressSortAlgorithm) + *p = x + return p +} + +func (x NethelpersAddressSortAlgorithm) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NethelpersAddressSortAlgorithm) Descriptor() protoreflect.EnumDescriptor { + return file_resource_definitions_enums_enums_proto_enumTypes[2].Descriptor() +} + +func (NethelpersAddressSortAlgorithm) Type() protoreflect.EnumType { + return &file_resource_definitions_enums_enums_proto_enumTypes[2] +} + +func (x NethelpersAddressSortAlgorithm) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NethelpersAddressSortAlgorithm.Descriptor instead. +func (NethelpersAddressSortAlgorithm) EnumDescriptor() ([]byte, []int) { + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{2} +} + // NethelpersADSelect is ADSelect. type NethelpersADSelect int32 @@ -195,11 +242,11 @@ func (x NethelpersADSelect) String() string { } func (NethelpersADSelect) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[2].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[3].Descriptor() } func (NethelpersADSelect) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[2] + return &file_resource_definitions_enums_enums_proto_enumTypes[3] } func (x NethelpersADSelect) Number() protoreflect.EnumNumber { @@ -208,7 +255,7 @@ func (x NethelpersADSelect) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersADSelect.Descriptor instead. func (NethelpersADSelect) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{2} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{3} } // NethelpersARPAllTargets is an ARP targets mode. @@ -242,11 +289,11 @@ func (x NethelpersARPAllTargets) String() string { } func (NethelpersARPAllTargets) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[3].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[4].Descriptor() } func (NethelpersARPAllTargets) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[3] + return &file_resource_definitions_enums_enums_proto_enumTypes[4] } func (x NethelpersARPAllTargets) Number() protoreflect.EnumNumber { @@ -255,7 +302,7 @@ func (x NethelpersARPAllTargets) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersARPAllTargets.Descriptor instead. func (NethelpersARPAllTargets) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{3} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{4} } // NethelpersARPValidate is an ARP Validation mode. @@ -295,11 +342,11 @@ func (x NethelpersARPValidate) String() string { } func (NethelpersARPValidate) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[4].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[5].Descriptor() } func (NethelpersARPValidate) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[4] + return &file_resource_definitions_enums_enums_proto_enumTypes[5] } func (x NethelpersARPValidate) Number() protoreflect.EnumNumber { @@ -308,7 +355,7 @@ func (x NethelpersARPValidate) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersARPValidate.Descriptor instead. func (NethelpersARPValidate) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{4} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{5} } // NethelpersBondMode is a bond mode. @@ -357,11 +404,11 @@ func (x NethelpersBondMode) String() string { } func (NethelpersBondMode) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[5].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[6].Descriptor() } func (NethelpersBondMode) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[5] + return &file_resource_definitions_enums_enums_proto_enumTypes[6] } func (x NethelpersBondMode) Number() protoreflect.EnumNumber { @@ -370,7 +417,7 @@ func (x NethelpersBondMode) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersBondMode.Descriptor instead. func (NethelpersBondMode) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{5} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{6} } // NethelpersBondXmitHashPolicy is a bond hash policy. @@ -413,11 +460,11 @@ func (x NethelpersBondXmitHashPolicy) String() string { } func (NethelpersBondXmitHashPolicy) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[6].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[7].Descriptor() } func (NethelpersBondXmitHashPolicy) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[6] + return &file_resource_definitions_enums_enums_proto_enumTypes[7] } func (x NethelpersBondXmitHashPolicy) Number() protoreflect.EnumNumber { @@ -426,7 +473,7 @@ func (x NethelpersBondXmitHashPolicy) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersBondXmitHashPolicy.Descriptor instead. func (NethelpersBondXmitHashPolicy) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{6} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{7} } // NethelpersConntrackState is a conntrack state. @@ -469,11 +516,11 @@ func (x NethelpersConntrackState) String() string { } func (NethelpersConntrackState) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[7].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[8].Descriptor() } func (NethelpersConntrackState) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[7] + return &file_resource_definitions_enums_enums_proto_enumTypes[8] } func (x NethelpersConntrackState) Number() protoreflect.EnumNumber { @@ -482,7 +529,7 @@ func (x NethelpersConntrackState) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersConntrackState.Descriptor instead. func (NethelpersConntrackState) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{7} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{8} } // NethelpersDuplex wraps ethtool.Duplex for YAML marshaling. @@ -519,11 +566,11 @@ func (x NethelpersDuplex) String() string { } func (NethelpersDuplex) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[8].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[9].Descriptor() } func (NethelpersDuplex) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[8] + return &file_resource_definitions_enums_enums_proto_enumTypes[9] } func (x NethelpersDuplex) Number() protoreflect.EnumNumber { @@ -532,7 +579,7 @@ func (x NethelpersDuplex) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersDuplex.Descriptor instead. func (NethelpersDuplex) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{8} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{9} } // NethelpersFailOverMAC is a MAC failover mode. @@ -569,11 +616,11 @@ func (x NethelpersFailOverMAC) String() string { } func (NethelpersFailOverMAC) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[9].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[10].Descriptor() } func (NethelpersFailOverMAC) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[9] + return &file_resource_definitions_enums_enums_proto_enumTypes[10] } func (x NethelpersFailOverMAC) Number() protoreflect.EnumNumber { @@ -582,7 +629,7 @@ func (x NethelpersFailOverMAC) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersFailOverMAC.Descriptor instead. func (NethelpersFailOverMAC) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{9} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{10} } // NethelpersFamily is a network family. @@ -619,11 +666,11 @@ func (x NethelpersFamily) String() string { } func (NethelpersFamily) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[10].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[11].Descriptor() } func (NethelpersFamily) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[10] + return &file_resource_definitions_enums_enums_proto_enumTypes[11] } func (x NethelpersFamily) Number() protoreflect.EnumNumber { @@ -632,7 +679,7 @@ func (x NethelpersFamily) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersFamily.Descriptor instead. func (NethelpersFamily) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{10} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{11} } // NethelpersLACPRate is a LACP rate. @@ -666,11 +713,11 @@ func (x NethelpersLACPRate) String() string { } func (NethelpersLACPRate) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[11].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[12].Descriptor() } func (NethelpersLACPRate) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[11] + return &file_resource_definitions_enums_enums_proto_enumTypes[12] } func (x NethelpersLACPRate) Number() protoreflect.EnumNumber { @@ -679,7 +726,7 @@ func (x NethelpersLACPRate) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersLACPRate.Descriptor instead. func (NethelpersLACPRate) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{11} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{12} } // NethelpersLinkType is a link type. @@ -938,11 +985,11 @@ func (x NethelpersLinkType) String() string { } func (NethelpersLinkType) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[12].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[13].Descriptor() } func (NethelpersLinkType) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[12] + return &file_resource_definitions_enums_enums_proto_enumTypes[13] } func (x NethelpersLinkType) Number() protoreflect.EnumNumber { @@ -951,7 +998,7 @@ func (x NethelpersLinkType) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersLinkType.Descriptor instead. func (NethelpersLinkType) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{12} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{13} } // NethelpersMatchOperator is a netfilter match operator. @@ -985,11 +1032,11 @@ func (x NethelpersMatchOperator) String() string { } func (NethelpersMatchOperator) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[13].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[14].Descriptor() } func (NethelpersMatchOperator) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[13] + return &file_resource_definitions_enums_enums_proto_enumTypes[14] } func (x NethelpersMatchOperator) Number() protoreflect.EnumNumber { @@ -998,7 +1045,7 @@ func (x NethelpersMatchOperator) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersMatchOperator.Descriptor instead. func (NethelpersMatchOperator) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{13} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{14} } // NethelpersNfTablesChainHook wraps nftables.ChainHook for YAML marshaling. @@ -1041,11 +1088,11 @@ func (x NethelpersNfTablesChainHook) String() string { } func (NethelpersNfTablesChainHook) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[14].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[15].Descriptor() } func (NethelpersNfTablesChainHook) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[14] + return &file_resource_definitions_enums_enums_proto_enumTypes[15] } func (x NethelpersNfTablesChainHook) Number() protoreflect.EnumNumber { @@ -1054,7 +1101,7 @@ func (x NethelpersNfTablesChainHook) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersNfTablesChainHook.Descriptor instead. func (NethelpersNfTablesChainHook) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{14} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{15} } // NethelpersNfTablesChainPriority wraps nftables.ChainPriority for YAML marshaling. @@ -1124,11 +1171,11 @@ func (x NethelpersNfTablesChainPriority) String() string { } func (NethelpersNfTablesChainPriority) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[15].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[16].Descriptor() } func (NethelpersNfTablesChainPriority) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[15] + return &file_resource_definitions_enums_enums_proto_enumTypes[16] } func (x NethelpersNfTablesChainPriority) Number() protoreflect.EnumNumber { @@ -1137,7 +1184,7 @@ func (x NethelpersNfTablesChainPriority) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersNfTablesChainPriority.Descriptor instead. func (NethelpersNfTablesChainPriority) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{15} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{16} } // NethelpersNfTablesVerdict wraps nftables.Verdict for YAML marshaling. @@ -1171,11 +1218,11 @@ func (x NethelpersNfTablesVerdict) String() string { } func (NethelpersNfTablesVerdict) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[16].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[17].Descriptor() } func (NethelpersNfTablesVerdict) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[16] + return &file_resource_definitions_enums_enums_proto_enumTypes[17] } func (x NethelpersNfTablesVerdict) Number() protoreflect.EnumNumber { @@ -1184,7 +1231,7 @@ func (x NethelpersNfTablesVerdict) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersNfTablesVerdict.Descriptor instead. func (NethelpersNfTablesVerdict) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{16} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{17} } // NethelpersOperationalState wraps rtnetlink.OperationalState for YAML marshaling. @@ -1233,11 +1280,11 @@ func (x NethelpersOperationalState) String() string { } func (NethelpersOperationalState) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[17].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[18].Descriptor() } func (NethelpersOperationalState) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[17] + return &file_resource_definitions_enums_enums_proto_enumTypes[18] } func (x NethelpersOperationalState) Number() protoreflect.EnumNumber { @@ -1246,7 +1293,7 @@ func (x NethelpersOperationalState) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersOperationalState.Descriptor instead. func (NethelpersOperationalState) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{17} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{18} } // NethelpersPort wraps ethtool.Port for YAML marshaling. @@ -1298,11 +1345,11 @@ func (x NethelpersPort) String() string { } func (NethelpersPort) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[18].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[19].Descriptor() } func (NethelpersPort) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[18] + return &file_resource_definitions_enums_enums_proto_enumTypes[19] } func (x NethelpersPort) Number() protoreflect.EnumNumber { @@ -1311,7 +1358,7 @@ func (x NethelpersPort) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersPort.Descriptor instead. func (NethelpersPort) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{18} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{19} } // NethelpersPrimaryReselect is an ARP targets mode. @@ -1348,11 +1395,11 @@ func (x NethelpersPrimaryReselect) String() string { } func (NethelpersPrimaryReselect) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[19].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[20].Descriptor() } func (NethelpersPrimaryReselect) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[19] + return &file_resource_definitions_enums_enums_proto_enumTypes[20] } func (x NethelpersPrimaryReselect) Number() protoreflect.EnumNumber { @@ -1361,7 +1408,7 @@ func (x NethelpersPrimaryReselect) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersPrimaryReselect.Descriptor instead. func (NethelpersPrimaryReselect) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{19} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{20} } // NethelpersProtocol is a inet protocol. @@ -1404,11 +1451,11 @@ func (x NethelpersProtocol) String() string { } func (NethelpersProtocol) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[20].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[21].Descriptor() } func (NethelpersProtocol) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[20] + return &file_resource_definitions_enums_enums_proto_enumTypes[21] } func (x NethelpersProtocol) Number() protoreflect.EnumNumber { @@ -1417,7 +1464,7 @@ func (x NethelpersProtocol) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersProtocol.Descriptor instead. func (NethelpersProtocol) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{20} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{21} } // NethelpersRouteFlag wraps RTM_F_* constants. @@ -1472,11 +1519,11 @@ func (x NethelpersRouteFlag) String() string { } func (NethelpersRouteFlag) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[21].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[22].Descriptor() } func (NethelpersRouteFlag) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[21] + return &file_resource_definitions_enums_enums_proto_enumTypes[22] } func (x NethelpersRouteFlag) Number() protoreflect.EnumNumber { @@ -1485,7 +1532,7 @@ func (x NethelpersRouteFlag) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersRouteFlag.Descriptor instead. func (NethelpersRouteFlag) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{21} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{22} } // NethelpersRouteProtocol is a routing protocol. @@ -1579,11 +1626,11 @@ func (x NethelpersRouteProtocol) String() string { } func (NethelpersRouteProtocol) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[22].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[23].Descriptor() } func (NethelpersRouteProtocol) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[22] + return &file_resource_definitions_enums_enums_proto_enumTypes[23] } func (x NethelpersRouteProtocol) Number() protoreflect.EnumNumber { @@ -1592,7 +1639,7 @@ func (x NethelpersRouteProtocol) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersRouteProtocol.Descriptor instead. func (NethelpersRouteProtocol) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{22} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{23} } // NethelpersRouteType is a route type. @@ -1656,11 +1703,11 @@ func (x NethelpersRouteType) String() string { } func (NethelpersRouteType) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[23].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[24].Descriptor() } func (NethelpersRouteType) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[23] + return &file_resource_definitions_enums_enums_proto_enumTypes[24] } func (x NethelpersRouteType) Number() protoreflect.EnumNumber { @@ -1669,7 +1716,7 @@ func (x NethelpersRouteType) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersRouteType.Descriptor instead. func (NethelpersRouteType) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{23} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{24} } // NethelpersRoutingTable is a routing table ID. @@ -1709,11 +1756,11 @@ func (x NethelpersRoutingTable) String() string { } func (NethelpersRoutingTable) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[24].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[25].Descriptor() } func (NethelpersRoutingTable) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[24] + return &file_resource_definitions_enums_enums_proto_enumTypes[25] } func (x NethelpersRoutingTable) Number() protoreflect.EnumNumber { @@ -1722,7 +1769,7 @@ func (x NethelpersRoutingTable) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersRoutingTable.Descriptor instead. func (NethelpersRoutingTable) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{24} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{25} } // NethelpersScope is an address scope. @@ -1765,11 +1812,11 @@ func (x NethelpersScope) String() string { } func (NethelpersScope) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[25].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[26].Descriptor() } func (NethelpersScope) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[25] + return &file_resource_definitions_enums_enums_proto_enumTypes[26] } func (x NethelpersScope) Number() protoreflect.EnumNumber { @@ -1778,7 +1825,7 @@ func (x NethelpersScope) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersScope.Descriptor instead. func (NethelpersScope) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{25} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{26} } // NethelpersVLANProtocol is a VLAN protocol. @@ -1815,11 +1862,11 @@ func (x NethelpersVLANProtocol) String() string { } func (NethelpersVLANProtocol) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[26].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[27].Descriptor() } func (NethelpersVLANProtocol) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[26] + return &file_resource_definitions_enums_enums_proto_enumTypes[27] } func (x NethelpersVLANProtocol) Number() protoreflect.EnumNumber { @@ -1828,7 +1875,7 @@ func (x NethelpersVLANProtocol) Number() protoreflect.EnumNumber { // Deprecated: Use NethelpersVLANProtocol.Descriptor instead. func (NethelpersVLANProtocol) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{26} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{27} } // BlockEncryptionKeyType describes encryption key type. @@ -1868,11 +1915,11 @@ func (x BlockEncryptionKeyType) String() string { } func (BlockEncryptionKeyType) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[27].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[28].Descriptor() } func (BlockEncryptionKeyType) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[27] + return &file_resource_definitions_enums_enums_proto_enumTypes[28] } func (x BlockEncryptionKeyType) Number() protoreflect.EnumNumber { @@ -1881,7 +1928,7 @@ func (x BlockEncryptionKeyType) Number() protoreflect.EnumNumber { // Deprecated: Use BlockEncryptionKeyType.Descriptor instead. func (BlockEncryptionKeyType) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{27} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{28} } // BlockEncryptionProviderType describes encryption provider type. @@ -1915,11 +1962,11 @@ func (x BlockEncryptionProviderType) String() string { } func (BlockEncryptionProviderType) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[28].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[29].Descriptor() } func (BlockEncryptionProviderType) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[28] + return &file_resource_definitions_enums_enums_proto_enumTypes[29] } func (x BlockEncryptionProviderType) Number() protoreflect.EnumNumber { @@ -1928,7 +1975,7 @@ func (x BlockEncryptionProviderType) Number() protoreflect.EnumNumber { // Deprecated: Use BlockEncryptionProviderType.Descriptor instead. func (BlockEncryptionProviderType) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{28} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{29} } // BlockFilesystemType describes filesystem type. @@ -1971,11 +2018,11 @@ func (x BlockFilesystemType) String() string { } func (BlockFilesystemType) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[29].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[30].Descriptor() } func (BlockFilesystemType) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[29] + return &file_resource_definitions_enums_enums_proto_enumTypes[30] } func (x BlockFilesystemType) Number() protoreflect.EnumNumber { @@ -1984,7 +2031,7 @@ func (x BlockFilesystemType) Number() protoreflect.EnumNumber { // Deprecated: Use BlockFilesystemType.Descriptor instead. func (BlockFilesystemType) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{29} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{30} } // BlockVolumePhase describes volume phase. @@ -2036,11 +2083,11 @@ func (x BlockVolumePhase) String() string { } func (BlockVolumePhase) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[30].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[31].Descriptor() } func (BlockVolumePhase) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[30] + return &file_resource_definitions_enums_enums_proto_enumTypes[31] } func (x BlockVolumePhase) Number() protoreflect.EnumNumber { @@ -2049,7 +2096,7 @@ func (x BlockVolumePhase) Number() protoreflect.EnumNumber { // Deprecated: Use BlockVolumePhase.Descriptor instead. func (BlockVolumePhase) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{30} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{31} } // BlockVolumeType describes volume type. @@ -2086,11 +2133,11 @@ func (x BlockVolumeType) String() string { } func (BlockVolumeType) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[31].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[32].Descriptor() } func (BlockVolumeType) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[31] + return &file_resource_definitions_enums_enums_proto_enumTypes[32] } func (x BlockVolumeType) Number() protoreflect.EnumNumber { @@ -2099,7 +2146,7 @@ func (x BlockVolumeType) Number() protoreflect.EnumNumber { // Deprecated: Use BlockVolumeType.Descriptor instead. func (BlockVolumeType) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{31} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{32} } // CriImageCacheStatus describes image cache status type. @@ -2139,11 +2186,11 @@ func (x CriImageCacheStatus) String() string { } func (CriImageCacheStatus) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[32].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[33].Descriptor() } func (CriImageCacheStatus) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[32] + return &file_resource_definitions_enums_enums_proto_enumTypes[33] } func (x CriImageCacheStatus) Number() protoreflect.EnumNumber { @@ -2152,7 +2199,7 @@ func (x CriImageCacheStatus) Number() protoreflect.EnumNumber { // Deprecated: Use CriImageCacheStatus.Descriptor instead. func (CriImageCacheStatus) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{32} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{33} } // CriImageCacheCopyStatus describes image cache copy status type. @@ -2192,11 +2239,11 @@ func (x CriImageCacheCopyStatus) String() string { } func (CriImageCacheCopyStatus) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[33].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[34].Descriptor() } func (CriImageCacheCopyStatus) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[33] + return &file_resource_definitions_enums_enums_proto_enumTypes[34] } func (x CriImageCacheCopyStatus) Number() protoreflect.EnumNumber { @@ -2205,7 +2252,7 @@ func (x CriImageCacheCopyStatus) Number() protoreflect.EnumNumber { // Deprecated: Use CriImageCacheCopyStatus.Descriptor instead. func (CriImageCacheCopyStatus) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{33} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{34} } // KubespanPeerState is KubeSpan peer current state. @@ -2242,11 +2289,11 @@ func (x KubespanPeerState) String() string { } func (KubespanPeerState) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[34].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[35].Descriptor() } func (KubespanPeerState) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[34] + return &file_resource_definitions_enums_enums_proto_enumTypes[35] } func (x KubespanPeerState) Number() protoreflect.EnumNumber { @@ -2255,7 +2302,7 @@ func (x KubespanPeerState) Number() protoreflect.EnumNumber { // Deprecated: Use KubespanPeerState.Descriptor instead. func (KubespanPeerState) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{34} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{35} } // NetworkConfigLayer describes network configuration layers, with lowest priority first. @@ -2298,11 +2345,11 @@ func (x NetworkConfigLayer) String() string { } func (NetworkConfigLayer) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[35].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[36].Descriptor() } func (NetworkConfigLayer) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[35] + return &file_resource_definitions_enums_enums_proto_enumTypes[36] } func (x NetworkConfigLayer) Number() protoreflect.EnumNumber { @@ -2311,7 +2358,7 @@ func (x NetworkConfigLayer) Number() protoreflect.EnumNumber { // Deprecated: Use NetworkConfigLayer.Descriptor instead. func (NetworkConfigLayer) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{35} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{36} } // NetworkOperator enumerates Talos network operators. @@ -2348,11 +2395,11 @@ func (x NetworkOperator) String() string { } func (NetworkOperator) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[36].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[37].Descriptor() } func (NetworkOperator) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[36] + return &file_resource_definitions_enums_enums_proto_enumTypes[37] } func (x NetworkOperator) Number() protoreflect.EnumNumber { @@ -2361,7 +2408,7 @@ func (x NetworkOperator) Number() protoreflect.EnumNumber { // Deprecated: Use NetworkOperator.Descriptor instead. func (NetworkOperator) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{36} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{37} } // RuntimeMachineStage describes the stage of the machine boot/run process. @@ -2416,11 +2463,11 @@ func (x RuntimeMachineStage) String() string { } func (RuntimeMachineStage) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[37].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[38].Descriptor() } func (RuntimeMachineStage) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[37] + return &file_resource_definitions_enums_enums_proto_enumTypes[38] } func (x RuntimeMachineStage) Number() protoreflect.EnumNumber { @@ -2429,7 +2476,7 @@ func (x RuntimeMachineStage) Number() protoreflect.EnumNumber { // Deprecated: Use RuntimeMachineStage.Descriptor instead. func (RuntimeMachineStage) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{37} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{38} } var File_resource_definitions_enums_enums_proto protoreflect.FileDescriptor @@ -2467,7 +2514,13 @@ var file_resource_definitions_enums_enums_proto_rawDesc = []byte{ 0x54, 0x45, 0x10, 0x80, 0x04, 0x12, 0x19, 0x0a, 0x14, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4d, 0x43, 0x5f, 0x41, 0x55, 0x54, 0x4f, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x10, 0x80, 0x08, 0x12, 0x1b, 0x0a, 0x16, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x54, 0x41, 0x42, - 0x4c, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x43, 0x59, 0x10, 0x80, 0x10, 0x2a, 0x58, 0x0a, + 0x4c, 0x45, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x43, 0x59, 0x10, 0x80, 0x10, 0x2a, 0x5e, 0x0a, + 0x1e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x6f, 0x72, 0x74, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, + 0x1d, 0x0a, 0x19, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, + 0x41, 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x56, 0x31, 0x10, 0x00, 0x12, 0x1d, + 0x0a, 0x19, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x53, 0x4f, 0x52, 0x54, 0x5f, 0x41, + 0x4c, 0x47, 0x4f, 0x52, 0x49, 0x54, 0x48, 0x4d, 0x5f, 0x56, 0x32, 0x10, 0x01, 0x2a, 0x58, 0x0a, 0x12, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x41, 0x44, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x14, 0x0a, 0x10, 0x41, 0x44, 0x5f, 0x53, 0x45, 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x41, 0x44, 0x5f, @@ -2920,46 +2973,47 @@ func file_resource_definitions_enums_enums_proto_rawDescGZIP() []byte { return file_resource_definitions_enums_enums_proto_rawDescData } -var file_resource_definitions_enums_enums_proto_enumTypes = make([]protoimpl.EnumInfo, 38) +var file_resource_definitions_enums_enums_proto_enumTypes = make([]protoimpl.EnumInfo, 39) var file_resource_definitions_enums_enums_proto_goTypes = []any{ (MachineType)(0), // 0: talos.resource.definitions.enums.MachineType (NethelpersAddressFlag)(0), // 1: talos.resource.definitions.enums.NethelpersAddressFlag - (NethelpersADSelect)(0), // 2: talos.resource.definitions.enums.NethelpersADSelect - (NethelpersARPAllTargets)(0), // 3: talos.resource.definitions.enums.NethelpersARPAllTargets - (NethelpersARPValidate)(0), // 4: talos.resource.definitions.enums.NethelpersARPValidate - (NethelpersBondMode)(0), // 5: talos.resource.definitions.enums.NethelpersBondMode - (NethelpersBondXmitHashPolicy)(0), // 6: talos.resource.definitions.enums.NethelpersBondXmitHashPolicy - (NethelpersConntrackState)(0), // 7: talos.resource.definitions.enums.NethelpersConntrackState - (NethelpersDuplex)(0), // 8: talos.resource.definitions.enums.NethelpersDuplex - (NethelpersFailOverMAC)(0), // 9: talos.resource.definitions.enums.NethelpersFailOverMAC - (NethelpersFamily)(0), // 10: talos.resource.definitions.enums.NethelpersFamily - (NethelpersLACPRate)(0), // 11: talos.resource.definitions.enums.NethelpersLACPRate - (NethelpersLinkType)(0), // 12: talos.resource.definitions.enums.NethelpersLinkType - (NethelpersMatchOperator)(0), // 13: talos.resource.definitions.enums.NethelpersMatchOperator - (NethelpersNfTablesChainHook)(0), // 14: talos.resource.definitions.enums.NethelpersNfTablesChainHook - (NethelpersNfTablesChainPriority)(0), // 15: talos.resource.definitions.enums.NethelpersNfTablesChainPriority - (NethelpersNfTablesVerdict)(0), // 16: talos.resource.definitions.enums.NethelpersNfTablesVerdict - (NethelpersOperationalState)(0), // 17: talos.resource.definitions.enums.NethelpersOperationalState - (NethelpersPort)(0), // 18: talos.resource.definitions.enums.NethelpersPort - (NethelpersPrimaryReselect)(0), // 19: talos.resource.definitions.enums.NethelpersPrimaryReselect - (NethelpersProtocol)(0), // 20: talos.resource.definitions.enums.NethelpersProtocol - (NethelpersRouteFlag)(0), // 21: talos.resource.definitions.enums.NethelpersRouteFlag - (NethelpersRouteProtocol)(0), // 22: talos.resource.definitions.enums.NethelpersRouteProtocol - (NethelpersRouteType)(0), // 23: talos.resource.definitions.enums.NethelpersRouteType - (NethelpersRoutingTable)(0), // 24: talos.resource.definitions.enums.NethelpersRoutingTable - (NethelpersScope)(0), // 25: talos.resource.definitions.enums.NethelpersScope - (NethelpersVLANProtocol)(0), // 26: talos.resource.definitions.enums.NethelpersVLANProtocol - (BlockEncryptionKeyType)(0), // 27: talos.resource.definitions.enums.BlockEncryptionKeyType - (BlockEncryptionProviderType)(0), // 28: talos.resource.definitions.enums.BlockEncryptionProviderType - (BlockFilesystemType)(0), // 29: talos.resource.definitions.enums.BlockFilesystemType - (BlockVolumePhase)(0), // 30: talos.resource.definitions.enums.BlockVolumePhase - (BlockVolumeType)(0), // 31: talos.resource.definitions.enums.BlockVolumeType - (CriImageCacheStatus)(0), // 32: talos.resource.definitions.enums.CriImageCacheStatus - (CriImageCacheCopyStatus)(0), // 33: talos.resource.definitions.enums.CriImageCacheCopyStatus - (KubespanPeerState)(0), // 34: talos.resource.definitions.enums.KubespanPeerState - (NetworkConfigLayer)(0), // 35: talos.resource.definitions.enums.NetworkConfigLayer - (NetworkOperator)(0), // 36: talos.resource.definitions.enums.NetworkOperator - (RuntimeMachineStage)(0), // 37: talos.resource.definitions.enums.RuntimeMachineStage + (NethelpersAddressSortAlgorithm)(0), // 2: talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + (NethelpersADSelect)(0), // 3: talos.resource.definitions.enums.NethelpersADSelect + (NethelpersARPAllTargets)(0), // 4: talos.resource.definitions.enums.NethelpersARPAllTargets + (NethelpersARPValidate)(0), // 5: talos.resource.definitions.enums.NethelpersARPValidate + (NethelpersBondMode)(0), // 6: talos.resource.definitions.enums.NethelpersBondMode + (NethelpersBondXmitHashPolicy)(0), // 7: talos.resource.definitions.enums.NethelpersBondXmitHashPolicy + (NethelpersConntrackState)(0), // 8: talos.resource.definitions.enums.NethelpersConntrackState + (NethelpersDuplex)(0), // 9: talos.resource.definitions.enums.NethelpersDuplex + (NethelpersFailOverMAC)(0), // 10: talos.resource.definitions.enums.NethelpersFailOverMAC + (NethelpersFamily)(0), // 11: talos.resource.definitions.enums.NethelpersFamily + (NethelpersLACPRate)(0), // 12: talos.resource.definitions.enums.NethelpersLACPRate + (NethelpersLinkType)(0), // 13: talos.resource.definitions.enums.NethelpersLinkType + (NethelpersMatchOperator)(0), // 14: talos.resource.definitions.enums.NethelpersMatchOperator + (NethelpersNfTablesChainHook)(0), // 15: talos.resource.definitions.enums.NethelpersNfTablesChainHook + (NethelpersNfTablesChainPriority)(0), // 16: talos.resource.definitions.enums.NethelpersNfTablesChainPriority + (NethelpersNfTablesVerdict)(0), // 17: talos.resource.definitions.enums.NethelpersNfTablesVerdict + (NethelpersOperationalState)(0), // 18: talos.resource.definitions.enums.NethelpersOperationalState + (NethelpersPort)(0), // 19: talos.resource.definitions.enums.NethelpersPort + (NethelpersPrimaryReselect)(0), // 20: talos.resource.definitions.enums.NethelpersPrimaryReselect + (NethelpersProtocol)(0), // 21: talos.resource.definitions.enums.NethelpersProtocol + (NethelpersRouteFlag)(0), // 22: talos.resource.definitions.enums.NethelpersRouteFlag + (NethelpersRouteProtocol)(0), // 23: talos.resource.definitions.enums.NethelpersRouteProtocol + (NethelpersRouteType)(0), // 24: talos.resource.definitions.enums.NethelpersRouteType + (NethelpersRoutingTable)(0), // 25: talos.resource.definitions.enums.NethelpersRoutingTable + (NethelpersScope)(0), // 26: talos.resource.definitions.enums.NethelpersScope + (NethelpersVLANProtocol)(0), // 27: talos.resource.definitions.enums.NethelpersVLANProtocol + (BlockEncryptionKeyType)(0), // 28: talos.resource.definitions.enums.BlockEncryptionKeyType + (BlockEncryptionProviderType)(0), // 29: talos.resource.definitions.enums.BlockEncryptionProviderType + (BlockFilesystemType)(0), // 30: talos.resource.definitions.enums.BlockFilesystemType + (BlockVolumePhase)(0), // 31: talos.resource.definitions.enums.BlockVolumePhase + (BlockVolumeType)(0), // 32: talos.resource.definitions.enums.BlockVolumeType + (CriImageCacheStatus)(0), // 33: talos.resource.definitions.enums.CriImageCacheStatus + (CriImageCacheCopyStatus)(0), // 34: talos.resource.definitions.enums.CriImageCacheCopyStatus + (KubespanPeerState)(0), // 35: talos.resource.definitions.enums.KubespanPeerState + (NetworkConfigLayer)(0), // 36: talos.resource.definitions.enums.NetworkConfigLayer + (NetworkOperator)(0), // 37: talos.resource.definitions.enums.NetworkOperator + (RuntimeMachineStage)(0), // 38: talos.resource.definitions.enums.RuntimeMachineStage } var file_resource_definitions_enums_enums_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -2979,7 +3033,7 @@ func file_resource_definitions_enums_enums_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_resource_definitions_enums_enums_proto_rawDesc, - NumEnums: 38, + NumEnums: 39, NumMessages: 0, NumExtensions: 0, NumServices: 0, diff --git a/pkg/machinery/api/resource/definitions/network/network.pb.go b/pkg/machinery/api/resource/definitions/network/network.pb.go index ad604161b5..ec97ef12b0 100644 --- a/pkg/machinery/api/resource/definitions/network/network.pb.go +++ b/pkg/machinery/api/resource/definitions/network/network.pb.go @@ -2243,18 +2243,65 @@ func (x *NodeAddressFilterSpec) GetExcludeSubnets() []*common.NetIPPrefix { return nil } +// NodeAddressSortAlgorithmSpec describes a filter for NodeAddresses. +type NodeAddressSortAlgorithmSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Algorithm enums.NethelpersAddressSortAlgorithm `protobuf:"varint,1,opt,name=algorithm,proto3,enum=talos.resource.definitions.enums.NethelpersAddressSortAlgorithm" json:"algorithm,omitempty"` +} + +func (x *NodeAddressSortAlgorithmSpec) Reset() { + *x = NodeAddressSortAlgorithmSpec{} + mi := &file_resource_definitions_network_network_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NodeAddressSortAlgorithmSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeAddressSortAlgorithmSpec) ProtoMessage() {} + +func (x *NodeAddressSortAlgorithmSpec) ProtoReflect() protoreflect.Message { + mi := &file_resource_definitions_network_network_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NodeAddressSortAlgorithmSpec.ProtoReflect.Descriptor instead. +func (*NodeAddressSortAlgorithmSpec) Descriptor() ([]byte, []int) { + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{28} +} + +func (x *NodeAddressSortAlgorithmSpec) GetAlgorithm() enums.NethelpersAddressSortAlgorithm { + if x != nil { + return x.Algorithm + } + return enums.NethelpersAddressSortAlgorithm(0) +} + // NodeAddressSpec describes a set of node addresses. type NodeAddressSpec struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Addresses []*common.NetIPPrefix `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` + Addresses []*common.NetIPPrefix `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` + SortAlgorithm enums.NethelpersAddressSortAlgorithm `protobuf:"varint,2,opt,name=sort_algorithm,json=sortAlgorithm,proto3,enum=talos.resource.definitions.enums.NethelpersAddressSortAlgorithm" json:"sort_algorithm,omitempty"` } func (x *NodeAddressSpec) Reset() { *x = NodeAddressSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[28] + mi := &file_resource_definitions_network_network_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2266,7 +2313,7 @@ func (x *NodeAddressSpec) String() string { func (*NodeAddressSpec) ProtoMessage() {} func (x *NodeAddressSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[28] + mi := &file_resource_definitions_network_network_proto_msgTypes[29] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2279,7 +2326,7 @@ func (x *NodeAddressSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use NodeAddressSpec.ProtoReflect.Descriptor instead. func (*NodeAddressSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{28} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{29} } func (x *NodeAddressSpec) GetAddresses() []*common.NetIPPrefix { @@ -2289,6 +2336,13 @@ func (x *NodeAddressSpec) GetAddresses() []*common.NetIPPrefix { return nil } +func (x *NodeAddressSpec) GetSortAlgorithm() enums.NethelpersAddressSortAlgorithm { + if x != nil { + return x.SortAlgorithm + } + return enums.NethelpersAddressSortAlgorithm(0) +} + // OperatorSpecSpec describes DNS resolvers. type OperatorSpecSpec struct { state protoimpl.MessageState @@ -2306,7 +2360,7 @@ type OperatorSpecSpec struct { func (x *OperatorSpecSpec) Reset() { *x = OperatorSpecSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[29] + mi := &file_resource_definitions_network_network_proto_msgTypes[30] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2318,7 +2372,7 @@ func (x *OperatorSpecSpec) String() string { func (*OperatorSpecSpec) ProtoMessage() {} func (x *OperatorSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[29] + mi := &file_resource_definitions_network_network_proto_msgTypes[30] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2331,7 +2385,7 @@ func (x *OperatorSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use OperatorSpecSpec.ProtoReflect.Descriptor instead. func (*OperatorSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{29} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{30} } func (x *OperatorSpecSpec) GetOperator() enums.NetworkOperator { @@ -2397,7 +2451,7 @@ type PortRange struct { func (x *PortRange) Reset() { *x = PortRange{} - mi := &file_resource_definitions_network_network_proto_msgTypes[30] + mi := &file_resource_definitions_network_network_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2409,7 +2463,7 @@ func (x *PortRange) String() string { func (*PortRange) ProtoMessage() {} func (x *PortRange) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[30] + mi := &file_resource_definitions_network_network_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2422,7 +2476,7 @@ func (x *PortRange) ProtoReflect() protoreflect.Message { // Deprecated: Use PortRange.ProtoReflect.Descriptor instead. func (*PortRange) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{30} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{31} } func (x *PortRange) GetLo() uint32 { @@ -2453,7 +2507,7 @@ type ProbeSpecSpec struct { func (x *ProbeSpecSpec) Reset() { *x = ProbeSpecSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[31] + mi := &file_resource_definitions_network_network_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2465,7 +2519,7 @@ func (x *ProbeSpecSpec) String() string { func (*ProbeSpecSpec) ProtoMessage() {} func (x *ProbeSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[31] + mi := &file_resource_definitions_network_network_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2478,7 +2532,7 @@ func (x *ProbeSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ProbeSpecSpec.ProtoReflect.Descriptor instead. func (*ProbeSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{31} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{32} } func (x *ProbeSpecSpec) GetInterval() *durationpb.Duration { @@ -2521,7 +2575,7 @@ type ProbeStatusSpec struct { func (x *ProbeStatusSpec) Reset() { *x = ProbeStatusSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[32] + mi := &file_resource_definitions_network_network_proto_msgTypes[33] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2533,7 +2587,7 @@ func (x *ProbeStatusSpec) String() string { func (*ProbeStatusSpec) ProtoMessage() {} func (x *ProbeStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[32] + mi := &file_resource_definitions_network_network_proto_msgTypes[33] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2546,7 +2600,7 @@ func (x *ProbeStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ProbeStatusSpec.ProtoReflect.Descriptor instead. func (*ProbeStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{32} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{33} } func (x *ProbeStatusSpec) GetSuccess() bool { @@ -2576,7 +2630,7 @@ type ResolverSpecSpec struct { func (x *ResolverSpecSpec) Reset() { *x = ResolverSpecSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[33] + mi := &file_resource_definitions_network_network_proto_msgTypes[34] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2588,7 +2642,7 @@ func (x *ResolverSpecSpec) String() string { func (*ResolverSpecSpec) ProtoMessage() {} func (x *ResolverSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[33] + mi := &file_resource_definitions_network_network_proto_msgTypes[34] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2601,7 +2655,7 @@ func (x *ResolverSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ResolverSpecSpec.ProtoReflect.Descriptor instead. func (*ResolverSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{33} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{34} } func (x *ResolverSpecSpec) GetDnsServers() []*common.NetIP { @@ -2637,7 +2691,7 @@ type ResolverStatusSpec struct { func (x *ResolverStatusSpec) Reset() { *x = ResolverStatusSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[34] + mi := &file_resource_definitions_network_network_proto_msgTypes[35] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2649,7 +2703,7 @@ func (x *ResolverStatusSpec) String() string { func (*ResolverStatusSpec) ProtoMessage() {} func (x *ResolverStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[34] + mi := &file_resource_definitions_network_network_proto_msgTypes[35] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2662,7 +2716,7 @@ func (x *ResolverStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use ResolverStatusSpec.ProtoReflect.Descriptor instead. func (*ResolverStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{34} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{35} } func (x *ResolverStatusSpec) GetDnsServers() []*common.NetIP { @@ -2702,7 +2756,7 @@ type RouteSpecSpec struct { func (x *RouteSpecSpec) Reset() { *x = RouteSpecSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[35] + mi := &file_resource_definitions_network_network_proto_msgTypes[36] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2714,7 +2768,7 @@ func (x *RouteSpecSpec) String() string { func (*RouteSpecSpec) ProtoMessage() {} func (x *RouteSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[35] + mi := &file_resource_definitions_network_network_proto_msgTypes[36] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2727,7 +2781,7 @@ func (x *RouteSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use RouteSpecSpec.ProtoReflect.Descriptor instead. func (*RouteSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{35} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{36} } func (x *RouteSpecSpec) GetFamily() enums.NethelpersFamily { @@ -2844,7 +2898,7 @@ type RouteStatusSpec struct { func (x *RouteStatusSpec) Reset() { *x = RouteStatusSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[36] + mi := &file_resource_definitions_network_network_proto_msgTypes[37] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2856,7 +2910,7 @@ func (x *RouteStatusSpec) String() string { func (*RouteStatusSpec) ProtoMessage() {} func (x *RouteStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[36] + mi := &file_resource_definitions_network_network_proto_msgTypes[37] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2869,7 +2923,7 @@ func (x *RouteStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use RouteStatusSpec.ProtoReflect.Descriptor instead. func (*RouteStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{36} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{37} } func (x *RouteStatusSpec) GetFamily() enums.NethelpersFamily { @@ -2974,7 +3028,7 @@ type STPSpec struct { func (x *STPSpec) Reset() { *x = STPSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[37] + mi := &file_resource_definitions_network_network_proto_msgTypes[38] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2986,7 +3040,7 @@ func (x *STPSpec) String() string { func (*STPSpec) ProtoMessage() {} func (x *STPSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[37] + mi := &file_resource_definitions_network_network_proto_msgTypes[38] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2999,7 +3053,7 @@ func (x *STPSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use STPSpec.ProtoReflect.Descriptor instead. func (*STPSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{37} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{38} } func (x *STPSpec) GetEnabled() bool { @@ -3023,7 +3077,7 @@ type StatusSpec struct { func (x *StatusSpec) Reset() { *x = StatusSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[38] + mi := &file_resource_definitions_network_network_proto_msgTypes[39] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3035,7 +3089,7 @@ func (x *StatusSpec) String() string { func (*StatusSpec) ProtoMessage() {} func (x *StatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[38] + mi := &file_resource_definitions_network_network_proto_msgTypes[39] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3048,7 +3102,7 @@ func (x *StatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusSpec.ProtoReflect.Descriptor instead. func (*StatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{38} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{39} } func (x *StatusSpec) GetAddressReady() bool { @@ -3091,7 +3145,7 @@ type TCPProbeSpec struct { func (x *TCPProbeSpec) Reset() { *x = TCPProbeSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[39] + mi := &file_resource_definitions_network_network_proto_msgTypes[40] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3103,7 +3157,7 @@ func (x *TCPProbeSpec) String() string { func (*TCPProbeSpec) ProtoMessage() {} func (x *TCPProbeSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[39] + mi := &file_resource_definitions_network_network_proto_msgTypes[40] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3116,7 +3170,7 @@ func (x *TCPProbeSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use TCPProbeSpec.ProtoReflect.Descriptor instead. func (*TCPProbeSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{39} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{40} } func (x *TCPProbeSpec) GetEndpoint() string { @@ -3145,7 +3199,7 @@ type TimeServerSpecSpec struct { func (x *TimeServerSpecSpec) Reset() { *x = TimeServerSpecSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[40] + mi := &file_resource_definitions_network_network_proto_msgTypes[41] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3157,7 +3211,7 @@ func (x *TimeServerSpecSpec) String() string { func (*TimeServerSpecSpec) ProtoMessage() {} func (x *TimeServerSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[40] + mi := &file_resource_definitions_network_network_proto_msgTypes[41] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3170,7 +3224,7 @@ func (x *TimeServerSpecSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use TimeServerSpecSpec.ProtoReflect.Descriptor instead. func (*TimeServerSpecSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{40} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{41} } func (x *TimeServerSpecSpec) GetNtpServers() []string { @@ -3198,7 +3252,7 @@ type TimeServerStatusSpec struct { func (x *TimeServerStatusSpec) Reset() { *x = TimeServerStatusSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[41] + mi := &file_resource_definitions_network_network_proto_msgTypes[42] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3210,7 +3264,7 @@ func (x *TimeServerStatusSpec) String() string { func (*TimeServerStatusSpec) ProtoMessage() {} func (x *TimeServerStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[41] + mi := &file_resource_definitions_network_network_proto_msgTypes[42] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3223,7 +3277,7 @@ func (x *TimeServerStatusSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use TimeServerStatusSpec.ProtoReflect.Descriptor instead. func (*TimeServerStatusSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{41} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{42} } func (x *TimeServerStatusSpec) GetNtpServers() []string { @@ -3246,7 +3300,7 @@ type VIPEquinixMetalSpec struct { func (x *VIPEquinixMetalSpec) Reset() { *x = VIPEquinixMetalSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[42] + mi := &file_resource_definitions_network_network_proto_msgTypes[43] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3258,7 +3312,7 @@ func (x *VIPEquinixMetalSpec) String() string { func (*VIPEquinixMetalSpec) ProtoMessage() {} func (x *VIPEquinixMetalSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[42] + mi := &file_resource_definitions_network_network_proto_msgTypes[43] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3271,7 +3325,7 @@ func (x *VIPEquinixMetalSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use VIPEquinixMetalSpec.ProtoReflect.Descriptor instead. func (*VIPEquinixMetalSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{42} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{43} } func (x *VIPEquinixMetalSpec) GetProjectId() string { @@ -3308,7 +3362,7 @@ type VIPHCloudSpec struct { func (x *VIPHCloudSpec) Reset() { *x = VIPHCloudSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[43] + mi := &file_resource_definitions_network_network_proto_msgTypes[44] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3320,7 +3374,7 @@ func (x *VIPHCloudSpec) String() string { func (*VIPHCloudSpec) ProtoMessage() {} func (x *VIPHCloudSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[43] + mi := &file_resource_definitions_network_network_proto_msgTypes[44] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3333,7 +3387,7 @@ func (x *VIPHCloudSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use VIPHCloudSpec.ProtoReflect.Descriptor instead. func (*VIPHCloudSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{43} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{44} } func (x *VIPHCloudSpec) GetDeviceId() int64 { @@ -3371,7 +3425,7 @@ type VIPOperatorSpec struct { func (x *VIPOperatorSpec) Reset() { *x = VIPOperatorSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[44] + mi := &file_resource_definitions_network_network_proto_msgTypes[45] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3383,7 +3437,7 @@ func (x *VIPOperatorSpec) String() string { func (*VIPOperatorSpec) ProtoMessage() {} func (x *VIPOperatorSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[44] + mi := &file_resource_definitions_network_network_proto_msgTypes[45] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3396,7 +3450,7 @@ func (x *VIPOperatorSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use VIPOperatorSpec.ProtoReflect.Descriptor instead. func (*VIPOperatorSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{44} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{45} } func (x *VIPOperatorSpec) GetIp() *common.NetIP { @@ -3439,7 +3493,7 @@ type VLANSpec struct { func (x *VLANSpec) Reset() { *x = VLANSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[45] + mi := &file_resource_definitions_network_network_proto_msgTypes[46] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3451,7 +3505,7 @@ func (x *VLANSpec) String() string { func (*VLANSpec) ProtoMessage() {} func (x *VLANSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[45] + mi := &file_resource_definitions_network_network_proto_msgTypes[46] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3464,7 +3518,7 @@ func (x *VLANSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use VLANSpec.ProtoReflect.Descriptor instead. func (*VLANSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{45} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{46} } func (x *VLANSpec) GetVid() uint32 { @@ -3496,7 +3550,7 @@ type WireguardPeer struct { func (x *WireguardPeer) Reset() { *x = WireguardPeer{} - mi := &file_resource_definitions_network_network_proto_msgTypes[46] + mi := &file_resource_definitions_network_network_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3508,7 +3562,7 @@ func (x *WireguardPeer) String() string { func (*WireguardPeer) ProtoMessage() {} func (x *WireguardPeer) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[46] + mi := &file_resource_definitions_network_network_proto_msgTypes[47] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3521,7 +3575,7 @@ func (x *WireguardPeer) ProtoReflect() protoreflect.Message { // Deprecated: Use WireguardPeer.ProtoReflect.Descriptor instead. func (*WireguardPeer) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{46} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{47} } func (x *WireguardPeer) GetPublicKey() string { @@ -3574,7 +3628,7 @@ type WireguardSpec struct { func (x *WireguardSpec) Reset() { *x = WireguardSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[47] + mi := &file_resource_definitions_network_network_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3586,7 +3640,7 @@ func (x *WireguardSpec) String() string { func (*WireguardSpec) ProtoMessage() {} func (x *WireguardSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[47] + mi := &file_resource_definitions_network_network_proto_msgTypes[48] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3599,7 +3653,7 @@ func (x *WireguardSpec) ProtoReflect() protoreflect.Message { // Deprecated: Use WireguardSpec.ProtoReflect.Descriptor instead. func (*WireguardSpec) Descriptor() ([]byte, []int) { - return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{47} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{48} } func (x *WireguardSpec) GetPrivateKey() string { @@ -4164,281 +4218,296 @@ var file_resource_definitions_network_network_proto_rawDesc = []byte{ 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x73, 0x22, 0x44, 0x0a, 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x09, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0xd7, 0x03, 0x0a, 0x10, 0x4f, 0x70, 0x65, - 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4d, 0x0a, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, - 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, - 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x69, 0x72, 0x65, 0x5f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x55, 0x70, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, - 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, - 0x50, 0x34, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, - 0x64, 0x68, 0x63, 0x70, 0x34, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, 0x36, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, 0x50, 0x36, 0x4f, - 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x64, 0x68, 0x63, - 0x70, 0x36, 0x12, 0x45, 0x0a, 0x03, 0x76, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x33, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x76, 0x69, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x22, 0x2b, 0x0a, 0x09, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x0e, 0x0a, 0x02, 0x6c, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x6c, 0x6f, 0x12, - 0x0e, 0x0a, 0x02, 0x68, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x68, 0x69, 0x22, - 0x90, 0x02, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x61, 0x69, 0x6c, - 0x75, 0x72, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x10, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x68, 0x72, 0x65, - 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x42, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x54, 0x43, 0x50, 0x50, 0x72, 0x6f, 0x62, 0x65, - 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, - 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc2, - 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, - 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x74, 0x73, 0x22, 0x7e, 0x0a, 0x1c, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x6f, 0x72, 0x74, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x5e, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, + 0x65, 0x72, 0x73, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x6f, 0x72, 0x74, 0x41, 0x6c, + 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, + 0x68, 0x6d, 0x22, 0xad, 0x01, 0x0a, 0x0f, 0x4e, 0x6f, 0x64, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x09, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x67, 0x0a, 0x0e, 0x73, 0x6f, 0x72, + 0x74, 0x5f, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x40, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x6f, 0x72, 0x74, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, + 0x74, 0x68, 0x6d, 0x52, 0x0d, 0x73, 0x6f, 0x72, 0x74, 0x41, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, + 0x68, 0x6d, 0x22, 0xd7, 0x03, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, + 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4d, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, + 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x6f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x5f, 0x75, + 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, + 0x55, 0x70, 0x12, 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, 0x50, 0x34, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x64, 0x68, 0x63, 0x70, 0x34, 0x12, + 0x4b, 0x0a, 0x05, 0x64, 0x68, 0x63, 0x70, 0x36, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, + 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x2e, 0x44, 0x48, 0x43, 0x50, 0x36, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, 0x64, 0x68, 0x63, 0x70, 0x36, 0x12, 0x45, 0x0a, 0x03, + 0x76, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, + 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, + 0x76, 0x69, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, - 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x73, 0x22, 0x6b, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, - 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, - 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, - 0x22, 0xde, 0x05, 0x0a, 0x0d, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x4a, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, - 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, - 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x35, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, - 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, - 0x65, 0x74, 0x49, 0x50, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x07, - 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x07, 0x67, 0x61, - 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, - 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, - 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, - 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, - 0x72, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x49, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, + 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x2b, 0x0a, 0x09, + 0x50, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x6c, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x68, 0x69, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x68, 0x69, 0x22, 0x90, 0x02, 0x0a, 0x0d, 0x50, 0x72, + 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x35, 0x0a, 0x08, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x12, 0x2b, 0x0a, 0x11, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x74, 0x68, + 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x66, + 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, + 0x42, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, - 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, - 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, - 0x55, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, - 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x2e, 0x54, 0x43, 0x50, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, + 0x74, 0x63, 0x70, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, + 0x79, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, + 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x4a, 0x0a, 0x0f, + 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x61, 0x73, + 0x74, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, + 0x61, 0x73, 0x74, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xc2, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, + 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, + 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, + 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x57, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x5f, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x22, 0x6b, 0x0a, + 0x12, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, + 0x70, 0x65, 0x63, 0x12, 0x2e, 0x0a, 0x0b, 0x64, 0x6e, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x64, 0x6e, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x73, 0x22, 0xde, 0x05, 0x0a, 0x0d, 0x52, + 0x6f, 0x75, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4a, 0x0a, 0x06, + 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, - 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, - 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, - 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, - 0x75, 0x22, 0xad, 0x05, 0x0a, 0x0f, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x4a, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, - 0x65, 0x72, 0x73, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, - 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x27, 0x0a, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, - 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x75, 0x74, 0x5f, - 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x22, - 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x47, - 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, - 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, - 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, - 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, - 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, - 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x55, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, - 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, - 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, - 0x75, 0x22, 0x23, 0x0a, 0x07, 0x53, 0x54, 0x50, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, - 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xaf, 0x01, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x6f, 0x73, - 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, - 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x74, 0x63, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, - 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x74, 0x63, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x61, 0x64, 0x79, 0x22, 0x5f, 0x0a, 0x0c, 0x54, 0x43, 0x50, 0x50, - 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, - 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x12, 0x54, 0x69, - 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, - 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x14, 0x54, 0x69, - 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x22, 0x6e, 0x0a, 0x13, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, - 0x78, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, - 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x6f, - 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x22, 0x68, 0x0a, 0x0d, 0x56, 0x49, 0x50, 0x48, 0x43, 0x6c, 0x6f, 0x75, 0x64, - 0x53, 0x70, 0x65, 0x63, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x81, 0x02, - 0x0a, 0x0f, 0x56, 0x49, 0x50, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, - 0x63, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x02, 0x69, 0x70, - 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x72, 0x61, 0x74, 0x75, 0x69, 0x74, 0x6f, 0x75, 0x73, 0x5f, 0x61, - 0x72, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x74, 0x75, 0x69, - 0x74, 0x6f, 0x75, 0x73, 0x41, 0x72, 0x70, 0x12, 0x5c, 0x0a, 0x0d, 0x65, 0x71, 0x75, 0x69, 0x6e, - 0x69, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, + 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x46, 0x61, 0x6d, 0x69, 0x6c, 0x79, + 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x25, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x06, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x12, + 0x22, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, + 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, + 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x4d, 0x65, - 0x74, 0x61, 0x6c, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0c, 0x65, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, - 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x07, 0x68, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, + 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x53, 0x63, 0x6f, 0x70, + 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x48, - 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x70, 0x65, 0x63, 0x52, 0x06, 0x68, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x22, 0x72, 0x0a, 0x08, 0x56, 0x4c, 0x41, 0x4e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x10, 0x0a, - 0x03, 0x76, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x76, 0x69, 0x64, 0x12, - 0x54, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, - 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x56, - 0x4c, 0x41, 0x4e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x84, 0x02, 0x0a, 0x0d, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, - 0x61, 0x72, 0x64, 0x50, 0x65, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x68, 0x61, - 0x72, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, - 0x72, 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x65, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x5d, 0x0a, 0x1d, 0x70, 0x65, 0x72, 0x73, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x70, 0x65, 0x72, 0x73, 0x69, - 0x73, 0x74, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, - 0x64, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, - 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x22, 0xde, 0x01, 0x0a, - 0x0d, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, - 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, - 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1f, - 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, - 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x61, 0x72, 0x6b, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, - 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x47, 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, - 0x72, 0x64, 0x50, 0x65, 0x65, 0x72, 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x42, 0x78, 0x0a, - 0x2a, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, + 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, + 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x55, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, + 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x12, 0x57, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5a, 0x4a, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, - 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, - 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, - 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x22, 0xad, 0x05, 0x0a, 0x0f, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x4a, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x32, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x46, 0x61, 0x6d, + 0x69, 0x6c, 0x79, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x50, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, + 0x50, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x67, 0x61, 0x74, + 0x65, 0x77, 0x61, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x07, 0x67, 0x61, 0x74, 0x65, 0x77, + 0x61, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x75, 0x74, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x4c, + 0x69, 0x6e, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x22, 0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x5f, + 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x6f, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x05, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, + 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, + 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x05, 0x73, 0x63, 0x6f, 0x70, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, + 0x6c, 0x70, 0x65, 0x72, 0x73, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, + 0x65, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x35, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, + 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x52, 0x6f, 0x75, + 0x74, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x66, 0x6c, 0x61, + 0x67, 0x73, 0x12, 0x55, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, + 0x72, 0x73, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x22, 0x23, 0x0a, 0x07, 0x53, + 0x54, 0x50, 0x53, 0x70, 0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x22, 0xaf, 0x01, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, + 0x23, 0x0a, 0x0d, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, + 0x65, 0x61, 0x64, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x52, 0x65, + 0x61, 0x64, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x5f, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x6f, 0x73, + 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x74, + 0x63, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, 0x74, 0x63, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x61, + 0x64, 0x79, 0x22, 0x5f, 0x0a, 0x0c, 0x54, 0x43, 0x50, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x33, + 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x12, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x74, + 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x57, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x34, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, + 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4c, + 0x61, 0x79, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x14, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, + 0x6e, 0x74, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0a, 0x6e, 0x74, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x22, 0x6e, 0x0a, + 0x13, 0x56, 0x49, 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x6c, + 0x53, 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, 0x70, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x68, 0x0a, + 0x0d, 0x56, 0x49, 0x50, 0x48, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1b, + 0x0a, 0x09, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x08, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, + 0x69, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x61, + 0x70, 0x69, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x81, 0x02, 0x0a, 0x0f, 0x56, 0x49, 0x50, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1d, 0x0a, 0x02, 0x69, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x02, 0x69, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x72, + 0x61, 0x74, 0x75, 0x69, 0x74, 0x6f, 0x75, 0x73, 0x5f, 0x61, 0x72, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x67, 0x72, 0x61, 0x74, 0x75, 0x69, 0x74, 0x6f, 0x75, 0x73, 0x41, 0x72, + 0x70, 0x12, 0x5c, 0x0a, 0x0d, 0x65, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, + 0x50, 0x45, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x53, 0x70, 0x65, + 0x63, 0x52, 0x0c, 0x65, 0x71, 0x75, 0x69, 0x6e, 0x69, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x12, + 0x4a, 0x0a, 0x07, 0x68, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x31, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2e, 0x56, 0x49, 0x50, 0x48, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, + 0x70, 0x65, 0x63, 0x52, 0x06, 0x68, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x22, 0x72, 0x0a, 0x08, 0x56, + 0x4c, 0x41, 0x4e, 0x53, 0x70, 0x65, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x76, 0x69, 0x64, 0x12, 0x54, 0x0a, 0x08, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x65, 0x6e, 0x75, 0x6d, 0x73, 0x2e, 0x4e, + 0x65, 0x74, 0x68, 0x65, 0x6c, 0x70, 0x65, 0x72, 0x73, 0x56, 0x4c, 0x41, 0x4e, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, + 0x84, 0x02, 0x0a, 0x0d, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x50, 0x65, 0x65, + 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x6b, 0x65, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x5d, 0x0a, 0x1d, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, + 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x1b, 0x70, 0x65, 0x72, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, 0x4b, + 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x12, 0x34, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, + 0x65, 0x74, 0x49, 0x50, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x22, 0xde, 0x01, 0x0a, 0x0d, 0x57, 0x69, 0x72, 0x65, 0x67, + 0x75, 0x61, 0x72, 0x64, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, + 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x72, + 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x5f, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0c, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6c, 0x6c, 0x4d, 0x61, 0x72, 0x6b, 0x12, 0x47, + 0x0a, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x2e, 0x57, 0x69, 0x72, 0x65, 0x67, 0x75, 0x61, 0x72, 0x64, 0x50, 0x65, 0x65, 0x72, + 0x52, 0x05, 0x70, 0x65, 0x65, 0x72, 0x73, 0x42, 0x78, 0x0a, 0x2a, 0x64, 0x65, 0x76, 0x2e, 0x74, + 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x6e, 0x65, + 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, + 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4453,7 +4522,7 @@ func file_resource_definitions_network_network_proto_rawDescGZIP() []byte { return file_resource_definitions_network_network_proto_rawDescData } -var file_resource_definitions_network_network_proto_msgTypes = make([]protoimpl.MessageInfo, 48) +var file_resource_definitions_network_network_proto_msgTypes = make([]protoimpl.MessageInfo, 49) var file_resource_definitions_network_network_proto_goTypes = []any{ (*AddressSpecSpec)(nil), // 0: talos.resource.definitions.network.AddressSpecSpec (*AddressStatusSpec)(nil), // 1: talos.resource.definitions.network.AddressStatusSpec @@ -4483,112 +4552,114 @@ var file_resource_definitions_network_network_proto_goTypes = []any{ (*NfTablesPortMatch)(nil), // 25: talos.resource.definitions.network.NfTablesPortMatch (*NfTablesRule)(nil), // 26: talos.resource.definitions.network.NfTablesRule (*NodeAddressFilterSpec)(nil), // 27: talos.resource.definitions.network.NodeAddressFilterSpec - (*NodeAddressSpec)(nil), // 28: talos.resource.definitions.network.NodeAddressSpec - (*OperatorSpecSpec)(nil), // 29: talos.resource.definitions.network.OperatorSpecSpec - (*PortRange)(nil), // 30: talos.resource.definitions.network.PortRange - (*ProbeSpecSpec)(nil), // 31: talos.resource.definitions.network.ProbeSpecSpec - (*ProbeStatusSpec)(nil), // 32: talos.resource.definitions.network.ProbeStatusSpec - (*ResolverSpecSpec)(nil), // 33: talos.resource.definitions.network.ResolverSpecSpec - (*ResolverStatusSpec)(nil), // 34: talos.resource.definitions.network.ResolverStatusSpec - (*RouteSpecSpec)(nil), // 35: talos.resource.definitions.network.RouteSpecSpec - (*RouteStatusSpec)(nil), // 36: talos.resource.definitions.network.RouteStatusSpec - (*STPSpec)(nil), // 37: talos.resource.definitions.network.STPSpec - (*StatusSpec)(nil), // 38: talos.resource.definitions.network.StatusSpec - (*TCPProbeSpec)(nil), // 39: talos.resource.definitions.network.TCPProbeSpec - (*TimeServerSpecSpec)(nil), // 40: talos.resource.definitions.network.TimeServerSpecSpec - (*TimeServerStatusSpec)(nil), // 41: talos.resource.definitions.network.TimeServerStatusSpec - (*VIPEquinixMetalSpec)(nil), // 42: talos.resource.definitions.network.VIPEquinixMetalSpec - (*VIPHCloudSpec)(nil), // 43: talos.resource.definitions.network.VIPHCloudSpec - (*VIPOperatorSpec)(nil), // 44: talos.resource.definitions.network.VIPOperatorSpec - (*VLANSpec)(nil), // 45: talos.resource.definitions.network.VLANSpec - (*WireguardPeer)(nil), // 46: talos.resource.definitions.network.WireguardPeer - (*WireguardSpec)(nil), // 47: talos.resource.definitions.network.WireguardSpec - (*common.NetIPPrefix)(nil), // 48: common.NetIPPrefix - (enums.NethelpersFamily)(0), // 49: talos.resource.definitions.enums.NethelpersFamily - (enums.NethelpersScope)(0), // 50: talos.resource.definitions.enums.NethelpersScope - (enums.NetworkConfigLayer)(0), // 51: talos.resource.definitions.enums.NetworkConfigLayer - (*common.NetIP)(nil), // 52: common.NetIP - (enums.NethelpersBondMode)(0), // 53: talos.resource.definitions.enums.NethelpersBondMode - (enums.NethelpersBondXmitHashPolicy)(0), // 54: talos.resource.definitions.enums.NethelpersBondXmitHashPolicy - (enums.NethelpersLACPRate)(0), // 55: talos.resource.definitions.enums.NethelpersLACPRate - (enums.NethelpersARPValidate)(0), // 56: talos.resource.definitions.enums.NethelpersARPValidate - (enums.NethelpersARPAllTargets)(0), // 57: talos.resource.definitions.enums.NethelpersARPAllTargets - (enums.NethelpersPrimaryReselect)(0), // 58: talos.resource.definitions.enums.NethelpersPrimaryReselect - (enums.NethelpersFailOverMAC)(0), // 59: talos.resource.definitions.enums.NethelpersFailOverMAC - (enums.NethelpersADSelect)(0), // 60: talos.resource.definitions.enums.NethelpersADSelect - (*common.NetIPPort)(nil), // 61: common.NetIPPort - (enums.NethelpersLinkType)(0), // 62: talos.resource.definitions.enums.NethelpersLinkType - (enums.NethelpersOperationalState)(0), // 63: talos.resource.definitions.enums.NethelpersOperationalState - (enums.NethelpersPort)(0), // 64: talos.resource.definitions.enums.NethelpersPort - (enums.NethelpersDuplex)(0), // 65: talos.resource.definitions.enums.NethelpersDuplex - (enums.NethelpersNfTablesChainHook)(0), // 66: talos.resource.definitions.enums.NethelpersNfTablesChainHook - (enums.NethelpersNfTablesChainPriority)(0), // 67: talos.resource.definitions.enums.NethelpersNfTablesChainPriority - (enums.NethelpersNfTablesVerdict)(0), // 68: talos.resource.definitions.enums.NethelpersNfTablesVerdict - (enums.NethelpersConntrackState)(0), // 69: talos.resource.definitions.enums.NethelpersConntrackState - (enums.NethelpersMatchOperator)(0), // 70: talos.resource.definitions.enums.NethelpersMatchOperator - (enums.NethelpersProtocol)(0), // 71: talos.resource.definitions.enums.NethelpersProtocol - (enums.NetworkOperator)(0), // 72: talos.resource.definitions.enums.NetworkOperator - (*durationpb.Duration)(nil), // 73: google.protobuf.Duration - (enums.NethelpersRoutingTable)(0), // 74: talos.resource.definitions.enums.NethelpersRoutingTable - (enums.NethelpersRouteType)(0), // 75: talos.resource.definitions.enums.NethelpersRouteType - (enums.NethelpersRouteProtocol)(0), // 76: talos.resource.definitions.enums.NethelpersRouteProtocol - (enums.NethelpersVLANProtocol)(0), // 77: talos.resource.definitions.enums.NethelpersVLANProtocol + (*NodeAddressSortAlgorithmSpec)(nil), // 28: talos.resource.definitions.network.NodeAddressSortAlgorithmSpec + (*NodeAddressSpec)(nil), // 29: talos.resource.definitions.network.NodeAddressSpec + (*OperatorSpecSpec)(nil), // 30: talos.resource.definitions.network.OperatorSpecSpec + (*PortRange)(nil), // 31: talos.resource.definitions.network.PortRange + (*ProbeSpecSpec)(nil), // 32: talos.resource.definitions.network.ProbeSpecSpec + (*ProbeStatusSpec)(nil), // 33: talos.resource.definitions.network.ProbeStatusSpec + (*ResolverSpecSpec)(nil), // 34: talos.resource.definitions.network.ResolverSpecSpec + (*ResolverStatusSpec)(nil), // 35: talos.resource.definitions.network.ResolverStatusSpec + (*RouteSpecSpec)(nil), // 36: talos.resource.definitions.network.RouteSpecSpec + (*RouteStatusSpec)(nil), // 37: talos.resource.definitions.network.RouteStatusSpec + (*STPSpec)(nil), // 38: talos.resource.definitions.network.STPSpec + (*StatusSpec)(nil), // 39: talos.resource.definitions.network.StatusSpec + (*TCPProbeSpec)(nil), // 40: talos.resource.definitions.network.TCPProbeSpec + (*TimeServerSpecSpec)(nil), // 41: talos.resource.definitions.network.TimeServerSpecSpec + (*TimeServerStatusSpec)(nil), // 42: talos.resource.definitions.network.TimeServerStatusSpec + (*VIPEquinixMetalSpec)(nil), // 43: talos.resource.definitions.network.VIPEquinixMetalSpec + (*VIPHCloudSpec)(nil), // 44: talos.resource.definitions.network.VIPHCloudSpec + (*VIPOperatorSpec)(nil), // 45: talos.resource.definitions.network.VIPOperatorSpec + (*VLANSpec)(nil), // 46: talos.resource.definitions.network.VLANSpec + (*WireguardPeer)(nil), // 47: talos.resource.definitions.network.WireguardPeer + (*WireguardSpec)(nil), // 48: talos.resource.definitions.network.WireguardSpec + (*common.NetIPPrefix)(nil), // 49: common.NetIPPrefix + (enums.NethelpersFamily)(0), // 50: talos.resource.definitions.enums.NethelpersFamily + (enums.NethelpersScope)(0), // 51: talos.resource.definitions.enums.NethelpersScope + (enums.NetworkConfigLayer)(0), // 52: talos.resource.definitions.enums.NetworkConfigLayer + (*common.NetIP)(nil), // 53: common.NetIP + (enums.NethelpersBondMode)(0), // 54: talos.resource.definitions.enums.NethelpersBondMode + (enums.NethelpersBondXmitHashPolicy)(0), // 55: talos.resource.definitions.enums.NethelpersBondXmitHashPolicy + (enums.NethelpersLACPRate)(0), // 56: talos.resource.definitions.enums.NethelpersLACPRate + (enums.NethelpersARPValidate)(0), // 57: talos.resource.definitions.enums.NethelpersARPValidate + (enums.NethelpersARPAllTargets)(0), // 58: talos.resource.definitions.enums.NethelpersARPAllTargets + (enums.NethelpersPrimaryReselect)(0), // 59: talos.resource.definitions.enums.NethelpersPrimaryReselect + (enums.NethelpersFailOverMAC)(0), // 60: talos.resource.definitions.enums.NethelpersFailOverMAC + (enums.NethelpersADSelect)(0), // 61: talos.resource.definitions.enums.NethelpersADSelect + (*common.NetIPPort)(nil), // 62: common.NetIPPort + (enums.NethelpersLinkType)(0), // 63: talos.resource.definitions.enums.NethelpersLinkType + (enums.NethelpersOperationalState)(0), // 64: talos.resource.definitions.enums.NethelpersOperationalState + (enums.NethelpersPort)(0), // 65: talos.resource.definitions.enums.NethelpersPort + (enums.NethelpersDuplex)(0), // 66: talos.resource.definitions.enums.NethelpersDuplex + (enums.NethelpersNfTablesChainHook)(0), // 67: talos.resource.definitions.enums.NethelpersNfTablesChainHook + (enums.NethelpersNfTablesChainPriority)(0), // 68: talos.resource.definitions.enums.NethelpersNfTablesChainPriority + (enums.NethelpersNfTablesVerdict)(0), // 69: talos.resource.definitions.enums.NethelpersNfTablesVerdict + (enums.NethelpersConntrackState)(0), // 70: talos.resource.definitions.enums.NethelpersConntrackState + (enums.NethelpersMatchOperator)(0), // 71: talos.resource.definitions.enums.NethelpersMatchOperator + (enums.NethelpersProtocol)(0), // 72: talos.resource.definitions.enums.NethelpersProtocol + (enums.NethelpersAddressSortAlgorithm)(0), // 73: talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + (enums.NetworkOperator)(0), // 74: talos.resource.definitions.enums.NetworkOperator + (*durationpb.Duration)(nil), // 75: google.protobuf.Duration + (enums.NethelpersRoutingTable)(0), // 76: talos.resource.definitions.enums.NethelpersRoutingTable + (enums.NethelpersRouteType)(0), // 77: talos.resource.definitions.enums.NethelpersRouteType + (enums.NethelpersRouteProtocol)(0), // 78: talos.resource.definitions.enums.NethelpersRouteProtocol + (enums.NethelpersVLANProtocol)(0), // 79: talos.resource.definitions.enums.NethelpersVLANProtocol } var file_resource_definitions_network_network_proto_depIdxs = []int32{ - 48, // 0: talos.resource.definitions.network.AddressSpecSpec.address:type_name -> common.NetIPPrefix - 49, // 1: talos.resource.definitions.network.AddressSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 50, // 2: talos.resource.definitions.network.AddressSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 51, // 3: talos.resource.definitions.network.AddressSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 48, // 4: talos.resource.definitions.network.AddressStatusSpec.address:type_name -> common.NetIPPrefix - 52, // 5: talos.resource.definitions.network.AddressStatusSpec.local:type_name -> common.NetIP - 52, // 6: talos.resource.definitions.network.AddressStatusSpec.broadcast:type_name -> common.NetIP - 52, // 7: talos.resource.definitions.network.AddressStatusSpec.anycast:type_name -> common.NetIP - 52, // 8: talos.resource.definitions.network.AddressStatusSpec.multicast:type_name -> common.NetIP - 49, // 9: talos.resource.definitions.network.AddressStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 50, // 10: talos.resource.definitions.network.AddressStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 53, // 11: talos.resource.definitions.network.BondMasterSpec.mode:type_name -> talos.resource.definitions.enums.NethelpersBondMode - 54, // 12: talos.resource.definitions.network.BondMasterSpec.hash_policy:type_name -> talos.resource.definitions.enums.NethelpersBondXmitHashPolicy - 55, // 13: talos.resource.definitions.network.BondMasterSpec.lacp_rate:type_name -> talos.resource.definitions.enums.NethelpersLACPRate - 56, // 14: talos.resource.definitions.network.BondMasterSpec.arp_validate:type_name -> talos.resource.definitions.enums.NethelpersARPValidate - 57, // 15: talos.resource.definitions.network.BondMasterSpec.arp_all_targets:type_name -> talos.resource.definitions.enums.NethelpersARPAllTargets - 58, // 16: talos.resource.definitions.network.BondMasterSpec.primary_reselect:type_name -> talos.resource.definitions.enums.NethelpersPrimaryReselect - 59, // 17: talos.resource.definitions.network.BondMasterSpec.fail_over_mac:type_name -> talos.resource.definitions.enums.NethelpersFailOverMAC - 60, // 18: talos.resource.definitions.network.BondMasterSpec.ad_select:type_name -> talos.resource.definitions.enums.NethelpersADSelect - 37, // 19: talos.resource.definitions.network.BridgeMasterSpec.stp:type_name -> talos.resource.definitions.network.STPSpec + 49, // 0: talos.resource.definitions.network.AddressSpecSpec.address:type_name -> common.NetIPPrefix + 50, // 1: talos.resource.definitions.network.AddressSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 51, // 2: talos.resource.definitions.network.AddressSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 52, // 3: talos.resource.definitions.network.AddressSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 49, // 4: talos.resource.definitions.network.AddressStatusSpec.address:type_name -> common.NetIPPrefix + 53, // 5: talos.resource.definitions.network.AddressStatusSpec.local:type_name -> common.NetIP + 53, // 6: talos.resource.definitions.network.AddressStatusSpec.broadcast:type_name -> common.NetIP + 53, // 7: talos.resource.definitions.network.AddressStatusSpec.anycast:type_name -> common.NetIP + 53, // 8: talos.resource.definitions.network.AddressStatusSpec.multicast:type_name -> common.NetIP + 50, // 9: talos.resource.definitions.network.AddressStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 51, // 10: talos.resource.definitions.network.AddressStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 54, // 11: talos.resource.definitions.network.BondMasterSpec.mode:type_name -> talos.resource.definitions.enums.NethelpersBondMode + 55, // 12: talos.resource.definitions.network.BondMasterSpec.hash_policy:type_name -> talos.resource.definitions.enums.NethelpersBondXmitHashPolicy + 56, // 13: talos.resource.definitions.network.BondMasterSpec.lacp_rate:type_name -> talos.resource.definitions.enums.NethelpersLACPRate + 57, // 14: talos.resource.definitions.network.BondMasterSpec.arp_validate:type_name -> talos.resource.definitions.enums.NethelpersARPValidate + 58, // 15: talos.resource.definitions.network.BondMasterSpec.arp_all_targets:type_name -> talos.resource.definitions.enums.NethelpersARPAllTargets + 59, // 16: talos.resource.definitions.network.BondMasterSpec.primary_reselect:type_name -> talos.resource.definitions.enums.NethelpersPrimaryReselect + 60, // 17: talos.resource.definitions.network.BondMasterSpec.fail_over_mac:type_name -> talos.resource.definitions.enums.NethelpersFailOverMAC + 61, // 18: talos.resource.definitions.network.BondMasterSpec.ad_select:type_name -> talos.resource.definitions.enums.NethelpersADSelect + 38, // 19: talos.resource.definitions.network.BridgeMasterSpec.stp:type_name -> talos.resource.definitions.network.STPSpec 6, // 20: talos.resource.definitions.network.BridgeMasterSpec.vlan:type_name -> talos.resource.definitions.network.BridgeVLANSpec - 61, // 21: talos.resource.definitions.network.HostDNSConfigSpec.listen_addresses:type_name -> common.NetIPPort - 52, // 22: talos.resource.definitions.network.HostDNSConfigSpec.service_host_dns_address:type_name -> common.NetIP - 51, // 23: talos.resource.definitions.network.HostnameSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 24: talos.resource.definitions.network.LinkSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType + 62, // 21: talos.resource.definitions.network.HostDNSConfigSpec.listen_addresses:type_name -> common.NetIPPort + 53, // 22: talos.resource.definitions.network.HostDNSConfigSpec.service_host_dns_address:type_name -> common.NetIP + 52, // 23: talos.resource.definitions.network.HostnameSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 63, // 24: talos.resource.definitions.network.LinkSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType 3, // 25: talos.resource.definitions.network.LinkSpecSpec.bond_slave:type_name -> talos.resource.definitions.network.BondSlave 5, // 26: talos.resource.definitions.network.LinkSpecSpec.bridge_slave:type_name -> talos.resource.definitions.network.BridgeSlave - 45, // 27: talos.resource.definitions.network.LinkSpecSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec + 46, // 27: talos.resource.definitions.network.LinkSpecSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec 2, // 28: talos.resource.definitions.network.LinkSpecSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec 4, // 29: talos.resource.definitions.network.LinkSpecSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec - 47, // 30: talos.resource.definitions.network.LinkSpecSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec - 51, // 31: talos.resource.definitions.network.LinkSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 32: talos.resource.definitions.network.LinkStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType - 63, // 33: talos.resource.definitions.network.LinkStatusSpec.operational_state:type_name -> talos.resource.definitions.enums.NethelpersOperationalState - 64, // 34: talos.resource.definitions.network.LinkStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort - 65, // 35: talos.resource.definitions.network.LinkStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex - 45, // 36: talos.resource.definitions.network.LinkStatusSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec + 48, // 30: talos.resource.definitions.network.LinkSpecSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec + 52, // 31: talos.resource.definitions.network.LinkSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 63, // 32: talos.resource.definitions.network.LinkStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType + 64, // 33: talos.resource.definitions.network.LinkStatusSpec.operational_state:type_name -> talos.resource.definitions.enums.NethelpersOperationalState + 65, // 34: talos.resource.definitions.network.LinkStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort + 66, // 35: talos.resource.definitions.network.LinkStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex + 46, // 36: talos.resource.definitions.network.LinkStatusSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec 4, // 37: talos.resource.definitions.network.LinkStatusSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec 2, // 38: talos.resource.definitions.network.LinkStatusSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec - 47, // 39: talos.resource.definitions.network.LinkStatusSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec - 48, // 40: talos.resource.definitions.network.NfTablesAddressMatch.include_subnets:type_name -> common.NetIPPrefix - 48, // 41: talos.resource.definitions.network.NfTablesAddressMatch.exclude_subnets:type_name -> common.NetIPPrefix - 66, // 42: talos.resource.definitions.network.NfTablesChainSpec.hook:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainHook - 67, // 43: talos.resource.definitions.network.NfTablesChainSpec.priority:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainPriority + 48, // 39: talos.resource.definitions.network.LinkStatusSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec + 49, // 40: talos.resource.definitions.network.NfTablesAddressMatch.include_subnets:type_name -> common.NetIPPrefix + 49, // 41: talos.resource.definitions.network.NfTablesAddressMatch.exclude_subnets:type_name -> common.NetIPPrefix + 67, // 42: talos.resource.definitions.network.NfTablesChainSpec.hook:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainHook + 68, // 43: talos.resource.definitions.network.NfTablesChainSpec.priority:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainPriority 26, // 44: talos.resource.definitions.network.NfTablesChainSpec.rules:type_name -> talos.resource.definitions.network.NfTablesRule - 68, // 45: talos.resource.definitions.network.NfTablesChainSpec.policy:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict - 69, // 46: talos.resource.definitions.network.NfTablesConntrackStateMatch.states:type_name -> talos.resource.definitions.enums.NethelpersConntrackState - 70, // 47: talos.resource.definitions.network.NfTablesIfNameMatch.operator:type_name -> talos.resource.definitions.enums.NethelpersMatchOperator - 71, // 48: talos.resource.definitions.network.NfTablesLayer4Match.protocol:type_name -> talos.resource.definitions.enums.NethelpersProtocol + 69, // 45: talos.resource.definitions.network.NfTablesChainSpec.policy:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict + 70, // 46: talos.resource.definitions.network.NfTablesConntrackStateMatch.states:type_name -> talos.resource.definitions.enums.NethelpersConntrackState + 71, // 47: talos.resource.definitions.network.NfTablesIfNameMatch.operator:type_name -> talos.resource.definitions.enums.NethelpersMatchOperator + 72, // 48: talos.resource.definitions.network.NfTablesLayer4Match.protocol:type_name -> talos.resource.definitions.enums.NethelpersProtocol 25, // 49: talos.resource.definitions.network.NfTablesLayer4Match.match_source_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch 25, // 50: talos.resource.definitions.network.NfTablesLayer4Match.match_destination_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch - 30, // 51: talos.resource.definitions.network.NfTablesPortMatch.ranges:type_name -> talos.resource.definitions.network.PortRange + 31, // 51: talos.resource.definitions.network.NfTablesPortMatch.ranges:type_name -> talos.resource.definitions.network.PortRange 21, // 52: talos.resource.definitions.network.NfTablesRule.match_o_if_name:type_name -> talos.resource.definitions.network.NfTablesIfNameMatch - 68, // 53: talos.resource.definitions.network.NfTablesRule.verdict:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict + 69, // 53: talos.resource.definitions.network.NfTablesRule.verdict:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict 24, // 54: talos.resource.definitions.network.NfTablesRule.match_mark:type_name -> talos.resource.definitions.network.NfTablesMark 24, // 55: talos.resource.definitions.network.NfTablesRule.set_mark:type_name -> talos.resource.definitions.network.NfTablesMark 17, // 56: talos.resource.definitions.network.NfTablesRule.match_source_address:type_name -> talos.resource.definitions.network.NfTablesAddressMatch @@ -4598,51 +4669,53 @@ var file_resource_definitions_network_network_proto_depIdxs = []int32{ 19, // 60: talos.resource.definitions.network.NfTablesRule.clamp_mss:type_name -> talos.resource.definitions.network.NfTablesClampMSS 23, // 61: talos.resource.definitions.network.NfTablesRule.match_limit:type_name -> talos.resource.definitions.network.NfTablesLimitMatch 20, // 62: talos.resource.definitions.network.NfTablesRule.match_conntrack_state:type_name -> talos.resource.definitions.network.NfTablesConntrackStateMatch - 48, // 63: talos.resource.definitions.network.NodeAddressFilterSpec.include_subnets:type_name -> common.NetIPPrefix - 48, // 64: talos.resource.definitions.network.NodeAddressFilterSpec.exclude_subnets:type_name -> common.NetIPPrefix - 48, // 65: talos.resource.definitions.network.NodeAddressSpec.addresses:type_name -> common.NetIPPrefix - 72, // 66: talos.resource.definitions.network.OperatorSpecSpec.operator:type_name -> talos.resource.definitions.enums.NetworkOperator - 7, // 67: talos.resource.definitions.network.OperatorSpecSpec.dhcp4:type_name -> talos.resource.definitions.network.DHCP4OperatorSpec - 8, // 68: talos.resource.definitions.network.OperatorSpecSpec.dhcp6:type_name -> talos.resource.definitions.network.DHCP6OperatorSpec - 44, // 69: talos.resource.definitions.network.OperatorSpecSpec.vip:type_name -> talos.resource.definitions.network.VIPOperatorSpec - 51, // 70: talos.resource.definitions.network.OperatorSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 73, // 71: talos.resource.definitions.network.ProbeSpecSpec.interval:type_name -> google.protobuf.Duration - 39, // 72: talos.resource.definitions.network.ProbeSpecSpec.tcp:type_name -> talos.resource.definitions.network.TCPProbeSpec - 51, // 73: talos.resource.definitions.network.ProbeSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 52, // 74: talos.resource.definitions.network.ResolverSpecSpec.dns_servers:type_name -> common.NetIP - 51, // 75: talos.resource.definitions.network.ResolverSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 52, // 76: talos.resource.definitions.network.ResolverStatusSpec.dns_servers:type_name -> common.NetIP - 49, // 77: talos.resource.definitions.network.RouteSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 48, // 78: talos.resource.definitions.network.RouteSpecSpec.destination:type_name -> common.NetIPPrefix - 52, // 79: talos.resource.definitions.network.RouteSpecSpec.source:type_name -> common.NetIP - 52, // 80: talos.resource.definitions.network.RouteSpecSpec.gateway:type_name -> common.NetIP - 74, // 81: talos.resource.definitions.network.RouteSpecSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable - 50, // 82: talos.resource.definitions.network.RouteSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 75, // 83: talos.resource.definitions.network.RouteSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType - 76, // 84: talos.resource.definitions.network.RouteSpecSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol - 51, // 85: talos.resource.definitions.network.RouteSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 49, // 86: talos.resource.definitions.network.RouteStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 48, // 87: talos.resource.definitions.network.RouteStatusSpec.destination:type_name -> common.NetIPPrefix - 52, // 88: talos.resource.definitions.network.RouteStatusSpec.source:type_name -> common.NetIP - 52, // 89: talos.resource.definitions.network.RouteStatusSpec.gateway:type_name -> common.NetIP - 74, // 90: talos.resource.definitions.network.RouteStatusSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable - 50, // 91: talos.resource.definitions.network.RouteStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 75, // 92: talos.resource.definitions.network.RouteStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType - 76, // 93: talos.resource.definitions.network.RouteStatusSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol - 73, // 94: talos.resource.definitions.network.TCPProbeSpec.timeout:type_name -> google.protobuf.Duration - 51, // 95: talos.resource.definitions.network.TimeServerSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 52, // 96: talos.resource.definitions.network.VIPOperatorSpec.ip:type_name -> common.NetIP - 42, // 97: talos.resource.definitions.network.VIPOperatorSpec.equinix_metal:type_name -> talos.resource.definitions.network.VIPEquinixMetalSpec - 43, // 98: talos.resource.definitions.network.VIPOperatorSpec.h_cloud:type_name -> talos.resource.definitions.network.VIPHCloudSpec - 77, // 99: talos.resource.definitions.network.VLANSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersVLANProtocol - 73, // 100: talos.resource.definitions.network.WireguardPeer.persistent_keepalive_interval:type_name -> google.protobuf.Duration - 48, // 101: talos.resource.definitions.network.WireguardPeer.allowed_ips:type_name -> common.NetIPPrefix - 46, // 102: talos.resource.definitions.network.WireguardSpec.peers:type_name -> talos.resource.definitions.network.WireguardPeer - 103, // [103:103] is the sub-list for method output_type - 103, // [103:103] is the sub-list for method input_type - 103, // [103:103] is the sub-list for extension type_name - 103, // [103:103] is the sub-list for extension extendee - 0, // [0:103] is the sub-list for field type_name + 49, // 63: talos.resource.definitions.network.NodeAddressFilterSpec.include_subnets:type_name -> common.NetIPPrefix + 49, // 64: talos.resource.definitions.network.NodeAddressFilterSpec.exclude_subnets:type_name -> common.NetIPPrefix + 73, // 65: talos.resource.definitions.network.NodeAddressSortAlgorithmSpec.algorithm:type_name -> talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + 49, // 66: talos.resource.definitions.network.NodeAddressSpec.addresses:type_name -> common.NetIPPrefix + 73, // 67: talos.resource.definitions.network.NodeAddressSpec.sort_algorithm:type_name -> talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + 74, // 68: talos.resource.definitions.network.OperatorSpecSpec.operator:type_name -> talos.resource.definitions.enums.NetworkOperator + 7, // 69: talos.resource.definitions.network.OperatorSpecSpec.dhcp4:type_name -> talos.resource.definitions.network.DHCP4OperatorSpec + 8, // 70: talos.resource.definitions.network.OperatorSpecSpec.dhcp6:type_name -> talos.resource.definitions.network.DHCP6OperatorSpec + 45, // 71: talos.resource.definitions.network.OperatorSpecSpec.vip:type_name -> talos.resource.definitions.network.VIPOperatorSpec + 52, // 72: talos.resource.definitions.network.OperatorSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 75, // 73: talos.resource.definitions.network.ProbeSpecSpec.interval:type_name -> google.protobuf.Duration + 40, // 74: talos.resource.definitions.network.ProbeSpecSpec.tcp:type_name -> talos.resource.definitions.network.TCPProbeSpec + 52, // 75: talos.resource.definitions.network.ProbeSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 53, // 76: talos.resource.definitions.network.ResolverSpecSpec.dns_servers:type_name -> common.NetIP + 52, // 77: talos.resource.definitions.network.ResolverSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 53, // 78: talos.resource.definitions.network.ResolverStatusSpec.dns_servers:type_name -> common.NetIP + 50, // 79: talos.resource.definitions.network.RouteSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 49, // 80: talos.resource.definitions.network.RouteSpecSpec.destination:type_name -> common.NetIPPrefix + 53, // 81: talos.resource.definitions.network.RouteSpecSpec.source:type_name -> common.NetIP + 53, // 82: talos.resource.definitions.network.RouteSpecSpec.gateway:type_name -> common.NetIP + 76, // 83: talos.resource.definitions.network.RouteSpecSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable + 51, // 84: talos.resource.definitions.network.RouteSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 77, // 85: talos.resource.definitions.network.RouteSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType + 78, // 86: talos.resource.definitions.network.RouteSpecSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol + 52, // 87: talos.resource.definitions.network.RouteSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 50, // 88: talos.resource.definitions.network.RouteStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 49, // 89: talos.resource.definitions.network.RouteStatusSpec.destination:type_name -> common.NetIPPrefix + 53, // 90: talos.resource.definitions.network.RouteStatusSpec.source:type_name -> common.NetIP + 53, // 91: talos.resource.definitions.network.RouteStatusSpec.gateway:type_name -> common.NetIP + 76, // 92: talos.resource.definitions.network.RouteStatusSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable + 51, // 93: talos.resource.definitions.network.RouteStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 77, // 94: talos.resource.definitions.network.RouteStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType + 78, // 95: talos.resource.definitions.network.RouteStatusSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol + 75, // 96: talos.resource.definitions.network.TCPProbeSpec.timeout:type_name -> google.protobuf.Duration + 52, // 97: talos.resource.definitions.network.TimeServerSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 53, // 98: talos.resource.definitions.network.VIPOperatorSpec.ip:type_name -> common.NetIP + 43, // 99: talos.resource.definitions.network.VIPOperatorSpec.equinix_metal:type_name -> talos.resource.definitions.network.VIPEquinixMetalSpec + 44, // 100: talos.resource.definitions.network.VIPOperatorSpec.h_cloud:type_name -> talos.resource.definitions.network.VIPHCloudSpec + 79, // 101: talos.resource.definitions.network.VLANSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersVLANProtocol + 75, // 102: talos.resource.definitions.network.WireguardPeer.persistent_keepalive_interval:type_name -> google.protobuf.Duration + 49, // 103: talos.resource.definitions.network.WireguardPeer.allowed_ips:type_name -> common.NetIPPrefix + 47, // 104: talos.resource.definitions.network.WireguardSpec.peers:type_name -> talos.resource.definitions.network.WireguardPeer + 105, // [105:105] is the sub-list for method output_type + 105, // [105:105] is the sub-list for method input_type + 105, // [105:105] is the sub-list for extension type_name + 105, // [105:105] is the sub-list for extension extendee + 0, // [0:105] is the sub-list for field type_name } func init() { file_resource_definitions_network_network_proto_init() } @@ -4656,7 +4729,7 @@ func file_resource_definitions_network_network_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_resource_definitions_network_network_proto_rawDesc, NumEnums: 0, - NumMessages: 48, + NumMessages: 49, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go b/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go index c4e860688d..6cab05d825 100644 --- a/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go @@ -2209,6 +2209,44 @@ func (m *NodeAddressFilterSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *NodeAddressSortAlgorithmSpec) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NodeAddressSortAlgorithmSpec) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *NodeAddressSortAlgorithmSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Algorithm != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Algorithm)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *NodeAddressSpec) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -2239,6 +2277,11 @@ func (m *NodeAddressSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.SortAlgorithm != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.SortAlgorithm)) + i-- + dAtA[i] = 0x10 + } if len(m.Addresses) > 0 { for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { if vtmsg, ok := interface{}(m.Addresses[iNdEx]).(interface { @@ -4469,6 +4512,19 @@ func (m *NodeAddressFilterSpec) SizeVT() (n int) { return n } +func (m *NodeAddressSortAlgorithmSpec) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Algorithm != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Algorithm)) + } + n += len(m.unknownFields) + return n +} + func (m *NodeAddressSpec) SizeVT() (n int) { if m == nil { return 0 @@ -4487,6 +4543,9 @@ func (m *NodeAddressSpec) SizeVT() (n int) { n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) } } + if m.SortAlgorithm != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.SortAlgorithm)) + } n += len(m.unknownFields) return n } @@ -10334,6 +10393,76 @@ func (m *NodeAddressFilterSpec) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *NodeAddressSortAlgorithmSpec) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeAddressSortAlgorithmSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeAddressSortAlgorithmSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Algorithm", wireType) + } + m.Algorithm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Algorithm |= enums.NethelpersAddressSortAlgorithm(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NodeAddressSpec) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -10405,6 +10534,25 @@ func (m *NodeAddressSpec) UnmarshalVT(dAtA []byte) error { } } iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SortAlgorithm", wireType) + } + m.SortAlgorithm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SortAlgorithm |= enums.NethelpersAddressSortAlgorithm(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/pkg/machinery/config/config/machine.go b/pkg/machinery/config/config/machine.go index 4d541a1476..614b97ea83 100644 --- a/pkg/machinery/config/config/machine.go +++ b/pkg/machinery/config/config/machine.go @@ -15,6 +15,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/cel" "github.com/siderolabs/talos/pkg/machinery/config/machine" + "github.com/siderolabs/talos/pkg/machinery/nethelpers" ) // MachineConfig defines the requirements for a config that pertains to machine @@ -451,6 +452,7 @@ type Features interface { HostDNS() HostDNS KubePrism() KubePrism ImageCache() ImageCache + NodeAddressSortAlgorithm() nethelpers.AddressSortAlgorithm } // KubernetesTalosAPIAccess describes the Kubernetes Talos API access features. diff --git a/pkg/machinery/config/schemas/config.schema.json b/pkg/machinery/config/schemas/config.schema.json index 9b4d5483c4..ebb6f79009 100644 --- a/pkg/machinery/config/schemas/config.schema.json +++ b/pkg/machinery/config/schemas/config.schema.json @@ -2114,6 +2114,13 @@ "description": "Enable Image Cache feature.\n", "markdownDescription": "Enable Image Cache feature.", "x-intellij-html-description": "\u003cp\u003eEnable Image Cache feature.\u003c/p\u003e\n" + }, + "nodeAddressSortAlgorithm": { + "type": "string", + "title": "nodeAddressSortAlgorithm", + "description": "Select the node address sort algorithm.\nThe ‘v1’ algorithm sorts addresses by the address itself.\nThe ‘v2’ algorithm prefers more specific prefixes.\nIf unset, defaults to ‘v1’.\n", + "markdownDescription": "Select the node address sort algorithm.\nThe 'v1' algorithm sorts addresses by the address itself.\nThe 'v2' algorithm prefers more specific prefixes.\nIf unset, defaults to 'v1'.", + "x-intellij-html-description": "\u003cp\u003eSelect the node address sort algorithm.\nThe \u0026lsquo;v1\u0026rsquo; algorithm sorts addresses by the address itself.\nThe \u0026lsquo;v2\u0026rsquo; algorithm prefers more specific prefixes.\nIf unset, defaults to \u0026lsquo;v1\u0026rsquo;.\u003c/p\u003e\n" } }, "additionalProperties": false, diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_features.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_features.go index 448cee3cfd..cdcf04db12 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_features.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_features.go @@ -8,6 +8,7 @@ import ( "github.com/siderolabs/go-pointer" "github.com/siderolabs/talos/pkg/machinery/config/config" + "github.com/siderolabs/talos/pkg/machinery/nethelpers" ) // RBACEnabled implements config.Features interface. @@ -66,6 +67,20 @@ func (f *FeaturesConfig) ImageCache() config.ImageCache { return f.ImageCacheSupport } +// NodeAddressSortAlgorithm implements config.Features interface. +func (f *FeaturesConfig) NodeAddressSortAlgorithm() nethelpers.AddressSortAlgorithm { + if f.FeatureNodeAddressSortAlgorithm == "" { + return nethelpers.AddressSortAlgorithmV1 + } + + res, err := nethelpers.AddressSortAlgorithmString(f.FeatureNodeAddressSortAlgorithm) + if err != nil { + return nethelpers.AddressSortAlgorithmV1 + } + + return res +} + const defaultKubePrismPort = 7445 // Enabled implements [config.KubePrism]. diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go index 5a3155b86e..665b8674d4 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_types.go @@ -2212,6 +2212,12 @@ type FeaturesConfig struct { // description: | // Enable Image Cache feature. ImageCacheSupport *ImageCacheConfig `yaml:"imageCache,omitempty"` + // description: | + // Select the node address sort algorithm. + // The 'v1' algorithm sorts addresses by the address itself. + // The 'v2' algorithm prefers more specific prefixes. + // If unset, defaults to 'v1'. + FeatureNodeAddressSortAlgorithm string `yaml:"nodeAddressSortAlgorithm,omitempty"` } // KubePrism describes the configuration for the KubePrism load balancer. diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go index 515c95968b..1c666f1ede 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_types_doc.go @@ -3537,6 +3537,13 @@ func (FeaturesConfig) Doc() *encoder.Doc { Description: "Enable Image Cache feature.", Comments: [3]string{"" /* encoder.HeadComment */, "Enable Image Cache feature." /* encoder.LineComment */, "" /* encoder.FootComment */}, }, + { + Name: "nodeAddressSortAlgorithm", + Type: "string", + Note: "", + Description: "Select the node address sort algorithm.\nThe 'v1' algorithm sorts addresses by the address itself.\nThe 'v2' algorithm prefers more specific prefixes.\nIf unset, defaults to 'v1'.", + Comments: [3]string{"" /* encoder.HeadComment */, "Select the node address sort algorithm." /* encoder.LineComment */, "" /* encoder.FootComment */}, + }, }, } diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go index 40a40e2881..7a192be3cf 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go @@ -324,6 +324,12 @@ func (c *Config) Validate(mode validation.RuntimeMode, options ...validation.Opt } } + if c.MachineConfig.MachineFeatures != nil && c.MachineConfig.MachineFeatures.FeatureNodeAddressSortAlgorithm != "" { + if _, err := nethelpers.AddressSortAlgorithmString(c.MachineConfig.MachineFeatures.FeatureNodeAddressSortAlgorithm); err != nil { + result = multierror.Append(result, fmt.Errorf("invalid node address sort algorithm: %w", err)) + } + } + if c.ConfigPersist != nil && !*c.ConfigPersist { result = multierror.Append(result, errors.New(".persist should be enabled")) } diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go index 36d30d4f26..85b9734caf 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go @@ -1911,6 +1911,30 @@ func TestValidate(t *testing.T) { }, }, }, + { + name: "MachineFeaturesInvalidAddressSortingAlgorithm", + config: &v1alpha1.Config{ + ConfigVersion: "v1alpha1", + MachineConfig: &v1alpha1.MachineConfig{ + MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, + MachineFeatures: &v1alpha1.FeaturesConfig{ + FeatureNodeAddressSortAlgorithm: "xyz", + }, + }, + ClusterConfig: &v1alpha1.ClusterConfig{ + ControlPlane: &v1alpha1.ControlPlaneConfig{ + Endpoint: &v1alpha1.Endpoint{ + endpointURL, + }, + }, + }, + }, + expectedError: "1 error occurred:\n\t* invalid node address sort algorithm: xyz does not belong to AddressSortAlgorithm values\n\n", + }, } { t.Run(test.name, func(t *testing.T) { t.Parallel() diff --git a/pkg/machinery/nethelpers/addresssortalgorithm.go b/pkg/machinery/nethelpers/addresssortalgorithm.go new file mode 100644 index 0000000000..9a95e05c7c --- /dev/null +++ b/pkg/machinery/nethelpers/addresssortalgorithm.go @@ -0,0 +1,16 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package nethelpers + +// AddressSortAlgorithm is an internal address sorting algorithm. +type AddressSortAlgorithm int + +// AddressSortAlgorithm contants. +// +//structprotogen:gen_enum +const ( + AddressSortAlgorithmV1 AddressSortAlgorithm = iota // v1 + AddressSortAlgorithmV2 // v2 +) diff --git a/pkg/machinery/nethelpers/arpalltargets_enumer.go b/pkg/machinery/nethelpers/arpalltargets_enumer.go index ff3f741410..73409b5ec5 100644 --- a/pkg/machinery/nethelpers/arpalltargets_enumer.go +++ b/pkg/machinery/nethelpers/arpalltargets_enumer.go @@ -1,4 +1,4 @@ -// Code generated by "enumer -type=ARPAllTargets,ARPValidate,AddressFlag,ADSelect,BondMode,BondXmitHashPolicy,ConntrackState,DefaultAction,Duplex,Family,LACPRate,LinkFlag,LinkType,MatchOperator,NfTablesChainHook,NfTablesChainPriority,NfTablesVerdict,OperationalState,Port,PrimaryReselect,Protocol,RouteFlag,RouteProtocol,RouteType,RoutingTable,Scope,Status,VLANProtocol -linecomment -text"; DO NOT EDIT. +// Code generated by "enumer -type=ARPAllTargets,ARPValidate,AddressFlag,AddressSortAlgorithm,ADSelect,BondMode,BondXmitHashPolicy,ConntrackState,DefaultAction,Duplex,Family,LACPRate,LinkFlag,LinkType,MatchOperator,NfTablesChainHook,NfTablesChainPriority,NfTablesVerdict,OperationalState,Port,PrimaryReselect,Protocol,RouteFlag,RouteProtocol,RouteType,RoutingTable,Scope,Status,VLANProtocol -linecomment -text"; DO NOT EDIT. package nethelpers @@ -309,6 +309,88 @@ func (i *AddressFlag) UnmarshalText(text []byte) error { return err } +const _AddressSortAlgorithmName = "v1v2" + +var _AddressSortAlgorithmIndex = [...]uint8{0, 2, 4} + +const _AddressSortAlgorithmLowerName = "v1v2" + +func (i AddressSortAlgorithm) String() string { + if i < 0 || i >= AddressSortAlgorithm(len(_AddressSortAlgorithmIndex)-1) { + return fmt.Sprintf("AddressSortAlgorithm(%d)", i) + } + return _AddressSortAlgorithmName[_AddressSortAlgorithmIndex[i]:_AddressSortAlgorithmIndex[i+1]] +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _AddressSortAlgorithmNoOp() { + var x [1]struct{} + _ = x[AddressSortAlgorithmV1-(0)] + _ = x[AddressSortAlgorithmV2-(1)] +} + +var _AddressSortAlgorithmValues = []AddressSortAlgorithm{AddressSortAlgorithmV1, AddressSortAlgorithmV2} + +var _AddressSortAlgorithmNameToValueMap = map[string]AddressSortAlgorithm{ + _AddressSortAlgorithmName[0:2]: AddressSortAlgorithmV1, + _AddressSortAlgorithmLowerName[0:2]: AddressSortAlgorithmV1, + _AddressSortAlgorithmName[2:4]: AddressSortAlgorithmV2, + _AddressSortAlgorithmLowerName[2:4]: AddressSortAlgorithmV2, +} + +var _AddressSortAlgorithmNames = []string{ + _AddressSortAlgorithmName[0:2], + _AddressSortAlgorithmName[2:4], +} + +// AddressSortAlgorithmString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func AddressSortAlgorithmString(s string) (AddressSortAlgorithm, error) { + if val, ok := _AddressSortAlgorithmNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _AddressSortAlgorithmNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to AddressSortAlgorithm values", s) +} + +// AddressSortAlgorithmValues returns all values of the enum +func AddressSortAlgorithmValues() []AddressSortAlgorithm { + return _AddressSortAlgorithmValues +} + +// AddressSortAlgorithmStrings returns a slice of all String values of the enum +func AddressSortAlgorithmStrings() []string { + strs := make([]string, len(_AddressSortAlgorithmNames)) + copy(strs, _AddressSortAlgorithmNames) + return strs +} + +// IsAAddressSortAlgorithm returns "true" if the value is listed in the enum definition. "false" otherwise +func (i AddressSortAlgorithm) IsAAddressSortAlgorithm() bool { + for _, v := range _AddressSortAlgorithmValues { + if i == v { + return true + } + } + return false +} + +// MarshalText implements the encoding.TextMarshaler interface for AddressSortAlgorithm +func (i AddressSortAlgorithm) MarshalText() ([]byte, error) { + return []byte(i.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface for AddressSortAlgorithm +func (i *AddressSortAlgorithm) UnmarshalText(text []byte) error { + var err error + *i, err = AddressSortAlgorithmString(string(text)) + return err +} + const _ADSelectName = "stablebandwidthcount" var _ADSelectIndex = [...]uint8{0, 6, 15, 20} diff --git a/pkg/machinery/nethelpers/nethelpers.go b/pkg/machinery/nethelpers/nethelpers.go index d3f7dea6e7..6229e773e7 100644 --- a/pkg/machinery/nethelpers/nethelpers.go +++ b/pkg/machinery/nethelpers/nethelpers.go @@ -5,5 +5,5 @@ // Package nethelpers provides types and type wrappers to support network resources. package nethelpers -//go:generate enumer -type=ARPAllTargets,ARPValidate,AddressFlag,ADSelect,BondMode,BondXmitHashPolicy,ConntrackState,DefaultAction,Duplex,Family,LACPRate,LinkFlag,LinkType,MatchOperator,NfTablesChainHook,NfTablesChainPriority,NfTablesVerdict,OperationalState,Port,PrimaryReselect,Protocol,RouteFlag,RouteProtocol,RouteType,RoutingTable,Scope,Status,VLANProtocol -linecomment -text +//go:generate enumer -type=ARPAllTargets,ARPValidate,AddressFlag,AddressSortAlgorithm,ADSelect,BondMode,BondXmitHashPolicy,ConntrackState,DefaultAction,Duplex,Family,LACPRate,LinkFlag,LinkType,MatchOperator,NfTablesChainHook,NfTablesChainPriority,NfTablesVerdict,OperationalState,Port,PrimaryReselect,Protocol,RouteFlag,RouteProtocol,RouteType,RoutingTable,Scope,Status,VLANProtocol -linecomment -text //go:generate enumer -type=FailOverMAC -linecomment diff --git a/pkg/machinery/resources/network/address_spec.go b/pkg/machinery/resources/network/address_spec.go index 9c66625580..642bc53cde 100644 --- a/pkg/machinery/resources/network/address_spec.go +++ b/pkg/machinery/resources/network/address_spec.go @@ -16,7 +16,7 @@ import ( "github.com/siderolabs/talos/pkg/machinery/proto" ) -//go:generate deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type HardwareAddrSpec -type HostDNSConfigSpec -type HostnameSpecSpec -type HostnameStatusSpec -type LinkRefreshSpec -type LinkSpecSpec -type LinkStatusSpec -type NfTablesChainSpec -type NodeAddressSpec -type NodeAddressFilterSpec -type OperatorSpecSpec -type ProbeSpecSpec -type ProbeStatusSpec -type ResolverSpecSpec -type ResolverStatusSpec -type RouteSpecSpec -type RouteStatusSpec -type StatusSpec -type TimeServerSpecSpec -type TimeServerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go . +//go:generate deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type HardwareAddrSpec -type HostDNSConfigSpec -type HostnameSpecSpec -type HostnameStatusSpec -type LinkRefreshSpec -type LinkSpecSpec -type LinkStatusSpec -type NfTablesChainSpec -type NodeAddressSpec -type NodeAddressSortAlgorithmSpec -type NodeAddressFilterSpec -type OperatorSpecSpec -type ProbeSpecSpec -type ProbeStatusSpec -type ResolverSpecSpec -type ResolverStatusSpec -type RouteSpecSpec -type RouteStatusSpec -type StatusSpec -type TimeServerSpecSpec -type TimeServerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go . // AddressSpecType is type of AddressSpec resource. const AddressSpecType = resource.Type("AddressSpecs.net.talos.dev") diff --git a/pkg/machinery/resources/network/deep_copy.generated.go b/pkg/machinery/resources/network/deep_copy.generated.go index 6e7e217b61..356f8470e6 100644 --- a/pkg/machinery/resources/network/deep_copy.generated.go +++ b/pkg/machinery/resources/network/deep_copy.generated.go @@ -2,7 +2,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -// Code generated by "deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type HardwareAddrSpec -type HostDNSConfigSpec -type HostnameSpecSpec -type HostnameStatusSpec -type LinkRefreshSpec -type LinkSpecSpec -type LinkStatusSpec -type NfTablesChainSpec -type NodeAddressSpec -type NodeAddressFilterSpec -type OperatorSpecSpec -type ProbeSpecSpec -type ProbeStatusSpec -type ResolverSpecSpec -type ResolverStatusSpec -type RouteSpecSpec -type RouteStatusSpec -type StatusSpec -type TimeServerSpecSpec -type TimeServerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. +// Code generated by "deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type HardwareAddrSpec -type HostDNSConfigSpec -type HostnameSpecSpec -type HostnameStatusSpec -type LinkRefreshSpec -type LinkSpecSpec -type LinkStatusSpec -type NfTablesChainSpec -type NodeAddressSpec -type NodeAddressSortAlgorithmSpec -type NodeAddressFilterSpec -type OperatorSpecSpec -type ProbeSpecSpec -type ProbeStatusSpec -type ResolverSpecSpec -type ResolverStatusSpec -type RouteSpecSpec -type RouteStatusSpec -type StatusSpec -type TimeServerSpecSpec -type TimeServerStatusSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT. package network @@ -222,6 +222,12 @@ func (o NodeAddressSpec) DeepCopy() NodeAddressSpec { return cp } +// DeepCopy generates a deep copy of NodeAddressSortAlgorithmSpec. +func (o NodeAddressSortAlgorithmSpec) DeepCopy() NodeAddressSortAlgorithmSpec { + var cp NodeAddressSortAlgorithmSpec = o + return cp +} + // DeepCopy generates a deep copy of NodeAddressFilterSpec. func (o NodeAddressFilterSpec) DeepCopy() NodeAddressFilterSpec { var cp NodeAddressFilterSpec = o diff --git a/pkg/machinery/resources/network/network_test.go b/pkg/machinery/resources/network/network_test.go index 2b3bb119f5..d57aef37c7 100644 --- a/pkg/machinery/resources/network/network_test.go +++ b/pkg/machinery/resources/network/network_test.go @@ -38,6 +38,7 @@ func TestRegisterResource(t *testing.T) { &network.NfTablesChain{}, &network.NodeAddress{}, &network.NodeAddressFilter{}, + &network.NodeAddressSortAlgorithm{}, &network.OperatorSpec{}, &network.ProbeSpec{}, &network.ResolverStatus{}, diff --git a/pkg/machinery/resources/network/node_address.go b/pkg/machinery/resources/network/node_address.go index f4e62dbff6..93952a5d09 100644 --- a/pkg/machinery/resources/network/node_address.go +++ b/pkg/machinery/resources/network/node_address.go @@ -15,6 +15,7 @@ import ( "github.com/cosi-project/runtime/pkg/resource/typed" "github.com/siderolabs/gen/xslices" + "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/proto" ) @@ -50,7 +51,8 @@ const ( // //gotagsrewrite:gen type NodeAddressSpec struct { - Addresses []netip.Prefix `yaml:"addresses" protobuf:"1"` + Addresses []netip.Prefix `yaml:"addresses" protobuf:"1"` + SortAlgorithm nethelpers.AddressSortAlgorithm `yaml:"sortAlgorithm" protobuf:"2"` } // NewNodeAddress initializes a NodeAddress resource. @@ -75,6 +77,10 @@ func (NodeAddressExtension) ResourceDefinition() meta.ResourceDefinitionSpec { Name: "Addresses", JSONPath: `{.addresses}`, }, + { + Name: "SortAlgorithm", + JSONPath: `{.sortAlgorithm}`, + }, }, } } diff --git a/pkg/machinery/resources/network/node_address_sort_algorithm.go b/pkg/machinery/resources/network/node_address_sort_algorithm.go new file mode 100644 index 0000000000..a6c30dd6bf --- /dev/null +++ b/pkg/machinery/resources/network/node_address_sort_algorithm.go @@ -0,0 +1,66 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package network + +import ( + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/resource/meta" + "github.com/cosi-project/runtime/pkg/resource/protobuf" + "github.com/cosi-project/runtime/pkg/resource/typed" + + "github.com/siderolabs/talos/pkg/machinery/nethelpers" + "github.com/siderolabs/talos/pkg/machinery/proto" +) + +// NodeAddressSortAlgorithmType is type of NodeAddressSortAlgorithm resource. +const NodeAddressSortAlgorithmType = resource.Type("NodeAddressSortAlgorithms.net.talos.dev") + +// NodeAddressSortAlgorithm resource holds filter for NodeAddress resources. +type NodeAddressSortAlgorithm = typed.Resource[NodeAddressSortAlgorithmSpec, NodeAddressSortAlgorithmExtension] + +// NodeAddressSortAlgorithmID is the resource ID for NodeAddressSortAlgorithm. +const NodeAddressSortAlgorithmID = "default" + +// NodeAddressSortAlgorithmSpec describes a filter for NodeAddresses. +// +//gotagsrewrite:gen +type NodeAddressSortAlgorithmSpec struct { + Algorithm nethelpers.AddressSortAlgorithm `yaml:"algorithm" protobuf:"1"` +} + +// NewNodeAddressSortAlgorithm initializes a NodeAddressSortAlgorithm resource. +func NewNodeAddressSortAlgorithm(namespace resource.Namespace, id resource.ID) *NodeAddressSortAlgorithm { + return typed.NewResource[NodeAddressSortAlgorithmSpec, NodeAddressSortAlgorithmExtension]( + resource.NewMetadata(namespace, NodeAddressSortAlgorithmType, id, resource.VersionUndefined), + NodeAddressSortAlgorithmSpec{}, + ) +} + +// NodeAddressSortAlgorithmExtension provides auxiliary methods for NodeAddressSortAlgorithm. +type NodeAddressSortAlgorithmExtension struct{} + +// ResourceDefinition implements [typed.Extension] interface. +func (NodeAddressSortAlgorithmExtension) ResourceDefinition() meta.ResourceDefinitionSpec { + return meta.ResourceDefinitionSpec{ + Type: NodeAddressSortAlgorithmType, + Aliases: []resource.Type{}, + DefaultNamespace: NamespaceName, + PrintColumns: []meta.PrintColumn{ + { + Name: "Algorithm", + JSONPath: `{.algorithm}`, + }, + }, + } +} + +func init() { + proto.RegisterDefaultTypes() + + err := protobuf.RegisterDynamic[NodeAddressSortAlgorithmSpec](NodeAddressSortAlgorithmType, &NodeAddressSortAlgorithm{}) + if err != nil { + panic(err) + } +} diff --git a/website/content/v1.9/reference/api.md b/website/content/v1.9/reference/api.md index 64d9b8fe48..9f2fe34f3d 100644 --- a/website/content/v1.9/reference/api.md +++ b/website/content/v1.9/reference/api.md @@ -79,6 +79,7 @@ description: Talos gRPC API reference. - [NethelpersARPAllTargets](#talos.resource.definitions.enums.NethelpersARPAllTargets) - [NethelpersARPValidate](#talos.resource.definitions.enums.NethelpersARPValidate) - [NethelpersAddressFlag](#talos.resource.definitions.enums.NethelpersAddressFlag) + - [NethelpersAddressSortAlgorithm](#talos.resource.definitions.enums.NethelpersAddressSortAlgorithm) - [NethelpersBondMode](#talos.resource.definitions.enums.NethelpersBondMode) - [NethelpersBondXmitHashPolicy](#talos.resource.definitions.enums.NethelpersBondXmitHashPolicy) - [NethelpersConntrackState](#talos.resource.definitions.enums.NethelpersConntrackState) @@ -217,6 +218,7 @@ description: Talos gRPC API reference. - [NfTablesPortMatch](#talos.resource.definitions.network.NfTablesPortMatch) - [NfTablesRule](#talos.resource.definitions.network.NfTablesRule) - [NodeAddressFilterSpec](#talos.resource.definitions.network.NodeAddressFilterSpec) + - [NodeAddressSortAlgorithmSpec](#talos.resource.definitions.network.NodeAddressSortAlgorithmSpec) - [NodeAddressSpec](#talos.resource.definitions.network.NodeAddressSpec) - [OperatorSpecSpec](#talos.resource.definitions.network.OperatorSpecSpec) - [PortRange](#talos.resource.definitions.network.PortRange) @@ -1657,6 +1659,18 @@ NethelpersAddressFlag wraps IFF_* constants. + + +### NethelpersAddressSortAlgorithm +NethelpersAddressSortAlgorithm is an internal address sorting algorithm. + +| Name | Number | Description | +| ---- | ------ | ----------- | +| ADDRESS_SORT_ALGORITHM_V1 | 0 | | +| ADDRESS_SORT_ALGORITHM_V2 | 1 | | + + + ### NethelpersBondMode @@ -4015,6 +4029,21 @@ NodeAddressFilterSpec describes a filter for NodeAddresses. + + +### NodeAddressSortAlgorithmSpec +NodeAddressSortAlgorithmSpec describes a filter for NodeAddresses. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| algorithm | [talos.resource.definitions.enums.NethelpersAddressSortAlgorithm](#talos.resource.definitions.enums.NethelpersAddressSortAlgorithm) | | | + + + + + + ### NodeAddressSpec @@ -4024,6 +4053,7 @@ NodeAddressSpec describes a set of node addresses. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | addresses | [common.NetIPPrefix](#common.NetIPPrefix) | repeated | | +| sort_algorithm | [talos.resource.definitions.enums.NethelpersAddressSortAlgorithm](#talos.resource.definitions.enums.NethelpersAddressSortAlgorithm) | | | diff --git a/website/content/v1.9/reference/configuration/v1alpha1/config.md b/website/content/v1.9/reference/configuration/v1alpha1/config.md index 0830a5963a..9c441f9f2a 100644 --- a/website/content/v1.9/reference/configuration/v1alpha1/config.md +++ b/website/content/v1.9/reference/configuration/v1alpha1/config.md @@ -2649,6 +2649,7 @@ kubernetesTalosAPIAccess: |`kubePrism` |KubePrism |
KubePrism - local proxy/load balancer on defined port that will distributerequests to all API servers in the cluster.
| | |`hostDNS` |HostDNSConfig |Configures host DNS caching resolver. | | |`imageCache` |ImageCacheConfig |Enable Image Cache feature. | | +|`nodeAddressSortAlgorithm` |string |
Select the node address sort algorithm.The 'v1' algorithm sorts addresses by the address itself.
The 'v2' algorithm prefers more specific prefixes.
If unset, defaults to 'v1'.
| | diff --git a/website/content/v1.9/schemas/config.schema.json b/website/content/v1.9/schemas/config.schema.json index 9b4d5483c4..ebb6f79009 100644 --- a/website/content/v1.9/schemas/config.schema.json +++ b/website/content/v1.9/schemas/config.schema.json @@ -2114,6 +2114,13 @@ "description": "Enable Image Cache feature.\n", "markdownDescription": "Enable Image Cache feature.", "x-intellij-html-description": "\u003cp\u003eEnable Image Cache feature.\u003c/p\u003e\n" + }, + "nodeAddressSortAlgorithm": { + "type": "string", + "title": "nodeAddressSortAlgorithm", + "description": "Select the node address sort algorithm.\nThe ‘v1’ algorithm sorts addresses by the address itself.\nThe ‘v2’ algorithm prefers more specific prefixes.\nIf unset, defaults to ‘v1’.\n", + "markdownDescription": "Select the node address sort algorithm.\nThe 'v1' algorithm sorts addresses by the address itself.\nThe 'v2' algorithm prefers more specific prefixes.\nIf unset, defaults to 'v1'.", + "x-intellij-html-description": "\u003cp\u003eSelect the node address sort algorithm.\nThe \u0026lsquo;v1\u0026rsquo; algorithm sorts addresses by the address itself.\nThe \u0026lsquo;v2\u0026rsquo; algorithm prefers more specific prefixes.\nIf unset, defaults to \u0026lsquo;v1\u0026rsquo;.\u003c/p\u003e\n" } }, "additionalProperties": false, diff --git a/website/content/v1.9/talos-guides/configuration/editing-machine-configuration.md b/website/content/v1.9/talos-guides/configuration/editing-machine-configuration.md index b03a3b0af7..e30b425f5b 100644 --- a/website/content/v1.9/talos-guides/configuration/editing-machine-configuration.md +++ b/website/content/v1.9/talos-guides/configuration/editing-machine-configuration.md @@ -54,6 +54,7 @@ The list of config changes allowed to be applied immediately in Talos {{< releas * `.machine.features.hostDNS` * `.machine.features.imageCache` * `.machine.features.kubePrism` +* `.machine.features.nodeAddressSortAlgorithm` ### `talosctl apply-config` From 2c71086ba680c2bbb7653f2808298e8296e73d20 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 4 Dec 2024 22:24:32 +0400 Subject: [PATCH 06/14] fix: lock provisioning order of user disk partitions Fixes #9877 As a side-effect, fix alignment of user disks for newer QEMU versions. Signed-off-by: Andrey Smirnov (cherry picked from commit dd61ad86105c07c1ff8a101a0542af61699f0df3) --- cmd/talosctl/cmd/mgmt/cluster/create.go | 6 ++++-- .../machined/pkg/controllers/block/user_disk_config.go | 6 +++++- .../pkg/controllers/block/user_disk_config_test.go | 1 + pkg/machinery/resources/block/volume_config.go | 5 +++-- pkg/provision/providers/vm/disk.go | 9 ++++++--- 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/cmd/talosctl/cmd/mgmt/cluster/create.go b/cmd/talosctl/cmd/mgmt/cluster/create.go index 9f86ed08b5..be237b4679 100644 --- a/cmd/talosctl/cmd/mgmt/cluster/create.go +++ b/cmd/talosctl/cmd/mgmt/cluster/create.go @@ -1162,6 +1162,8 @@ func parseCPUShare(cpus string) (int64, error) { } func getDisks() ([]*provision.Disk, error) { + const GPTAlignment = 2 * 1024 * 1024 // 2 MB + // should have at least a single primary disk disks := []*provision.Disk{ { @@ -1211,8 +1213,8 @@ func getDisks() ([]*provision.Disk, error) { } disks = append(disks, &provision.Disk{ - // add 1 MB to make extra room for GPT and alignment - Size: diskSize + 2*1024*1024, + // add 2 MB per partition to make extra room for GPT and alignment + Size: diskSize + GPTAlignment*uint64(len(diskPartitions)+1), Partitions: diskPartitions, SkipPreallocate: !clusterDiskPreallocate, Driver: "ide", diff --git a/internal/app/machined/pkg/controllers/block/user_disk_config.go b/internal/app/machined/pkg/controllers/block/user_disk_config.go index 3c3ac9e039..17401a19c5 100644 --- a/internal/app/machined/pkg/controllers/block/user_disk_config.go +++ b/internal/app/machined/pkg/controllers/block/user_disk_config.go @@ -105,7 +105,11 @@ func (ctrl *UserDiskConfigController) Run(ctx context.Context, r controller.Runt vc.TypedSpec().Type = block.VolumeTypePartition vc.TypedSpec().Provisioning = block.ProvisioningSpec{ - Wave: block.WaveUserDisks, + // it's crucial to keep the order of provisioning locked within each disk, otherwise + // provisioning might order them different way, and create partitions in wrong order + // the matcher on partition idx would then discover partitions in wrong order, and mount them + // in wrong order + Wave: block.WaveLegacyUserDisks + idx, DiskSelector: block.DiskSelector{ Match: diskPathMatch(resolvedDevicePath), }, diff --git a/internal/app/machined/pkg/controllers/block/user_disk_config_test.go b/internal/app/machined/pkg/controllers/block/user_disk_config_test.go index e460bbe766..e4e556d633 100644 --- a/internal/app/machined/pkg/controllers/block/user_disk_config_test.go +++ b/internal/app/machined/pkg/controllers/block/user_disk_config_test.go @@ -132,6 +132,7 @@ func (suite *UserDiskConfigSuite) TestReconcileUserDisk() { ctest.AssertResource(suite, id, func(r *block.VolumeConfig, asrt *assert.Assertions) { asrt.NotEmpty(r.TypedSpec().Provisioning) asrt.Contains(r.Metadata().Labels().Raw(), block.UserDiskLabel) + asrt.GreaterOrEqual(r.TypedSpec().Provisioning.Wave, block.WaveLegacyUserDisks) }) } diff --git a/pkg/machinery/resources/block/volume_config.go b/pkg/machinery/resources/block/volume_config.go index a068f3a358..6ca21c51d3 100644 --- a/pkg/machinery/resources/block/volume_config.go +++ b/pkg/machinery/resources/block/volume_config.go @@ -45,8 +45,9 @@ type VolumeConfigSpec struct { // Wave constants. const ( - WaveSystemDisk = -1 - WaveUserDisks = 0 + WaveSystemDisk = -1 + WaveUserDisks = 0 + WaveLegacyUserDisks = 1000000 // legacy user disks rely on specific order of provisioning ) // ProvisioningSpec is the spec for volume provisioning. diff --git a/pkg/provision/providers/vm/disk.go b/pkg/provision/providers/vm/disk.go index d19ebf3128..4c95bd7ef4 100644 --- a/pkg/provision/providers/vm/disk.go +++ b/pkg/provision/providers/vm/disk.go @@ -24,10 +24,13 @@ func (p *Provisioner) UserDiskName(index int) string { // CreateDisks creates empty disk files for each disk. func (p *Provisioner) CreateDisks(state *State, nodeReq provision.NodeRequest) (diskPaths []string, err error) { + const QEMUAlignment = 4 * 1024 * 1024 // 4 MiB, required by QEMU + diskPaths = make([]string, len(nodeReq.Disks)) for i, disk := range nodeReq.Disks { diskPath := state.GetRelativePath(fmt.Sprintf("%s-%d.disk", nodeReq.Name, i)) + diskSize := (disk.Size + QEMUAlignment - 1) / QEMUAlignment * QEMUAlignment var diskF *os.File @@ -38,13 +41,13 @@ func (p *Provisioner) CreateDisks(state *State, nodeReq provision.NodeRequest) ( defer diskF.Close() //nolint:errcheck - if err = diskF.Truncate(int64(disk.Size)); err != nil { + if err = diskF.Truncate(int64(diskSize)); err != nil { return nil, err } if !disk.SkipPreallocate { - if err = syscall.Fallocate(int(diskF.Fd()), 0, 0, int64(disk.Size)); err != nil { - fmt.Fprintf(os.Stderr, "WARNING: failed to preallocate disk space for %q (size %d): %s", diskPath, disk.Size, err) + if err = syscall.Fallocate(int(diskF.Fd()), 0, 0, int64(diskSize)); err != nil { + fmt.Fprintf(os.Stderr, "WARNING: failed to preallocate disk space for %q (size %d): %s", diskPath, diskSize, err) } } From 67fdd10bdcd352864413ff6bd854b51550eaf76d Mon Sep 17 00:00:00 2001 From: Dmitriy Matrenichev Date: Tue, 3 Dec 2024 23:57:44 +0300 Subject: [PATCH 07/14] chore: add integration tests for image-cache Provide separate `integration/image-cache` tag. Closes #9860 Signed-off-by: Dmitriy Matrenichev (cherry picked from commit c4724fc97598d8764b00fb56971d997a349a92e5) --- .github/workflows/ci.yaml | 101 ++++++++++++++++++++++++++++- .kres.yaml | 55 ++++++++++++++++ Makefile | 7 ++ hack/test/e2e-qemu.sh | 8 +++ hack/test/e2e.sh | 9 ++- hack/test/patches/image-cache.yaml | 25 +++++++ internal/integration/cli/image.go | 11 +++- internal/integration/cli/list.go | 46 +++++++------ pkg/imager/cache/cache.go | 35 ++++++---- 9 files changed, 258 insertions(+), 39 deletions(-) create mode 100644 hack/test/patches/image-cache.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9dbef22c77..742eedc218 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-12-04T15:25:22Z by kres 232fe63. +# Generated on 2024-12-06T17:21:12Z by kres 1ebe796. name: default concurrency: @@ -1606,6 +1606,105 @@ jobs: TF_SCRIPT_DIR: _out/contrib run: | make e2e-cloud-tf + integration-image-cache: + permissions: + actions: read + contents: write + issues: read + packages: write + pull-requests: read + runs-on: + - self-hosted + - talos + if: contains(fromJSON(needs.default.outputs.labels), 'integration/image-cache') + needs: + - default + steps: + - name: gather-system-info + id: system-info + uses: kenchan0130/actions-system-info@v1.3.0 + continue-on-error: true + - name: print-system-info + run: | + MEMORY_GB=$((${{ steps.system-info.outputs.totalmem }}/1024/1024/1024)) + + OUTPUTS=( + "CPU Core: ${{ steps.system-info.outputs.cpu-core }}" + "CPU Model: ${{ steps.system-info.outputs.cpu-model }}" + "Hostname: ${{ steps.system-info.outputs.hostname }}" + "NodeName: ${NODE_NAME}" + "Kernel release: ${{ steps.system-info.outputs.kernel-release }}" + "Kernel version: ${{ steps.system-info.outputs.kernel-version }}" + "Name: ${{ steps.system-info.outputs.name }}" + "Platform: ${{ steps.system-info.outputs.platform }}" + "Release: ${{ steps.system-info.outputs.release }}" + "Total memory: ${MEMORY_GB} GB" + ) + + for OUTPUT in "${OUTPUTS[@]}";do + echo "${OUTPUT}" + done + continue-on-error: true + - name: checkout + uses: actions/checkout@v4 + - name: Unshallow + run: | + git fetch --prune --unshallow + - name: Set up Docker Buildx + id: setup-buildx + uses: docker/setup-buildx-action@v3 + with: + driver: remote + endpoint: tcp://buildkit-amd64.ci.svc.cluster.local:1234 + timeout-minutes: 10 + - name: Download artifacts + if: github.event_name != 'schedule' + uses: actions/download-artifact@v4 + with: + name: talos-artifacts + path: _out + - name: Fix artifact permissions + if: github.event_name != 'schedule' + run: | + xargs -a _out/executable-artifacts -I {} chmod +x {} + - name: ci-temp-release-tag + if: github.event_name != 'schedule' + run: | + make ci-temp-release-tag + - name: uki-certs + if: github.event_name == 'schedule' + env: + PLATFORM: linux/amd64 + run: | + make uki-certs + - name: image-cache + env: + IMAGE_REGISTRY: registry.dev.siderolabs.io + MORE_IMAGES: alpine;registry.k8s.io/conformance:v1.32.0-rc.1;registry.k8s.io/e2e-test-images/busybox:1.36.1-1;registry.k8s.io/e2e-test-images/agnhost:2.53;registry.k8s.io/e2e-test-images/httpd:2.4.38-4;registry.k8s.io/e2e-test-images/nonewprivs:1.3;registry.k8s.io/e2e-test-images/jessie-dnsutils:1.7;registry.k8s.io/e2e-test-images/nautilus:1.7;registry.k8s.io/e2e-test-images/sample-apiserver:1.29.2;registry.k8s.io/e2e-test-images/nginx:1.14-4;registry.k8s.io/etcd:3.5.16-0;registry.k8s.io/e2e-test-images/httpd:2.4.39-4 + PLATFORM: linux/amd64,linux/arm64 + PUSH: "true" + run: | + make cache-create + - name: e2e-image-cache + env: + GITHUB_STEP_NAME: ${{ github.job}}-e2e-image-cache + IMAGE_REGISTRY: registry.dev.siderolabs.io + REGISTRY_MIRROR_FLAGS: "no" + SHORT_INTEGRATION_TEST: "yes" + VIA_MAINTENANCE_MODE: "true" + WITH_CONFIG_PATCH: '@hack/test/patches/image-cache.yaml' + WITH_ISO: "true" + run: | + sudo -E make e2e-qemu + - name: save artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: talos-logs-integration-image-cache + path: |- + /tmp/logs-*.tar.gz + /tmp/support-*.zip + retention-days: "5" integration-image-factory: permissions: actions: read diff --git a/.kres.yaml b/.kres.yaml index 9f9308ca4b..d6000eedaf 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -72,6 +72,7 @@ spec: - integration-images - integration-reproducibility-test - integration-cloud-images + - integration-image-cache - integration-image-factory - integration-aws - integration-aws-nvidia-oss @@ -1514,6 +1515,60 @@ spec: PLATFORM: linux/amd64,linux/arm64 IMAGE_REGISTRY: registry.dev.siderolabs.io - name: cloud-images + - name: integration-image-cache + buildxOptions: + enabled: true + depends: + - default + runners: + - self-hosted + - talos + triggerLabels: + - integration/image-cache + steps: + - name: download-artifacts + conditions: + - not-on-schedule + artifactStep: + type: download + artifactName: talos-artifacts + artifactPath: _out + - name: ci-temp-release-tag + conditions: + - not-on-schedule + - name: uki-certs + conditions: + - only-on-schedule + environment: + PLATFORM: linux/amd64 + - name: image-cache + command: cache-create + environment: + PLATFORM: linux/amd64,linux/arm64 + IMAGE_REGISTRY: registry.dev.siderolabs.io + PUSH: true + MORE_IMAGES: "alpine;registry.k8s.io/conformance:v1.32.0-rc.1;registry.k8s.io/e2e-test-images/busybox:1.36.1-1;registry.k8s.io/e2e-test-images/agnhost:2.53;registry.k8s.io/e2e-test-images/httpd:2.4.38-4;registry.k8s.io/e2e-test-images/nonewprivs:1.3;registry.k8s.io/e2e-test-images/jessie-dnsutils:1.7;registry.k8s.io/e2e-test-images/nautilus:1.7;registry.k8s.io/e2e-test-images/sample-apiserver:1.29.2;registry.k8s.io/e2e-test-images/nginx:1.14-4;registry.k8s.io/etcd:3.5.16-0;registry.k8s.io/e2e-test-images/httpd:2.4.39-4" + - name: e2e-image-cache + command: e2e-qemu + withSudo: true + environment: + GITHUB_STEP_NAME: ${{ github.job}}-e2e-image-cache + IMAGE_REGISTRY: registry.dev.siderolabs.io + REGISTRY_MIRROR_FLAGS: no + SHORT_INTEGRATION_TEST: yes + VIA_MAINTENANCE_MODE: true + WITH_CONFIG_PATCH: '@hack/test/patches/image-cache.yaml' + WITH_ISO: true + - name: save-talos-logs + conditions: + - always + artifactStep: + type: upload + artifactName: talos-logs-integration-image-cache + disableExecutableListGeneration: true + artifactPath: /tmp/logs-*.tar.gz + additionalArtifacts: + - "/tmp/support-*.zip" - name: integration-image-factory buildxOptions: enabled: true diff --git a/Makefile b/Makefile index d5fb64a256..179d06de84 100644 --- a/Makefile +++ b/Makefile @@ -125,6 +125,7 @@ SHORT_INTEGRATION_TEST ?= CUSTOM_CNI_URL ?= INSTALLER_ARCH ?= all IMAGER_ARGS ?= +MORE_IMAGES ?= CGO_ENABLED ?= 0 GO_BUILDFLAGS ?= @@ -459,6 +460,12 @@ uki-certs: talosctl ## Generate test certificates for SecureBoot/PCR Signing @$(TALOSCTL_EXECUTABLE) gen secureboot pcr @$(TALOSCTL_EXECUTABLE) gen secureboot database +.PHONY: cache-create +cache-create: installer imager ## Generate image cache. + @( $(TALOSCTL_EXECUTABLE) images default | grep -v 'siderolabs/installer'; echo "$(REGISTRY_AND_USERNAME)/installer:$(IMAGE_TAG)"; echo "$(MORE_IMAGES)" | tr ';' '\n' ) | $(TALOSCTL_EXECUTABLE) images cache-create --image-cache-path=/tmp/cache.tar --images=- --force + @crane push /tmp/cache.tar $(REGISTRY_AND_USERNAME)/image-cache:$(IMAGE_TAG) + @$(MAKE) image-iso IMAGER_ARGS="--image-cache=$(REGISTRY_AND_USERNAME)/image-cache:$(IMAGE_TAG) --extra-kernel-arg='console=ttyS0'" + # Code Quality api-descriptors: ## Generates API descriptors used to detect breaking API changes. diff --git a/hack/test/e2e-qemu.sh b/hack/test/e2e-qemu.sh index 51e6c0aef4..e91f362053 100755 --- a/hack/test/e2e-qemu.sh +++ b/hack/test/e2e-qemu.sh @@ -131,6 +131,14 @@ case "${WITH_CONFIG_PATCH:-false}" in ;; esac +case "${WITH_ISO:-false}" in + false) + ;; + *) + QEMU_FLAGS+=("--iso-path=${ARTIFACTS}/metal-amd64.iso") + ;; +esac + case "${WITH_CONFIG_PATCH_WORKER:-false}" in false) ;; diff --git a/hack/test/e2e.sh b/hack/test/e2e.sh index 4a8241dd11..75089755be 100755 --- a/hack/test/e2e.sh +++ b/hack/test/e2e.sh @@ -142,6 +142,12 @@ function dump_cluster_state { } function build_registry_mirrors { + if [[ "${REGISTRY_MIRROR_FLAGS:-yes}" == "no" ]]; then + REGISTRY_MIRROR_FLAGS=() + + return + fi + if [[ "${CI:-false}" == "true" ]]; then REGISTRY_MIRROR_FLAGS=() @@ -151,9 +157,6 @@ function build_registry_mirrors { REGISTRY_MIRROR_FLAGS+=("--registry-mirror=${registry}=http://${addr}:5000") done - else - # use the value from the environment, if present - REGISTRY_MIRROR_FLAGS=("${REGISTRY_MIRROR_FLAGS:-}") fi } diff --git a/hack/test/patches/image-cache.yaml b/hack/test/patches/image-cache.yaml new file mode 100644 index 0000000000..76b1585856 --- /dev/null +++ b/hack/test/patches/image-cache.yaml @@ -0,0 +1,25 @@ +machine: + features: + imageCache: + localEnabled: true + registries: + mirrors: + "*": + skipFallback: true + endpoints: + - http://172.20.0.251:65000 + k8s.gcr.io: + skipFallback: true + endpoints: + - http://172.20.0.251:65000 + registry.k8s.io: + skipFallback: true + endpoints: + - http://172.20.0.251:65000 +--- +apiVersion: v1alpha1 +kind: VolumeConfig +name: IMAGECACHE +provisioning: + diskSelector: + match: 'system_disk' diff --git a/internal/integration/cli/image.go b/internal/integration/cli/image.go index 32c624625c..4f58391422 100644 --- a/internal/integration/cli/image.go +++ b/internal/integration/cli/image.go @@ -47,10 +47,19 @@ func (suite *ImageSuite) TestList() { ) } +var imageCacheQuery = []string{"get", "imagecacheconfig", "--output", "jsonpath='{.spec.copyStatus}'"} + // TestPull verifies pulling images to the CRI. func (suite *ImageSuite) TestPull() { + const image = "registry.k8s.io/kube-apiserver:v1.27.0" + node := suite.RandomDiscoveredNodeInternalIP() - image := "registry.k8s.io/kube-apiserver:v1.27.0" + + if stdout, _ := suite.RunCLI(imageCacheQuery); strings.Contains(stdout, "ready") { + suite.T().Logf("skipping as the image cache is present") + + return + } suite.RunCLI([]string{"image", "pull", "--nodes", node, image}, base.StdoutEmpty(), diff --git a/internal/integration/cli/list.go b/internal/integration/cli/list.go index fd8c3a6468..2999f10598 100644 --- a/internal/integration/cli/list.go +++ b/internal/integration/cli/list.go @@ -7,7 +7,6 @@ package cli import ( - "fmt" "os" "regexp" "strings" @@ -40,10 +39,17 @@ func (suite *ListSuite) TestSuccess() { // TestDepth tests various combinations of --recurse and --depth flags. func (suite *ListSuite) TestDepth() { - suite.T().Parallel() - node := suite.RandomDiscoveredNodeInternalIP(machine.TypeControlPlane) + // Expected maximum number of separators in the output + // In plain terms, it's the maximum depth of the directory tree + maxSeps := 5 + + if stdout, _ := suite.RunCLI(imageCacheQuery); strings.Contains(stdout, "ready") { + // Image cache paths parts are longer + maxSeps = 8 + } + // checks that enough separators are encountered in the output runAndCheck := func(t *testing.T, expectedSeparators int, flags ...string) { args := append([]string{"list", "--nodes", node, "/system"}, flags...) @@ -59,24 +65,28 @@ func (suite *ListSuite) TestDepth() { for _, line := range lines[2:] { actualSeparators := strings.Count(strings.Fields(line)[1], string(os.PathSeparator)) - msg := fmt.Sprintf( - "too many separators (actualSeparators = %d, expectedSeparators = %d)\nflags: %s\nlines:\n%s", - actualSeparators, expectedSeparators, strings.Join(flags, " "), strings.Join(lines, "\n"), - ) - if !assert.LessOrEqual(t, actualSeparators, expectedSeparators, msg) { + if !assert.LessOrEqual( + t, + actualSeparators, + expectedSeparators, + "too many separators, flags: %s\nlines:\n%s", + strings.Join(flags, " "), + stdout, + ) { return } - if maxActualSeparators < actualSeparators { - maxActualSeparators = actualSeparators - } + maxActualSeparators = max(maxActualSeparators, actualSeparators) } - msg := fmt.Sprintf( - "not enough separators (maxActualSeparators = %d, expectedSeparators = %d)\nflags: %s\nlines:\n%s", - maxActualSeparators, expectedSeparators, strings.Join(flags, " "), strings.Join(lines, "\n"), + assert.Equal( + t, + expectedSeparators, + maxActualSeparators, + "not enough separators, \nflags: %s\nlines:\n%s", + strings.Join(flags, " "), + stdout, ) - assert.Equal(t, maxActualSeparators, expectedSeparators, msg) } for _, test := range []struct { @@ -84,19 +94,15 @@ func (suite *ListSuite) TestDepth() { flags []string }{ {separators: 0}, - {separators: 0, flags: []string{"--recurse=false"}}, - {separators: 0, flags: []string{"--depth=-1"}}, {separators: 0, flags: []string{"--depth=0"}}, {separators: 0, flags: []string{"--depth=1"}}, {separators: 1, flags: []string{"--depth=2"}}, {separators: 2, flags: []string{"--depth=3"}}, - - {separators: 5, flags: []string{"--recurse=true"}}, + {separators: maxSeps, flags: []string{"--recurse=true"}}, } { suite.Run(strings.Join(test.flags, ","), func() { - suite.T().Parallel() runAndCheck(suite.T(), test.separators, test.flags...) }) } diff --git a/pkg/imager/cache/cache.go b/pkg/imager/cache/cache.go index df2c12ed22..9f5af3726b 100644 --- a/pkg/imager/cache/cache.go +++ b/pkg/imager/cache/cache.go @@ -37,6 +37,15 @@ const ( manifestsDir = "manifests" ) +// rewriteRegistry name back to workaround https://github.com/google/go-containerregistry/pull/69. +func rewriteRegistry(registryName, origRef string) string { + if registryName == name.DefaultRegistry && !strings.HasPrefix(origRef, name.DefaultRegistry+"/") { + return "docker.io" + } + + return registryName +} + // Generate generates a cache tarball from the given images. // //nolint:gocyclo,cyclop @@ -65,9 +74,7 @@ func Generate(images []string, platform string, insecure bool, imageLayerCachePa return err } - nameOptions := []name.Option{ - name.StrictValidation, - } + var nameOptions []name.Option craneOpts := []crane.Option{ crane.WithAuthFromKeychain( @@ -99,17 +106,17 @@ func Generate(images []string, platform string, insecure bool, imageLayerCachePa return fmt.Errorf("parsing reference %q: %w", src, err) } - referenceDir := filepath.Join(tmpDir, manifestsDir, ref.Context().RegistryStr(), ref.Context().RepositoryStr(), "reference") - digestDir := filepath.Join(tmpDir, manifestsDir, ref.Context().RegistryStr(), ref.Context().RepositoryStr(), "digest") + referenceDir := filepath.Join(tmpDir, manifestsDir, rewriteRegistry(ref.Context().RegistryStr(), src), ref.Context().RepositoryStr(), "reference") + digestDir := filepath.Join(tmpDir, manifestsDir, rewriteRegistry(ref.Context().RegistryStr(), src), ref.Context().RepositoryStr(), "digest") - // get the tag from the reference (if it's there) - var tag name.Tag + // if the reference was parsed as a tag, use it + tag, ok := ref.(name.Tag) - base, _, ok := strings.Cut(src, "@") if !ok { - tag, _ = name.NewTag(src, nameOptions...) //nolint:errcheck - } else { - tag, _ = name.NewTag(base, nameOptions...) //nolint:errcheck + if base, _, ok := strings.Cut(src, "@"); ok { + // if the reference was a digest, but contained a tag, re-parse it + tag, _ = name.NewTag(base, nameOptions...) //nolint:errcheck + } } if err = os.MkdirAll(referenceDir, 0o755); err != nil { @@ -121,11 +128,11 @@ func Generate(images []string, platform string, insecure bool, imageLayerCachePa } manifest, err := crane.Manifest( - src, + ref.String(), craneOpts..., ) if err != nil { - return fmt.Errorf("fetching manifest %q: %w", src, err) + return fmt.Errorf("fetching manifest %q: %w", ref.String(), err) } rmt, err := remote.Get( @@ -133,7 +140,7 @@ func Generate(images []string, platform string, insecure bool, imageLayerCachePa remoteOpts..., ) if err != nil { - return fmt.Errorf("fetching image %q: %w", src, err) + return fmt.Errorf("fetching image %q: %w", ref.String(), err) } if tag.TagStr() != "" { From f9699249084b2587b831b9cd8461b5b15e1cae6a Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 5 Dec 2024 14:47:47 +0400 Subject: [PATCH 08/14] chore: update Go to 1.23.4 Via pkgs/tools. Signed-off-by: Andrey Smirnov (cherry picked from commit d0773ff09df84b2dac8ecadc91023596050ce098) --- Makefile | 2 +- hack/release.toml | 2 +- pkg/machinery/constants/constants.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 179d06de84..d8483130a4 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ ZSTD_COMPRESSION_LEVEL ?= 18 CI_RELEASE_TAG := $(shell git log --oneline --format=%B -n 1 HEAD^2 -- 2>/dev/null | head -n 1 | sed -r "/^release\(.*\)/ s/^release\((.*)\):.*$$/\\1/; t; Q") ARTIFACTS := _out -TOOLS ?= ghcr.io/siderolabs/tools:v1.9.0 +TOOLS ?= ghcr.io/siderolabs/tools:v1.9.0-1-geaad82f DEBUG_TOOLS_SOURCE := scratch diff --git a/hack/release.toml b/hack/release.toml index e4c24705f8..ae019f55da 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -25,7 +25,7 @@ preface = """ * runc: 1.2.1 * CoreDNS: 1.12.0 -Talos is built with Go 1.23.3. +Talos is built with Go 1.23.4. """ [notes.cgroupsv1] diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 8b43867201..69c4dc8901 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -1095,7 +1095,7 @@ const ( DBusClientSocketLabel = "system_u:object_r:dbus_client_socket_t:s0" // GoVersion is the version of Go compiler this release was built with. - GoVersion = "go1.23.3" + GoVersion = "go1.23.4" // KubernetesTalosAPIServiceName is the name of the Kubernetes service to access Talos API. KubernetesTalosAPIServiceName = "talos" From 58e18de0b9d2ad055b0ecaea98e8dfb811660e61 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 6 Dec 2024 19:22:33 +0400 Subject: [PATCH 09/14] chore: add version compatibility for Talos 1.10 To be backported to 1.9 machinery to provide some forward compatibility. Signed-off-by: Andrey Smirnov (cherry picked from commit 14841750bf2fc09a9de0b32a7af0dc3f76e1019a) --- .../compatibility/kubernetes_version.go | 3 ++ .../compatibility/kubernetes_version_test.go | 37 +++++++++++++- .../compatibility/talos110/talos110.go | 28 +++++++++++ pkg/machinery/compatibility/talos_version.go | 4 ++ .../compatibility/talos_version_test.go | 49 +++++++++++++++++-- pkg/machinery/config/contract.go | 1 + pkg/machinery/config/contract_test.go | 23 +++++++++ 7 files changed, 139 insertions(+), 6 deletions(-) create mode 100644 pkg/machinery/compatibility/talos110/talos110.go diff --git a/pkg/machinery/compatibility/kubernetes_version.go b/pkg/machinery/compatibility/kubernetes_version.go index 8a3cac2714..6e25ae5d17 100644 --- a/pkg/machinery/compatibility/kubernetes_version.go +++ b/pkg/machinery/compatibility/kubernetes_version.go @@ -10,6 +10,7 @@ import ( "github.com/blang/semver/v4" "github.com/siderolabs/gen/pair/ordered" + "github.com/siderolabs/talos/pkg/machinery/compatibility/talos110" "github.com/siderolabs/talos/pkg/machinery/compatibility/talos12" "github.com/siderolabs/talos/pkg/machinery/compatibility/talos13" "github.com/siderolabs/talos/pkg/machinery/compatibility/talos14" @@ -64,6 +65,8 @@ func (v *KubernetesVersion) SupportedWith(target *TalosVersion) error { minK8sVersion, maxK8sVersion = talos18.MinimumKubernetesVersion, talos18.MaximumKubernetesVersion case talos19.MajorMinor: // upgrades to 1.9.x minK8sVersion, maxK8sVersion = talos19.MinimumKubernetesVersion, talos19.MaximumKubernetesVersion + case talos110.MajorMinor: // upgrades to 1.10.x + minK8sVersion, maxK8sVersion = talos110.MinimumKubernetesVersion, talos110.MaximumKubernetesVersion default: return fmt.Errorf("compatibility with version %s is not supported", target.String()) } diff --git a/pkg/machinery/compatibility/kubernetes_version_test.go b/pkg/machinery/compatibility/kubernetes_version_test.go index 11eb97545c..402440e772 100644 --- a/pkg/machinery/compatibility/kubernetes_version_test.go +++ b/pkg/machinery/compatibility/kubernetes_version_test.go @@ -286,12 +286,45 @@ func TestKubernetesCompatibility19(t *testing.T) { } } +func TestKubernetesCompatibility110(t *testing.T) { + for _, tt := range []kubernetesVersionTest{ + { + kubernetesVersion: "1.29.1", + target: "1.10.0", + }, + { + kubernetesVersion: "1.28.1", + target: "1.10.0", + }, + { + kubernetesVersion: "1.32.3", + target: "1.10.0-beta.0", + }, + { + kubernetesVersion: "1.33.0-rc.0", + target: "1.10.7", + }, + { + kubernetesVersion: "1.34.0-alpha.0", + target: "1.10.0", + expectedError: "version of Kubernetes 1.34.0-alpha.0 is too new to be used with Talos 1.10.0", + }, + { + kubernetesVersion: "1.27.1", + target: "1.10.0", + expectedError: "version of Kubernetes 1.27.1 is too old to be used with Talos 1.10.0", + }, + } { + runKubernetesVersionTest(t, tt) + } +} + func TestKubernetesCompatibilityUnsupported(t *testing.T) { for _, tt := range []kubernetesVersionTest{ { kubernetesVersion: "1.25.0", - target: "1.10.0-alpha.0", - expectedError: "compatibility with version 1.10.0-alpha.0 is not supported", + target: "1.11.0-alpha.0", + expectedError: "compatibility with version 1.11.0-alpha.0 is not supported", }, { kubernetesVersion: "1.25.0", diff --git a/pkg/machinery/compatibility/talos110/talos110.go b/pkg/machinery/compatibility/talos110/talos110.go new file mode 100644 index 0000000000..c9f1c54728 --- /dev/null +++ b/pkg/machinery/compatibility/talos110/talos110.go @@ -0,0 +1,28 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package talos110 provides compatibility constants for Talos 1.10. +package talos110 + +import ( + "github.com/blang/semver/v4" +) + +// MajorMinor is the major.minor version of Talos 1.10. +var MajorMinor = [2]uint64{1, 10} + +// MinimumHostUpgradeVersion is the minimum version of Talos that can be upgraded to 1.10. +var MinimumHostUpgradeVersion = semver.MustParse("1.8.0") + +// MaximumHostDowngradeVersion is the maximum (not inclusive) version of Talos that can be downgraded to 1.10. +var MaximumHostDowngradeVersion = semver.MustParse("1.12.0") + +// DeniedHostUpgradeVersions are the versions of Talos that cannot be upgraded to 1.10. +var DeniedHostUpgradeVersions []semver.Version + +// MinimumKubernetesVersion is the minimum version of Kubernetes is supported with 1.10. +var MinimumKubernetesVersion = semver.MustParse("1.28.0") + +// MaximumKubernetesVersion is the maximum version of Kubernetes is supported with 1.10. +var MaximumKubernetesVersion = semver.MustParse("1.33.99") diff --git a/pkg/machinery/compatibility/talos_version.go b/pkg/machinery/compatibility/talos_version.go index 5d5b392c85..7c6281af39 100644 --- a/pkg/machinery/compatibility/talos_version.go +++ b/pkg/machinery/compatibility/talos_version.go @@ -11,6 +11,7 @@ import ( "github.com/siderolabs/gen/pair/ordered" "github.com/siderolabs/talos/pkg/machinery/api/machine" + "github.com/siderolabs/talos/pkg/machinery/compatibility/talos110" "github.com/siderolabs/talos/pkg/machinery/compatibility/talos12" "github.com/siderolabs/talos/pkg/machinery/compatibility/talos13" "github.com/siderolabs/talos/pkg/machinery/compatibility/talos14" @@ -98,6 +99,9 @@ func (v *TalosVersion) UpgradeableFrom(host *TalosVersion) error { case talos19.MajorMinor: // upgrades to 1.9.x minHostUpgradeVersion, maxHostDowngradeVersion = talos19.MinimumHostUpgradeVersion, talos19.MaximumHostDowngradeVersion deniedHostUpgradeVersions = talos19.DeniedHostUpgradeVersions + case talos110.MajorMinor: // upgrades to 1.10.x + minHostUpgradeVersion, maxHostDowngradeVersion = talos110.MinimumHostUpgradeVersion, talos110.MaximumHostDowngradeVersion + deniedHostUpgradeVersions = talos110.DeniedHostUpgradeVersions default: return fmt.Errorf("upgrades to version %s are not supported", v.version.String()) } diff --git a/pkg/machinery/compatibility/talos_version_test.go b/pkg/machinery/compatibility/talos_version_test.go index 4293b206e9..b259076895 100644 --- a/pkg/machinery/compatibility/talos_version_test.go +++ b/pkg/machinery/compatibility/talos_version_test.go @@ -327,17 +327,58 @@ func TestTalosUpgradeCompatibility19(t *testing.T) { } } +func TestTalosUpgradeCompatibility110(t *testing.T) { + for _, tt := range []talosVersionTest{ + { + host: "1.8.0", + target: "1.10.0", + }, + { + host: "1.9.0-alpha.0", + target: "1.10.0", + }, + { + host: "1.8.0", + target: "1.10.0-alpha.0", + }, + { + host: "1.9.3", + target: "1.10.1", + }, + { + host: "1.10.0-beta.0", + target: "1.10.0", + }, + { + host: "1.10.5", + target: "1.10.3", + }, + { + host: "1.7.0", + target: "1.10.0", + expectedError: `host version 1.7.0 is too old to upgrade to Talos 1.10.0`, + }, + { + host: "1.12.0-alpha.0", + target: "1.10.0", + expectedError: `host version 1.12.0-alpha.0 is too new to downgrade to Talos 1.10.0`, + }, + } { + runTalosVersionTest(t, tt) + } +} + func TestTalosUpgradeCompatibilityUnsupported(t *testing.T) { for _, tt := range []talosVersionTest{ { host: "1.3.0", - target: "1.10.0-alpha.0", - expectedError: `upgrades to version 1.10.0-alpha.0 are not supported`, + target: "1.11.0-alpha.0", + expectedError: `upgrades to version 1.11.0-alpha.0 are not supported`, }, { host: "1.4.0", - target: "1.11.0-alpha.0", - expectedError: `upgrades to version 1.11.0-alpha.0 are not supported`, + target: "1.12.0-alpha.0", + expectedError: `upgrades to version 1.12.0-alpha.0 are not supported`, }, } { runTalosVersionTest(t, tt) diff --git a/pkg/machinery/config/contract.go b/pkg/machinery/config/contract.go index d8f27a53c6..f9ab5c7c46 100644 --- a/pkg/machinery/config/contract.go +++ b/pkg/machinery/config/contract.go @@ -25,6 +25,7 @@ type VersionContract struct { // Well-known Talos version contracts. var ( TalosVersionCurrent = (*VersionContract)(nil) + TalosVersion1_10 = &VersionContract{1, 10} TalosVersion1_9 = &VersionContract{1, 9} TalosVersion1_8 = &VersionContract{1, 8} TalosVersion1_7 = &VersionContract{1, 7} diff --git a/pkg/machinery/config/contract_test.go b/pkg/machinery/config/contract_test.go index 0994630aa6..6191d62952 100644 --- a/pkg/machinery/config/contract_test.go +++ b/pkg/machinery/config/contract_test.go @@ -67,6 +67,29 @@ func TestContractCurrent(t *testing.T) { assert.True(t, contract.SecureBootEnrollEnforcementSupported()) } +func TestContract1_10(t *testing.T) { + contract := config.TalosVersion1_9 + + assert.True(t, contract.PodSecurityAdmissionEnabled()) + assert.True(t, contract.StableHostnameEnabled()) + assert.True(t, contract.KubeletDefaultRuntimeSeccompProfileEnabled()) + assert.False(t, contract.KubernetesAlternateImageRegistries()) + assert.True(t, contract.KubernetesAllowSchedulingOnControlPlanes()) + assert.True(t, contract.KubernetesDiscoveryBackendDisabled()) + assert.True(t, contract.ApidExtKeyUsageCheckEnabled()) + assert.True(t, contract.APIServerAuditPolicySupported()) + assert.True(t, contract.KubeletManifestsDirectoryDisabled()) + assert.True(t, contract.SecretboxEncryptionSupported()) + assert.True(t, contract.DiskQuotaSupportEnabled()) + assert.True(t, contract.KubePrismEnabled()) + assert.True(t, contract.HostDNSEnabled()) + assert.True(t, contract.UseRSAServiceAccountKey()) + assert.True(t, contract.ClusterNameForWorkers()) + assert.True(t, contract.HostDNSForwardKubeDNSToHost()) + assert.True(t, contract.AddExcludeFromExternalLoadBalancer()) + assert.True(t, contract.SecureBootEnrollEnforcementSupported()) +} + func TestContract1_9(t *testing.T) { contract := config.TalosVersion1_9 From 50ea588133405c67770917a7a424f33dd8d17545 Mon Sep 17 00:00:00 2001 From: Utku Ozdemir Date: Sun, 8 Dec 2024 23:29:52 +0100 Subject: [PATCH 10/14] docs: fix a few mistakes in release notes Couple of syntax and grammar corrections. Signed-off-by: Utku Ozdemir (cherry picked from commit cb4d9d673432e4a0fba0d87bc64fde620d991082) --- hack/release.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hack/release.toml b/hack/release.toml index ae019f55da..c31dfcf44a 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -40,7 +40,7 @@ Support for cgroupsv1 is deprecated, and will be removed in Talos 1.10 (for non- Starting with Talos 1.9, `.cluster.apiServer.authorizationConfig` field supports setting [Kubernetes API server authorization modes](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#using-configuration-file-for-authorization) using the `--authorization-config` flag. -The machine config field supports a list of `authorizers`. For eg: +The machine config field supports a list of `authorizers`. For instance: ```yaml cluster: @@ -48,12 +48,12 @@ cluster: authorizationConfig: - type: Node name: Node - - type RBAC + - type: RBAC name: rbac ``` For new cluster if the Kubernetes API server supports the `--authorization-config` flag, it'll be used by default instead of the `--authorization-mode` flag. -By default Talos will always add the `Node` and ` RBAC` authorizers to the list. +By default Talos will always add the `Node` and `RBAC` authorizers to the list. When upgrading if either a user-provided `authorization-mode` or `authorization-webhook-*` flag is set via `.cluster.apiServer.extraArgs`, it'll be used instead of the new `AuthorizationConfig`. @@ -79,7 +79,7 @@ Refer to the [documentation](https://www.talos.dev/v1.9/kubernetes-guides/config [notes.auditd] title = "Auditd" description = """\ -Talos Linux now starts a auditd service by default. +Talos Linux now starts an auditd service by default. Logs can be read with `talosctl logs auditd`. """ From 3a0c34538cc5e633204b487afb03ca4e3e016d81 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 6 Dec 2024 19:02:15 +0400 Subject: [PATCH 11/14] fix: install iptables-nft to the host These are used by CNI plugins. Fixes #9883 See https://github.com/siderolabs/pkgs/pull/1106 Signed-off-by: Andrey Smirnov (cherry picked from commit 07220fe7f5a22444f7a085f5868f628ddd912b6d) --- Dockerfile | 12 ++++++++++++ Makefile | 6 +++++- pkg/machinery/gendata/data/pkgs | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f1278f0133..93375e6982 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,8 @@ ARG PKG_IPTABLES=scratch ARG PKG_IPXE=scratch ARG PKG_LIBINIH=scratch ARG PKG_LIBJSON_C=scratch +ARG PKG_LIBMNL=scratch +ARG PKG_LIBNFTNL=scratch ARG PKG_LIBPOPT=scratch ARG PKG_LIBSEPOL=scratch ARG PKG_LIBSELINUX=scratch @@ -92,6 +94,12 @@ FROM --platform=arm64 ${PKG_LIBINIH} AS pkg-libinih-arm64 FROM --platform=amd64 ${PKG_LIBJSON_C} AS pkg-libjson-c-amd64 FROM --platform=arm64 ${PKG_LIBJSON_C} AS pkg-libjson-c-arm64 +FROM --platform=amd64 ${PKG_LIBMNL} AS pkg-libmnl-amd64 +FROM --platform=arm64 ${PKG_LIBMNL} AS pkg-libmnl-arm64 + +FROM --platform=amd64 ${PKG_LIBNFTNL} AS pkg-libnftnl-amd64 +FROM --platform=arm64 ${PKG_LIBNFTNL} AS pkg-libnftnl-arm64 + FROM --platform=amd64 ${PKG_LIBPOPT} AS pkg-libpopt-amd64 FROM --platform=arm64 ${PKG_LIBPOPT} AS pkg-libpopt-arm64 @@ -683,6 +691,8 @@ COPY --link --from=pkg-libcap-amd64 / /rootfs COPY --link --from=pkg-iptables-amd64 / /rootfs COPY --link --from=pkg-libinih-amd64 / /rootfs COPY --link --from=pkg-libjson-c-amd64 / /rootfs +COPY --link --from=pkg-libmnl-amd64 / /rootfs +COPY --link --from=pkg-libnftnl-amd64 / /rootfs COPY --link --from=pkg-libpopt-amd64 / /rootfs COPY --link --from=pkg-liburcu-amd64 / /rootfs COPY --link --from=pkg-libsepol-amd64 / /rootfs @@ -757,6 +767,8 @@ COPY --link --from=pkg-libcap-arm64 / /rootfs COPY --link --from=pkg-iptables-arm64 / /rootfs COPY --link --from=pkg-libinih-arm64 / /rootfs COPY --link --from=pkg-libjson-c-arm64 / /rootfs +COPY --link --from=pkg-libmnl-arm64 / /rootfs +COPY --link --from=pkg-libnftnl-arm64 / /rootfs COPY --link --from=pkg-libpopt-arm64 / /rootfs COPY --link --from=pkg-liburcu-arm64 / /rootfs COPY --link --from=pkg-libsepol-arm64 / /rootfs diff --git a/Makefile b/Makefile index d8483130a4..38e83f1253 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ TOOLS ?= ghcr.io/siderolabs/tools:v1.9.0-1-geaad82f DEBUG_TOOLS_SOURCE := scratch PKGS_PREFIX ?= ghcr.io/siderolabs -PKGS ?= v1.9.0-1-gb047e41 +PKGS ?= v1.9.0-5-g5d559d0 EXTRAS ?= v1.9.0 KRES_IMAGE ?= ghcr.io/siderolabs/kres:latest @@ -43,6 +43,8 @@ PKG_IPTABLES ?= $(PKGS_PREFIX)/iptables:$(PKGS) PKG_IPXE ?= $(PKGS_PREFIX)/ipxe:$(PKGS) PKG_LIBINIH ?= $(PKGS_PREFIX)/libinih:$(PKGS) PKG_LIBJSON_C ?= $(PKGS_PREFIX)/libjson-c:$(PKGS) +PKG_LIBMNL ?= $(PKGS_PREFIX)/libmnl:$(PKGS) +PKG_LIBNFTNL ?= $(PKGS_PREFIX)/libnftnl:$(PKGS) PKG_LIBPOPT ?= $(PKGS_PREFIX)/libpopt:$(PKGS) PKG_LIBSEPOL ?= $(PKGS_PREFIX)/libsepol:$(PKGS) PKG_LIBSELINUX ?= $(PKGS_PREFIX)/libselinux:$(PKGS) @@ -220,6 +222,8 @@ COMMON_ARGS += --build-arg=PKG_IPTABLES=$(PKG_IPTABLES) COMMON_ARGS += --build-arg=PKG_IPXE=$(PKG_IPXE) COMMON_ARGS += --build-arg=PKG_LIBINIH=$(PKG_LIBINIH) COMMON_ARGS += --build-arg=PKG_LIBJSON_C=$(PKG_LIBJSON_C) +COMMON_ARGS += --build-arg=PKG_LIBMNL=$(PKG_LIBMNL) +COMMON_ARGS += --build-arg=PKG_LIBNFTNL=$(PKG_LIBNFTNL) COMMON_ARGS += --build-arg=PKG_LIBSEPOL=$(PKG_LIBSEPOL) COMMON_ARGS += --build-arg=PKG_LIBSELINUX=$(PKG_LIBSELINUX) COMMON_ARGS += --build-arg=PKG_PCRE2=$(PKG_PCRE2) diff --git a/pkg/machinery/gendata/data/pkgs b/pkg/machinery/gendata/data/pkgs index bcf503a0aa..25910c7fd7 100644 --- a/pkg/machinery/gendata/data/pkgs +++ b/pkg/machinery/gendata/data/pkgs @@ -1 +1 @@ -v1.9.0-1-gb047e41 \ No newline at end of file +v1.9.0-5-g5d559d0 \ No newline at end of file From ebf1d844e6f341ed60c6c27769a1a12aa2c8af33 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Fri, 6 Dec 2024 22:11:44 +0400 Subject: [PATCH 12/14] feat: update Linux to 6.12.3 Latest 6.12.x release. Signed-off-by: Andrey Smirnov (cherry picked from commit c3537b2f5491a890f626ba8fc47034d5059808af) --- .conform.yaml | 4 ++-- .kres.yaml | 1 + hack/release.toml | 2 +- pkg/machinery/constants/constants.go | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.conform.yaml b/.conform.yaml index e95ecdf107..696bba42a1 100644 --- a/.conform.yaml +++ b/.conform.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-07-05T14:59:05Z by kres 8c8b007. +# Generated on 2024-12-09T11:04:11Z by kres 8183c20. policies: - type: commit @@ -12,7 +12,7 @@ policies: gitHubOrganization: siderolabs spellcheck: locale: US - maximumOfOneCommit: true + maximumOfOneCommit: false header: length: 89 imperative: true diff --git a/.kres.yaml b/.kres.yaml index d6000eedaf..6a7b77e904 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -19,6 +19,7 @@ spec: --- kind: common.Repository spec: + conformMaximumOfOneCommit: false conformScopes: - apid - machined diff --git a/hack/release.toml b/hack/release.toml index c31dfcf44a..dd1372045c 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -18,7 +18,7 @@ preface = """ [notes.updates] title = "Component Updates" description = """\ -* Linux: 6.12.1 +* Linux: 6.12.3 * containerd: 2.0.0 * Flannel: 0.26.1 * Kubernetes: 1.32.0-rc.1 diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 69c4dc8901..9cef83902c 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -14,7 +14,7 @@ import ( const ( // DefaultKernelVersion is the default Linux kernel version. - DefaultKernelVersion = "6.12.1-talos" + DefaultKernelVersion = "6.12.3-talos" // KernelModulesPath is the default path to the kernel modules without the kernel version. KernelModulesPath = "/lib/modules" From c715695c6d29280df08658c928a926c1e48b10a9 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Mon, 9 Dec 2024 19:34:21 +0400 Subject: [PATCH 13/14] test: fix user namespace test, TPM2 fixes Make sure the test runs on a specific node, wait for swtpm to be up. Signed-off-by: Andrey Smirnov --- .../k8s/testdata/usernamespace.yaml | 1 + internal/integration/k8s/usernamespace.go | 8 ++++++- pkg/provision/providers/qemu/launch.go | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/internal/integration/k8s/testdata/usernamespace.yaml b/internal/integration/k8s/testdata/usernamespace.yaml index 3feaa32104..dc399a1295 100644 --- a/internal/integration/k8s/testdata/usernamespace.yaml +++ b/internal/integration/k8s/testdata/usernamespace.yaml @@ -5,6 +5,7 @@ metadata: namespace: default spec: hostUsers: false + nodeName: $NODE$ containers: - name: userns command: ["/bin/sh", "-c", "--"] diff --git a/internal/integration/k8s/usernamespace.go b/internal/integration/k8s/usernamespace.go index 7b40881e07..7a317b7313 100644 --- a/internal/integration/k8s/usernamespace.go +++ b/internal/integration/k8s/usernamespace.go @@ -96,7 +96,13 @@ func (suite *UserNamespaceSuite) TestUserNamespace() { } } - usernamespacePodManifest := suite.ParseManifests(userNamespacePodSpec) + k8sNode, err := suite.GetK8sNodeByInternalIP(ctx, node) + suite.Require().NoError(err) + + suite.T().Logf("testing k8s user namespace on node %q (%q)", node, k8sNode.Name) + + // bind the pod to the node + usernamespacePodManifest := suite.ParseManifests(bytes.ReplaceAll(userNamespacePodSpec, []byte("$NODE$"), []byte(k8sNode.Name))) suite.T().Cleanup(func() { cleanUpCtx, cleanupCancel := context.WithTimeout(context.Background(), time.Minute) diff --git a/pkg/provision/providers/qemu/launch.go b/pkg/provision/providers/qemu/launch.go index efe9aa0554..4a06f0f0d3 100644 --- a/pkg/provision/providers/qemu/launch.go +++ b/pkg/provision/providers/qemu/launch.go @@ -15,6 +15,7 @@ import ( "path/filepath" "strconv" "strings" + "time" "github.com/alexflint/go-filemutex" "github.com/containernetworking/cni/libcni" @@ -428,6 +429,10 @@ func launchVM(config *LaunchConfig) error { return err } + if err := waitForFileToExist(tpm2SocketPath, 5*time.Second); err != nil { + return err + } + args = append(args, config.ArchitectureData.TPMDeviceArgs(tpm2SocketPath)..., ) @@ -565,3 +570,21 @@ func Launch() error { } }) } + +func waitForFileToExist(path string, timeout time.Duration) error { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + if _, err := os.Stat(path); err == nil { + return nil + } + } + + time.Sleep(100 * time.Millisecond) + } +} From 830e95ace13dacfe8a61dcdda7771c7dd5f3fe3c Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 10 Dec 2024 14:10:35 +0400 Subject: [PATCH 14/14] feat: update Linux to 6.12.4 Update to the latest 6.12.x, fixes kexec reboot in QEMU. Signed-off-by: Andrey Smirnov (cherry picked from commit d946ccae31b87559a06cb1cefcefe8f937b73d8b) --- Makefile | 2 +- hack/release.toml | 2 +- pkg/machinery/constants/constants.go | 2 +- pkg/machinery/gendata/data/pkgs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 38e83f1253..6e0aa90b1d 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ TOOLS ?= ghcr.io/siderolabs/tools:v1.9.0-1-geaad82f DEBUG_TOOLS_SOURCE := scratch PKGS_PREFIX ?= ghcr.io/siderolabs -PKGS ?= v1.9.0-5-g5d559d0 +PKGS ?= v1.9.0-6-gabba1d8 EXTRAS ?= v1.9.0 KRES_IMAGE ?= ghcr.io/siderolabs/kres:latest diff --git a/hack/release.toml b/hack/release.toml index dd1372045c..f1c8b422be 100644 --- a/hack/release.toml +++ b/hack/release.toml @@ -18,7 +18,7 @@ preface = """ [notes.updates] title = "Component Updates" description = """\ -* Linux: 6.12.3 +* Linux: 6.12.4 * containerd: 2.0.0 * Flannel: 0.26.1 * Kubernetes: 1.32.0-rc.1 diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index 9cef83902c..6e76a357fa 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -14,7 +14,7 @@ import ( const ( // DefaultKernelVersion is the default Linux kernel version. - DefaultKernelVersion = "6.12.3-talos" + DefaultKernelVersion = "6.12.4-talos" // KernelModulesPath is the default path to the kernel modules without the kernel version. KernelModulesPath = "/lib/modules" diff --git a/pkg/machinery/gendata/data/pkgs b/pkg/machinery/gendata/data/pkgs index 25910c7fd7..18cd1e1fc5 100644 --- a/pkg/machinery/gendata/data/pkgs +++ b/pkg/machinery/gendata/data/pkgs @@ -1 +1 @@ -v1.9.0-5-g5d559d0 \ No newline at end of file +v1.9.0-6-gabba1d8 \ No newline at end of file