From 70612c1f9fc9056e8a3669ff10a385c4e8e03350 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Tue, 19 Aug 2025 16:28:45 +0400 Subject: [PATCH] refactor: split the PlatformConfigController Fixes #10992 The plan is detailed in the issue, but tl;dr is to get one big controller into 4 smaller controllers, each doing its own part of the work. Each controller has its own set of tests. Signed-off-by: Andrey Smirnov --- api/resource/definitions/enums/enums.proto | 32 +- .../definitions/network/network.proto | 18 + .../controllers/network/node_address_test.go | 2 +- .../controllers/network/platform_config.go | 520 +-------- .../network/platform_config_apply.go | 450 ++++++++ .../network/platform_config_apply_test.go | 314 +++++ .../network/platform_config_load.go | 150 +++ .../network/platform_config_load_test.go | 85 ++ .../network/platform_config_store.go | 154 +++ .../network/platform_config_store_test.go | 101 ++ .../network/platform_config_test.go | 435 ++----- internal/app/machined/pkg/runtime/platform.go | 38 +- .../runtime/v1alpha2/v1alpha2_controller.go | 3 + .../pkg/runtime/v1alpha2/v1alpha2_state.go | 1 + .../resource/definitions/enums/enums.pb.go | 262 ++--- .../definitions/network/network.pb.go | 547 +++++---- .../definitions/network/network_vtproto.pb.go | 665 +++++++++++ .../resources/network/address_spec.go | 2 +- .../resources/network/deep_copy.generated.go | 72 +- .../resources/network/network_test.go | 1 + .../resources/network/platform_config.go | 100 ++ .../resources/network/platform_config_test.go | 17 +- tools/structprotogen/proto/proto.go | 2 + website/content/v1.12/reference/api.md | 1016 +++++++++-------- 24 files changed, 3228 insertions(+), 1759 deletions(-) create mode 100644 internal/app/machined/pkg/controllers/network/platform_config_apply.go create mode 100644 internal/app/machined/pkg/controllers/network/platform_config_apply_test.go create mode 100644 internal/app/machined/pkg/controllers/network/platform_config_load.go create mode 100644 internal/app/machined/pkg/controllers/network/platform_config_load_test.go create mode 100644 internal/app/machined/pkg/controllers/network/platform_config_store.go create mode 100644 internal/app/machined/pkg/controllers/network/platform_config_store_test.go create mode 100644 pkg/machinery/resources/network/platform_config.go rename internal/app/machined/pkg/runtime/platform_test.go => pkg/machinery/resources/network/platform_config_test.go (61%) diff --git a/api/resource/definitions/enums/enums.proto b/api/resource/definitions/enums/enums.proto index b87416306..17c47d887 100755 --- a/api/resource/definitions/enums/enums.proto +++ b/api/resource/definitions/enums/enums.proto @@ -438,22 +438,6 @@ enum KubespanPeerState { PEER_STATE_DOWN = 2; } -// NetworkConfigLayer describes network configuration layers, with lowest priority first. -enum NetworkConfigLayer { - CONFIG_DEFAULT = 0; - CONFIG_CMDLINE = 1; - CONFIG_PLATFORM = 2; - CONFIG_OPERATOR = 3; - CONFIG_MACHINE_CONFIGURATION = 4; -} - -// NetworkOperator enumerates Talos network operators. -enum NetworkOperator { - OPERATOR_DHCP4 = 0; - OPERATOR_DHCP6 = 1; - OPERATOR_VIP = 2; -} - // RuntimeMachineStage describes the stage of the machine boot/run process. enum RuntimeMachineStage { MACHINE_STAGE_UNKNOWN = 0; @@ -481,3 +465,19 @@ enum RuntimeFIPSState { FIPS_STATE_STRICT = 2; } +// NetworkConfigLayer describes network configuration layers, with lowest priority first. +enum NetworkConfigLayer { + CONFIG_DEFAULT = 0; + CONFIG_CMDLINE = 1; + CONFIG_PLATFORM = 2; + CONFIG_OPERATOR = 3; + CONFIG_MACHINE_CONFIGURATION = 4; +} + +// NetworkOperator enumerates Talos network operators. +enum NetworkOperator { + OPERATOR_DHCP4 = 0; + OPERATOR_DHCP6 = 1; + OPERATOR_VIP = 2; +} + diff --git a/api/resource/definitions/network/network.proto b/api/resource/definitions/network/network.proto index 1c2383937..014a31e26 100755 --- a/api/resource/definitions/network/network.proto +++ b/api/resource/definitions/network/network.proto @@ -8,6 +8,7 @@ option java_package = "dev.talos.api.resource.definitions.network"; import "common/common.proto"; import "google/protobuf/duration.proto"; import "resource/definitions/enums/enums.proto"; +import "resource/definitions/runtime/runtime.proto"; // AddressSpecSpec describes status of rendered secrets. message AddressSpecSpec { @@ -385,6 +386,23 @@ message OperatorSpecSpec { talos.resource.definitions.enums.NetworkConfigLayer config_layer = 7; } +// PlatformConfigSpec describes platform network configuration. +// +// This structure is marshaled to STATE partition to persist cached network configuration across +// reboots. +message PlatformConfigSpec { + repeated AddressSpecSpec addresses = 1; + repeated LinkSpecSpec links = 2; + repeated RouteSpecSpec routes = 3; + repeated HostnameSpecSpec hostnames = 4; + repeated ResolverSpecSpec resolvers = 5; + repeated TimeServerSpecSpec time_servers = 6; + repeated OperatorSpecSpec operators = 7; + repeated common.NetIP external_ips = 8; + repeated ProbeSpecSpec probes = 9; + talos.resource.definitions.runtime.PlatformMetadataSpec metadata = 10; +} + // PortRange describes a range of ports. // // Range is [lo, hi]. 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 ead2f4c08..3dc1d9112 100644 --- a/internal/app/machined/pkg/controllers/network/node_address_test.go +++ b/internal/app/machined/pkg/controllers/network/node_address_test.go @@ -89,7 +89,7 @@ func (suite *NodeAddressSuite) newAddress(addr netip.Prefix, link *network.LinkS } func (suite *NodeAddressSuite) newExternalAddress(addr netip.Prefix) { - var platformConfigController netctrl.PlatformConfigController + var platformConfigController netctrl.PlatformConfigApplyController addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID("external", addr)) addressStatus.TypedSpec().Address = addr diff --git a/internal/app/machined/pkg/controllers/network/platform_config.go b/internal/app/machined/pkg/controllers/network/platform_config.go index 8698e5532..eddf0c27d 100644 --- a/internal/app/machined/pkg/controllers/network/platform_config.go +++ b/internal/app/machined/pkg/controllers/network/platform_config.go @@ -5,43 +5,25 @@ package network import ( - "bytes" "context" "fmt" - "net/netip" - "os" - "path/filepath" "sync" "time" "github.com/cenkalti/backoff/v4" "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" "go.uber.org/zap" - "gopkg.in/yaml.v3" - "github.com/siderolabs/talos/internal/app/machined/pkg/automaton" - "github.com/siderolabs/talos/internal/app/machined/pkg/automaton/blockautomaton" v1alpha1runtime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" - "github.com/siderolabs/talos/pkg/machinery/constants" - "github.com/siderolabs/talos/pkg/machinery/nethelpers" - "github.com/siderolabs/talos/pkg/machinery/resources/block" "github.com/siderolabs/talos/pkg/machinery/resources/network" - runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) -// Virtual link name for external IPs. -const externalLink = "external" - -// PlatformConfigController manages updates hostnames and addressstatuses based on platform information. +// PlatformConfigController runs the platform config acquire code and publishes the result as a resource. type PlatformConfigController struct { V1alpha1Platform v1alpha1runtime.Platform PlatformState state.State - - stateMachine blockautomaton.VolumeMounterAutomaton - cachedNetworkConfig, activeNetworkConfig, networkConfigToPersist *v1alpha1runtime.PlatformNetworkConfig - cachedNetworkConfigLoaded bool } // Name implements controller.Controller interface. @@ -51,67 +33,16 @@ func (ctrl *PlatformConfigController) Name() string { // Inputs implements controller.Controller interface. func (ctrl *PlatformConfigController) Inputs() []controller.Input { - return []controller.Input{ - { - Namespace: block.NamespaceName, - Type: block.VolumeMountStatusType, - Kind: controller.InputStrong, - }, - { - Namespace: block.NamespaceName, - Type: block.VolumeMountRequestType, - Kind: controller.InputDestroyReady, - }, - } + return nil } // Outputs implements controller.Controller interface. func (ctrl *PlatformConfigController) Outputs() []controller.Output { return []controller.Output{ { - Type: block.VolumeMountRequestType, + Type: network.PlatformConfigType, Kind: controller.OutputShared, }, - { - Type: network.AddressSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.LinkSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.RouteSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.HostnameSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.ResolverSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.TimeServerSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.AddressStatusType, - Kind: controller.OutputShared, - }, - { - Type: network.OperatorSpecType, - Kind: controller.OutputShared, - }, - { - Type: network.ProbeSpecType, - Kind: controller.OutputShared, - }, - { - Type: runtimeres.PlatformMetadataType, - Kind: controller.OutputExclusive, - }, } } @@ -151,11 +82,6 @@ func (ctrl *PlatformConfigController) Run(ctx context.Context, r controller.Runt r.QueueReconcile() - // the main loop of the controller does the following: - // 1. there are two sources platform network config: cached config in STATE (from previous boot) and live config from the platform - // 2. we should prefer live config over cached config always - // 3. when we get a new config from the platform, we should persist it to the STATE partition - // 4. any new (either cached or received from the platform) platform network config should be applied to the network stack for { select { case <-ctx.Done(): @@ -166,48 +92,15 @@ func (ctrl *PlatformConfigController) Run(ctx context.Context, r controller.Runt continue } - if ctrl.activeNetworkConfig != nil && ctrl.activeNetworkConfig.Equal(networkConfig) { - // network config has no changes, skip applying - continue - } - - // prefer live network config over any previous config, and schedule to persist it - ctrl.activeNetworkConfig = networkConfig - ctrl.networkConfigToPersist = networkConfig - } - - if ctrl.activeNetworkConfig != nil { - if err := ctrl.apply(ctx, r); err != nil { - return err - } - } - - // we either need to save new network config, or we don't have any and we need to load cached config - pendingStateOperation := ctrl.networkConfigToPersist != nil || (ctrl.activeNetworkConfig == nil && !ctrl.cachedNetworkConfigLoaded) - - if pendingStateOperation && ctrl.stateMachine == nil { - ctrl.stateMachine = blockautomaton.NewVolumeMounter( - ctrl.Name(), constants.StatePartitionLabel, - ctrl.loadStore(), - ) - } - - if ctrl.stateMachine != nil { - if err := ctrl.stateMachine.Run(ctx, r, logger, - automaton.WithAfterFunc(func() error { - ctrl.stateMachine = nil - - // cached network is only used as last resort - if ctrl.activeNetworkConfig == nil { - ctrl.activeNetworkConfig = ctrl.cachedNetworkConfig - } - - r.QueueReconcile() + if err := safe.WriterModify(ctx, r, + network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID), + func(out *network.PlatformConfig) error { + *out.TypedSpec() = *networkConfig return nil - }), + }, ); err != nil { - return fmt.Errorf("error running volume mounter machine: %w", err) + return fmt.Errorf("error modifying active network config: %w", err) } } @@ -215,363 +108,6 @@ func (ctrl *PlatformConfigController) Run(ctx context.Context, r controller.Runt } } -func (ctrl *PlatformConfigController) loadStore() func( - ctx context.Context, r controller.ReaderWriter, logger *zap.Logger, mountStatus *block.VolumeMountStatus, -) error { - return func(ctx context.Context, r controller.ReaderWriter, logger *zap.Logger, mountStatus *block.VolumeMountStatus) error { - rootPath := mountStatus.TypedSpec().Target - // no matter what this function will do or fail, we should try just once to load the cached network config - ctrl.cachedNetworkConfigLoaded = true - - // first, if we have network config, save it - if ctrl.networkConfigToPersist != nil { - if err := ctrl.storeConfig(filepath.Join(rootPath, constants.PlatformNetworkConfigFilename), ctrl.networkConfigToPersist); err != nil { - return fmt.Errorf("error saving platform network config: %w", err) - } - - logger.Debug("stored active platform network config") - - // mark it as nil as it was saved - ctrl.networkConfigToPersist = nil - - return nil - } - - // if we don't have cached network config, load it - if ctrl.cachedNetworkConfig == nil { - var err error - - ctrl.cachedNetworkConfig, err = ctrl.loadConfig(filepath.Join(rootPath, constants.PlatformNetworkConfigFilename)) - if err != nil { - logger.Warn("ignored failure loading cached platform network config", zap.Error(err)) - } else if ctrl.cachedNetworkConfig != nil { - logger.Debug("loaded cached platform network config") - } - } - - return nil - } -} - -//nolint:dupl,gocyclo -func (ctrl *PlatformConfigController) apply(ctx context.Context, r controller.Runtime) error { - networkConfig := ctrl.activeNetworkConfig - - metadataLength := 0 - - if networkConfig.Metadata != nil { - metadataLength = 1 - } - - // handle all network specs in a loop as all specs can be handled in a similar way - for _, specType := range []struct { - length int - getter func(i int) any - idBuilder func(spec any) (resource.ID, error) - resourceBuilder func(id string) resource.Resource - resourceModifier func(newSpec any) func(r resource.Resource) error - }{ - // AddressSpec - { - length: len(networkConfig.Addresses), - getter: func(i int) any { - return networkConfig.Addresses[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - addressSpec := spec.(network.AddressSpecSpec) //nolint:forcetypeassert - - return network.LayeredID(network.ConfigPlatform, network.AddressID(addressSpec.LinkName, addressSpec.Address)), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewAddressSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.AddressSpec).TypedSpec() - - *spec = newSpec.(network.AddressSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // LinkSpec - { - length: len(networkConfig.Links), - getter: func(i int) any { - return networkConfig.Links[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - linkSpec := spec.(network.LinkSpecSpec) //nolint:forcetypeassert - - return network.LayeredID(network.ConfigPlatform, network.LinkID(linkSpec.Name)), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewLinkSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.LinkSpec).TypedSpec() - - *spec = newSpec.(network.LinkSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // RouteSpec - { - length: len(networkConfig.Routes), - getter: func(i int) any { - return networkConfig.Routes[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - routeSpec := spec.(network.RouteSpecSpec) //nolint:forcetypeassert - - return network.LayeredID( - network.ConfigPlatform, - network.RouteID(routeSpec.Table, routeSpec.Family, routeSpec.Destination, routeSpec.Gateway, routeSpec.Priority, routeSpec.OutLinkName), - ), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewRouteSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.RouteSpec).TypedSpec() - - *spec = newSpec.(network.RouteSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // HostnameSpec - { - length: len(networkConfig.Hostnames), - getter: func(i int) any { - return networkConfig.Hostnames[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - return network.LayeredID(network.ConfigPlatform, network.HostnameID), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewHostnameSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.HostnameSpec).TypedSpec() - - *spec = newSpec.(network.HostnameSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // ResolverSpec - { - length: len(networkConfig.Resolvers), - getter: func(i int) any { - return networkConfig.Resolvers[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - return network.LayeredID(network.ConfigPlatform, network.ResolverID), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewResolverSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.ResolverSpec).TypedSpec() - - *spec = newSpec.(network.ResolverSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // TimeServerSpec - { - length: len(networkConfig.TimeServers), - getter: func(i int) any { - return networkConfig.TimeServers[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - return network.LayeredID(network.ConfigPlatform, network.TimeServerID), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewTimeServerSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.TimeServerSpec).TypedSpec() - - *spec = newSpec.(network.TimeServerSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // OperatorSpec - { - length: len(networkConfig.Operators), - getter: func(i int) any { - return networkConfig.Operators[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - operatorSpec := spec.(network.OperatorSpecSpec) //nolint:forcetypeassert - - return network.LayeredID(network.ConfigPlatform, network.OperatorID(operatorSpec.Operator, operatorSpec.LinkName)), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewOperatorSpec(network.ConfigNamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.OperatorSpec).TypedSpec() - - *spec = newSpec.(network.OperatorSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // ExternalIPs - { - length: len(networkConfig.ExternalIPs), - getter: func(i int) any { - return networkConfig.ExternalIPs[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - ipAddr := spec.(netip.Addr) //nolint:forcetypeassert - ipPrefix := netip.PrefixFrom(ipAddr, ipAddr.BitLen()) - - return network.AddressID(externalLink, ipPrefix), nil - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewAddressStatus(network.NamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - ipAddr := newSpec.(netip.Addr) //nolint:forcetypeassert - ipPrefix := netip.PrefixFrom(ipAddr, ipAddr.BitLen()) - - status := r.(*network.AddressStatus).TypedSpec() - - status.Address = ipPrefix - status.LinkName = externalLink - - if ipAddr.Is4() { - status.Family = nethelpers.FamilyInet4 - } else { - status.Family = nethelpers.FamilyInet6 - } - - status.Scope = nethelpers.ScopeGlobal - - return nil - } - }, - }, - // ProbeSpec - { - length: len(networkConfig.Probes), - getter: func(i int) any { - return networkConfig.Probes[i] - }, - idBuilder: func(spec any) (resource.ID, error) { - probeSpec := spec.(network.ProbeSpecSpec) //nolint:forcetypeassert - - return probeSpec.ID() - }, - resourceBuilder: func(id string) resource.Resource { - return network.NewProbeSpec(network.NamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - spec := r.(*network.ProbeSpec).TypedSpec() - - *spec = newSpec.(network.ProbeSpecSpec) //nolint:forcetypeassert - spec.ConfigLayer = network.ConfigPlatform - - return nil - } - }, - }, - // Platform metadata - { - length: metadataLength, - getter: func(i int) any { - return networkConfig.Metadata - }, - idBuilder: func(spec any) (resource.ID, error) { - return runtimeres.PlatformMetadataID, nil - }, - resourceBuilder: func(id string) resource.Resource { - return runtimeres.NewPlatformMetadataSpec(runtimeres.NamespaceName, id) - }, - resourceModifier: func(newSpec any) func(r resource.Resource) error { - return func(r resource.Resource) error { - metadata := newSpec.(*runtimeres.PlatformMetadataSpec) //nolint:forcetypeassert - - *r.(*runtimeres.PlatformMetadata).TypedSpec() = *metadata - - return nil - } - }, - }, - } { - touchedIDs := make(map[resource.ID]struct{}, specType.length) - - resourceEmpty := specType.resourceBuilder("") - resourceNamespace := resourceEmpty.Metadata().Namespace() - resourceType := resourceEmpty.Metadata().Type() - - for i := range specType.length { - spec := specType.getter(i) - - id, err := specType.idBuilder(spec) - if err != nil { - return fmt.Errorf("error building resource %s ID: %w", resourceType, err) - } - - if err = r.Modify(ctx, specType.resourceBuilder(id), specType.resourceModifier(spec)); err != nil { - return fmt.Errorf("error modifying resource %s: %w", resourceType, err) - } - - touchedIDs[id] = struct{}{} - } - - list, err := r.List(ctx, resource.NewMetadata(resourceNamespace, resourceType, "", resource.VersionUndefined)) - if err != nil { - return fmt.Errorf("error listing resources: %w", err) - } - - for _, res := range list.Items { - if res.Metadata().Owner() != ctrl.Name() { - continue - } - - if _, ok := touchedIDs[res.Metadata().ID()]; ok { - continue - } - - if err = r.Destroy(ctx, res.Metadata()); err != nil { - return fmt.Errorf("error deleting %s: %w", res, err) - } - } - } - - return nil -} - func (ctrl *PlatformConfigController) runWithRestarts(ctx context.Context, logger *zap.Logger, f func() error) { backoff := backoff.NewExponentialBackOff() @@ -617,39 +153,3 @@ func (ctrl *PlatformConfigController) runWithPanicHandler(logger *zap.Logger, f return } - -func (ctrl *PlatformConfigController) loadConfig(path string) (*v1alpha1runtime.PlatformNetworkConfig, error) { - marshaled, err := os.ReadFile(path) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - - return nil, err - } - - var networkConfig v1alpha1runtime.PlatformNetworkConfig - - if err = yaml.Unmarshal(marshaled, &networkConfig); err != nil { - return nil, fmt.Errorf("error unmarshaling network config: %w", err) - } - - return &networkConfig, nil -} - -func (ctrl *PlatformConfigController) storeConfig(path string, networkConfig *v1alpha1runtime.PlatformNetworkConfig) error { - marshaled, err := yaml.Marshal(networkConfig) - if err != nil { - return fmt.Errorf("error marshaling network config: %w", err) - } - - if _, err := os.Stat(path); err == nil { - existing, err := os.ReadFile(path) - if err == nil && bytes.Equal(marshaled, existing) { - // existing contents are identical, skip writing to avoid no-op writes - return nil - } - } - - return os.WriteFile(path, marshaled, 0o400) -} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_apply.go b/internal/app/machined/pkg/controllers/network/platform_config_apply.go new file mode 100644 index 000000000..f4acdc37c --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/platform_config_apply.go @@ -0,0 +1,450 @@ +// 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" + "net/netip" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/safe" + "go.uber.org/zap" + + "github.com/siderolabs/talos/pkg/machinery/nethelpers" + "github.com/siderolabs/talos/pkg/machinery/resources/network" + runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// Virtual link name for external IPs. +const externalLink = "external" + +// PlatformConfigApplyController applies active (or cached) platform network config to the network stack. +type PlatformConfigApplyController struct{} + +// Name implements controller.Controller interface. +func (ctrl *PlatformConfigApplyController) Name() string { + return "network.PlatformConfigApplyController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *PlatformConfigApplyController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: network.NamespaceName, + Type: network.PlatformConfigType, + Kind: controller.InputWeak, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *PlatformConfigApplyController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: network.AddressSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.LinkSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.RouteSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.HostnameSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.ResolverSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.TimeServerSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.AddressStatusType, + Kind: controller.OutputShared, + }, + { + Type: network.OperatorSpecType, + Kind: controller.OutputShared, + }, + { + Type: network.ProbeSpecType, + Kind: controller.OutputShared, + }, + { + Type: runtimeres.PlatformMetadataType, + Kind: controller.OutputExclusive, + }, + } +} + +// Run implements controller.Controller interface. +// +//nolint:gocyclo,cyclop +func (ctrl *PlatformConfigApplyController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + platformConfigs, err := safe.ReaderListAll[*network.PlatformConfig](ctx, r) + if err != nil { + return fmt.Errorf("error listing platform configs: %w", err) + } + + var platformConfig *network.PlatformConfig + + // we always prefer "active" to "cached" + for cfg := range platformConfigs.All() { + switch cfg.Metadata().ID() { + case network.PlatformConfigActiveID: + platformConfig = cfg + case network.PlatformConfigCachedID: + if platformConfig == nil { + platformConfig = cfg + } + } + } + + // if we don't have any config yet, wait... + if platformConfig == nil { + continue + } + + if err := ctrl.apply(ctx, r, platformConfig); err != nil { + return err + } + + r.ResetRestartBackoff() + } +} + +//nolint:dupl,gocyclo +func (ctrl *PlatformConfigApplyController) apply(ctx context.Context, r controller.Runtime, platformConfig *network.PlatformConfig) error { + networkConfig := platformConfig.TypedSpec() + + metadataLength := 0 + + if networkConfig.Metadata != nil { + metadataLength = 1 + } + + // handle all network specs in a loop as all specs can be handled in a similar way + for _, specType := range []struct { + length int + getter func(i int) any + idBuilder func(spec any) (resource.ID, error) + resourceBuilder func(id string) resource.Resource + resourceModifier func(newSpec any) func(r resource.Resource) error + }{ + // AddressSpec + { + length: len(networkConfig.Addresses), + getter: func(i int) any { + return networkConfig.Addresses[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + addressSpec := spec.(network.AddressSpecSpec) //nolint:forcetypeassert + + return network.LayeredID(network.ConfigPlatform, network.AddressID(addressSpec.LinkName, addressSpec.Address)), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewAddressSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.AddressSpec).TypedSpec() + + *spec = newSpec.(network.AddressSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // LinkSpec + { + length: len(networkConfig.Links), + getter: func(i int) any { + return networkConfig.Links[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + linkSpec := spec.(network.LinkSpecSpec) //nolint:forcetypeassert + + return network.LayeredID(network.ConfigPlatform, network.LinkID(linkSpec.Name)), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewLinkSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.LinkSpec).TypedSpec() + + *spec = newSpec.(network.LinkSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // RouteSpec + { + length: len(networkConfig.Routes), + getter: func(i int) any { + return networkConfig.Routes[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + routeSpec := spec.(network.RouteSpecSpec) //nolint:forcetypeassert + + return network.LayeredID( + network.ConfigPlatform, + network.RouteID(routeSpec.Table, routeSpec.Family, routeSpec.Destination, routeSpec.Gateway, routeSpec.Priority, routeSpec.OutLinkName), + ), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewRouteSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.RouteSpec).TypedSpec() + + *spec = newSpec.(network.RouteSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // HostnameSpec + { + length: len(networkConfig.Hostnames), + getter: func(i int) any { + return networkConfig.Hostnames[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + return network.LayeredID(network.ConfigPlatform, network.HostnameID), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewHostnameSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.HostnameSpec).TypedSpec() + + *spec = newSpec.(network.HostnameSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // ResolverSpec + { + length: len(networkConfig.Resolvers), + getter: func(i int) any { + return networkConfig.Resolvers[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + return network.LayeredID(network.ConfigPlatform, network.ResolverID), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewResolverSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.ResolverSpec).TypedSpec() + + *spec = newSpec.(network.ResolverSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // TimeServerSpec + { + length: len(networkConfig.TimeServers), + getter: func(i int) any { + return networkConfig.TimeServers[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + return network.LayeredID(network.ConfigPlatform, network.TimeServerID), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewTimeServerSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.TimeServerSpec).TypedSpec() + + *spec = newSpec.(network.TimeServerSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // OperatorSpec + { + length: len(networkConfig.Operators), + getter: func(i int) any { + return networkConfig.Operators[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + operatorSpec := spec.(network.OperatorSpecSpec) //nolint:forcetypeassert + + return network.LayeredID(network.ConfigPlatform, network.OperatorID(operatorSpec.Operator, operatorSpec.LinkName)), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewOperatorSpec(network.ConfigNamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.OperatorSpec).TypedSpec() + + *spec = newSpec.(network.OperatorSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // ExternalIPs + { + length: len(networkConfig.ExternalIPs), + getter: func(i int) any { + return networkConfig.ExternalIPs[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + ipAddr := spec.(netip.Addr) //nolint:forcetypeassert + ipPrefix := netip.PrefixFrom(ipAddr, ipAddr.BitLen()) + + return network.AddressID(externalLink, ipPrefix), nil + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewAddressStatus(network.NamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + ipAddr := newSpec.(netip.Addr) //nolint:forcetypeassert + ipPrefix := netip.PrefixFrom(ipAddr, ipAddr.BitLen()) + + status := r.(*network.AddressStatus).TypedSpec() + + status.Address = ipPrefix + status.LinkName = externalLink + + if ipAddr.Is4() { + status.Family = nethelpers.FamilyInet4 + } else { + status.Family = nethelpers.FamilyInet6 + } + + status.Scope = nethelpers.ScopeGlobal + + return nil + } + }, + }, + // ProbeSpec + { + length: len(networkConfig.Probes), + getter: func(i int) any { + return networkConfig.Probes[i] + }, + idBuilder: func(spec any) (resource.ID, error) { + probeSpec := spec.(network.ProbeSpecSpec) //nolint:forcetypeassert + + return probeSpec.ID() + }, + resourceBuilder: func(id string) resource.Resource { + return network.NewProbeSpec(network.NamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + spec := r.(*network.ProbeSpec).TypedSpec() + + *spec = newSpec.(network.ProbeSpecSpec) //nolint:forcetypeassert + spec.ConfigLayer = network.ConfigPlatform + + return nil + } + }, + }, + // Platform metadata + { + length: metadataLength, + getter: func(i int) any { + return networkConfig.Metadata + }, + idBuilder: func(spec any) (resource.ID, error) { + return runtimeres.PlatformMetadataID, nil + }, + resourceBuilder: func(id string) resource.Resource { + return runtimeres.NewPlatformMetadataSpec(runtimeres.NamespaceName, id) + }, + resourceModifier: func(newSpec any) func(r resource.Resource) error { + return func(r resource.Resource) error { + metadata := newSpec.(*runtimeres.PlatformMetadataSpec) //nolint:forcetypeassert + + *r.(*runtimeres.PlatformMetadata).TypedSpec() = *metadata + + return nil + } + }, + }, + } { + touchedIDs := make(map[resource.ID]struct{}, specType.length) + + resourceEmpty := specType.resourceBuilder("") + resourceNamespace := resourceEmpty.Metadata().Namespace() + resourceType := resourceEmpty.Metadata().Type() + + for i := range specType.length { + spec := specType.getter(i) + + id, err := specType.idBuilder(spec) + if err != nil { + return fmt.Errorf("error building resource %s ID: %w", resourceType, err) + } + + if err = r.Modify(ctx, specType.resourceBuilder(id), specType.resourceModifier(spec)); err != nil { + return fmt.Errorf("error modifying resource %s: %w", resourceType, err) + } + + touchedIDs[id] = struct{}{} + } + + list, err := r.List(ctx, resource.NewMetadata(resourceNamespace, resourceType, "", resource.VersionUndefined)) + if err != nil { + return fmt.Errorf("error listing resources: %w", err) + } + + for _, res := range list.Items { + if res.Metadata().Owner() != ctrl.Name() { + continue + } + + if _, ok := touchedIDs[res.Metadata().ID()]; ok { + continue + } + + if err = r.Destroy(ctx, res.Metadata()); err != nil { + return fmt.Errorf("error deleting %s: %w", res, err) + } + } + } + + return nil +} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_apply_test.go b/internal/app/machined/pkg/controllers/network/platform_config_apply_test.go new file mode 100644 index 000000000..9d4b94018 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/platform_config_apply_test.go @@ -0,0 +1,314 @@ +// 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/. + +//nolint:dupl +package network_test + +import ( + "fmt" + "net/netip" + "testing" + "time" + + "github.com/cosi-project/runtime/pkg/resource/rtestutils" + "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/pkg/machinery/nethelpers" + "github.com/siderolabs/talos/pkg/machinery/resources/network" + runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +type PlatformConfigApplySuite struct { + ctest.DefaultSuite +} + +func (suite *PlatformConfigApplySuite) TestHostname() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigCachedID) + platformConfig.TypedSpec().Hostnames = []network.HostnameSpecSpec{ + { + Hostname: "talos-e2e-897b4e49-gcp-controlplane-jvcnl", + Domainname: "c.talos-testbed.internal", + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResource(suite, "platform/hostname", func(hostname *network.HostnameSpec, asrt *assert.Assertions) { + spec := hostname.TypedSpec() + + asrt.Equal("talos-e2e-897b4e49-gcp-controlplane-jvcnl", spec.Hostname) + asrt.Equal("c.talos-testbed.internal", spec.Domainname) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestHostnameNoDomain() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Hostnames = []network.HostnameSpecSpec{ + { + Hostname: "talos-e2e-897b4e49-gcp-controlplane-jvcnl", + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResource(suite, "platform/hostname", func(hostname *network.HostnameSpec, asrt *assert.Assertions) { + spec := hostname.TypedSpec() + + asrt.Equal("talos-e2e-897b4e49-gcp-controlplane-jvcnl", spec.Hostname) + asrt.Equal("", spec.Domainname) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestAddresses() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Addresses = []network.AddressSpecSpec{ + { + Address: netip.MustParsePrefix("192.168.1.24/24"), + LinkName: "eth0", + Family: nethelpers.FamilyInet4, + ConfigLayer: network.ConfigPlatform, + }, + { + Address: netip.MustParsePrefix("2001:fd::3/64"), + LinkName: "eth0", + Family: nethelpers.FamilyInet6, + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "platform/eth0/192.168.1.24/24", + "platform/eth0/2001:fd::3/64", + }, func(r *network.AddressSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + switch r.Metadata().ID() { + case "platform/eth0/192.168.1.24/24": + asrt.Equal(nethelpers.FamilyInet4, spec.Family) + asrt.Equal("192.168.1.24/24", spec.Address.String()) + case "platform/eth0/2001:fd::3/64": + asrt.Equal(nethelpers.FamilyInet6, spec.Family) + asrt.Equal("2001:fd::3/64", spec.Address.String()) + } + + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestLinks() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Links = []network.LinkSpecSpec{ + { + Name: "eth0", + Up: true, + ConfigLayer: network.ConfigPlatform, + }, + { + Name: "eth1", + Up: true, + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "platform/eth0", + "platform/eth1", + }, func(r *network.LinkSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.True(spec.Up) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestRoutes() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Routes = []network.RouteSpecSpec{ + { + Family: nethelpers.FamilyInet4, + Gateway: netip.MustParseAddr("10.0.0.1"), + OutLinkName: "eth0", + Table: nethelpers.TableMain, + Protocol: nethelpers.ProtocolStatic, + Type: nethelpers.TypeUnicast, + Priority: 1024, + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "platform/inet4/10.0.0.1//1024", + }, func(r *network.RouteSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.Equal("10.0.0.1", spec.Gateway.String()) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestOperators() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Operators = []network.OperatorSpecSpec{ + { + ConfigLayer: network.ConfigPlatform, + LinkName: "eth1", + Operator: network.OperatorDHCP4, + DHCP4: network.DHCP4OperatorSpec{}, + }, + { + ConfigLayer: network.ConfigPlatform, + LinkName: "eth2", + Operator: network.OperatorDHCP4, + DHCP4: network.DHCP4OperatorSpec{}, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "platform/dhcp4/eth1", + "platform/dhcp4/eth2", + }, func(r *network.OperatorSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.Equal(network.OperatorDHCP4, spec.Operator) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestResolvers() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Resolvers = []network.ResolverSpecSpec{ + { + DNSServers: []netip.Addr{netip.MustParseAddr("1.1.1.1")}, + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "platform/resolvers", + }, func(r *network.ResolverSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.Equal("[1.1.1.1]", fmt.Sprintf("%s", spec.DNSServers)) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestTimeServers() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().TimeServers = []network.TimeServerSpecSpec{ + { + NTPServers: []string{"pool.ntp.org"}, + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "platform/timeservers", + }, func(r *network.TimeServerSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.Equal("[pool.ntp.org]", fmt.Sprintf("%s", spec.NTPServers)) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }, rtestutils.WithNamespace(network.ConfigNamespaceName)) +} + +func (suite *PlatformConfigApplySuite) TestProbes() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Probes = []network.ProbeSpecSpec{ + { + Interval: time.Second, + TCP: network.TCPProbeSpec{ + Endpoint: "example.com:80", + Timeout: time.Second, + }, + ConfigLayer: network.ConfigPlatform, + }, + { + Interval: time.Second, + TCP: network.TCPProbeSpec{ + Endpoint: "example.com:443", + Timeout: time.Second, + }, + ConfigLayer: network.ConfigPlatform, + }, + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "tcp:example.com:80", + "tcp:example.com:443", + }, func(r *network.ProbeSpec, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.Equal(time.Second, spec.Interval) + asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) + }) +} + +func (suite *PlatformConfigApplySuite) TestExternalIPs() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().ExternalIPs = []netip.Addr{ + netip.MustParseAddr("10.3.4.5"), + netip.MustParseAddr("2001:470:6d:30e:96f4:4219:5733:b860"), + } + suite.Create(platformConfig) + + ctest.AssertResources(suite, []string{ + "external/10.3.4.5/32", + "external/2001:470:6d:30e:96f4:4219:5733:b860/128", + }, func(r *network.AddressStatus, asrt *assert.Assertions) { + spec := r.TypedSpec() + + asrt.Equal("external", spec.LinkName) + asrt.Equal(nethelpers.ScopeGlobal, spec.Scope) + + if r.Metadata().ID() == "external/10.3.4.5/32" { + asrt.Equal(nethelpers.FamilyInet4, spec.Family) + } else { + asrt.Equal(nethelpers.FamilyInet6, spec.Family) + } + }) +} + +func (suite *PlatformConfigApplySuite) TestMetadata() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Metadata = &runtimeres.PlatformMetadataSpec{ + Platform: "mock", + Zone: "mock-zone", + } + suite.Create(platformConfig) + + ctest.AssertResource(suite, runtimeres.PlatformMetadataID, + func(r *runtimeres.PlatformMetadata, asrt *assert.Assertions) { + asrt.Equal("mock", r.TypedSpec().Platform) + asrt.Equal("mock-zone", r.TypedSpec().Zone) + }) +} + +func TestPlatformConfigApplySuite(t *testing.T) { + t.Parallel() + + suite.Run(t, &PlatformConfigApplySuite{ + DefaultSuite: ctest.DefaultSuite{ + Timeout: 5 * time.Second, + AfterSetup: func(suite *ctest.DefaultSuite) { + suite.Require().NoError( + suite.Runtime().RegisterController( + &netctrl.PlatformConfigApplyController{}, + )) + }, + }, + }) +} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_load.go b/internal/app/machined/pkg/controllers/network/platform_config_load.go new file mode 100644 index 000000000..ad2d6213a --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/platform_config_load.go @@ -0,0 +1,150 @@ +// 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" + "os" + "path/filepath" + + "github.com/cosi-project/runtime/pkg/controller" + "github.com/cosi-project/runtime/pkg/safe" + "go.uber.org/zap" + "gopkg.in/yaml.v3" + + "github.com/siderolabs/talos/internal/app/machined/pkg/automaton" + "github.com/siderolabs/talos/internal/app/machined/pkg/automaton/blockautomaton" + "github.com/siderolabs/talos/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/resources/block" + "github.com/siderolabs/talos/pkg/machinery/resources/network" +) + +// PlatformConfigLoadController loads cached platform network config from STATE. +type PlatformConfigLoadController struct { + stateMachine blockautomaton.VolumeMounterAutomaton +} + +// Name implements controller.Controller interface. +func (ctrl *PlatformConfigLoadController) Name() string { + return "network.PlatformConfigLoadController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *PlatformConfigLoadController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: block.NamespaceName, + Type: block.VolumeMountStatusType, + Kind: controller.InputStrong, + }, + { + Namespace: block.NamespaceName, + Type: block.VolumeMountRequestType, + Kind: controller.InputDestroyReady, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *PlatformConfigLoadController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: block.VolumeMountRequestType, + Kind: controller.OutputShared, + }, + { + Type: network.PlatformConfigType, + Kind: controller.OutputShared, + }, + } +} + +// Run implements controller.Controller interface. +// +//nolint:gocyclo +func (ctrl *PlatformConfigLoadController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + if ctrl.stateMachine == nil { + ctrl.stateMachine = blockautomaton.NewVolumeMounter( + ctrl.Name(), constants.StatePartitionLabel, + ctrl.load(), + blockautomaton.WithReadOnly(true), + ) + } + + if err := ctrl.stateMachine.Run(ctx, r, logger, + automaton.WithAfterFunc(func() error { + ctrl.stateMachine = nil + + return nil + }), + ); err != nil { + return fmt.Errorf("error running volume mounter machine: %w", err) + } + + if ctrl.stateMachine == nil { + // we read only once, so once read, we should stop + return nil + } + + r.ResetRestartBackoff() + } +} + +func (ctrl *PlatformConfigLoadController) load() func( + ctx context.Context, r controller.ReaderWriter, logger *zap.Logger, mountStatus *block.VolumeMountStatus, +) error { + return func(ctx context.Context, r controller.ReaderWriter, logger *zap.Logger, mountStatus *block.VolumeMountStatus) error { + rootPath := mountStatus.TypedSpec().Target + + cachedNetworkConfig, err := ctrl.loadConfig(filepath.Join(rootPath, constants.PlatformNetworkConfigFilename)) + if err != nil { + logger.Warn("ignored failure loading cached platform network config", zap.Error(err)) + } else if cachedNetworkConfig != nil { + logger.Debug("loaded cached platform network config") + } + + if cachedNetworkConfig != nil { + if err := safe.WriterModify(ctx, r, + network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigCachedID), + func(out *network.PlatformConfig) error { + *out.TypedSpec() = *cachedNetworkConfig + + return nil + }, + ); err != nil { + return fmt.Errorf("error modifying cached platform network config: %w", err) + } + } + + return nil + } +} + +func (ctrl *PlatformConfigLoadController) loadConfig(path string) (*network.PlatformConfigSpec, error) { + marshaled, err := os.ReadFile(path) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + + return nil, err + } + + var networkConfig network.PlatformConfigSpec + + if err = yaml.Unmarshal(marshaled, &networkConfig); err != nil { + return nil, fmt.Errorf("error unmarshaling network config: %w", err) + } + + return &networkConfig, nil +} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_load_test.go b/internal/app/machined/pkg/controllers/network/platform_config_load_test.go new file mode 100644 index 000000000..112291819 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/platform_config_load_test.go @@ -0,0 +1,85 @@ +// 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/. + +//nolint:dupl +package network_test + +import ( + "net/netip" + "os" + "path/filepath" + "testing" + "time" + + "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/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/resources/block" + "github.com/siderolabs/talos/pkg/machinery/resources/network" +) + +type PlatformConfigLoadSuite struct { + ctest.DefaultSuite +} + +func (suite *PlatformConfigLoadSuite) TestLoadConfig() { + statePath := suite.T().TempDir() + mountID := (&netctrl.PlatformConfigLoadController{}).Name() + "-" + constants.StatePartitionLabel + + suite.Require().NoError( + os.WriteFile( + filepath.Join(statePath, constants.PlatformNetworkConfigFilename), + []byte(sampleStoredConfig), + 0o400, + ), + ) + + ctest.AssertResource(suite, mountID, func(mountRequest *block.VolumeMountRequest, asrt *assert.Assertions) { + asrt.Equal(constants.StatePartitionLabel, mountRequest.TypedSpec().VolumeID) + }) + + volumeMountStatus := block.NewVolumeMountStatus(block.NamespaceName, mountID) + volumeMountStatus.TypedSpec().Target = statePath + suite.Create(volumeMountStatus) + + ctest.AssertNoResource[*block.VolumeMountRequest](suite, mountID) + + suite.Destroy(volumeMountStatus) + + ctest.AssertResource(suite, network.PlatformConfigCachedID, func(cachedConfig *network.PlatformConfig, asrt *assert.Assertions) { + asrt.Equal( + []network.HostnameSpecSpec{ + { + Hostname: "talos-e2e-897b4e49-gcp-controlplane-jvcnl", + }, + }, + cachedConfig.TypedSpec().Hostnames, + ) + asrt.Equal( + []netip.Addr{ + netip.MustParseAddr("10.3.4.5"), + netip.MustParseAddr("2001:470:6d:30e:96f4:4219:5733:b860"), + }, + cachedConfig.TypedSpec().ExternalIPs, + ) + }) +} + +func TestPlatformConfigLoadSuite(t *testing.T) { + t.Parallel() + + suite.Run(t, &PlatformConfigLoadSuite{ + DefaultSuite: ctest.DefaultSuite{ + Timeout: 5 * time.Second, + AfterSetup: func(suite *ctest.DefaultSuite) { + suite.Require().NoError( + suite.Runtime().RegisterController(&netctrl.PlatformConfigLoadController{}), + ) + }, + }, + }) +} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_store.go b/internal/app/machined/pkg/controllers/network/platform_config_store.go new file mode 100644 index 000000000..0cb69ee86 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/platform_config_store.go @@ -0,0 +1,154 @@ +// 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 ( + "bytes" + "context" + "fmt" + "os" + "path/filepath" + + "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" + "gopkg.in/yaml.v3" + + "github.com/siderolabs/talos/internal/app/machined/pkg/automaton" + "github.com/siderolabs/talos/internal/app/machined/pkg/automaton/blockautomaton" + "github.com/siderolabs/talos/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/resources/block" + "github.com/siderolabs/talos/pkg/machinery/resources/network" +) + +// PlatformConfigStoreController stores (caches) active platform network config in STATE. +type PlatformConfigStoreController struct { + stateMachine blockautomaton.VolumeMounterAutomaton + configToStore, lastStoredConfig *network.PlatformConfig +} + +// Name implements controller.Controller interface. +func (ctrl *PlatformConfigStoreController) Name() string { + return "network.PlatformConfigStoreController" +} + +// Inputs implements controller.Controller interface. +func (ctrl *PlatformConfigStoreController) Inputs() []controller.Input { + return []controller.Input{ + { + Namespace: network.NamespaceName, + Type: network.PlatformConfigType, + ID: optional.Some(network.PlatformConfigActiveID), + Kind: controller.InputStrong, + }, + { + Namespace: block.NamespaceName, + Type: block.VolumeMountStatusType, + Kind: controller.InputStrong, + }, + { + Namespace: block.NamespaceName, + Type: block.VolumeMountRequestType, + Kind: controller.InputDestroyReady, + }, + } +} + +// Outputs implements controller.Controller interface. +func (ctrl *PlatformConfigStoreController) Outputs() []controller.Output { + return []controller.Output{ + { + Type: block.VolumeMountRequestType, + Kind: controller.OutputShared, + }, + } +} + +// Run implements controller.Controller interface. +// +//nolint:gocyclo +func (ctrl *PlatformConfigStoreController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error { + for { + select { + case <-ctx.Done(): + return nil + case <-r.EventCh(): + } + + activeConfig, err := safe.ReaderGetByID[*network.PlatformConfig](ctx, r, network.PlatformConfigActiveID) + if err != nil { + if state.IsNotFoundError(err) { + // no active network config found, wait more + continue + } + + return fmt.Errorf("error getting active network config: %w", err) + } + + // if we haven't stored any config yet, or the active config has changed + if ctrl.lastStoredConfig == nil || !activeConfig.TypedSpec().Equal(ctrl.lastStoredConfig.TypedSpec()) { + ctrl.configToStore = activeConfig + } + + if ctrl.stateMachine == nil && ctrl.configToStore != nil { + ctrl.stateMachine = blockautomaton.NewVolumeMounter( + ctrl.Name(), constants.StatePartitionLabel, + ctrl.store(), + ) + } + + if ctrl.stateMachine != nil { + if err := ctrl.stateMachine.Run(ctx, r, logger, + automaton.WithAfterFunc(func() error { + ctrl.stateMachine = nil + + return nil + }), + ); err != nil { + return fmt.Errorf("error running volume mounter machine: %w", err) + } + } + + r.ResetRestartBackoff() + } +} + +func (ctrl *PlatformConfigStoreController) store() func( + ctx context.Context, r controller.ReaderWriter, logger *zap.Logger, mountStatus *block.VolumeMountStatus, +) error { + return func(ctx context.Context, r controller.ReaderWriter, logger *zap.Logger, mountStatus *block.VolumeMountStatus) error { + rootPath := mountStatus.TypedSpec().Target + + if err := ctrl.storeConfig(filepath.Join(rootPath, constants.PlatformNetworkConfigFilename), ctrl.configToStore); err != nil { + return fmt.Errorf("error saving platform network config: %w", err) + } + + // remember last stored config + ctrl.lastStoredConfig, ctrl.configToStore = ctrl.configToStore, nil + + logger.Debug("stored active platform network config") + + return nil + } +} + +func (ctrl *PlatformConfigStoreController) storeConfig(path string, networkConfig *network.PlatformConfig) error { + marshaled, err := yaml.Marshal(networkConfig.TypedSpec()) + if err != nil { + return fmt.Errorf("error marshaling network config: %w", err) + } + + if _, err := os.Stat(path); err == nil { + existing, err := os.ReadFile(path) + if err == nil && bytes.Equal(marshaled, existing) { + // existing contents are identical, skip writing to avoid no-op writes + return nil + } + } + + return os.WriteFile(path, marshaled, 0o400) +} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_store_test.go b/internal/app/machined/pkg/controllers/network/platform_config_store_test.go new file mode 100644 index 000000000..463049cc6 --- /dev/null +++ b/internal/app/machined/pkg/controllers/network/platform_config_store_test.go @@ -0,0 +1,101 @@ +// 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/. + +//nolint:dupl +package network_test + +import ( + "net/netip" + "os" + "path/filepath" + "testing" + "time" + + "github.com/cosi-project/runtime/pkg/resource" + "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/pkg/machinery/constants" + "github.com/siderolabs/talos/pkg/machinery/resources/block" + "github.com/siderolabs/talos/pkg/machinery/resources/network" +) + +type PlatformConfigStoreSuite struct { + ctest.DefaultSuite +} + +const sampleStoredConfig = "addresses: []\nlinks: []\nroutes: []\nhostnames:\n - hostname: talos-e2e-897b4e49-gcp-controlplane-jvcnl\n domainname: \"\"\n layer: default\nresolvers: []\ntimeServers: []\noperators: []\nexternalIPs:\n - 10.3.4.5\n - 2001:470:6d:30e:96f4:4219:5733:b860\n" //nolint:lll + +func (suite *PlatformConfigStoreSuite) TestStoreConfig() { + platformConfig := network.NewPlatformConfig(network.NamespaceName, network.PlatformConfigActiveID) + platformConfig.TypedSpec().Hostnames = []network.HostnameSpecSpec{ + { + Hostname: "talos-e2e-897b4e49-gcp-controlplane-jvcnl", + }, + } + platformConfig.TypedSpec().ExternalIPs = []netip.Addr{ + netip.MustParseAddr("10.3.4.5"), + netip.MustParseAddr("2001:470:6d:30e:96f4:4219:5733:b860"), + } + suite.Create(platformConfig) + + statePath := suite.T().TempDir() + mountID := (&netctrl.PlatformConfigStoreController{}).Name() + "-" + constants.StatePartitionLabel + + ctest.AssertResource(suite, mountID, func(mountRequest *block.VolumeMountRequest, asrt *assert.Assertions) { + asrt.Equal(constants.StatePartitionLabel, mountRequest.TypedSpec().VolumeID) + }) + + volumeMountStatus := block.NewVolumeMountStatus(block.NamespaceName, mountID) + volumeMountStatus.TypedSpec().Target = statePath + suite.Create(volumeMountStatus) + + suite.EventuallyWithT(func(collect *assert.CollectT) { + asrt := assert.New(collect) + + contents, err := os.ReadFile(filepath.Join(statePath, constants.PlatformNetworkConfigFilename)) + asrt.NoError(err) + + asrt.Equal(sampleStoredConfig, string(contents)) + }, time.Second, 10*time.Millisecond) + + ctest.AssertResources(suite, []resource.ID{volumeMountStatus.Metadata().ID()}, func(vms *block.VolumeMountStatus, asrt *assert.Assertions) { + asrt.True(vms.Metadata().Finalizers().Empty()) + }) + + suite.Destroy(volumeMountStatus) + + ctest.AssertNoResource[*block.VolumeMountRequest](suite, mountID) + + // do an update which should not trigger store operation + platformConfig.Metadata().Labels().Set("foo", "bar") + suite.Update(platformConfig) + + ctest.AssertNoResource[*block.VolumeMountRequest](suite, mountID) + + // now update configuration + platformConfig.TypedSpec().Hostnames = nil + suite.Update(platformConfig) + + ctest.AssertResource(suite, mountID, func(mountRequest *block.VolumeMountRequest, asrt *assert.Assertions) { + asrt.Equal(constants.StatePartitionLabel, mountRequest.TypedSpec().VolumeID) + }) +} + +func TestPlatformConfigStoreSuite(t *testing.T) { + t.Parallel() + + suite.Run(t, &PlatformConfigStoreSuite{ + DefaultSuite: ctest.DefaultSuite{ + Timeout: 5 * time.Second, + AfterSetup: func(suite *ctest.DefaultSuite) { + suite.Require().NoError( + suite.Runtime().RegisterController(&netctrl.PlatformConfigStoreController{}), + ) + }, + }, + }) +} diff --git a/internal/app/machined/pkg/controllers/network/platform_config_test.go b/internal/app/machined/pkg/controllers/network/platform_config_test.go index b4f8844d7..964cf814f 100644 --- a/internal/app/machined/pkg/controllers/network/platform_config_test.go +++ b/internal/app/machined/pkg/controllers/network/platform_config_test.go @@ -7,16 +7,13 @@ package network_test import ( "context" - "fmt" "net/netip" - "os" - "path/filepath" + "strings" "testing" "time" - "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/siderolabs/go-procfs/procfs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" @@ -24,10 +21,8 @@ import ( "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest" netctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/network" v1alpha1runtime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" - "github.com/siderolabs/talos/pkg/machinery/constants" "github.com/siderolabs/talos/pkg/machinery/imager/quirks" "github.com/siderolabs/talos/pkg/machinery/nethelpers" - "github.com/siderolabs/talos/pkg/machinery/resources/block" "github.com/siderolabs/talos/pkg/machinery/resources/network" runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) @@ -39,388 +34,112 @@ type PlatformConfigSuite struct { func (suite *PlatformConfigSuite) TestNoPlatform() { suite.Require().NoError(suite.Runtime().RegisterController(&netctrl.PlatformConfigController{})) - ctest.AssertNoResource[*network.HostnameSpec](suite, "platform/hostname", rtestutils.WithNamespace(network.ConfigNamespaceName)) + ctest.AssertNoResource[*network.PlatformConfig](suite, network.PlatformConfigActiveID) } -func (suite *PlatformConfigSuite) TestPlatformMockHostname() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl.c.talos-testbed.internal")}, - }, - ), - ) - - ctest.AssertResource(suite, "platform/hostname", func(hostname *network.HostnameSpec, asrt *assert.Assertions) { - spec := hostname.TypedSpec() - - asrt.Equal("talos-e2e-897b4e49-gcp-controlplane-jvcnl", spec.Hostname) - asrt.Equal("c.talos-testbed.internal", spec.Domainname) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockHostnameNoDomain() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl")}, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResource(suite, "platform/hostname", func(hostname *network.HostnameSpec, asrt *assert.Assertions) { - spec := hostname.TypedSpec() - - asrt.Equal("talos-e2e-897b4e49-gcp-controlplane-jvcnl", spec.Hostname) - asrt.Equal("", spec.Domainname) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockAddresses() { +func (suite *PlatformConfigSuite) TestPlatform() { suite.Require().NoError( suite.Runtime().RegisterController( &netctrl.PlatformConfigController{ V1alpha1Platform: &platformMock{ + hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl.c.talos-testbed.internal"), addresses: []netip.Prefix{ netip.MustParsePrefix("192.168.1.24/24"), netip.MustParsePrefix("2001:fd::3/64"), }, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "platform/eth0/192.168.1.24/24", - "platform/eth0/2001:fd::3/64", - }, func(r *network.AddressSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - switch r.Metadata().ID() { - case "platform/eth0/192.168.1.24/24": - asrt.Equal(nethelpers.FamilyInet4, spec.Family) - asrt.Equal("192.168.1.24/24", spec.Address.String()) - case "platform/eth0/2001:fd::3/64": - asrt.Equal(nethelpers.FamilyInet6, spec.Family) - asrt.Equal("2001:fd::3/64", spec.Address.String()) - } - - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockLinks() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - linksUp: []string{"eth0", "eth1"}, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "platform/eth0", - "platform/eth1", - }, func(r *network.LinkSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.True(spec.Up) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockRoutes() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ defaultRoutes: []netip.Addr{netip.MustParseAddr("10.0.0.1")}, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "platform/inet4/10.0.0.1//1024", - }, func(r *network.RouteSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal("10.0.0.1", spec.Gateway.String()) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockOperators() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - dhcp4Links: []string{"eth1", "eth2"}, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "platform/dhcp4/eth1", - "platform/dhcp4/eth2", - }, func(r *network.OperatorSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal(network.OperatorDHCP4, spec.Operator) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockResolvers() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - resolvers: []netip.Addr{netip.MustParseAddr("1.1.1.1")}, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "platform/resolvers", - }, func(r *network.ResolverSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal("[1.1.1.1]", fmt.Sprintf("%s", spec.DNSServers)) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockTimeServers() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - timeServers: []string{"pool.ntp.org"}, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "platform/timeservers", - }, func(r *network.TimeServerSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal("[pool.ntp.org]", fmt.Sprintf("%s", spec.NTPServers)) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) -} - -func (suite *PlatformConfigSuite) TestPlatformMockProbes() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - tcpProbes: []string{"example.com:80", "example.com:443"}, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "tcp:example.com:80", - "tcp:example.com:443", - }, func(r *network.ProbeSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal(time.Second, spec.Interval) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }) -} - -func (suite *PlatformConfigSuite) TestPlatformMockExternalIPs() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ + linksUp: []string{"eth0", "eth1"}, + dhcp4Links: []string{"eth1", "eth2"}, + resolvers: []netip.Addr{netip.MustParseAddr("1.1.1.1")}, + timeServers: []string{"pool.ntp.org"}, + tcpProbes: []string{"example.com:80", "example.com:443"}, externalIPs: []netip.Addr{ netip.MustParseAddr("10.3.4.5"), netip.MustParseAddr("2001:470:6d:30e:96f4:4219:5733:b860"), }, - }, - PlatformState: suite.State(), - }, - ), - ) - - ctest.AssertResources(suite, []string{ - "external/10.3.4.5/32", - "external/2001:470:6d:30e:96f4:4219:5733:b860/128", - }, func(r *network.AddressStatus, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal("external", spec.LinkName) - asrt.Equal(nethelpers.ScopeGlobal, spec.Scope) - - if r.Metadata().ID() == "external/10.3.4.5/32" { - asrt.Equal(nethelpers.FamilyInet4, spec.Family) - } else { - asrt.Equal(nethelpers.FamilyInet6, spec.Family) - } - }) -} - -func (suite *PlatformConfigSuite) TestPlatformMockMetadata() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ metadata: &runtimeres.PlatformMetadataSpec{ Platform: "mock", Zone: "mock-zone", }, }, - PlatformState: suite.State(), }, ), ) - ctest.AssertResource(suite, runtimeres.PlatformMetadataID, - func(r *runtimeres.PlatformMetadata, asrt *assert.Assertions) { - asrt.Equal("mock", r.TypedSpec().Platform) - asrt.Equal("mock-zone", r.TypedSpec().Zone) - }) -} + ctest.AssertResource(suite, network.PlatformConfigActiveID, func(cfg *network.PlatformConfig, asrt *assert.Assertions) { + spec := cfg.TypedSpec() -const sampleStoredConfig = "addresses: []\nlinks: []\nroutes: []\nhostnames:\n - hostname: talos-e2e-897b4e49-gcp-controlplane-jvcnl\n domainname: \"\"\n layer: default\nresolvers: []\ntimeServers: []\noperators: []\nexternalIPs:\n - 10.3.4.5\n - 2001:470:6d:30e:96f4:4219:5733:b860\n" //nolint:lll - -func (suite *PlatformConfigSuite) TestStoreConfig() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl"), - externalIPs: []netip.Addr{ - netip.MustParseAddr("10.3.4.5"), - netip.MustParseAddr("2001:470:6d:30e:96f4:4219:5733:b860"), - }, - }, - PlatformState: suite.State(), - }, - ), - ) - - // wait for the controller to acquire the config - ctest.AssertResources(suite, []string{ - "external/10.3.4.5/32", - }, func(r *network.AddressStatus, asrt *assert.Assertions) {}) - - statePath := suite.T().TempDir() - mountID := (&netctrl.PlatformConfigController{}).Name() + "-" + constants.StatePartitionLabel - - ctest.AssertResource(suite, mountID, func(mountRequest *block.VolumeMountRequest, asrt *assert.Assertions) { - asrt.Equal(constants.StatePartitionLabel, mountRequest.TypedSpec().VolumeID) + asrt.Equal( + []string{"talos-e2e-897b4e49-gcp-controlplane-jvcnl.c.talos-testbed.internal"}, + xslices.Map(spec.Hostnames, func(h network.HostnameSpecSpec) string { + return h.FQDN() + }), + ) + asrt.Equal( + []string{"192.168.1.24/24", "2001:fd::3/64"}, + xslices.Map(spec.Addresses, func(a network.AddressSpecSpec) string { + return a.Address.String() + }), + ) + asrt.Equal( + []string{"10.0.0.1"}, + xslices.Map(spec.Routes, func(r network.RouteSpecSpec) string { + return r.Gateway.String() + }), + ) + asrt.Equal( + []string{"eth0", "eth1"}, + xslices.Map(spec.Links, func(l network.LinkSpecSpec) string { + return l.Name + }), + ) + asrt.Equal( + []string{"eth1", "eth2"}, + xslices.Map(spec.Operators, func(l network.OperatorSpecSpec) string { + return l.LinkName + }), + ) + asrt.Equal( + []string{"1.1.1.1"}, + xslices.Map(spec.Resolvers, func(r network.ResolverSpecSpec) string { + return strings.Join(xslices.Map(r.DNSServers, netip.Addr.String), ", ") + }), + ) + asrt.Equal( + []string{"pool.ntp.org"}, + xslices.Map(spec.TimeServers, func(t network.TimeServerSpecSpec) string { + return strings.Join(t.NTPServers, ", ") + }), + ) + asrt.Equal( + []string{"example.com:80", "example.com:443"}, + xslices.Map(spec.Probes, func(p network.ProbeSpecSpec) string { + return p.TCP.Endpoint + }), + ) + asrt.Equal( + []string{"10.3.4.5", "2001:470:6d:30e:96f4:4219:5733:b860"}, + xslices.Map(spec.ExternalIPs, netip.Addr.String), + ) + asrt.Equal( + "mock", + spec.Metadata.Platform, + ) + asrt.Equal( + "mock-zone", + spec.Metadata.Zone, + ) }) - - volumeMountStatus := block.NewVolumeMountStatus(block.NamespaceName, mountID) - volumeMountStatus.TypedSpec().Target = statePath - suite.Create(volumeMountStatus) - - suite.EventuallyWithT(func(collect *assert.CollectT) { - asrt := assert.New(collect) - - contents, err := os.ReadFile(filepath.Join(statePath, constants.PlatformNetworkConfigFilename)) - asrt.NoError(err) - - asrt.Equal(sampleStoredConfig, string(contents)) - }, time.Second, 10*time.Millisecond) - - ctest.AssertResources(suite, []resource.ID{volumeMountStatus.Metadata().ID()}, func(vms *block.VolumeMountStatus, asrt *assert.Assertions) { - asrt.True(vms.Metadata().Finalizers().Empty()) - }) - - suite.Destroy(volumeMountStatus) - - ctest.AssertNoResource[*block.VolumeMountRequest](suite, mountID) -} - -func (suite *PlatformConfigSuite) TestLoadConfig() { - suite.Require().NoError( - suite.Runtime().RegisterController( - &netctrl.PlatformConfigController{ - V1alpha1Platform: &platformMock{ - noData: true, - }, - PlatformState: suite.State(), - }, - ), - ) - - statePath := suite.T().TempDir() - mountID := (&netctrl.PlatformConfigController{}).Name() + "-" + constants.StatePartitionLabel - - suite.Require().NoError( - os.WriteFile( - filepath.Join(statePath, constants.PlatformNetworkConfigFilename), - []byte(sampleStoredConfig), - 0o400, - ), - ) - - ctest.AssertResource(suite, mountID, func(mountRequest *block.VolumeMountRequest, asrt *assert.Assertions) { - asrt.Equal(constants.StatePartitionLabel, mountRequest.TypedSpec().VolumeID) - }) - - volumeMountStatus := block.NewVolumeMountStatus(block.NamespaceName, mountID) - volumeMountStatus.TypedSpec().Target = statePath - suite.Create(volumeMountStatus) - - ctest.AssertNoResource[*block.VolumeMountRequest](suite, mountID) - - suite.Destroy(volumeMountStatus) - - // controller should pick up cached network configuration - ctest.AssertResources(suite, []string{ - "external/10.3.4.5/32", - "external/2001:470:6d:30e:96f4:4219:5733:b860/128", - }, func(r *network.AddressStatus, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal("external", spec.LinkName) - asrt.Equal(nethelpers.ScopeGlobal, spec.Scope) - - if r.Metadata().ID() == "external/10.3.4.5/32" { - asrt.Equal(nethelpers.FamilyInet4, spec.Family) - } else { - asrt.Equal(nethelpers.FamilyInet6, spec.Family) - } - }) - - ctest.AssertResources(suite, []string{ - "platform/hostname", - }, func(r *network.HostnameSpec, asrt *assert.Assertions) { - spec := r.TypedSpec() - - asrt.Equal("talos-e2e-897b4e49-gcp-controlplane-jvcnl", spec.Hostname) - asrt.Equal("", spec.Domainname) - asrt.Equal(network.ConfigPlatform, spec.ConfigLayer) - }, rtestutils.WithNamespace(network.ConfigNamespaceName)) } func TestPlatformConfigSuite(t *testing.T) { t.Parallel() - suite.Run(t, new(PlatformConfigSuite)) + suite.Run(t, &PlatformConfigSuite{ + DefaultSuite: ctest.DefaultSuite{ + Timeout: 5 * time.Second, + }, + }) } type platformMock struct { diff --git a/internal/app/machined/pkg/runtime/platform.go b/internal/app/machined/pkg/runtime/platform.go index 9ca8756ad..6f70f8f2e 100644 --- a/internal/app/machined/pkg/runtime/platform.go +++ b/internal/app/machined/pkg/runtime/platform.go @@ -5,17 +5,13 @@ package runtime import ( - "bytes" "context" - "net/netip" "github.com/cosi-project/runtime/pkg/state" "github.com/siderolabs/go-procfs/procfs" - "gopkg.in/yaml.v3" "github.com/siderolabs/talos/pkg/machinery/imager/quirks" "github.com/siderolabs/talos/pkg/machinery/resources/network" - "github.com/siderolabs/talos/pkg/machinery/resources/runtime" ) // Platform defines the requirements for a platform. @@ -47,36 +43,4 @@ type Platform interface { // // This structure is marshaled to STATE partition to persist cached network configuration across // reboots. -type PlatformNetworkConfig struct { - Addresses []network.AddressSpecSpec `yaml:"addresses"` - Links []network.LinkSpecSpec `yaml:"links"` - Routes []network.RouteSpecSpec `yaml:"routes"` - - Hostnames []network.HostnameSpecSpec `yaml:"hostnames"` - Resolvers []network.ResolverSpecSpec `yaml:"resolvers"` - TimeServers []network.TimeServerSpecSpec `yaml:"timeServers"` - - Operators []network.OperatorSpecSpec `yaml:"operators"` - - ExternalIPs []netip.Addr `yaml:"externalIPs"` - - Probes []network.ProbeSpecSpec `yaml:"probes,omitempty"` - - Metadata *runtime.PlatformMetadataSpec `yaml:"metadata,omitempty"` -} - -// Equal compares two network configurations. -func (p *PlatformNetworkConfig) Equal(other *PlatformNetworkConfig) bool { - // we will compare by marshaling to YAML - // and then comparing the bytes - // this is not the most efficient way to do this, - // but it will handle omitting empty fields - m1, err1 := yaml.Marshal(p) - - m2, err2 := yaml.Marshal(other) - if err1 != nil || err2 != nil { - return false - } - - return bytes.Equal(m1, m2) -} +type PlatformNetworkConfig = network.PlatformConfigSpec diff --git a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go index 35a260b1d..071b9fc3c 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_controller.go @@ -281,10 +281,13 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error &network.OperatorVIPConfigController{ Cmdline: procfs.ProcCmdline(), }, + &network.PlatformConfigApplyController{}, &network.PlatformConfigController{ V1alpha1Platform: ctrl.v1alpha1Runtime.State().Platform(), PlatformState: ctrl.v1alpha1Runtime.State().V1Alpha2().Resources(), }, + &network.PlatformConfigLoadController{}, + &network.PlatformConfigStoreController{}, &network.ProbeController{}, &network.ResolverConfigController{ 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 d6fee5d90..11063f17f 100644 --- a/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go +++ b/internal/app/machined/pkg/runtime/v1alpha2/v1alpha2_state.go @@ -190,6 +190,7 @@ func NewState() (*State, error) { &network.NodeAddressFilter{}, &network.NodeAddressSortAlgorithm{}, &network.OperatorSpec{}, + &network.PlatformConfig{}, &network.ProbeSpec{}, &network.ProbeStatus{}, &network.ResolverStatus{}, diff --git a/pkg/machinery/api/resource/definitions/enums/enums.pb.go b/pkg/machinery/api/resource/definitions/enums/enums.pb.go index f3df45af2..0a72eeb91 100644 --- a/pkg/machinery/api/resource/definitions/enums/enums.pb.go +++ b/pkg/machinery/api/resource/definitions/enums/enums.pb.go @@ -2374,112 +2374,6 @@ func (KubespanPeerState) EnumDescriptor() ([]byte, []int) { return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{36} } -// NetworkConfigLayer describes network configuration layers, with lowest priority first. -type NetworkConfigLayer int32 - -const ( - NetworkConfigLayer_CONFIG_DEFAULT NetworkConfigLayer = 0 - NetworkConfigLayer_CONFIG_CMDLINE NetworkConfigLayer = 1 - NetworkConfigLayer_CONFIG_PLATFORM NetworkConfigLayer = 2 - NetworkConfigLayer_CONFIG_OPERATOR NetworkConfigLayer = 3 - NetworkConfigLayer_CONFIG_MACHINE_CONFIGURATION NetworkConfigLayer = 4 -) - -// Enum value maps for NetworkConfigLayer. -var ( - NetworkConfigLayer_name = map[int32]string{ - 0: "CONFIG_DEFAULT", - 1: "CONFIG_CMDLINE", - 2: "CONFIG_PLATFORM", - 3: "CONFIG_OPERATOR", - 4: "CONFIG_MACHINE_CONFIGURATION", - } - NetworkConfigLayer_value = map[string]int32{ - "CONFIG_DEFAULT": 0, - "CONFIG_CMDLINE": 1, - "CONFIG_PLATFORM": 2, - "CONFIG_OPERATOR": 3, - "CONFIG_MACHINE_CONFIGURATION": 4, - } -) - -func (x NetworkConfigLayer) Enum() *NetworkConfigLayer { - p := new(NetworkConfigLayer) - *p = x - return p -} - -func (x NetworkConfigLayer) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (NetworkConfigLayer) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[37].Descriptor() -} - -func (NetworkConfigLayer) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[37] -} - -func (x NetworkConfigLayer) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use NetworkConfigLayer.Descriptor instead. -func (NetworkConfigLayer) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{37} -} - -// NetworkOperator enumerates Talos network operators. -type NetworkOperator int32 - -const ( - NetworkOperator_OPERATOR_DHCP4 NetworkOperator = 0 - NetworkOperator_OPERATOR_DHCP6 NetworkOperator = 1 - NetworkOperator_OPERATOR_VIP NetworkOperator = 2 -) - -// Enum value maps for NetworkOperator. -var ( - NetworkOperator_name = map[int32]string{ - 0: "OPERATOR_DHCP4", - 1: "OPERATOR_DHCP6", - 2: "OPERATOR_VIP", - } - NetworkOperator_value = map[string]int32{ - "OPERATOR_DHCP4": 0, - "OPERATOR_DHCP6": 1, - "OPERATOR_VIP": 2, - } -) - -func (x NetworkOperator) Enum() *NetworkOperator { - p := new(NetworkOperator) - *p = x - return p -} - -func (x NetworkOperator) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (NetworkOperator) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[38].Descriptor() -} - -func (NetworkOperator) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[38] -} - -func (x NetworkOperator) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use NetworkOperator.Descriptor instead. -func (NetworkOperator) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{38} -} - // RuntimeMachineStage describes the stage of the machine boot/run process. type RuntimeMachineStage int32 @@ -2532,11 +2426,11 @@ func (x RuntimeMachineStage) String() string { } func (RuntimeMachineStage) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[39].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[37].Descriptor() } func (RuntimeMachineStage) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[39] + return &file_resource_definitions_enums_enums_proto_enumTypes[37] } func (x RuntimeMachineStage) Number() protoreflect.EnumNumber { @@ -2545,7 +2439,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{39} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{37} } // RuntimeSELinuxState describes the current SELinux status. @@ -2582,11 +2476,11 @@ func (x RuntimeSELinuxState) String() string { } func (RuntimeSELinuxState) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[40].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[38].Descriptor() } func (RuntimeSELinuxState) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[40] + return &file_resource_definitions_enums_enums_proto_enumTypes[38] } func (x RuntimeSELinuxState) Number() protoreflect.EnumNumber { @@ -2595,7 +2489,7 @@ func (x RuntimeSELinuxState) Number() protoreflect.EnumNumber { // Deprecated: Use RuntimeSELinuxState.Descriptor instead. func (RuntimeSELinuxState) EnumDescriptor() ([]byte, []int) { - return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{40} + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{38} } // RuntimeFIPSState describes the current FIPS status. @@ -2632,11 +2526,11 @@ func (x RuntimeFIPSState) String() string { } func (RuntimeFIPSState) Descriptor() protoreflect.EnumDescriptor { - return file_resource_definitions_enums_enums_proto_enumTypes[41].Descriptor() + return file_resource_definitions_enums_enums_proto_enumTypes[39].Descriptor() } func (RuntimeFIPSState) Type() protoreflect.EnumType { - return &file_resource_definitions_enums_enums_proto_enumTypes[41] + return &file_resource_definitions_enums_enums_proto_enumTypes[39] } func (x RuntimeFIPSState) Number() protoreflect.EnumNumber { @@ -2645,6 +2539,112 @@ func (x RuntimeFIPSState) Number() protoreflect.EnumNumber { // Deprecated: Use RuntimeFIPSState.Descriptor instead. func (RuntimeFIPSState) EnumDescriptor() ([]byte, []int) { + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{39} +} + +// NetworkConfigLayer describes network configuration layers, with lowest priority first. +type NetworkConfigLayer int32 + +const ( + NetworkConfigLayer_CONFIG_DEFAULT NetworkConfigLayer = 0 + NetworkConfigLayer_CONFIG_CMDLINE NetworkConfigLayer = 1 + NetworkConfigLayer_CONFIG_PLATFORM NetworkConfigLayer = 2 + NetworkConfigLayer_CONFIG_OPERATOR NetworkConfigLayer = 3 + NetworkConfigLayer_CONFIG_MACHINE_CONFIGURATION NetworkConfigLayer = 4 +) + +// Enum value maps for NetworkConfigLayer. +var ( + NetworkConfigLayer_name = map[int32]string{ + 0: "CONFIG_DEFAULT", + 1: "CONFIG_CMDLINE", + 2: "CONFIG_PLATFORM", + 3: "CONFIG_OPERATOR", + 4: "CONFIG_MACHINE_CONFIGURATION", + } + NetworkConfigLayer_value = map[string]int32{ + "CONFIG_DEFAULT": 0, + "CONFIG_CMDLINE": 1, + "CONFIG_PLATFORM": 2, + "CONFIG_OPERATOR": 3, + "CONFIG_MACHINE_CONFIGURATION": 4, + } +) + +func (x NetworkConfigLayer) Enum() *NetworkConfigLayer { + p := new(NetworkConfigLayer) + *p = x + return p +} + +func (x NetworkConfigLayer) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NetworkConfigLayer) Descriptor() protoreflect.EnumDescriptor { + return file_resource_definitions_enums_enums_proto_enumTypes[40].Descriptor() +} + +func (NetworkConfigLayer) Type() protoreflect.EnumType { + return &file_resource_definitions_enums_enums_proto_enumTypes[40] +} + +func (x NetworkConfigLayer) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NetworkConfigLayer.Descriptor instead. +func (NetworkConfigLayer) EnumDescriptor() ([]byte, []int) { + return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{40} +} + +// NetworkOperator enumerates Talos network operators. +type NetworkOperator int32 + +const ( + NetworkOperator_OPERATOR_DHCP4 NetworkOperator = 0 + NetworkOperator_OPERATOR_DHCP6 NetworkOperator = 1 + NetworkOperator_OPERATOR_VIP NetworkOperator = 2 +) + +// Enum value maps for NetworkOperator. +var ( + NetworkOperator_name = map[int32]string{ + 0: "OPERATOR_DHCP4", + 1: "OPERATOR_DHCP6", + 2: "OPERATOR_VIP", + } + NetworkOperator_value = map[string]int32{ + "OPERATOR_DHCP4": 0, + "OPERATOR_DHCP6": 1, + "OPERATOR_VIP": 2, + } +) + +func (x NetworkOperator) Enum() *NetworkOperator { + p := new(NetworkOperator) + *p = x + return p +} + +func (x NetworkOperator) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (NetworkOperator) Descriptor() protoreflect.EnumDescriptor { + return file_resource_definitions_enums_enums_proto_enumTypes[41].Descriptor() +} + +func (NetworkOperator) Type() protoreflect.EnumType { + return &file_resource_definitions_enums_enums_proto_enumTypes[41] +} + +func (x NetworkOperator) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use NetworkOperator.Descriptor instead. +func (NetworkOperator) EnumDescriptor() ([]byte, []int) { return file_resource_definitions_enums_enums_proto_rawDescGZIP(), []int{41} } @@ -2990,17 +2990,7 @@ const file_resource_definitions_enums_enums_proto_rawDesc = "" + "\x11KubespanPeerState\x12\x16\n" + "\x12PEER_STATE_UNKNOWN\x10\x00\x12\x11\n" + "\rPEER_STATE_UP\x10\x01\x12\x13\n" + - "\x0fPEER_STATE_DOWN\x10\x02*\x88\x01\n" + - "\x12NetworkConfigLayer\x12\x12\n" + - "\x0eCONFIG_DEFAULT\x10\x00\x12\x12\n" + - "\x0eCONFIG_CMDLINE\x10\x01\x12\x13\n" + - "\x0fCONFIG_PLATFORM\x10\x02\x12\x13\n" + - "\x0fCONFIG_OPERATOR\x10\x03\x12 \n" + - "\x1cCONFIG_MACHINE_CONFIGURATION\x10\x04*K\n" + - "\x0fNetworkOperator\x12\x12\n" + - "\x0eOPERATOR_DHCP4\x10\x00\x12\x12\n" + - "\x0eOPERATOR_DHCP6\x10\x01\x12\x10\n" + - "\fOPERATOR_VIP\x10\x02*\x9b\x02\n" + + "\x0fPEER_STATE_DOWN\x10\x02*\x9b\x02\n" + "\x13RuntimeMachineStage\x12\x19\n" + "\x15MACHINE_STAGE_UNKNOWN\x10\x00\x12\x19\n" + "\x15MACHINE_STAGE_BOOTING\x10\x01\x12\x1c\n" + @@ -3018,7 +3008,17 @@ const file_resource_definitions_enums_enums_proto_rawDesc = "" + "\x10RuntimeFIPSState\x12\x17\n" + "\x13FIPS_STATE_DISABLED\x10\x00\x12\x16\n" + "\x12FIPS_STATE_ENABLED\x10\x01\x12\x15\n" + - "\x11FIPS_STATE_STRICT\x10\x02Bt\n" + + "\x11FIPS_STATE_STRICT\x10\x02*\x88\x01\n" + + "\x12NetworkConfigLayer\x12\x12\n" + + "\x0eCONFIG_DEFAULT\x10\x00\x12\x12\n" + + "\x0eCONFIG_CMDLINE\x10\x01\x12\x13\n" + + "\x0fCONFIG_PLATFORM\x10\x02\x12\x13\n" + + "\x0fCONFIG_OPERATOR\x10\x03\x12 \n" + + "\x1cCONFIG_MACHINE_CONFIGURATION\x10\x04*K\n" + + "\x0fNetworkOperator\x12\x12\n" + + "\x0eOPERATOR_DHCP4\x10\x00\x12\x12\n" + + "\x0eOPERATOR_DHCP6\x10\x01\x12\x10\n" + + "\fOPERATOR_VIP\x10\x02Bt\n" + "(dev.talos.api.resource.definitions.enumsZHgithub.com/siderolabs/talos/pkg/machinery/api/resource/definitions/enumsb\x06proto3" var ( @@ -3072,11 +3072,11 @@ var file_resource_definitions_enums_enums_proto_goTypes = []any{ (CriImageCacheStatus)(0), // 34: talos.resource.definitions.enums.CriImageCacheStatus (CriImageCacheCopyStatus)(0), // 35: talos.resource.definitions.enums.CriImageCacheCopyStatus (KubespanPeerState)(0), // 36: talos.resource.definitions.enums.KubespanPeerState - (NetworkConfigLayer)(0), // 37: talos.resource.definitions.enums.NetworkConfigLayer - (NetworkOperator)(0), // 38: talos.resource.definitions.enums.NetworkOperator - (RuntimeMachineStage)(0), // 39: talos.resource.definitions.enums.RuntimeMachineStage - (RuntimeSELinuxState)(0), // 40: talos.resource.definitions.enums.RuntimeSELinuxState - (RuntimeFIPSState)(0), // 41: talos.resource.definitions.enums.RuntimeFIPSState + (RuntimeMachineStage)(0), // 37: talos.resource.definitions.enums.RuntimeMachineStage + (RuntimeSELinuxState)(0), // 38: talos.resource.definitions.enums.RuntimeSELinuxState + (RuntimeFIPSState)(0), // 39: talos.resource.definitions.enums.RuntimeFIPSState + (NetworkConfigLayer)(0), // 40: talos.resource.definitions.enums.NetworkConfigLayer + (NetworkOperator)(0), // 41: talos.resource.definitions.enums.NetworkOperator } var file_resource_definitions_enums_enums_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type diff --git a/pkg/machinery/api/resource/definitions/network/network.pb.go b/pkg/machinery/api/resource/definitions/network/network.pb.go index 68f89c072..ed54e1008 100644 --- a/pkg/machinery/api/resource/definitions/network/network.pb.go +++ b/pkg/machinery/api/resource/definitions/network/network.pb.go @@ -17,6 +17,7 @@ import ( common "github.com/siderolabs/talos/pkg/machinery/api/common" enums "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/enums" + runtime "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/runtime" ) const ( @@ -3159,6 +3160,126 @@ func (x *OperatorSpecSpec) GetConfigLayer() enums.NetworkConfigLayer { return enums.NetworkConfigLayer(0) } +// PlatformConfigSpec describes platform network configuration. +// +// This structure is marshaled to STATE partition to persist cached network configuration across +// reboots. +type PlatformConfigSpec struct { + state protoimpl.MessageState `protogen:"open.v1"` + Addresses []*AddressSpecSpec `protobuf:"bytes,1,rep,name=addresses,proto3" json:"addresses,omitempty"` + Links []*LinkSpecSpec `protobuf:"bytes,2,rep,name=links,proto3" json:"links,omitempty"` + Routes []*RouteSpecSpec `protobuf:"bytes,3,rep,name=routes,proto3" json:"routes,omitempty"` + Hostnames []*HostnameSpecSpec `protobuf:"bytes,4,rep,name=hostnames,proto3" json:"hostnames,omitempty"` + Resolvers []*ResolverSpecSpec `protobuf:"bytes,5,rep,name=resolvers,proto3" json:"resolvers,omitempty"` + TimeServers []*TimeServerSpecSpec `protobuf:"bytes,6,rep,name=time_servers,json=timeServers,proto3" json:"time_servers,omitempty"` + Operators []*OperatorSpecSpec `protobuf:"bytes,7,rep,name=operators,proto3" json:"operators,omitempty"` + ExternalIps []*common.NetIP `protobuf:"bytes,8,rep,name=external_ips,json=externalIps,proto3" json:"external_ips,omitempty"` + Probes []*ProbeSpecSpec `protobuf:"bytes,9,rep,name=probes,proto3" json:"probes,omitempty"` + Metadata *runtime.PlatformMetadataSpec `protobuf:"bytes,10,opt,name=metadata,proto3" json:"metadata,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PlatformConfigSpec) Reset() { + *x = PlatformConfigSpec{} + mi := &file_resource_definitions_network_network_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PlatformConfigSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PlatformConfigSpec) ProtoMessage() {} + +func (x *PlatformConfigSpec) ProtoReflect() protoreflect.Message { + mi := &file_resource_definitions_network_network_proto_msgTypes[39] + 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 PlatformConfigSpec.ProtoReflect.Descriptor instead. +func (*PlatformConfigSpec) Descriptor() ([]byte, []int) { + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{39} +} + +func (x *PlatformConfigSpec) GetAddresses() []*AddressSpecSpec { + if x != nil { + return x.Addresses + } + return nil +} + +func (x *PlatformConfigSpec) GetLinks() []*LinkSpecSpec { + if x != nil { + return x.Links + } + return nil +} + +func (x *PlatformConfigSpec) GetRoutes() []*RouteSpecSpec { + if x != nil { + return x.Routes + } + return nil +} + +func (x *PlatformConfigSpec) GetHostnames() []*HostnameSpecSpec { + if x != nil { + return x.Hostnames + } + return nil +} + +func (x *PlatformConfigSpec) GetResolvers() []*ResolverSpecSpec { + if x != nil { + return x.Resolvers + } + return nil +} + +func (x *PlatformConfigSpec) GetTimeServers() []*TimeServerSpecSpec { + if x != nil { + return x.TimeServers + } + return nil +} + +func (x *PlatformConfigSpec) GetOperators() []*OperatorSpecSpec { + if x != nil { + return x.Operators + } + return nil +} + +func (x *PlatformConfigSpec) GetExternalIps() []*common.NetIP { + if x != nil { + return x.ExternalIps + } + return nil +} + +func (x *PlatformConfigSpec) GetProbes() []*ProbeSpecSpec { + if x != nil { + return x.Probes + } + return nil +} + +func (x *PlatformConfigSpec) GetMetadata() *runtime.PlatformMetadataSpec { + if x != nil { + return x.Metadata + } + return nil +} + // PortRange describes a range of ports. // // Range is [lo, hi]. @@ -3172,7 +3293,7 @@ type PortRange struct { func (x *PortRange) Reset() { *x = PortRange{} - 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) } @@ -3184,7 +3305,7 @@ func (x *PortRange) String() string { func (*PortRange) ProtoMessage() {} func (x *PortRange) 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 { @@ -3197,7 +3318,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{39} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{40} } func (x *PortRange) GetLo() uint32 { @@ -3227,7 +3348,7 @@ type ProbeSpecSpec struct { func (x *ProbeSpecSpec) Reset() { *x = ProbeSpecSpec{} - 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) } @@ -3239,7 +3360,7 @@ func (x *ProbeSpecSpec) String() string { func (*ProbeSpecSpec) ProtoMessage() {} func (x *ProbeSpecSpec) 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 { @@ -3252,7 +3373,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{40} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{41} } func (x *ProbeSpecSpec) GetInterval() *durationpb.Duration { @@ -3294,7 +3415,7 @@ type ProbeStatusSpec struct { func (x *ProbeStatusSpec) Reset() { *x = ProbeStatusSpec{} - 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) } @@ -3306,7 +3427,7 @@ func (x *ProbeStatusSpec) String() string { func (*ProbeStatusSpec) ProtoMessage() {} func (x *ProbeStatusSpec) 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 { @@ -3319,7 +3440,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{41} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{42} } func (x *ProbeStatusSpec) GetSuccess() bool { @@ -3348,7 +3469,7 @@ type ResolverSpecSpec struct { func (x *ResolverSpecSpec) Reset() { *x = ResolverSpecSpec{} - 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) } @@ -3360,7 +3481,7 @@ func (x *ResolverSpecSpec) String() string { func (*ResolverSpecSpec) ProtoMessage() {} func (x *ResolverSpecSpec) 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 { @@ -3373,7 +3494,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{42} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{43} } func (x *ResolverSpecSpec) GetDnsServers() []*common.NetIP { @@ -3408,7 +3529,7 @@ type ResolverStatusSpec struct { func (x *ResolverStatusSpec) Reset() { *x = ResolverStatusSpec{} - 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) } @@ -3420,7 +3541,7 @@ func (x *ResolverStatusSpec) String() string { func (*ResolverStatusSpec) ProtoMessage() {} func (x *ResolverStatusSpec) 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 { @@ -3433,7 +3554,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{43} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{44} } func (x *ResolverStatusSpec) GetDnsServers() []*common.NetIP { @@ -3472,7 +3593,7 @@ type RouteSpecSpec struct { func (x *RouteSpecSpec) Reset() { *x = RouteSpecSpec{} - 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) } @@ -3484,7 +3605,7 @@ func (x *RouteSpecSpec) String() string { func (*RouteSpecSpec) ProtoMessage() {} func (x *RouteSpecSpec) 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 { @@ -3497,7 +3618,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{44} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{45} } func (x *RouteSpecSpec) GetFamily() enums.NethelpersFamily { @@ -3613,7 +3734,7 @@ type RouteStatusSpec struct { func (x *RouteStatusSpec) Reset() { *x = RouteStatusSpec{} - 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) } @@ -3625,7 +3746,7 @@ func (x *RouteStatusSpec) String() string { func (*RouteStatusSpec) ProtoMessage() {} func (x *RouteStatusSpec) 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 { @@ -3638,7 +3759,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{45} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{46} } func (x *RouteStatusSpec) GetFamily() enums.NethelpersFamily { @@ -3742,7 +3863,7 @@ type STPSpec struct { func (x *STPSpec) Reset() { *x = STPSpec{} - 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) } @@ -3754,7 +3875,7 @@ func (x *STPSpec) String() string { func (*STPSpec) ProtoMessage() {} func (x *STPSpec) 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 { @@ -3767,7 +3888,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{46} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{47} } func (x *STPSpec) GetEnabled() bool { @@ -3790,7 +3911,7 @@ type StatusSpec struct { func (x *StatusSpec) Reset() { *x = StatusSpec{} - 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) } @@ -3802,7 +3923,7 @@ func (x *StatusSpec) String() string { func (*StatusSpec) ProtoMessage() {} func (x *StatusSpec) 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 { @@ -3815,7 +3936,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{47} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{48} } func (x *StatusSpec) GetAddressReady() bool { @@ -3857,7 +3978,7 @@ type TCPProbeSpec struct { func (x *TCPProbeSpec) Reset() { *x = TCPProbeSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[48] + mi := &file_resource_definitions_network_network_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3869,7 +3990,7 @@ func (x *TCPProbeSpec) String() string { func (*TCPProbeSpec) ProtoMessage() {} func (x *TCPProbeSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[48] + mi := &file_resource_definitions_network_network_proto_msgTypes[49] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3882,7 +4003,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{48} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{49} } func (x *TCPProbeSpec) GetEndpoint() string { @@ -3910,7 +4031,7 @@ type TimeServerSpecSpec struct { func (x *TimeServerSpecSpec) Reset() { *x = TimeServerSpecSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[49] + mi := &file_resource_definitions_network_network_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3922,7 +4043,7 @@ func (x *TimeServerSpecSpec) String() string { func (*TimeServerSpecSpec) ProtoMessage() {} func (x *TimeServerSpecSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[49] + mi := &file_resource_definitions_network_network_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3935,7 +4056,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{49} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{50} } func (x *TimeServerSpecSpec) GetNtpServers() []string { @@ -3962,7 +4083,7 @@ type TimeServerStatusSpec struct { func (x *TimeServerStatusSpec) Reset() { *x = TimeServerStatusSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[50] + mi := &file_resource_definitions_network_network_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3974,7 +4095,7 @@ func (x *TimeServerStatusSpec) String() string { func (*TimeServerStatusSpec) ProtoMessage() {} func (x *TimeServerStatusSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[50] + mi := &file_resource_definitions_network_network_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3987,7 +4108,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{50} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{51} } func (x *TimeServerStatusSpec) GetNtpServers() []string { @@ -4009,7 +4130,7 @@ type VIPEquinixMetalSpec struct { func (x *VIPEquinixMetalSpec) Reset() { *x = VIPEquinixMetalSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[51] + mi := &file_resource_definitions_network_network_proto_msgTypes[52] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4021,7 +4142,7 @@ func (x *VIPEquinixMetalSpec) String() string { func (*VIPEquinixMetalSpec) ProtoMessage() {} func (x *VIPEquinixMetalSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[51] + mi := &file_resource_definitions_network_network_proto_msgTypes[52] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4034,7 +4155,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{51} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{52} } func (x *VIPEquinixMetalSpec) GetProjectId() string { @@ -4070,7 +4191,7 @@ type VIPHCloudSpec struct { func (x *VIPHCloudSpec) Reset() { *x = VIPHCloudSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[52] + mi := &file_resource_definitions_network_network_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4082,7 +4203,7 @@ func (x *VIPHCloudSpec) String() string { func (*VIPHCloudSpec) ProtoMessage() {} func (x *VIPHCloudSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[52] + mi := &file_resource_definitions_network_network_proto_msgTypes[53] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4095,7 +4216,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{52} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{53} } func (x *VIPHCloudSpec) GetDeviceId() int64 { @@ -4132,7 +4253,7 @@ type VIPOperatorSpec struct { func (x *VIPOperatorSpec) Reset() { *x = VIPOperatorSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[53] + mi := &file_resource_definitions_network_network_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4144,7 +4265,7 @@ func (x *VIPOperatorSpec) String() string { func (*VIPOperatorSpec) ProtoMessage() {} func (x *VIPOperatorSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[53] + mi := &file_resource_definitions_network_network_proto_msgTypes[54] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4157,7 +4278,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{53} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{54} } func (x *VIPOperatorSpec) GetIp() *common.NetIP { @@ -4199,7 +4320,7 @@ type VLANSpec struct { func (x *VLANSpec) Reset() { *x = VLANSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[54] + mi := &file_resource_definitions_network_network_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4211,7 +4332,7 @@ func (x *VLANSpec) String() string { func (*VLANSpec) ProtoMessage() {} func (x *VLANSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[54] + mi := &file_resource_definitions_network_network_proto_msgTypes[55] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4224,7 +4345,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{54} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{55} } func (x *VLANSpec) GetVid() uint32 { @@ -4255,7 +4376,7 @@ type WireguardPeer struct { func (x *WireguardPeer) Reset() { *x = WireguardPeer{} - mi := &file_resource_definitions_network_network_proto_msgTypes[55] + mi := &file_resource_definitions_network_network_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4267,7 +4388,7 @@ func (x *WireguardPeer) String() string { func (*WireguardPeer) ProtoMessage() {} func (x *WireguardPeer) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[55] + mi := &file_resource_definitions_network_network_proto_msgTypes[56] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4280,7 +4401,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{55} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{56} } func (x *WireguardPeer) GetPublicKey() string { @@ -4332,7 +4453,7 @@ type WireguardSpec struct { func (x *WireguardSpec) Reset() { *x = WireguardSpec{} - mi := &file_resource_definitions_network_network_proto_msgTypes[56] + mi := &file_resource_definitions_network_network_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4344,7 +4465,7 @@ func (x *WireguardSpec) String() string { func (*WireguardSpec) ProtoMessage() {} func (x *WireguardSpec) ProtoReflect() protoreflect.Message { - mi := &file_resource_definitions_network_network_proto_msgTypes[56] + mi := &file_resource_definitions_network_network_proto_msgTypes[57] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4357,7 +4478,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{56} + return file_resource_definitions_network_network_proto_rawDescGZIP(), []int{57} } func (x *WireguardSpec) GetPrivateKey() string { @@ -4399,7 +4520,7 @@ var File_resource_definitions_network_network_proto protoreflect.FileDescriptor const file_resource_definitions_network_network_proto_rawDesc = "" + "\n" + - "*resource/definitions/network/network.proto\x12\"talos.resource.definitions.network\x1a\x13common/common.proto\x1a\x1egoogle/protobuf/duration.proto\x1a&resource/definitions/enums/enums.proto\"\xa9\x03\n" + + "*resource/definitions/network/network.proto\x12\"talos.resource.definitions.network\x1a\x13common/common.proto\x1a\x1egoogle/protobuf/duration.proto\x1a&resource/definitions/enums/enums.proto\x1a*resource/definitions/runtime/runtime.proto\"\xa9\x03\n" + "\x0fAddressSpecSpec\x12-\n" + "\aaddress\x18\x01 \x01(\v2\x13.common.NetIPPrefixR\aaddress\x12\x1b\n" + "\tlink_name\x18\x02 \x01(\tR\blinkName\x12J\n" + @@ -4692,7 +4813,19 @@ const file_resource_definitions_network_network_proto_rawDesc = "" + "\x05dhcp4\x18\x04 \x01(\v25.talos.resource.definitions.network.DHCP4OperatorSpecR\x05dhcp4\x12K\n" + "\x05dhcp6\x18\x05 \x01(\v25.talos.resource.definitions.network.DHCP6OperatorSpecR\x05dhcp6\x12E\n" + "\x03vip\x18\x06 \x01(\v23.talos.resource.definitions.network.VIPOperatorSpecR\x03vip\x12W\n" + - "\fconfig_layer\x18\a \x01(\x0e24.talos.resource.definitions.enums.NetworkConfigLayerR\vconfigLayer\"+\n" + + "\fconfig_layer\x18\a \x01(\x0e24.talos.resource.definitions.enums.NetworkConfigLayerR\vconfigLayer\"\xa4\x06\n" + + "\x12PlatformConfigSpec\x12Q\n" + + "\taddresses\x18\x01 \x03(\v23.talos.resource.definitions.network.AddressSpecSpecR\taddresses\x12F\n" + + "\x05links\x18\x02 \x03(\v20.talos.resource.definitions.network.LinkSpecSpecR\x05links\x12I\n" + + "\x06routes\x18\x03 \x03(\v21.talos.resource.definitions.network.RouteSpecSpecR\x06routes\x12R\n" + + "\thostnames\x18\x04 \x03(\v24.talos.resource.definitions.network.HostnameSpecSpecR\thostnames\x12R\n" + + "\tresolvers\x18\x05 \x03(\v24.talos.resource.definitions.network.ResolverSpecSpecR\tresolvers\x12Y\n" + + "\ftime_servers\x18\x06 \x03(\v26.talos.resource.definitions.network.TimeServerSpecSpecR\vtimeServers\x12R\n" + + "\toperators\x18\a \x03(\v24.talos.resource.definitions.network.OperatorSpecSpecR\toperators\x120\n" + + "\fexternal_ips\x18\b \x03(\v2\r.common.NetIPR\vexternalIps\x12I\n" + + "\x06probes\x18\t \x03(\v21.talos.resource.definitions.network.ProbeSpecSpecR\x06probes\x12T\n" + + "\bmetadata\x18\n" + + " \x01(\v28.talos.resource.definitions.runtime.PlatformMetadataSpecR\bmetadata\"+\n" + "\tPortRange\x12\x0e\n" + "\x02lo\x18\x01 \x01(\aR\x02lo\x12\x0e\n" + "\x02hi\x18\x02 \x01(\aR\x02hi\"\x90\x02\n" + @@ -4811,7 +4944,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, 58) +var file_resource_definitions_network_network_proto_msgTypes = make([]protoimpl.MessageInfo, 59) 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 @@ -4852,123 +4985,125 @@ var file_resource_definitions_network_network_proto_goTypes = []any{ (*NodeAddressSortAlgorithmSpec)(nil), // 36: talos.resource.definitions.network.NodeAddressSortAlgorithmSpec (*NodeAddressSpec)(nil), // 37: talos.resource.definitions.network.NodeAddressSpec (*OperatorSpecSpec)(nil), // 38: talos.resource.definitions.network.OperatorSpecSpec - (*PortRange)(nil), // 39: talos.resource.definitions.network.PortRange - (*ProbeSpecSpec)(nil), // 40: talos.resource.definitions.network.ProbeSpecSpec - (*ProbeStatusSpec)(nil), // 41: talos.resource.definitions.network.ProbeStatusSpec - (*ResolverSpecSpec)(nil), // 42: talos.resource.definitions.network.ResolverSpecSpec - (*ResolverStatusSpec)(nil), // 43: talos.resource.definitions.network.ResolverStatusSpec - (*RouteSpecSpec)(nil), // 44: talos.resource.definitions.network.RouteSpecSpec - (*RouteStatusSpec)(nil), // 45: talos.resource.definitions.network.RouteStatusSpec - (*STPSpec)(nil), // 46: talos.resource.definitions.network.STPSpec - (*StatusSpec)(nil), // 47: talos.resource.definitions.network.StatusSpec - (*TCPProbeSpec)(nil), // 48: talos.resource.definitions.network.TCPProbeSpec - (*TimeServerSpecSpec)(nil), // 49: talos.resource.definitions.network.TimeServerSpecSpec - (*TimeServerStatusSpec)(nil), // 50: talos.resource.definitions.network.TimeServerStatusSpec - (*VIPEquinixMetalSpec)(nil), // 51: talos.resource.definitions.network.VIPEquinixMetalSpec - (*VIPHCloudSpec)(nil), // 52: talos.resource.definitions.network.VIPHCloudSpec - (*VIPOperatorSpec)(nil), // 53: talos.resource.definitions.network.VIPOperatorSpec - (*VLANSpec)(nil), // 54: talos.resource.definitions.network.VLANSpec - (*WireguardPeer)(nil), // 55: talos.resource.definitions.network.WireguardPeer - (*WireguardSpec)(nil), // 56: talos.resource.definitions.network.WireguardSpec - nil, // 57: talos.resource.definitions.network.EthernetSpecSpec.FeaturesEntry - (*common.NetIPPrefix)(nil), // 58: common.NetIPPrefix - (enums.NethelpersFamily)(0), // 59: talos.resource.definitions.enums.NethelpersFamily - (enums.NethelpersScope)(0), // 60: talos.resource.definitions.enums.NethelpersScope - (enums.NetworkConfigLayer)(0), // 61: talos.resource.definitions.enums.NetworkConfigLayer - (*common.NetIP)(nil), // 62: common.NetIP - (enums.NethelpersBondMode)(0), // 63: talos.resource.definitions.enums.NethelpersBondMode - (enums.NethelpersBondXmitHashPolicy)(0), // 64: talos.resource.definitions.enums.NethelpersBondXmitHashPolicy - (enums.NethelpersLACPRate)(0), // 65: talos.resource.definitions.enums.NethelpersLACPRate - (enums.NethelpersARPValidate)(0), // 66: talos.resource.definitions.enums.NethelpersARPValidate - (enums.NethelpersARPAllTargets)(0), // 67: talos.resource.definitions.enums.NethelpersARPAllTargets - (enums.NethelpersPrimaryReselect)(0), // 68: talos.resource.definitions.enums.NethelpersPrimaryReselect - (enums.NethelpersFailOverMAC)(0), // 69: talos.resource.definitions.enums.NethelpersFailOverMAC - (enums.NethelpersADSelect)(0), // 70: talos.resource.definitions.enums.NethelpersADSelect - (enums.NethelpersPort)(0), // 71: talos.resource.definitions.enums.NethelpersPort - (enums.NethelpersDuplex)(0), // 72: talos.resource.definitions.enums.NethelpersDuplex - (*common.NetIPPort)(nil), // 73: common.NetIPPort - (enums.NethelpersLinkType)(0), // 74: talos.resource.definitions.enums.NethelpersLinkType - (enums.NethelpersOperationalState)(0), // 75: talos.resource.definitions.enums.NethelpersOperationalState - (enums.NethelpersNfTablesChainHook)(0), // 76: talos.resource.definitions.enums.NethelpersNfTablesChainHook - (enums.NethelpersNfTablesChainPriority)(0), // 77: talos.resource.definitions.enums.NethelpersNfTablesChainPriority - (enums.NethelpersNfTablesVerdict)(0), // 78: talos.resource.definitions.enums.NethelpersNfTablesVerdict - (enums.NethelpersConntrackState)(0), // 79: talos.resource.definitions.enums.NethelpersConntrackState - (enums.NethelpersICMPType)(0), // 80: talos.resource.definitions.enums.NethelpersICMPType - (enums.NethelpersMatchOperator)(0), // 81: talos.resource.definitions.enums.NethelpersMatchOperator - (enums.NethelpersProtocol)(0), // 82: talos.resource.definitions.enums.NethelpersProtocol - (enums.NethelpersAddressSortAlgorithm)(0), // 83: talos.resource.definitions.enums.NethelpersAddressSortAlgorithm - (enums.NetworkOperator)(0), // 84: talos.resource.definitions.enums.NetworkOperator - (*durationpb.Duration)(nil), // 85: google.protobuf.Duration - (enums.NethelpersRoutingTable)(0), // 86: talos.resource.definitions.enums.NethelpersRoutingTable - (enums.NethelpersRouteType)(0), // 87: talos.resource.definitions.enums.NethelpersRouteType - (enums.NethelpersRouteProtocol)(0), // 88: talos.resource.definitions.enums.NethelpersRouteProtocol - (enums.NethelpersVLANProtocol)(0), // 89: talos.resource.definitions.enums.NethelpersVLANProtocol + (*PlatformConfigSpec)(nil), // 39: talos.resource.definitions.network.PlatformConfigSpec + (*PortRange)(nil), // 40: talos.resource.definitions.network.PortRange + (*ProbeSpecSpec)(nil), // 41: talos.resource.definitions.network.ProbeSpecSpec + (*ProbeStatusSpec)(nil), // 42: talos.resource.definitions.network.ProbeStatusSpec + (*ResolverSpecSpec)(nil), // 43: talos.resource.definitions.network.ResolverSpecSpec + (*ResolverStatusSpec)(nil), // 44: talos.resource.definitions.network.ResolverStatusSpec + (*RouteSpecSpec)(nil), // 45: talos.resource.definitions.network.RouteSpecSpec + (*RouteStatusSpec)(nil), // 46: talos.resource.definitions.network.RouteStatusSpec + (*STPSpec)(nil), // 47: talos.resource.definitions.network.STPSpec + (*StatusSpec)(nil), // 48: talos.resource.definitions.network.StatusSpec + (*TCPProbeSpec)(nil), // 49: talos.resource.definitions.network.TCPProbeSpec + (*TimeServerSpecSpec)(nil), // 50: talos.resource.definitions.network.TimeServerSpecSpec + (*TimeServerStatusSpec)(nil), // 51: talos.resource.definitions.network.TimeServerStatusSpec + (*VIPEquinixMetalSpec)(nil), // 52: talos.resource.definitions.network.VIPEquinixMetalSpec + (*VIPHCloudSpec)(nil), // 53: talos.resource.definitions.network.VIPHCloudSpec + (*VIPOperatorSpec)(nil), // 54: talos.resource.definitions.network.VIPOperatorSpec + (*VLANSpec)(nil), // 55: talos.resource.definitions.network.VLANSpec + (*WireguardPeer)(nil), // 56: talos.resource.definitions.network.WireguardPeer + (*WireguardSpec)(nil), // 57: talos.resource.definitions.network.WireguardSpec + nil, // 58: talos.resource.definitions.network.EthernetSpecSpec.FeaturesEntry + (*common.NetIPPrefix)(nil), // 59: common.NetIPPrefix + (enums.NethelpersFamily)(0), // 60: talos.resource.definitions.enums.NethelpersFamily + (enums.NethelpersScope)(0), // 61: talos.resource.definitions.enums.NethelpersScope + (enums.NetworkConfigLayer)(0), // 62: talos.resource.definitions.enums.NetworkConfigLayer + (*common.NetIP)(nil), // 63: common.NetIP + (enums.NethelpersBondMode)(0), // 64: talos.resource.definitions.enums.NethelpersBondMode + (enums.NethelpersBondXmitHashPolicy)(0), // 65: talos.resource.definitions.enums.NethelpersBondXmitHashPolicy + (enums.NethelpersLACPRate)(0), // 66: talos.resource.definitions.enums.NethelpersLACPRate + (enums.NethelpersARPValidate)(0), // 67: talos.resource.definitions.enums.NethelpersARPValidate + (enums.NethelpersARPAllTargets)(0), // 68: talos.resource.definitions.enums.NethelpersARPAllTargets + (enums.NethelpersPrimaryReselect)(0), // 69: talos.resource.definitions.enums.NethelpersPrimaryReselect + (enums.NethelpersFailOverMAC)(0), // 70: talos.resource.definitions.enums.NethelpersFailOverMAC + (enums.NethelpersADSelect)(0), // 71: talos.resource.definitions.enums.NethelpersADSelect + (enums.NethelpersPort)(0), // 72: talos.resource.definitions.enums.NethelpersPort + (enums.NethelpersDuplex)(0), // 73: talos.resource.definitions.enums.NethelpersDuplex + (*common.NetIPPort)(nil), // 74: common.NetIPPort + (enums.NethelpersLinkType)(0), // 75: talos.resource.definitions.enums.NethelpersLinkType + (enums.NethelpersOperationalState)(0), // 76: talos.resource.definitions.enums.NethelpersOperationalState + (enums.NethelpersNfTablesChainHook)(0), // 77: talos.resource.definitions.enums.NethelpersNfTablesChainHook + (enums.NethelpersNfTablesChainPriority)(0), // 78: talos.resource.definitions.enums.NethelpersNfTablesChainPriority + (enums.NethelpersNfTablesVerdict)(0), // 79: talos.resource.definitions.enums.NethelpersNfTablesVerdict + (enums.NethelpersConntrackState)(0), // 80: talos.resource.definitions.enums.NethelpersConntrackState + (enums.NethelpersICMPType)(0), // 81: talos.resource.definitions.enums.NethelpersICMPType + (enums.NethelpersMatchOperator)(0), // 82: talos.resource.definitions.enums.NethelpersMatchOperator + (enums.NethelpersProtocol)(0), // 83: talos.resource.definitions.enums.NethelpersProtocol + (enums.NethelpersAddressSortAlgorithm)(0), // 84: talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + (enums.NetworkOperator)(0), // 85: talos.resource.definitions.enums.NetworkOperator + (*runtime.PlatformMetadataSpec)(nil), // 86: talos.resource.definitions.runtime.PlatformMetadataSpec + (*durationpb.Duration)(nil), // 87: google.protobuf.Duration + (enums.NethelpersRoutingTable)(0), // 88: talos.resource.definitions.enums.NethelpersRoutingTable + (enums.NethelpersRouteType)(0), // 89: talos.resource.definitions.enums.NethelpersRouteType + (enums.NethelpersRouteProtocol)(0), // 90: talos.resource.definitions.enums.NethelpersRouteProtocol + (enums.NethelpersVLANProtocol)(0), // 91: talos.resource.definitions.enums.NethelpersVLANProtocol } var file_resource_definitions_network_network_proto_depIdxs = []int32{ - 58, // 0: talos.resource.definitions.network.AddressSpecSpec.address:type_name -> common.NetIPPrefix - 59, // 1: talos.resource.definitions.network.AddressSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 60, // 2: talos.resource.definitions.network.AddressSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 61, // 3: talos.resource.definitions.network.AddressSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 58, // 4: talos.resource.definitions.network.AddressStatusSpec.address:type_name -> common.NetIPPrefix - 62, // 5: talos.resource.definitions.network.AddressStatusSpec.local:type_name -> common.NetIP - 62, // 6: talos.resource.definitions.network.AddressStatusSpec.broadcast:type_name -> common.NetIP - 62, // 7: talos.resource.definitions.network.AddressStatusSpec.anycast:type_name -> common.NetIP - 62, // 8: talos.resource.definitions.network.AddressStatusSpec.multicast:type_name -> common.NetIP - 59, // 9: talos.resource.definitions.network.AddressStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 60, // 10: talos.resource.definitions.network.AddressStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 63, // 11: talos.resource.definitions.network.BondMasterSpec.mode:type_name -> talos.resource.definitions.enums.NethelpersBondMode - 64, // 12: talos.resource.definitions.network.BondMasterSpec.hash_policy:type_name -> talos.resource.definitions.enums.NethelpersBondXmitHashPolicy - 65, // 13: talos.resource.definitions.network.BondMasterSpec.lacp_rate:type_name -> talos.resource.definitions.enums.NethelpersLACPRate - 66, // 14: talos.resource.definitions.network.BondMasterSpec.arp_validate:type_name -> talos.resource.definitions.enums.NethelpersARPValidate - 67, // 15: talos.resource.definitions.network.BondMasterSpec.arp_all_targets:type_name -> talos.resource.definitions.enums.NethelpersARPAllTargets - 68, // 16: talos.resource.definitions.network.BondMasterSpec.primary_reselect:type_name -> talos.resource.definitions.enums.NethelpersPrimaryReselect - 69, // 17: talos.resource.definitions.network.BondMasterSpec.fail_over_mac:type_name -> talos.resource.definitions.enums.NethelpersFailOverMAC - 70, // 18: talos.resource.definitions.network.BondMasterSpec.ad_select:type_name -> talos.resource.definitions.enums.NethelpersADSelect - 46, // 19: talos.resource.definitions.network.BridgeMasterSpec.stp:type_name -> talos.resource.definitions.network.STPSpec + 59, // 0: talos.resource.definitions.network.AddressSpecSpec.address:type_name -> common.NetIPPrefix + 60, // 1: talos.resource.definitions.network.AddressSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 61, // 2: talos.resource.definitions.network.AddressSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 62, // 3: talos.resource.definitions.network.AddressSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 59, // 4: talos.resource.definitions.network.AddressStatusSpec.address:type_name -> common.NetIPPrefix + 63, // 5: talos.resource.definitions.network.AddressStatusSpec.local:type_name -> common.NetIP + 63, // 6: talos.resource.definitions.network.AddressStatusSpec.broadcast:type_name -> common.NetIP + 63, // 7: talos.resource.definitions.network.AddressStatusSpec.anycast:type_name -> common.NetIP + 63, // 8: talos.resource.definitions.network.AddressStatusSpec.multicast:type_name -> common.NetIP + 60, // 9: talos.resource.definitions.network.AddressStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 61, // 10: talos.resource.definitions.network.AddressStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 64, // 11: talos.resource.definitions.network.BondMasterSpec.mode:type_name -> talos.resource.definitions.enums.NethelpersBondMode + 65, // 12: talos.resource.definitions.network.BondMasterSpec.hash_policy:type_name -> talos.resource.definitions.enums.NethelpersBondXmitHashPolicy + 66, // 13: talos.resource.definitions.network.BondMasterSpec.lacp_rate:type_name -> talos.resource.definitions.enums.NethelpersLACPRate + 67, // 14: talos.resource.definitions.network.BondMasterSpec.arp_validate:type_name -> talos.resource.definitions.enums.NethelpersARPValidate + 68, // 15: talos.resource.definitions.network.BondMasterSpec.arp_all_targets:type_name -> talos.resource.definitions.enums.NethelpersARPAllTargets + 69, // 16: talos.resource.definitions.network.BondMasterSpec.primary_reselect:type_name -> talos.resource.definitions.enums.NethelpersPrimaryReselect + 70, // 17: talos.resource.definitions.network.BondMasterSpec.fail_over_mac:type_name -> talos.resource.definitions.enums.NethelpersFailOverMAC + 71, // 18: talos.resource.definitions.network.BondMasterSpec.ad_select:type_name -> talos.resource.definitions.enums.NethelpersADSelect + 47, // 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 13, // 21: talos.resource.definitions.network.EthernetSpecSpec.rings:type_name -> talos.resource.definitions.network.EthernetRingsSpec - 57, // 22: talos.resource.definitions.network.EthernetSpecSpec.features:type_name -> talos.resource.definitions.network.EthernetSpecSpec.FeaturesEntry + 58, // 22: talos.resource.definitions.network.EthernetSpecSpec.features:type_name -> talos.resource.definitions.network.EthernetSpecSpec.FeaturesEntry 10, // 23: talos.resource.definitions.network.EthernetSpecSpec.channels:type_name -> talos.resource.definitions.network.EthernetChannelsSpec - 71, // 24: talos.resource.definitions.network.EthernetStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort - 72, // 25: talos.resource.definitions.network.EthernetStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex + 72, // 24: talos.resource.definitions.network.EthernetStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort + 73, // 25: talos.resource.definitions.network.EthernetStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex 14, // 26: talos.resource.definitions.network.EthernetStatusSpec.rings:type_name -> talos.resource.definitions.network.EthernetRingsStatus 12, // 27: talos.resource.definitions.network.EthernetStatusSpec.features:type_name -> talos.resource.definitions.network.EthernetFeatureStatus 11, // 28: talos.resource.definitions.network.EthernetStatusSpec.channels:type_name -> talos.resource.definitions.network.EthernetChannelsStatus - 73, // 29: talos.resource.definitions.network.HostDNSConfigSpec.listen_addresses:type_name -> common.NetIPPort - 62, // 30: talos.resource.definitions.network.HostDNSConfigSpec.service_host_dns_address:type_name -> common.NetIP - 61, // 31: talos.resource.definitions.network.HostnameSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 74, // 32: talos.resource.definitions.network.LinkSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType + 74, // 29: talos.resource.definitions.network.HostDNSConfigSpec.listen_addresses:type_name -> common.NetIPPort + 63, // 30: talos.resource.definitions.network.HostDNSConfigSpec.service_host_dns_address:type_name -> common.NetIP + 62, // 31: talos.resource.definitions.network.HostnameSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 75, // 32: talos.resource.definitions.network.LinkSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType 3, // 33: talos.resource.definitions.network.LinkSpecSpec.bond_slave:type_name -> talos.resource.definitions.network.BondSlave 5, // 34: talos.resource.definitions.network.LinkSpecSpec.bridge_slave:type_name -> talos.resource.definitions.network.BridgeSlave - 54, // 35: talos.resource.definitions.network.LinkSpecSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec + 55, // 35: talos.resource.definitions.network.LinkSpecSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec 2, // 36: talos.resource.definitions.network.LinkSpecSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec 4, // 37: talos.resource.definitions.network.LinkSpecSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec - 56, // 38: talos.resource.definitions.network.LinkSpecSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec - 61, // 39: talos.resource.definitions.network.LinkSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 74, // 40: talos.resource.definitions.network.LinkStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType - 75, // 41: talos.resource.definitions.network.LinkStatusSpec.operational_state:type_name -> talos.resource.definitions.enums.NethelpersOperationalState - 71, // 42: talos.resource.definitions.network.LinkStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort - 72, // 43: talos.resource.definitions.network.LinkStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex - 54, // 44: talos.resource.definitions.network.LinkStatusSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec + 57, // 38: talos.resource.definitions.network.LinkSpecSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec + 62, // 39: talos.resource.definitions.network.LinkSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 75, // 40: talos.resource.definitions.network.LinkStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersLinkType + 76, // 41: talos.resource.definitions.network.LinkStatusSpec.operational_state:type_name -> talos.resource.definitions.enums.NethelpersOperationalState + 72, // 42: talos.resource.definitions.network.LinkStatusSpec.port:type_name -> talos.resource.definitions.enums.NethelpersPort + 73, // 43: talos.resource.definitions.network.LinkStatusSpec.duplex:type_name -> talos.resource.definitions.enums.NethelpersDuplex + 55, // 44: talos.resource.definitions.network.LinkStatusSpec.vlan:type_name -> talos.resource.definitions.network.VLANSpec 4, // 45: talos.resource.definitions.network.LinkStatusSpec.bridge_master:type_name -> talos.resource.definitions.network.BridgeMasterSpec 2, // 46: talos.resource.definitions.network.LinkStatusSpec.bond_master:type_name -> talos.resource.definitions.network.BondMasterSpec - 56, // 47: talos.resource.definitions.network.LinkStatusSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec - 58, // 48: talos.resource.definitions.network.NfTablesAddressMatch.include_subnets:type_name -> common.NetIPPrefix - 58, // 49: talos.resource.definitions.network.NfTablesAddressMatch.exclude_subnets:type_name -> common.NetIPPrefix - 76, // 50: talos.resource.definitions.network.NfTablesChainSpec.hook:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainHook - 77, // 51: talos.resource.definitions.network.NfTablesChainSpec.priority:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainPriority + 57, // 47: talos.resource.definitions.network.LinkStatusSpec.wireguard:type_name -> talos.resource.definitions.network.WireguardSpec + 59, // 48: talos.resource.definitions.network.NfTablesAddressMatch.include_subnets:type_name -> common.NetIPPrefix + 59, // 49: talos.resource.definitions.network.NfTablesAddressMatch.exclude_subnets:type_name -> common.NetIPPrefix + 77, // 50: talos.resource.definitions.network.NfTablesChainSpec.hook:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainHook + 78, // 51: talos.resource.definitions.network.NfTablesChainSpec.priority:type_name -> talos.resource.definitions.enums.NethelpersNfTablesChainPriority 34, // 52: talos.resource.definitions.network.NfTablesChainSpec.rules:type_name -> talos.resource.definitions.network.NfTablesRule - 78, // 53: talos.resource.definitions.network.NfTablesChainSpec.policy:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict - 79, // 54: talos.resource.definitions.network.NfTablesConntrackStateMatch.states:type_name -> talos.resource.definitions.enums.NethelpersConntrackState - 80, // 55: talos.resource.definitions.network.NfTablesICMPTypeMatch.types:type_name -> talos.resource.definitions.enums.NethelpersICMPType - 81, // 56: talos.resource.definitions.network.NfTablesIfNameMatch.operator:type_name -> talos.resource.definitions.enums.NethelpersMatchOperator - 82, // 57: talos.resource.definitions.network.NfTablesLayer4Match.protocol:type_name -> talos.resource.definitions.enums.NethelpersProtocol + 79, // 53: talos.resource.definitions.network.NfTablesChainSpec.policy:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict + 80, // 54: talos.resource.definitions.network.NfTablesConntrackStateMatch.states:type_name -> talos.resource.definitions.enums.NethelpersConntrackState + 81, // 55: talos.resource.definitions.network.NfTablesICMPTypeMatch.types:type_name -> talos.resource.definitions.enums.NethelpersICMPType + 82, // 56: talos.resource.definitions.network.NfTablesIfNameMatch.operator:type_name -> talos.resource.definitions.enums.NethelpersMatchOperator + 83, // 57: talos.resource.definitions.network.NfTablesLayer4Match.protocol:type_name -> talos.resource.definitions.enums.NethelpersProtocol 33, // 58: talos.resource.definitions.network.NfTablesLayer4Match.match_source_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch 33, // 59: talos.resource.definitions.network.NfTablesLayer4Match.match_destination_port:type_name -> talos.resource.definitions.network.NfTablesPortMatch 28, // 60: talos.resource.definitions.network.NfTablesLayer4Match.match_icmp_type:type_name -> talos.resource.definitions.network.NfTablesICMPTypeMatch - 39, // 61: talos.resource.definitions.network.NfTablesPortMatch.ranges:type_name -> talos.resource.definitions.network.PortRange + 40, // 61: talos.resource.definitions.network.NfTablesPortMatch.ranges:type_name -> talos.resource.definitions.network.PortRange 29, // 62: talos.resource.definitions.network.NfTablesRule.match_o_if_name:type_name -> talos.resource.definitions.network.NfTablesIfNameMatch - 78, // 63: talos.resource.definitions.network.NfTablesRule.verdict:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict + 79, // 63: talos.resource.definitions.network.NfTablesRule.verdict:type_name -> talos.resource.definitions.enums.NethelpersNfTablesVerdict 32, // 64: talos.resource.definitions.network.NfTablesRule.match_mark:type_name -> talos.resource.definitions.network.NfTablesMark 32, // 65: talos.resource.definitions.network.NfTablesRule.set_mark:type_name -> talos.resource.definitions.network.NfTablesMark 24, // 66: talos.resource.definitions.network.NfTablesRule.match_source_address:type_name -> talos.resource.definitions.network.NfTablesAddressMatch @@ -4978,53 +5113,63 @@ var file_resource_definitions_network_network_proto_depIdxs = []int32{ 26, // 70: talos.resource.definitions.network.NfTablesRule.clamp_mss:type_name -> talos.resource.definitions.network.NfTablesClampMSS 31, // 71: talos.resource.definitions.network.NfTablesRule.match_limit:type_name -> talos.resource.definitions.network.NfTablesLimitMatch 27, // 72: talos.resource.definitions.network.NfTablesRule.match_conntrack_state:type_name -> talos.resource.definitions.network.NfTablesConntrackStateMatch - 58, // 73: talos.resource.definitions.network.NodeAddressFilterSpec.include_subnets:type_name -> common.NetIPPrefix - 58, // 74: talos.resource.definitions.network.NodeAddressFilterSpec.exclude_subnets:type_name -> common.NetIPPrefix - 83, // 75: talos.resource.definitions.network.NodeAddressSortAlgorithmSpec.algorithm:type_name -> talos.resource.definitions.enums.NethelpersAddressSortAlgorithm - 58, // 76: talos.resource.definitions.network.NodeAddressSpec.addresses:type_name -> common.NetIPPrefix - 83, // 77: talos.resource.definitions.network.NodeAddressSpec.sort_algorithm:type_name -> talos.resource.definitions.enums.NethelpersAddressSortAlgorithm - 84, // 78: talos.resource.definitions.network.OperatorSpecSpec.operator:type_name -> talos.resource.definitions.enums.NetworkOperator + 59, // 73: talos.resource.definitions.network.NodeAddressFilterSpec.include_subnets:type_name -> common.NetIPPrefix + 59, // 74: talos.resource.definitions.network.NodeAddressFilterSpec.exclude_subnets:type_name -> common.NetIPPrefix + 84, // 75: talos.resource.definitions.network.NodeAddressSortAlgorithmSpec.algorithm:type_name -> talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + 59, // 76: talos.resource.definitions.network.NodeAddressSpec.addresses:type_name -> common.NetIPPrefix + 84, // 77: talos.resource.definitions.network.NodeAddressSpec.sort_algorithm:type_name -> talos.resource.definitions.enums.NethelpersAddressSortAlgorithm + 85, // 78: talos.resource.definitions.network.OperatorSpecSpec.operator:type_name -> talos.resource.definitions.enums.NetworkOperator 7, // 79: talos.resource.definitions.network.OperatorSpecSpec.dhcp4:type_name -> talos.resource.definitions.network.DHCP4OperatorSpec 8, // 80: talos.resource.definitions.network.OperatorSpecSpec.dhcp6:type_name -> talos.resource.definitions.network.DHCP6OperatorSpec - 53, // 81: talos.resource.definitions.network.OperatorSpecSpec.vip:type_name -> talos.resource.definitions.network.VIPOperatorSpec - 61, // 82: talos.resource.definitions.network.OperatorSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 85, // 83: talos.resource.definitions.network.ProbeSpecSpec.interval:type_name -> google.protobuf.Duration - 48, // 84: talos.resource.definitions.network.ProbeSpecSpec.tcp:type_name -> talos.resource.definitions.network.TCPProbeSpec - 61, // 85: talos.resource.definitions.network.ProbeSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 86: talos.resource.definitions.network.ResolverSpecSpec.dns_servers:type_name -> common.NetIP - 61, // 87: talos.resource.definitions.network.ResolverSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 88: talos.resource.definitions.network.ResolverStatusSpec.dns_servers:type_name -> common.NetIP - 59, // 89: talos.resource.definitions.network.RouteSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 58, // 90: talos.resource.definitions.network.RouteSpecSpec.destination:type_name -> common.NetIPPrefix - 62, // 91: talos.resource.definitions.network.RouteSpecSpec.source:type_name -> common.NetIP - 62, // 92: talos.resource.definitions.network.RouteSpecSpec.gateway:type_name -> common.NetIP - 86, // 93: talos.resource.definitions.network.RouteSpecSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable - 60, // 94: talos.resource.definitions.network.RouteSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 87, // 95: talos.resource.definitions.network.RouteSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType - 88, // 96: talos.resource.definitions.network.RouteSpecSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol - 61, // 97: talos.resource.definitions.network.RouteSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 59, // 98: talos.resource.definitions.network.RouteStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily - 58, // 99: talos.resource.definitions.network.RouteStatusSpec.destination:type_name -> common.NetIPPrefix - 62, // 100: talos.resource.definitions.network.RouteStatusSpec.source:type_name -> common.NetIP - 62, // 101: talos.resource.definitions.network.RouteStatusSpec.gateway:type_name -> common.NetIP - 86, // 102: talos.resource.definitions.network.RouteStatusSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable - 60, // 103: talos.resource.definitions.network.RouteStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope - 87, // 104: talos.resource.definitions.network.RouteStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType - 88, // 105: talos.resource.definitions.network.RouteStatusSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol - 85, // 106: talos.resource.definitions.network.TCPProbeSpec.timeout:type_name -> google.protobuf.Duration - 61, // 107: talos.resource.definitions.network.TimeServerSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer - 62, // 108: talos.resource.definitions.network.VIPOperatorSpec.ip:type_name -> common.NetIP - 51, // 109: talos.resource.definitions.network.VIPOperatorSpec.equinix_metal:type_name -> talos.resource.definitions.network.VIPEquinixMetalSpec - 52, // 110: talos.resource.definitions.network.VIPOperatorSpec.h_cloud:type_name -> talos.resource.definitions.network.VIPHCloudSpec - 89, // 111: talos.resource.definitions.network.VLANSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersVLANProtocol - 85, // 112: talos.resource.definitions.network.WireguardPeer.persistent_keepalive_interval:type_name -> google.protobuf.Duration - 58, // 113: talos.resource.definitions.network.WireguardPeer.allowed_ips:type_name -> common.NetIPPrefix - 55, // 114: talos.resource.definitions.network.WireguardSpec.peers:type_name -> talos.resource.definitions.network.WireguardPeer - 115, // [115:115] is the sub-list for method output_type - 115, // [115:115] is the sub-list for method input_type - 115, // [115:115] is the sub-list for extension type_name - 115, // [115:115] is the sub-list for extension extendee - 0, // [0:115] is the sub-list for field type_name + 54, // 81: talos.resource.definitions.network.OperatorSpecSpec.vip:type_name -> talos.resource.definitions.network.VIPOperatorSpec + 62, // 82: talos.resource.definitions.network.OperatorSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 0, // 83: talos.resource.definitions.network.PlatformConfigSpec.addresses:type_name -> talos.resource.definitions.network.AddressSpecSpec + 22, // 84: talos.resource.definitions.network.PlatformConfigSpec.links:type_name -> talos.resource.definitions.network.LinkSpecSpec + 45, // 85: talos.resource.definitions.network.PlatformConfigSpec.routes:type_name -> talos.resource.definitions.network.RouteSpecSpec + 19, // 86: talos.resource.definitions.network.PlatformConfigSpec.hostnames:type_name -> talos.resource.definitions.network.HostnameSpecSpec + 43, // 87: talos.resource.definitions.network.PlatformConfigSpec.resolvers:type_name -> talos.resource.definitions.network.ResolverSpecSpec + 50, // 88: talos.resource.definitions.network.PlatformConfigSpec.time_servers:type_name -> talos.resource.definitions.network.TimeServerSpecSpec + 38, // 89: talos.resource.definitions.network.PlatformConfigSpec.operators:type_name -> talos.resource.definitions.network.OperatorSpecSpec + 63, // 90: talos.resource.definitions.network.PlatformConfigSpec.external_ips:type_name -> common.NetIP + 41, // 91: talos.resource.definitions.network.PlatformConfigSpec.probes:type_name -> talos.resource.definitions.network.ProbeSpecSpec + 86, // 92: talos.resource.definitions.network.PlatformConfigSpec.metadata:type_name -> talos.resource.definitions.runtime.PlatformMetadataSpec + 87, // 93: talos.resource.definitions.network.ProbeSpecSpec.interval:type_name -> google.protobuf.Duration + 49, // 94: talos.resource.definitions.network.ProbeSpecSpec.tcp:type_name -> talos.resource.definitions.network.TCPProbeSpec + 62, // 95: talos.resource.definitions.network.ProbeSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 63, // 96: talos.resource.definitions.network.ResolverSpecSpec.dns_servers:type_name -> common.NetIP + 62, // 97: talos.resource.definitions.network.ResolverSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 63, // 98: talos.resource.definitions.network.ResolverStatusSpec.dns_servers:type_name -> common.NetIP + 60, // 99: talos.resource.definitions.network.RouteSpecSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 59, // 100: talos.resource.definitions.network.RouteSpecSpec.destination:type_name -> common.NetIPPrefix + 63, // 101: talos.resource.definitions.network.RouteSpecSpec.source:type_name -> common.NetIP + 63, // 102: talos.resource.definitions.network.RouteSpecSpec.gateway:type_name -> common.NetIP + 88, // 103: talos.resource.definitions.network.RouteSpecSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable + 61, // 104: talos.resource.definitions.network.RouteSpecSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 89, // 105: talos.resource.definitions.network.RouteSpecSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType + 90, // 106: talos.resource.definitions.network.RouteSpecSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol + 62, // 107: talos.resource.definitions.network.RouteSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 60, // 108: talos.resource.definitions.network.RouteStatusSpec.family:type_name -> talos.resource.definitions.enums.NethelpersFamily + 59, // 109: talos.resource.definitions.network.RouteStatusSpec.destination:type_name -> common.NetIPPrefix + 63, // 110: talos.resource.definitions.network.RouteStatusSpec.source:type_name -> common.NetIP + 63, // 111: talos.resource.definitions.network.RouteStatusSpec.gateway:type_name -> common.NetIP + 88, // 112: talos.resource.definitions.network.RouteStatusSpec.table:type_name -> talos.resource.definitions.enums.NethelpersRoutingTable + 61, // 113: talos.resource.definitions.network.RouteStatusSpec.scope:type_name -> talos.resource.definitions.enums.NethelpersScope + 89, // 114: talos.resource.definitions.network.RouteStatusSpec.type:type_name -> talos.resource.definitions.enums.NethelpersRouteType + 90, // 115: talos.resource.definitions.network.RouteStatusSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersRouteProtocol + 87, // 116: talos.resource.definitions.network.TCPProbeSpec.timeout:type_name -> google.protobuf.Duration + 62, // 117: talos.resource.definitions.network.TimeServerSpecSpec.config_layer:type_name -> talos.resource.definitions.enums.NetworkConfigLayer + 63, // 118: talos.resource.definitions.network.VIPOperatorSpec.ip:type_name -> common.NetIP + 52, // 119: talos.resource.definitions.network.VIPOperatorSpec.equinix_metal:type_name -> talos.resource.definitions.network.VIPEquinixMetalSpec + 53, // 120: talos.resource.definitions.network.VIPOperatorSpec.h_cloud:type_name -> talos.resource.definitions.network.VIPHCloudSpec + 91, // 121: talos.resource.definitions.network.VLANSpec.protocol:type_name -> talos.resource.definitions.enums.NethelpersVLANProtocol + 87, // 122: talos.resource.definitions.network.WireguardPeer.persistent_keepalive_interval:type_name -> google.protobuf.Duration + 59, // 123: talos.resource.definitions.network.WireguardPeer.allowed_ips:type_name -> common.NetIPPrefix + 56, // 124: talos.resource.definitions.network.WireguardSpec.peers:type_name -> talos.resource.definitions.network.WireguardPeer + 125, // [125:125] is the sub-list for method output_type + 125, // [125:125] is the sub-list for method input_type + 125, // [125:125] is the sub-list for extension type_name + 125, // [125:125] is the sub-list for extension extendee + 0, // [0:125] is the sub-list for field type_name } func init() { file_resource_definitions_network_network_proto_init() } @@ -5038,7 +5183,7 @@ func file_resource_definitions_network_network_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_resource_definitions_network_network_proto_rawDesc), len(file_resource_definitions_network_network_proto_rawDesc)), NumEnums: 0, - NumMessages: 58, + NumMessages: 59, 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 5deae3977..4cfdda2ec 100644 --- a/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/network/network_vtproto.pb.go @@ -17,6 +17,7 @@ import ( common "github.com/siderolabs/talos/pkg/machinery/api/common" enums "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/enums" + runtime "github.com/siderolabs/talos/pkg/machinery/api/resource/definitions/runtime" ) const ( @@ -3070,6 +3071,181 @@ func (m *OperatorSpecSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PlatformConfigSpec) 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 *PlatformConfigSpec) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PlatformConfigSpec) 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.Metadata != nil { + if vtmsg, ok := interface{}(m.Metadata).(interface { + MarshalToSizedBufferVT([]byte) (int, error) + }); ok { + size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + } else { + encoded, err := proto.Marshal(m.Metadata) + if err != nil { + return 0, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(encoded))) + } + i-- + dAtA[i] = 0x52 + } + if len(m.Probes) > 0 { + for iNdEx := len(m.Probes) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Probes[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x4a + } + } + if len(m.ExternalIps) > 0 { + for iNdEx := len(m.ExternalIps) - 1; iNdEx >= 0; iNdEx-- { + if vtmsg, ok := interface{}(m.ExternalIps[iNdEx]).(interface { + MarshalToSizedBufferVT([]byte) (int, error) + }); ok { + size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + } else { + encoded, err := proto.Marshal(m.ExternalIps[iNdEx]) + if err != nil { + return 0, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(encoded))) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.Operators) > 0 { + for iNdEx := len(m.Operators) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Operators[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x3a + } + } + if len(m.TimeServers) > 0 { + for iNdEx := len(m.TimeServers) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.TimeServers[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } + } + if len(m.Resolvers) > 0 { + for iNdEx := len(m.Resolvers) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Resolvers[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + } + if len(m.Hostnames) > 0 { + for iNdEx := len(m.Hostnames) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Hostnames[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } + } + if len(m.Routes) > 0 { + for iNdEx := len(m.Routes) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Routes[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Links) > 0 { + for iNdEx := len(m.Links) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Links[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + } + if len(m.Addresses) > 0 { + for iNdEx := len(m.Addresses) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Addresses[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *PortRange) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -5536,6 +5712,86 @@ func (m *OperatorSpecSpec) SizeVT() (n int) { return n } +func (m *PlatformConfigSpec) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Addresses) > 0 { + for _, e := range m.Addresses { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Links) > 0 { + for _, e := range m.Links { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Routes) > 0 { + for _, e := range m.Routes { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Hostnames) > 0 { + for _, e := range m.Hostnames { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Resolvers) > 0 { + for _, e := range m.Resolvers { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.TimeServers) > 0 { + for _, e := range m.TimeServers { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Operators) > 0 { + for _, e := range m.Operators { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.ExternalIps) > 0 { + for _, e := range m.ExternalIps { + if size, ok := interface{}(e).(interface { + SizeVT() int + }); ok { + l = size.SizeVT() + } else { + l = proto.Size(e) + } + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if len(m.Probes) > 0 { + for _, e := range m.Probes { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if m.Metadata != nil { + if size, ok := interface{}(m.Metadata).(interface { + SizeVT() int + }); ok { + l = size.SizeVT() + } else { + l = proto.Size(m.Metadata) + } + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + func (m *PortRange) SizeVT() (n int) { if m == nil { return 0 @@ -13597,6 +13853,415 @@ func (m *OperatorSpecSpec) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *PlatformConfigSpec) 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: PlatformConfigSpec: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PlatformConfigSpec: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Addresses", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Addresses = append(m.Addresses, &AddressSpecSpec{}) + if err := m.Addresses[len(m.Addresses)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Links", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Links = append(m.Links, &LinkSpecSpec{}) + if err := m.Links[len(m.Links)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Routes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Routes = append(m.Routes, &RouteSpecSpec{}) + if err := m.Routes[len(m.Routes)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hostnames", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hostnames = append(m.Hostnames, &HostnameSpecSpec{}) + if err := m.Hostnames[len(m.Hostnames)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resolvers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Resolvers = append(m.Resolvers, &ResolverSpecSpec{}) + if err := m.Resolvers[len(m.Resolvers)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeServers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TimeServers = append(m.TimeServers, &TimeServerSpecSpec{}) + if err := m.TimeServers[len(m.TimeServers)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Operators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Operators = append(m.Operators, &OperatorSpecSpec{}) + if err := m.Operators[len(m.Operators)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExternalIps", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ExternalIps = append(m.ExternalIps, &common.NetIP{}) + if unmarshal, ok := interface{}(m.ExternalIps[len(m.ExternalIps)-1]).(interface { + UnmarshalVT([]byte) error + }); ok { + if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.ExternalIps[len(m.ExternalIps)-1]); err != nil { + return err + } + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Probes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Probes = append(m.Probes, &ProbeSpecSpec{}) + if err := m.Probes[len(m.Probes)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Metadata == nil { + m.Metadata = &runtime.PlatformMetadataSpec{} + } + if unmarshal, ok := interface{}(m.Metadata).(interface { + UnmarshalVT([]byte) error + }); ok { + if err := unmarshal.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + } else { + if err := proto.Unmarshal(dAtA[iNdEx:postIndex], m.Metadata); err != nil { + return err + } + } + iNdEx = postIndex + 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 *PortRange) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/machinery/resources/network/address_spec.go b/pkg/machinery/resources/network/address_spec.go index d9df5e36c..be8b235d0 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 go tool github.com/siderolabs/deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type EthernetSpecSpec -type EthernetStatusSpec -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 . +//go:generate go tool github.com/siderolabs/deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type EthernetSpecSpec -type EthernetStatusSpec -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 PlatformConfigSpec -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 bb5a9dde2..385c5f39c 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 EthernetSpecSpec -type EthernetStatusSpec -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. +// Code generated by "deep-copy -type AddressSpecSpec -type AddressStatusSpec -type DNSResolveCacheSpec -type EthernetSpecSpec -type EthernetStatusSpec -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 PlatformConfigSpec -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 @@ -450,6 +450,76 @@ func (o OperatorSpecSpec) DeepCopy() OperatorSpecSpec { return cp } +// DeepCopy generates a deep copy of PlatformConfigSpec. +func (o PlatformConfigSpec) DeepCopy() PlatformConfigSpec { + var cp PlatformConfigSpec = o + if o.Addresses != nil { + cp.Addresses = make([]AddressSpecSpec, len(o.Addresses)) + copy(cp.Addresses, o.Addresses) + for i2 := range o.Addresses { + cp.Addresses[i2] = o.Addresses[i2].DeepCopy() + } + } + if o.Links != nil { + cp.Links = make([]LinkSpecSpec, len(o.Links)) + copy(cp.Links, o.Links) + for i2 := range o.Links { + cp.Links[i2] = o.Links[i2].DeepCopy() + } + } + if o.Routes != nil { + cp.Routes = make([]RouteSpecSpec, len(o.Routes)) + copy(cp.Routes, o.Routes) + for i2 := range o.Routes { + cp.Routes[i2] = o.Routes[i2].DeepCopy() + } + } + if o.Hostnames != nil { + cp.Hostnames = make([]HostnameSpecSpec, len(o.Hostnames)) + copy(cp.Hostnames, o.Hostnames) + for i2 := range o.Hostnames { + cp.Hostnames[i2] = o.Hostnames[i2].DeepCopy() + } + } + if o.Resolvers != nil { + cp.Resolvers = make([]ResolverSpecSpec, len(o.Resolvers)) + copy(cp.Resolvers, o.Resolvers) + for i2 := range o.Resolvers { + cp.Resolvers[i2] = o.Resolvers[i2].DeepCopy() + } + } + if o.TimeServers != nil { + cp.TimeServers = make([]TimeServerSpecSpec, len(o.TimeServers)) + copy(cp.TimeServers, o.TimeServers) + for i2 := range o.TimeServers { + cp.TimeServers[i2] = o.TimeServers[i2].DeepCopy() + } + } + if o.Operators != nil { + cp.Operators = make([]OperatorSpecSpec, len(o.Operators)) + copy(cp.Operators, o.Operators) + for i2 := range o.Operators { + cp.Operators[i2] = o.Operators[i2].DeepCopy() + } + } + if o.ExternalIPs != nil { + cp.ExternalIPs = make([]netip.Addr, len(o.ExternalIPs)) + copy(cp.ExternalIPs, o.ExternalIPs) + } + if o.Probes != nil { + cp.Probes = make([]ProbeSpecSpec, len(o.Probes)) + copy(cp.Probes, o.Probes) + for i2 := range o.Probes { + cp.Probes[i2] = o.Probes[i2].DeepCopy() + } + } + if o.Metadata != nil { + retV := o.Metadata.DeepCopy() + cp.Metadata = &retV + } + return cp +} + // DeepCopy generates a deep copy of ProbeSpecSpec. func (o ProbeSpecSpec) DeepCopy() ProbeSpecSpec { var cp ProbeSpecSpec = o diff --git a/pkg/machinery/resources/network/network_test.go b/pkg/machinery/resources/network/network_test.go index 9c6e50993..454647b7a 100644 --- a/pkg/machinery/resources/network/network_test.go +++ b/pkg/machinery/resources/network/network_test.go @@ -41,6 +41,7 @@ func TestRegisterResource(t *testing.T) { &network.NodeAddressFilter{}, &network.NodeAddressSortAlgorithm{}, &network.OperatorSpec{}, + &network.PlatformConfig{}, &network.ProbeSpec{}, &network.ResolverStatus{}, &network.ResolverSpec{}, diff --git a/pkg/machinery/resources/network/platform_config.go b/pkg/machinery/resources/network/platform_config.go new file mode 100644 index 000000000..399a58571 --- /dev/null +++ b/pkg/machinery/resources/network/platform_config.go @@ -0,0 +1,100 @@ +// 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 ( + "bytes" + "net/netip" + + "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" + "gopkg.in/yaml.v3" + + "github.com/siderolabs/talos/pkg/machinery/proto" + "github.com/siderolabs/talos/pkg/machinery/resources/runtime" +) + +// PlatformConfigType is type of PlatformConfig resource. +const PlatformConfigType = resource.Type("PlatformConfigs.net.talos.dev") + +// PlatformConfig resource holds DNS resolver info. +type PlatformConfig = typed.Resource[PlatformConfigSpec, PlatformConfigExtension] + +// PlatformConfigActiveID is the ID of instance containing active config. +const PlatformConfigActiveID resource.ID = "active" + +// PlatformConfigCachedID is the ID of instance containing cached (persisted) config. +const PlatformConfigCachedID resource.ID = "cached" + +// PlatformConfigSpec describes platform network configuration. +// +// This structure is marshaled to STATE partition to persist cached network configuration across +// reboots. +// +//gotagsrewrite:gen +type PlatformConfigSpec struct { + Addresses []AddressSpecSpec `yaml:"addresses" protobuf:"1"` + Links []LinkSpecSpec `yaml:"links" protobuf:"2"` + Routes []RouteSpecSpec `yaml:"routes" protobuf:"3"` + + Hostnames []HostnameSpecSpec `yaml:"hostnames" protobuf:"4"` + Resolvers []ResolverSpecSpec `yaml:"resolvers" protobuf:"5"` + TimeServers []TimeServerSpecSpec `yaml:"timeServers" protobuf:"6"` + + Operators []OperatorSpecSpec `yaml:"operators" protobuf:"7"` + + ExternalIPs []netip.Addr `yaml:"externalIPs" protobuf:"8"` + + Probes []ProbeSpecSpec `yaml:"probes,omitempty" protobuf:"9"` + + Metadata *runtime.PlatformMetadataSpec `yaml:"metadata,omitempty" protobuf:"10"` +} + +// Equal compares two platform network configurations. +func (p *PlatformConfigSpec) Equal(other *PlatformConfigSpec) bool { + // we will compare by marshaling to YAML + // and then comparing the bytes + // this is not the most efficient way to do this, + // but it will handle omitting empty fields + m1, err1 := yaml.Marshal(p) + + m2, err2 := yaml.Marshal(other) + if err1 != nil || err2 != nil { + return false + } + + return bytes.Equal(m1, m2) +} + +// NewPlatformConfig initializes a PlatformConfig resource. +func NewPlatformConfig(namespace resource.Namespace, id resource.ID) *PlatformConfig { + return typed.NewResource[PlatformConfigSpec, PlatformConfigExtension]( + resource.NewMetadata(namespace, PlatformConfigType, id, resource.VersionUndefined), + PlatformConfigSpec{}, + ) +} + +// PlatformConfigExtension provides auxiliary methods for PlatformConfig. +type PlatformConfigExtension struct{} + +// ResourceDefinition implements [typed.Extension] interface. +func (PlatformConfigExtension) ResourceDefinition() meta.ResourceDefinitionSpec { + return meta.ResourceDefinitionSpec{ + Type: PlatformConfigType, + Aliases: []resource.Type{}, + DefaultNamespace: NamespaceName, + } +} + +func init() { + proto.RegisterDefaultTypes() + + err := protobuf.RegisterDynamic[PlatformConfigSpec](PlatformConfigType, &PlatformConfig{}) + if err != nil { + panic(err) + } +} diff --git a/internal/app/machined/pkg/runtime/platform_test.go b/pkg/machinery/resources/network/platform_config_test.go similarity index 61% rename from internal/app/machined/pkg/runtime/platform_test.go rename to pkg/machinery/resources/network/platform_config_test.go index 9c1168bd2..d4ac6308b 100644 --- a/internal/app/machined/pkg/runtime/platform_test.go +++ b/pkg/machinery/resources/network/platform_config_test.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/. -package runtime_test +package network_test import ( "net/netip" @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/assert" - "github.com/siderolabs/talos/internal/app/machined/pkg/runtime" "github.com/siderolabs/talos/pkg/machinery/nethelpers" "github.com/siderolabs/talos/pkg/machinery/resources/network" ) @@ -18,16 +17,16 @@ import ( func TestPlatformConfigEqual(t *testing.T) { t.Parallel() - assert.True(t, (&runtime.PlatformNetworkConfig{}).Equal(&runtime.PlatformNetworkConfig{})) - assert.True(t, (&runtime.PlatformNetworkConfig{Addresses: []network.AddressSpecSpec{}}).Equal(&runtime.PlatformNetworkConfig{})) - assert.True(t, (&runtime.PlatformNetworkConfig{Addresses: []network.AddressSpecSpec{ + assert.True(t, (&network.PlatformConfigSpec{}).Equal(&network.PlatformConfigSpec{})) + assert.True(t, (&network.PlatformConfigSpec{Addresses: []network.AddressSpecSpec{}}).Equal(&network.PlatformConfigSpec{})) + assert.True(t, (&network.PlatformConfigSpec{Addresses: []network.AddressSpecSpec{ { Address: netip.MustParsePrefix("192.168.68.54/22"), LinkName: "eth0", Family: nethelpers.FamilyInet4, Scope: nethelpers.ScopeGlobal, }, - }}).Equal(&runtime.PlatformNetworkConfig{Addresses: []network.AddressSpecSpec{ + }}).Equal(&network.PlatformConfigSpec{Addresses: []network.AddressSpecSpec{ { Address: netip.MustParsePrefix("192.168.68.54/22"), LinkName: "eth0", @@ -36,15 +35,15 @@ func TestPlatformConfigEqual(t *testing.T) { }, }})) - assert.False(t, (&runtime.PlatformNetworkConfig{}).Equal(nil)) - assert.False(t, (&runtime.PlatformNetworkConfig{Addresses: []network.AddressSpecSpec{ + assert.False(t, (&network.PlatformConfigSpec{}).Equal(nil)) + assert.False(t, (&network.PlatformConfigSpec{Addresses: []network.AddressSpecSpec{ { Address: netip.MustParsePrefix("192.168.68.1/22"), LinkName: "eth0", Family: nethelpers.FamilyInet4, Scope: nethelpers.ScopeGlobal, }, - }}).Equal(&runtime.PlatformNetworkConfig{Addresses: []network.AddressSpecSpec{ + }}).Equal(&network.PlatformConfigSpec{Addresses: []network.AddressSpecSpec{ { Address: netip.MustParsePrefix("192.168.68.2/22"), LinkName: "eth1", diff --git a/tools/structprotogen/proto/proto.go b/tools/structprotogen/proto/proto.go index eb2e0c6e8..a5af6a392 100644 --- a/tools/structprotogen/proto/proto.go +++ b/tools/structprotogen/proto/proto.go @@ -402,6 +402,8 @@ func formatTypeName(fieldTypePkg string, fieldType string, declPkg string) (stri case typeData{"github.com/siderolabs/talos/pkg/machinery/resources/cri", "RegistryConfig"}: // This is a hack, but I (Dmitry) don't have enough patience to figure out why we don't support complex maps return "resource/definitions/cri/registry.proto", "talos.resource.definitions.cri.RegistryConfig" + case typeData{"github.com/siderolabs/talos/pkg/machinery/resources/runtime", "PlatformMetadataSpec"}: + return "resource/definitions/runtime/runtime.proto", "talos.resource.definitions.runtime.PlatformMetadataSpec" default: return "", "" } diff --git a/website/content/v1.12/reference/api.md b/website/content/v1.12/reference/api.md index 099b8bba8..ccb82ab6b 100644 --- a/website/content/v1.12/reference/api.md +++ b/website/content/v1.12/reference/api.md @@ -430,6 +430,35 @@ description: Talos gRPC API reference. - [PeerSpecSpec](#talos.resource.definitions.kubespan.PeerSpecSpec) - [PeerStatusSpec](#talos.resource.definitions.kubespan.PeerStatusSpec) +- [resource/definitions/runtime/runtime.proto](#resource/definitions/runtime/runtime.proto) + - [BootedEntrySpec](#talos.resource.definitions.runtime.BootedEntrySpec) + - [DevicesStatusSpec](#talos.resource.definitions.runtime.DevicesStatusSpec) + - [DiagnosticSpec](#talos.resource.definitions.runtime.DiagnosticSpec) + - [EventSinkConfigSpec](#talos.resource.definitions.runtime.EventSinkConfigSpec) + - [ExtensionServiceConfigFile](#talos.resource.definitions.runtime.ExtensionServiceConfigFile) + - [ExtensionServiceConfigSpec](#talos.resource.definitions.runtime.ExtensionServiceConfigSpec) + - [ExtensionServiceConfigStatusSpec](#talos.resource.definitions.runtime.ExtensionServiceConfigStatusSpec) + - [KernelCmdlineSpec](#talos.resource.definitions.runtime.KernelCmdlineSpec) + - [KernelModuleSpecSpec](#talos.resource.definitions.runtime.KernelModuleSpecSpec) + - [KernelParamSpecSpec](#talos.resource.definitions.runtime.KernelParamSpecSpec) + - [KernelParamStatusSpec](#talos.resource.definitions.runtime.KernelParamStatusSpec) + - [KmsgLogConfigSpec](#talos.resource.definitions.runtime.KmsgLogConfigSpec) + - [LoadedKernelModuleSpec](#talos.resource.definitions.runtime.LoadedKernelModuleSpec) + - [MachineStatusSpec](#talos.resource.definitions.runtime.MachineStatusSpec) + - [MachineStatusStatus](#talos.resource.definitions.runtime.MachineStatusStatus) + - [MaintenanceServiceConfigSpec](#talos.resource.definitions.runtime.MaintenanceServiceConfigSpec) + - [MetaKeySpec](#talos.resource.definitions.runtime.MetaKeySpec) + - [MetaLoadedSpec](#talos.resource.definitions.runtime.MetaLoadedSpec) + - [MountStatusSpec](#talos.resource.definitions.runtime.MountStatusSpec) + - [PlatformMetadataSpec](#talos.resource.definitions.runtime.PlatformMetadataSpec) + - [PlatformMetadataSpec.TagsEntry](#talos.resource.definitions.runtime.PlatformMetadataSpec.TagsEntry) + - [SBOMItemSpec](#talos.resource.definitions.runtime.SBOMItemSpec) + - [SecurityStateSpec](#talos.resource.definitions.runtime.SecurityStateSpec) + - [UniqueMachineTokenSpec](#talos.resource.definitions.runtime.UniqueMachineTokenSpec) + - [UnmetCondition](#talos.resource.definitions.runtime.UnmetCondition) + - [WatchdogTimerConfigSpec](#talos.resource.definitions.runtime.WatchdogTimerConfigSpec) + - [WatchdogTimerStatusSpec](#talos.resource.definitions.runtime.WatchdogTimerStatusSpec) + - [resource/definitions/network/network.proto](#resource/definitions/network/network.proto) - [AddressSpecSpec](#talos.resource.definitions.network.AddressSpecSpec) - [AddressStatusSpec](#talos.resource.definitions.network.AddressStatusSpec) @@ -471,6 +500,7 @@ description: Talos gRPC API reference. - [NodeAddressSortAlgorithmSpec](#talos.resource.definitions.network.NodeAddressSortAlgorithmSpec) - [NodeAddressSpec](#talos.resource.definitions.network.NodeAddressSpec) - [OperatorSpecSpec](#talos.resource.definitions.network.OperatorSpecSpec) + - [PlatformConfigSpec](#talos.resource.definitions.network.PlatformConfigSpec) - [PortRange](#talos.resource.definitions.network.PortRange) - [ProbeSpecSpec](#talos.resource.definitions.network.ProbeSpecSpec) - [ProbeStatusSpec](#talos.resource.definitions.network.ProbeStatusSpec) @@ -495,35 +525,6 @@ description: Talos gRPC API reference. - [CPUStat](#talos.resource.definitions.perf.CPUStat) - [MemorySpec](#talos.resource.definitions.perf.MemorySpec) -- [resource/definitions/runtime/runtime.proto](#resource/definitions/runtime/runtime.proto) - - [BootedEntrySpec](#talos.resource.definitions.runtime.BootedEntrySpec) - - [DevicesStatusSpec](#talos.resource.definitions.runtime.DevicesStatusSpec) - - [DiagnosticSpec](#talos.resource.definitions.runtime.DiagnosticSpec) - - [EventSinkConfigSpec](#talos.resource.definitions.runtime.EventSinkConfigSpec) - - [ExtensionServiceConfigFile](#talos.resource.definitions.runtime.ExtensionServiceConfigFile) - - [ExtensionServiceConfigSpec](#talos.resource.definitions.runtime.ExtensionServiceConfigSpec) - - [ExtensionServiceConfigStatusSpec](#talos.resource.definitions.runtime.ExtensionServiceConfigStatusSpec) - - [KernelCmdlineSpec](#talos.resource.definitions.runtime.KernelCmdlineSpec) - - [KernelModuleSpecSpec](#talos.resource.definitions.runtime.KernelModuleSpecSpec) - - [KernelParamSpecSpec](#talos.resource.definitions.runtime.KernelParamSpecSpec) - - [KernelParamStatusSpec](#talos.resource.definitions.runtime.KernelParamStatusSpec) - - [KmsgLogConfigSpec](#talos.resource.definitions.runtime.KmsgLogConfigSpec) - - [LoadedKernelModuleSpec](#talos.resource.definitions.runtime.LoadedKernelModuleSpec) - - [MachineStatusSpec](#talos.resource.definitions.runtime.MachineStatusSpec) - - [MachineStatusStatus](#talos.resource.definitions.runtime.MachineStatusStatus) - - [MaintenanceServiceConfigSpec](#talos.resource.definitions.runtime.MaintenanceServiceConfigSpec) - - [MetaKeySpec](#talos.resource.definitions.runtime.MetaKeySpec) - - [MetaLoadedSpec](#talos.resource.definitions.runtime.MetaLoadedSpec) - - [MountStatusSpec](#talos.resource.definitions.runtime.MountStatusSpec) - - [PlatformMetadataSpec](#talos.resource.definitions.runtime.PlatformMetadataSpec) - - [PlatformMetadataSpec.TagsEntry](#talos.resource.definitions.runtime.PlatformMetadataSpec.TagsEntry) - - [SBOMItemSpec](#talos.resource.definitions.runtime.SBOMItemSpec) - - [SecurityStateSpec](#talos.resource.definitions.runtime.SecurityStateSpec) - - [UniqueMachineTokenSpec](#talos.resource.definitions.runtime.UniqueMachineTokenSpec) - - [UnmetCondition](#talos.resource.definitions.runtime.UnmetCondition) - - [WatchdogTimerConfigSpec](#talos.resource.definitions.runtime.WatchdogTimerConfigSpec) - - [WatchdogTimerStatusSpec](#talos.resource.definitions.runtime.WatchdogTimerStatusSpec) - - [resource/definitions/secrets/secrets.proto](#resource/definitions/secrets/secrets.proto) - [APICertsSpec](#talos.resource.definitions.secrets.APICertsSpec) - [CertSANSpec](#talos.resource.definitions.secrets.CertSANSpec) @@ -7428,6 +7429,471 @@ PeerStatusSpec describes PeerStatus state. + + + + + + + + + + + +

