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`