Top

+ +## resource/definitions/runtime/runtime.proto + + + + + +### BootedEntrySpec +BootedEntrySpec describes the booted entry resource properties. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| booted_entry | [string](#string) | | | + + + + + + + + +### DevicesStatusSpec +DevicesStatusSpec is the spec for devices status. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| ready | [bool](#bool) | | | + + + + + + + + +### DiagnosticSpec +DiagnosticSpec is the spec for devices status. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| message | [string](#string) | | | +| details | [string](#string) | repeated | | + + + + + + + + +### EventSinkConfigSpec +EventSinkConfigSpec describes configuration of Talos event log streaming. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| endpoint | [string](#string) | | | + + + + + + + + +### ExtensionServiceConfigFile +ExtensionServiceConfigFile describes extensions service config files. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| content | [string](#string) | | | +| mount_path | [string](#string) | | | + + + + + + + + +### ExtensionServiceConfigSpec +ExtensionServiceConfigSpec describes status of rendered extensions service config files. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| files | [ExtensionServiceConfigFile](#talos.resource.definitions.runtime.ExtensionServiceConfigFile) | repeated | | +| environment | [string](#string) | repeated | | + + + + + + + + +### ExtensionServiceConfigStatusSpec +ExtensionServiceConfigStatusSpec describes status of rendered extensions service config files. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| spec_version | [string](#string) | | | + + + + + + + + +### KernelCmdlineSpec +KernelCmdlineSpec presents kernel command line (contents of /proc/cmdline). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| cmdline | [string](#string) | | | + + + + + + + + +### KernelModuleSpecSpec +KernelModuleSpecSpec describes Linux kernel module to load. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | | +| parameters | [string](#string) | repeated | | + + + + + + + + +### KernelParamSpecSpec +KernelParamSpecSpec describes status of the defined sysctls. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [string](#string) | | | +| ignore_errors | [bool](#bool) | | | + + + + + + + + +### KernelParamStatusSpec +KernelParamStatusSpec describes status of the defined sysctls. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| current | [string](#string) | | | +| default | [string](#string) | | | +| unsupported | [bool](#bool) | | | + + + + + + + + +### KmsgLogConfigSpec +KmsgLogConfigSpec describes configuration for kmsg log streaming. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| destinations | [common.URL](#common.URL) | repeated | | + + + + + + + + +### LoadedKernelModuleSpec +LoadedKernelModuleSpec describes Linux kernel module to load. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| size | [int64](#int64) | | | +| reference_count | [int64](#int64) | | | +| dependencies | [string](#string) | repeated | | +| state | [string](#string) | | | +| address | [string](#string) | | | + + + + + + + + +### MachineStatusSpec +MachineStatusSpec describes status of the defined sysctls. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| stage | [talos.resource.definitions.enums.RuntimeMachineStage](#talos.resource.definitions.enums.RuntimeMachineStage) | | | +| status | [MachineStatusStatus](#talos.resource.definitions.runtime.MachineStatusStatus) | | | + + + + + + + + +### MachineStatusStatus +MachineStatusStatus describes machine current status at the stage. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| ready | [bool](#bool) | | | +| unmet_conditions | [UnmetCondition](#talos.resource.definitions.runtime.UnmetCondition) | repeated | | + + + + + + + + +### MaintenanceServiceConfigSpec +MaintenanceServiceConfigSpec describes configuration for maintenance service API. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| listen_address | [string](#string) | | | +| reachable_addresses | [common.NetIP](#common.NetIP) | repeated | | + + + + + + + + +### MetaKeySpec +MetaKeySpec describes status of the defined sysctls. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| value | [string](#string) | | | + + + + + + + + +### MetaLoadedSpec +MetaLoadedSpec is the spec for meta loaded. The Done field is always true when resource exists. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| done | [bool](#bool) | | | + + + + + + + + +### MountStatusSpec +MountStatusSpec describes status of the defined sysctls. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| source | [string](#string) | | | +| target | [string](#string) | | | +| filesystem_type | [string](#string) | | | +| options | [string](#string) | repeated | | +| encrypted | [bool](#bool) | | | +| encryption_providers | [string](#string) | repeated | | + + + + + + + + +### PlatformMetadataSpec +PlatformMetadataSpec describes platform metadata properties. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| platform | [string](#string) | | | +| hostname | [string](#string) | | | +| region | [string](#string) | | | +| zone | [string](#string) | | | +| instance_type | [string](#string) | | | +| instance_id | [string](#string) | | | +| provider_id | [string](#string) | | | +| spot | [bool](#bool) | | | +| internal_dns | [string](#string) | | | +| external_dns | [string](#string) | | | +| tags | [PlatformMetadataSpec.TagsEntry](#talos.resource.definitions.runtime.PlatformMetadataSpec.TagsEntry) | repeated | | + + + + + + + + +### PlatformMetadataSpec.TagsEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [string](#string) | | | + + + + + + + + +### SBOMItemSpec +SBOMItemSpec describes the SBOM item resource properties. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | | +| version | [string](#string) | | | +| license | [string](#string) | | | +| cp_es | [string](#string) | repeated | | +| pur_ls | [string](#string) | repeated | | +| extension | [bool](#bool) | | | + + + + + + + + +### SecurityStateSpec +SecurityStateSpec describes the security state resource properties. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| secure_boot | [bool](#bool) | | | +| uki_signing_key_fingerprint | [string](#string) | | | +| pcr_signing_key_fingerprint | [string](#string) | | | +| se_linux_state | [talos.resource.definitions.enums.RuntimeSELinuxState](#talos.resource.definitions.enums.RuntimeSELinuxState) | | | +| booted_with_uki | [bool](#bool) | | | +| fips_state | [talos.resource.definitions.enums.RuntimeFIPSState](#talos.resource.definitions.enums.RuntimeFIPSState) | | | + + + + + + + + +### UniqueMachineTokenSpec +UniqueMachineTokenSpec is the spec for the machine unique token. Token can be empty if machine wasn't assigned any. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| token | [string](#string) | | | + + + + + + + + +### UnmetCondition +UnmetCondition is a failure which prevents machine from being ready at the stage. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| name | [string](#string) | | | +| reason | [string](#string) | | | + + + + + + + + +### WatchdogTimerConfigSpec +WatchdogTimerConfigSpec describes configuration of watchdog timer. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| device | [string](#string) | | | +| timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | | + + + + + + + + +### WatchdogTimerStatusSpec +WatchdogTimerStatusSpec describes configuration of watchdog timer. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| device | [string](#string) | | | +| timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | | +| feed_interval | [google.protobuf.Duration](#google.protobuf.Duration) | | | + + + + + @@ -8227,6 +8693,33 @@ OperatorSpecSpec describes DNS resolvers. + + +### PlatformConfigSpec +PlatformConfigSpec describes platform network configuration. + +This structure is marshaled to STATE partition to persist cached network configuration across +reboots. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| addresses | [AddressSpecSpec](#talos.resource.definitions.network.AddressSpecSpec) | repeated | | +| links | [LinkSpecSpec](#talos.resource.definitions.network.LinkSpecSpec) | repeated | | +| routes | [RouteSpecSpec](#talos.resource.definitions.network.RouteSpecSpec) | repeated | | +| hostnames | [HostnameSpecSpec](#talos.resource.definitions.network.HostnameSpecSpec) | repeated | | +| resolvers | [ResolverSpecSpec](#talos.resource.definitions.network.ResolverSpecSpec) | repeated | | +| time_servers | [TimeServerSpecSpec](#talos.resource.definitions.network.TimeServerSpecSpec) | repeated | | +| operators | [OperatorSpecSpec](#talos.resource.definitions.network.OperatorSpecSpec) | repeated | | +| external_ips | [common.NetIP](#common.NetIP) | repeated | | +| probes | [ProbeSpecSpec](#talos.resource.definitions.network.ProbeSpecSpec) | repeated | | +| metadata | [talos.resource.definitions.runtime.PlatformMetadataSpec](#talos.resource.definitions.runtime.PlatformMetadataSpec) | | | + + + + + + ### PortRange @@ -8675,471 +9168,6 @@ MemorySpec represents the last Memory stats snapshot. - - - - - - - - - - - -

Top

- -## resource/definitions/runtime/runtime.proto - - - - - -### BootedEntrySpec -BootedEntrySpec describes the booted entry resource properties. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| booted_entry | [string](#string) | | | - - - - - - - - -### DevicesStatusSpec -DevicesStatusSpec is the spec for devices status. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ready | [bool](#bool) | | | - - - - - - - - -### DiagnosticSpec -DiagnosticSpec is the spec for devices status. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| message | [string](#string) | | | -| details | [string](#string) | repeated | | - - - - - - - - -### EventSinkConfigSpec -EventSinkConfigSpec describes configuration of Talos event log streaming. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| endpoint | [string](#string) | | | - - - - - - - - -### ExtensionServiceConfigFile -ExtensionServiceConfigFile describes extensions service config files. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| content | [string](#string) | | | -| mount_path | [string](#string) | | | - - - - - - - - -### ExtensionServiceConfigSpec -ExtensionServiceConfigSpec describes status of rendered extensions service config files. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| files | [ExtensionServiceConfigFile](#talos.resource.definitions.runtime.ExtensionServiceConfigFile) | repeated | | -| environment | [string](#string) | repeated | | - - - - - - - - -### ExtensionServiceConfigStatusSpec -ExtensionServiceConfigStatusSpec describes status of rendered extensions service config files. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| spec_version | [string](#string) | | | - - - - - - - - -### KernelCmdlineSpec -KernelCmdlineSpec presents kernel command line (contents of /proc/cmdline). - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| cmdline | [string](#string) | | | - - - - - - - - -### KernelModuleSpecSpec -KernelModuleSpecSpec describes Linux kernel module to load. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| parameters | [string](#string) | repeated | | - - - - - - - - -### KernelParamSpecSpec -KernelParamSpecSpec describes status of the defined sysctls. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| value | [string](#string) | | | -| ignore_errors | [bool](#bool) | | | - - - - - - - - -### KernelParamStatusSpec -KernelParamStatusSpec describes status of the defined sysctls. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| current | [string](#string) | | | -| default | [string](#string) | | | -| unsupported | [bool](#bool) | | | - - - - - - - - -### KmsgLogConfigSpec -KmsgLogConfigSpec describes configuration for kmsg log streaming. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| destinations | [common.URL](#common.URL) | repeated | | - - - - - - - - -### LoadedKernelModuleSpec -LoadedKernelModuleSpec describes Linux kernel module to load. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| size | [int64](#int64) | | | -| reference_count | [int64](#int64) | | | -| dependencies | [string](#string) | repeated | | -| state | [string](#string) | | | -| address | [string](#string) | | | - - - - - - - - -### MachineStatusSpec -MachineStatusSpec describes status of the defined sysctls. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| stage | [talos.resource.definitions.enums.RuntimeMachineStage](#talos.resource.definitions.enums.RuntimeMachineStage) | | | -| status | [MachineStatusStatus](#talos.resource.definitions.runtime.MachineStatusStatus) | | | - - - - - - - - -### MachineStatusStatus -MachineStatusStatus describes machine current status at the stage. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ready | [bool](#bool) | | | -| unmet_conditions | [UnmetCondition](#talos.resource.definitions.runtime.UnmetCondition) | repeated | | - - - - - - - - -### MaintenanceServiceConfigSpec -MaintenanceServiceConfigSpec describes configuration for maintenance service API. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| listen_address | [string](#string) | | | -| reachable_addresses | [common.NetIP](#common.NetIP) | repeated | | - - - - - - - - -### MetaKeySpec -MetaKeySpec describes status of the defined sysctls. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| value | [string](#string) | | | - - - - - - - - -### MetaLoadedSpec -MetaLoadedSpec is the spec for meta loaded. The Done field is always true when resource exists. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| done | [bool](#bool) | | | - - - - - - - - -### MountStatusSpec -MountStatusSpec describes status of the defined sysctls. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| source | [string](#string) | | | -| target | [string](#string) | | | -| filesystem_type | [string](#string) | | | -| options | [string](#string) | repeated | | -| encrypted | [bool](#bool) | | | -| encryption_providers | [string](#string) | repeated | | - - - - - - - - -### PlatformMetadataSpec -PlatformMetadataSpec describes platform metadata properties. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| platform | [string](#string) | | | -| hostname | [string](#string) | | | -| region | [string](#string) | | | -| zone | [string](#string) | | | -| instance_type | [string](#string) | | | -| instance_id | [string](#string) | | | -| provider_id | [string](#string) | | | -| spot | [bool](#bool) | | | -| internal_dns | [string](#string) | | | -| external_dns | [string](#string) | | | -| tags | [PlatformMetadataSpec.TagsEntry](#talos.resource.definitions.runtime.PlatformMetadataSpec.TagsEntry) | repeated | | - - - - - - - - -### PlatformMetadataSpec.TagsEntry - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| key | [string](#string) | | | -| value | [string](#string) | | | - - - - - - - - -### SBOMItemSpec -SBOMItemSpec describes the SBOM item resource properties. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| version | [string](#string) | | | -| license | [string](#string) | | | -| cp_es | [string](#string) | repeated | | -| pur_ls | [string](#string) | repeated | | -| extension | [bool](#bool) | | | - - - - - - - - -### SecurityStateSpec -SecurityStateSpec describes the security state resource properties. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| secure_boot | [bool](#bool) | | | -| uki_signing_key_fingerprint | [string](#string) | | | -| pcr_signing_key_fingerprint | [string](#string) | | | -| se_linux_state | [talos.resource.definitions.enums.RuntimeSELinuxState](#talos.resource.definitions.enums.RuntimeSELinuxState) | | | -| booted_with_uki | [bool](#bool) | | | -| fips_state | [talos.resource.definitions.enums.RuntimeFIPSState](#talos.resource.definitions.enums.RuntimeFIPSState) | | | - - - - - - - - -### UniqueMachineTokenSpec -UniqueMachineTokenSpec is the spec for the machine unique token. Token can be empty if machine wasn't assigned any. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| token | [string](#string) | | | - - - - - - - - -### UnmetCondition -UnmetCondition is a failure which prevents machine from being ready at the stage. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| name | [string](#string) | | | -| reason | [string](#string) | | | - - - - - - - - -### WatchdogTimerConfigSpec -WatchdogTimerConfigSpec describes configuration of watchdog timer. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| device | [string](#string) | | | -| timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | | - - - - - - - - -### WatchdogTimerStatusSpec -WatchdogTimerStatusSpec describes configuration of watchdog timer. - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| device | [string](#string) | | | -| timeout | [google.protobuf.Duration](#google.protobuf.Duration) | | | -| feed_interval | [google.protobuf.Duration](#google.protobuf.Duration) | | | - - - - -