refactor: make maintenance service controller-based

Fixes #7430

Introduce a set of resources which look similar to other API
implementations: CA, certs, cert SANs, etc.

Introduce a controller which manages the service based on resource
state.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
This commit is contained in:
Andrey Smirnov 2023-07-04 18:53:57 +04:00
parent d23d04de2a
commit bdb96189fa
No known key found for this signature in database
GPG Key ID: 7B26396447AB6DFD
43 changed files with 2861 additions and 426 deletions

View File

@ -53,6 +53,12 @@ message MachineStatusStatus {
repeated UnmetCondition unmet_conditions = 2;
}
// MaintenanceServiceConfigSpec describes configuration for maintenance service API.
message MaintenanceServiceConfigSpec {
string listen_address = 1;
repeated common.NetIP reachable_addresses = 2;
}
// MetaKeySpec describes status of the defined sysctls.
message MetaKeySpec {
string value = 1;

View File

@ -73,6 +73,17 @@ message KubernetesRootSpec {
repeated common.NetIP api_server_ips = 14;
}
// MaintenanceRootSpec describes maintenance service CA.
message MaintenanceRootSpec {
common.PEMEncodedCertificateAndKey ca = 1;
}
// MaintenanceServiceCertsSpec describes maintenance service certs secrets.
message MaintenanceServiceCertsSpec {
common.PEMEncodedCertificateAndKey ca = 1;
common.PEMEncodedCertificateAndKey server = 2;
}
// OSRootSpec describes operating system CA.
message OSRootSpec {
common.PEMEncodedCertificateAndKey ca = 1;

View File

@ -188,7 +188,9 @@ func (ctrl *APILoadBalancerController) startLoadBalancer(lbCfg *k8s.LoadBalancer
ctrl.balancerHost = spec.Host
ctrl.balancerPort = spec.Port
lb, err := controlplane.NewLoadBalancer(ctrl.balancerHost, ctrl.balancerPort, logger)
lb, err := controlplane.NewLoadBalancer(ctrl.balancerHost, ctrl.balancerPort,
logger.WithOptions(zap.IncreaseLevel(zap.ErrorLevel)), // silence the load balancer logs
)
if err != nil {
return fmt.Errorf("failed to create load balancer: %w", err)
}

View File

@ -0,0 +1,129 @@
// 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 runtime
import (
"context"
"fmt"
"net/netip"
"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/slices"
"github.com/siderolabs/go-pointer"
"go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/nethelpers"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
"github.com/siderolabs/talos/pkg/machinery/resources/siderolink"
)
// MaintenanceConfigController manages Maintenance Service config: which address it should listen on, etc.
type MaintenanceConfigController struct{}
// Name implements controller.Controller interface.
func (ctrl *MaintenanceConfigController) Name() string {
return "runtime.MaintenanceConfigController"
}
// Inputs implements controller.Controller interface.
func (ctrl *MaintenanceConfigController) Inputs() []controller.Input {
return []controller.Input{
{
Namespace: config.NamespaceName,
Type: siderolink.ConfigType,
ID: pointer.To(siderolink.ConfigID),
},
{
Namespace: network.NamespaceName,
Type: network.NodeAddressType,
ID: pointer.To(network.NodeAddressCurrentID),
},
}
}
// Outputs implements controller.Controller interface.
func (ctrl *MaintenanceConfigController) Outputs() []controller.Output {
return []controller.Output{
{
Type: runtime.MaintenanceServiceConfigType,
Kind: controller.OutputExclusive,
},
}
}
// Run implements controller.Controller interface.
//
//nolint:gocyclo
func (ctrl *MaintenanceConfigController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
for {
select {
case <-ctx.Done():
return nil
case <-r.EventCh():
}
nodeAddresses, err := safe.ReaderGetByID[*network.NodeAddress](ctx, r, network.NodeAddressCurrentID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("error getting node address: %w", err)
}
var (
listenAddress string
reachableAddresses []netip.Addr
)
if nodeAddresses != nil {
reachableAddresses = nodeAddresses.TypedSpec().IPs()
}
_, err = safe.ReaderGetByID[*siderolink.Config](ctx, r, siderolink.ConfigID)
// check if SideroLink config exists:
switch {
// * if it exists, find the SideroLink address and listen only on it
case err == nil:
if nodeAddresses != nil {
sideroLinkAddresses := slices.Filter(nodeAddresses.TypedSpec().IPs(), func(addr netip.Addr) bool {
return network.IsULA(addr, network.ULASideroLink)
})
if len(sideroLinkAddresses) > 0 {
listenAddress = nethelpers.JoinHostPort(sideroLinkAddresses[0].String(), constants.ApidPort)
reachableAddresses = sideroLinkAddresses[:1]
}
}
// * if it doesn't exist, listen on '*'
case state.IsNotFoundError(err):
listenAddress = fmt.Sprintf(":%d", constants.ApidPort)
default:
return fmt.Errorf("error getting siderolink config: %w", err)
}
if listenAddress == "" {
// drop config
if err = r.Destroy(ctx, runtime.NewMaintenanceServiceConfig().Metadata()); err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("error destroying maintenance config: %w", err)
}
} else {
// create/update config
if err = safe.WriterModify[*runtime.MaintenanceServiceConfig](ctx, r, runtime.NewMaintenanceServiceConfig(),
func(config *runtime.MaintenanceServiceConfig) error {
config.TypedSpec().ListenAddress = listenAddress
config.TypedSpec().ReachableAddresses = reachableAddresses
return nil
}); err != nil {
return fmt.Errorf("error updating maintenance config: %w", err)
}
}
r.ResetRestartBackoff()
}
}

View File

@ -0,0 +1,64 @@
// 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 runtime_test
import (
"net/netip"
"testing"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"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"
runtimectrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
"github.com/siderolabs/talos/pkg/machinery/resources/siderolink"
)
func TestMaintenanceConfigSuite(t *testing.T) {
suite.Run(t, &MaintenanceConfigSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 5 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(&runtimectrl.MaintenanceConfigController{}))
},
},
})
}
type MaintenanceConfigSuite struct {
ctest.DefaultSuite
}
func (suite *MaintenanceConfigSuite) TestReconcile() {
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{runtime.MaintenanceServiceConfigID},
func(cfg *runtime.MaintenanceServiceConfig, asrt *assert.Assertions) {
asrt.Equal(":50000", cfg.TypedSpec().ListenAddress)
asrt.Nil(cfg.TypedSpec().ReachableAddresses)
})
siderolinkConfig := siderolink.NewConfig(config.NamespaceName, siderolink.ConfigID)
suite.Require().NoError(suite.State().Create(suite.Ctx(), siderolinkConfig))
rtestutils.AssertNoResource[*runtime.MaintenanceServiceConfig](suite.Ctx(), suite.T(), suite.State(), runtime.MaintenanceServiceConfigID)
nodeAddresses := network.NewNodeAddress(network.NamespaceName, network.NodeAddressCurrentID)
nodeAddresses.TypedSpec().Addresses = []netip.Prefix{
netip.MustParsePrefix("172.16.0.1/24"),
netip.MustParsePrefix("fdae:41e4:649b:9303:2a07:9c7:5b08:aef7/64"),
}
suite.Require().NoError(suite.State().Create(suite.Ctx(), nodeAddresses))
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{runtime.MaintenanceServiceConfigID},
func(cfg *runtime.MaintenanceServiceConfig, asrt *assert.Assertions) {
asrt.Equal("[fdae:41e4:649b:9303:2a07:9c7:5b08:aef7]:50000", cfg.TypedSpec().ListenAddress)
asrt.Equal([]netip.Addr{netip.MustParseAddr("fdae:41e4:649b:9303:2a07:9c7:5b08:aef7")}, cfg.TypedSpec().ReachableAddresses)
})
}

View File

@ -0,0 +1,283 @@
// 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 runtime
import (
"context"
"fmt"
"net"
"net/netip"
"reflect"
"sync"
"time"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/crypto/x509"
"github.com/siderolabs/gen/slices"
"github.com/siderolabs/go-pointer"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"github.com/siderolabs/talos/internal/app/maintenance"
"github.com/siderolabs/talos/pkg/grpc/factory"
"github.com/siderolabs/talos/pkg/grpc/middleware/authz"
machineryconfig "github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
// MaintenanceServiceController runs the maintenance service based on the configuration.
type MaintenanceServiceController struct{}
// Name implements controller.Controller interface.
func (ctrl *MaintenanceServiceController) Name() string {
return "runtime.MaintenanceServiceController"
}
// Inputs implements controller.Controller interface.
func (ctrl *MaintenanceServiceController) Inputs() []controller.Input {
return []controller.Input{
{
Namespace: runtime.NamespaceName,
Type: runtime.MaintenanceServiceRequestType,
ID: pointer.To(runtime.MaintenanceServiceRequestID),
Kind: controller.InputStrong,
},
{
Namespace: runtime.NamespaceName,
Type: runtime.MaintenanceServiceConfigType,
ID: pointer.To(runtime.MaintenanceServiceConfigID),
Kind: controller.InputWeak,
},
{
Namespace: secrets.NamespaceName,
Type: secrets.MaintenanceServiceCertsType,
ID: pointer.To(secrets.MaintenanceServiceCertsID),
Kind: controller.InputWeak,
},
}
}
// Outputs implements controller.Controller interface.
func (ctrl *MaintenanceServiceController) Outputs() []controller.Output {
return []controller.Output{
{
Type: config.MachineConfigType,
Kind: controller.OutputShared,
},
}
}
// Run implements controller.Controller interface.
//
//nolint:gocyclo,cyclop
func (ctrl *MaintenanceServiceController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
var (
server *grpc.Server
serverWg sync.WaitGroup
listener net.Listener
lastReachableAddresses []string
lastCertificateFingerprint string
usagePrinted bool
)
shutdownServer := func(ctx context.Context) {
if server != nil {
shutdownCtx, shutdownCancel := context.WithTimeout(ctx, 5*time.Second)
defer shutdownCancel()
factory.ServerGracefulStop(server, shutdownCtx)
serverWg.Wait()
server = nil
}
if listener != nil {
listener.Close() //nolint:errcheck
listener = nil
lastReachableAddresses = nil
}
}
defer shutdownServer(context.Background())
cfgCh := make(chan machineryconfig.Provider)
srv := maintenance.New(cfgCh)
injector := &authz.Injector{
Mode: authz.ReadOnly,
Logger: logger.Sugar().Debugf,
}
tlsProvider := maintenance.NewTLSProvider()
for {
select {
case <-ctx.Done():
return nil
case cfg := <-cfgCh:
configResource := config.NewMachineConfigWithID(cfg, config.MaintenanceID)
oldConfigResource, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.MaintenanceID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("failed to get machine config: %w", err)
}
if state.IsNotFoundError(err) {
if err = r.Create(ctx, configResource); err != nil {
return fmt.Errorf("failed to create machine config: %w", err)
}
} else {
configResource.Metadata().SetVersion(oldConfigResource.Metadata().Version())
if err = configResource.Metadata().SetOwner(oldConfigResource.Metadata().Owner()); err != nil {
return fmt.Errorf("error setting owner: %w", err)
}
if err = r.Update(ctx, configResource); err != nil {
return fmt.Errorf("failed to update machine config: %w", err)
}
}
continue
case <-r.EventCh():
}
request, err := safe.ReaderGetByID[*runtime.MaintenanceServiceRequest](ctx, r, runtime.MaintenanceServiceRequestID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("failed to get maintenance service request: %w", err)
}
if request == nil {
// no request, nothing to do
shutdownServer(ctx)
continue
}
if request.Metadata().Phase() == resource.PhaseTearingDown {
// stop the server & remove the finalizer
shutdownServer(ctx)
if err = r.RemoveFinalizer(ctx, request.Metadata(), ctrl.Name()); err != nil {
return fmt.Errorf("failed to remove finalizer: %w", err)
}
continue
}
cfg, err := safe.ReaderGetByID[*runtime.MaintenanceServiceConfig](ctx, r, runtime.MaintenanceServiceConfigID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("failed to get maintenance service config: %w", err)
}
cert, err := safe.ReaderGetByID[*secrets.MaintenanceServiceCerts](ctx, r, secrets.MaintenanceServiceCertsID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("failed to get maintenance service certs: %w", err)
}
if cert != nil {
if err = tlsProvider.Update(cert); err != nil {
return fmt.Errorf("failed to update tls provider: %w", err)
}
}
// immediately add a finalizer
if err = r.AddFinalizer(ctx, request.Metadata(), ctrl.Name()); err != nil {
return fmt.Errorf("failed to add finalizer: %w", err)
}
if cfg == nil {
// no config, nothing to do
shutdownServer(ctx)
continue
}
if listener == nil {
listener, err = net.Listen("tcp", cfg.TypedSpec().ListenAddress)
if err != nil {
return fmt.Errorf("failed to listen: %w", err)
}
}
if server == nil {
tlsConfig, err := tlsProvider.TLSConfig()
if err != nil {
return fmt.Errorf("failed to get tls config: %w", err)
}
server = factory.NewServer(
srv,
factory.WithDefaultLog(),
factory.ServerOptions(
grpc.Creds(
credentials.NewTLS(tlsConfig),
),
),
factory.WithUnaryInterceptor(injector.UnaryInterceptor()),
factory.WithStreamInterceptor(injector.StreamInterceptor()),
)
serverWg.Add(1)
go func() {
defer serverWg.Done()
//nolint:errcheck
server.Serve(listener)
}()
}
// print additional information for the user on important state changes
reachableAddresses := slices.Map(cfg.TypedSpec().ReachableAddresses, netip.Addr.String)
if !reflect.DeepEqual(lastReachableAddresses, reachableAddresses) {
logger.Info("this machine is reachable at:")
for _, addr := range reachableAddresses {
logger.Info("\t" + addr)
}
lastReachableAddresses = reachableAddresses
}
if cert != nil {
certificateFingerprint, err := x509.SPKIFingerprintFromPEM(cert.TypedSpec().Server.Crt)
if err != nil {
return fmt.Errorf("failed to get certificate fingerprint: %w", err)
}
fingerprint := certificateFingerprint.String()
if fingerprint != lastCertificateFingerprint {
logger.Info("server certificate issued", zap.String("fingerprint", fingerprint))
}
lastCertificateFingerprint = fingerprint
}
if !usagePrinted && len(reachableAddresses) > 0 && lastCertificateFingerprint != "" {
firstIP := reachableAddresses[0]
logger.Sugar().Info("upload configuration using talosctl:")
logger.Sugar().Infof("\ttalosctl apply-config --insecure --nodes %s --file <config.yaml>", firstIP)
logger.Sugar().Info("or apply configuration using talosctl interactive installer:")
logger.Sugar().Infof("\ttalosctl apply-config --insecure --nodes %s --mode=interactive", firstIP)
logger.Sugar().Info("optionally with node fingerprint check:")
logger.Sugar().Infof("\ttalosctl apply-config --insecure --nodes %s --cert-fingerprint '%s' --file <config.yaml>", firstIP, lastCertificateFingerprint)
usagePrinted = true
}
r.ResetRestartBackoff()
}
}

View File

@ -0,0 +1,223 @@
// 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 runtime_test
import (
"context"
"crypto/tls"
"net"
"net/netip"
"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/cosi-project/runtime/pkg/state/registry"
"github.com/siderolabs/go-retry/retry"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
runtimectrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/secrets"
talosruntime "github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
"github.com/siderolabs/talos/internal/app/maintenance"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/resources/hardware"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
)
func TestMaintenanceServiceSuite(t *testing.T) {
suite.Run(t, &MaintenanceServiceSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 5 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
maintenance.InjectController(mockController{s: suite.State()})
suite.Require().NoError(suite.Runtime().RegisterController(&secrets.MaintenanceRootController{}))
suite.Require().NoError(suite.Runtime().RegisterController(&secrets.MaintenanceCertSANsController{}))
suite.Require().NoError(suite.Runtime().RegisterController(&secrets.MaintenanceController{}))
suite.Require().NoError(suite.Runtime().RegisterController(&runtimectrl.MaintenanceServiceController{}))
},
},
})
}
type MaintenanceServiceSuite struct {
ctest.DefaultSuite
}
func (suite *MaintenanceServiceSuite) findListenAddr() string {
l, err := net.Listen("tcp", "127.0.0.1:0")
suite.Require().NoError(err)
addr := l.Addr().String()
suite.Require().NoError(l.Close())
return addr
}
func (suite *MaintenanceServiceSuite) TestRunService() {
nodeAddresses := network.NewNodeAddress(network.NamespaceName, network.NodeAddressAccumulativeID)
nodeAddresses.TypedSpec().Addresses = []netip.Prefix{netip.MustParsePrefix("10.0.0.1/24")}
suite.Require().NoError(suite.State().Create(suite.Ctx(), nodeAddresses))
maintenanceConfig := runtime.NewMaintenanceServiceConfig()
maintenanceConfig.TypedSpec().ListenAddress = suite.findListenAddr()
maintenanceConfig.TypedSpec().ReachableAddresses = []netip.Addr{netip.MustParseAddr("10.0.0.1")}
suite.Require().NoError(suite.State().Create(suite.Ctx(), maintenanceConfig))
maintenanceRequest := runtime.NewMaintenanceServiceRequest()
suite.Require().NoError(suite.State().Create(suite.Ctx(), maintenanceRequest))
// wait for the service to be up
suite.AssertWithin(time.Second, 10*time.Millisecond, func() error {
c, err := net.Dial("tcp", maintenanceConfig.TypedSpec().ListenAddress)
if c != nil {
c.Close() //nolint:errcheck
}
return retry.ExpectedError(err)
})
// test API
mc, err := client.New(suite.Ctx(),
client.WithTLSConfig(&tls.Config{
InsecureSkipVerify: true,
}), client.WithEndpoints(maintenanceConfig.TypedSpec().ListenAddress),
)
suite.Require().NoError(err)
_, err = mc.Version(suite.Ctx())
suite.Require().ErrorContains(err, "API is not implemented in maintenance mode")
suite.Require().NoError(mc.Close())
// teardown the maintenance service
_, err = suite.State().Teardown(suite.Ctx(), maintenanceRequest.Metadata())
suite.Require().NoError(err)
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{runtime.MaintenanceServiceRequestID},
func(r *runtime.MaintenanceServiceRequest, asrt *assert.Assertions) {
asrt.Empty(r.Metadata().Finalizers())
})
suite.Require().NoError(suite.State().Destroy(suite.Ctx(), maintenanceRequest.Metadata()))
_, err = net.Dial("tcp", maintenanceConfig.TypedSpec().ListenAddress)
suite.Require().ErrorContains(err, "connection refused")
}
type mockController struct {
s state.State
}
type mockState struct {
s state.State
}
func (mock mockController) Runtime() talosruntime.Runtime {
return mock
}
func (mockController) Sequencer() talosruntime.Sequencer {
return nil
}
func (mockController) Run(context.Context, talosruntime.Sequence, any, ...talosruntime.LockOption) error {
return nil
}
func (mockController) V1Alpha2() talosruntime.V1Alpha2Controller {
return nil
}
func (mock mockController) Config() config.Config {
return nil
}
func (mock mockController) ConfigContainer() config.Container {
return nil
}
func (mock mockController) LoadAndValidateConfig([]byte) (config.Provider, error) {
return nil, nil
}
func (mock mockController) RollbackToConfigAfter([]byte, time.Duration) error {
return nil
}
func (mock mockController) CancelConfigRollbackTimeout() {
}
func (mock mockController) SetConfig(config.Provider) error {
return nil
}
func (mock mockController) CanApplyImmediate(config.Provider) error {
return nil
}
func (mock mockController) GetSystemInformation(context.Context) (*hardware.SystemInformation, error) {
return nil, nil
}
func (mock mockController) State() talosruntime.State {
return mockState(mock)
}
func (mock mockController) Events() talosruntime.EventStream {
return nil
}
func (mock mockController) Logging() talosruntime.LoggingManager {
return nil
}
func (mock mockController) NodeName() (string, error) {
return "", nil
}
func (mock mockController) IsBootstrapAllowed() bool {
return false
}
func (mock mockState) Platform() talosruntime.Platform {
return nil
}
func (mock mockState) Machine() talosruntime.MachineState {
return nil
}
func (mock mockState) Cluster() talosruntime.ClusterState {
return nil
}
func (mock mockState) V1Alpha2() talosruntime.V1Alpha2State {
return mock
}
func (mock mockState) Resources() state.State {
return mock.s
}
func (mock mockState) NamespaceRegistry() *registry.NamespaceRegistry {
return nil
}
func (mock mockState) ResourceRegistry() *registry.ResourceRegistry {
return nil
}
func (mock mockState) SetConfig(config.Provider) error {
return nil
}

View File

@ -0,0 +1,143 @@
// 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 secrets
import (
"context"
stdlibx509 "crypto/x509"
"fmt"
"time"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/crypto/x509"
"github.com/siderolabs/go-pointer"
"go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
timeresource "github.com/siderolabs/talos/pkg/machinery/resources/time"
"github.com/siderolabs/talos/pkg/machinery/resources/v1alpha1"
)
// MaintenanceController manages secrets.MaintenanceServiceCerts.
type MaintenanceController struct{}
// Name implements controller.Controller interface.
func (ctrl *MaintenanceController) Name() string {
return "secrets.MaintenanceController"
}
// Inputs implements controller.Controller interface.
func (ctrl *MaintenanceController) Inputs() []controller.Input {
return []controller.Input{
{
Namespace: secrets.NamespaceName,
Type: secrets.MaintenanceRootType,
ID: pointer.To(secrets.MaintenanceRootID),
Kind: controller.InputWeak,
},
{
Namespace: secrets.NamespaceName,
Type: secrets.CertSANType,
ID: pointer.To(secrets.CertSANMaintenanceID),
Kind: controller.InputWeak,
},
// time status isn't fetched, but the fact that it is in dependencies means
// that certs will be regenerated on time sync/jump (as reconcile will be triggered)
{
Namespace: v1alpha1.NamespaceName,
Type: timeresource.StatusType,
ID: pointer.To(timeresource.StatusID),
Kind: controller.InputWeak,
},
}
}
// Outputs implements controller.Controller interface.
func (ctrl *MaintenanceController) Outputs() []controller.Output {
return []controller.Output{
{
Type: secrets.MaintenanceServiceCertsType,
Kind: controller.OutputExclusive,
},
}
}
// Run implements controller.Controller interface.
//
//nolint:gocyclo
func (ctrl *MaintenanceController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
refreshTicker := time.NewTicker(x509.DefaultCertificateValidityDuration / 2)
defer refreshTicker.Stop()
for {
select {
case <-ctx.Done():
return nil
case <-r.EventCh():
case <-refreshTicker.C:
}
rootSecrets, err := safe.ReaderGetByID[*secrets.MaintenanceRoot](ctx, r, secrets.MaintenanceRootID)
if err != nil {
if state.IsNotFoundError(err) {
continue
}
return fmt.Errorf("error getting maintenance root secrets: %w", err)
}
certSANs, err := safe.ReaderGetByID[*secrets.CertSAN](ctx, r, secrets.CertSANMaintenanceID)
if err != nil {
if state.IsNotFoundError(err) {
continue
}
return fmt.Errorf("error getting certSANs: %w", err)
}
ca, err := x509.NewCertificateAuthorityFromCertificateAndKey(rootSecrets.TypedSpec().CA)
if err != nil {
return fmt.Errorf("failed to parse CA certificate: %w", err)
}
serverCert, err := x509.NewKeyPair(ca,
x509.IPAddresses(certSANs.TypedSpec().StdIPs()),
x509.DNSNames(certSANs.TypedSpec().DNSNames),
x509.CommonName(certSANs.TypedSpec().FQDN),
x509.NotAfter(time.Now().Add(x509.DefaultCertificateValidityDuration)),
x509.KeyUsage(stdlibx509.KeyUsageDigitalSignature),
x509.ExtKeyUsage([]stdlibx509.ExtKeyUsage{
stdlibx509.ExtKeyUsageServerAuth,
}),
)
if err != nil {
return fmt.Errorf("failed to generate maintenance server cert: %w", err)
}
if err = safe.WriterModify(ctx, r, secrets.NewMaintenanceServiceCerts(),
func(maintenanceSecrets *secrets.MaintenanceServiceCerts) error {
spec := maintenanceSecrets.TypedSpec()
spec.CA = &x509.PEMEncodedCertificateAndKey{
Crt: rootSecrets.TypedSpec().CA.Crt,
}
spec.Server = x509.NewCertificateAndKeyFromKeyPair(serverCert)
return nil
}); err != nil {
return fmt.Errorf("error modifying resource: %w", err)
}
serverFingerprint, _ := x509.SPKIFingerprintFromDER(serverCert.Certificate.Certificate[0]) //nolint:errcheck
logger.Debug("generated new certificates",
zap.Stringer("server", serverFingerprint),
)
r.ResetRestartBackoff()
}
}

View File

@ -0,0 +1,111 @@
// 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 secrets
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"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/go-pointer"
"go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
// MaintenanceCertSANsController manages secrets.APICertSANs based on configuration.
type MaintenanceCertSANsController struct{}
// Name implements controller.Controller interface.
func (ctrl *MaintenanceCertSANsController) Name() string {
return "secrets.MaintenanceCertSANsController"
}
// Inputs implements controller.Controller interface.
//
//nolint:dupl
func (ctrl *MaintenanceCertSANsController) Inputs() []controller.Input {
return []controller.Input{
{
Namespace: network.NamespaceName,
Type: network.HostnameStatusType,
ID: pointer.To(network.HostnameID),
Kind: controller.InputWeak,
},
{
Namespace: network.NamespaceName,
Type: network.NodeAddressType,
ID: pointer.To(network.NodeAddressAccumulativeID),
Kind: controller.InputWeak,
},
}
}
// Outputs implements controller.Controller interface.
func (ctrl *MaintenanceCertSANsController) Outputs() []controller.Output {
return []controller.Output{
{
Type: secrets.CertSANType,
Kind: controller.OutputShared,
},
}
}
// Run implements controller.Controller interface.
//
//nolint:gocyclo
func (ctrl *MaintenanceCertSANsController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
for {
select {
case <-ctx.Done():
return nil
case <-r.EventCh():
}
hostnameStatus, err := safe.ReaderGetByID[*network.HostnameStatus](ctx, r, network.HostnameID)
if err != nil && !state.IsNotFoundError(err) {
return fmt.Errorf("failed to get hostname status: %w", err)
}
nodeAddresses, err := safe.ReaderGetByID[*network.NodeAddress](ctx, r, network.NodeAddressAccumulativeID)
if err != nil {
if state.IsNotFoundError(err) {
continue
}
return err
}
if err = r.Modify(ctx, secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANMaintenanceID), func(r resource.Resource) error {
spec := r.(*secrets.CertSAN).TypedSpec()
spec.Reset()
spec.AppendIPs(nodeAddresses.TypedSpec().IPs()...)
spec.AppendIPs(netip.MustParseAddr("127.0.0.1"))
spec.AppendIPs(netip.MustParseAddr("::1"))
if hostnameStatus != nil {
spec.AppendDNSNames(hostnameStatus.TypedSpec().DNSNames()...)
}
spec.FQDN = constants.MaintenanceServiceCommonName
spec.Sort()
return nil
}); err != nil {
return err
}
r.ResetRestartBackoff()
}
}

View File

@ -0,0 +1,67 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package secrets_test
import (
"fmt"
"net/netip"
"testing"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"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"
secretsctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/secrets"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
func TestMaintenanceCertSANsSuite(t *testing.T) {
suite.Run(t, &MaintenanceCertSANsSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 2 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(&secretsctrl.MaintenanceCertSANsController{}))
},
},
})
}
type MaintenanceCertSANsSuite struct {
ctest.DefaultSuite
}
func (suite *MaintenanceCertSANsSuite) TestReconcile() {
nodeAddresses := network.NewNodeAddress(
network.NamespaceName,
network.NodeAddressAccumulativeID,
)
nodeAddresses.TypedSpec().Addresses = []netip.Prefix{
netip.MustParsePrefix("10.2.1.3/24"),
netip.MustParsePrefix("172.16.0.1/32"),
}
suite.Require().NoError(suite.State().Create(suite.Ctx(), nodeAddresses))
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.CertSANMaintenanceID},
func(certSANs *secrets.CertSAN, asrt *assert.Assertions) {
asrt.Empty(certSANs.TypedSpec().DNSNames)
asrt.Equal("[10.2.1.3 127.0.0.1 172.16.0.1 ::1]", fmt.Sprintf("%v", certSANs.TypedSpec().IPs))
asrt.Equal(constants.MaintenanceServiceCommonName, certSANs.TypedSpec().FQDN)
})
hostnameStatus := network.NewHostnameStatus(network.NamespaceName, network.HostnameID)
hostnameStatus.TypedSpec().Hostname = "bar"
hostnameStatus.TypedSpec().Domainname = "some.org"
suite.Require().NoError(suite.State().Create(suite.Ctx(), hostnameStatus))
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.CertSANMaintenanceID},
func(certSANs *secrets.CertSAN, asrt *assert.Assertions) {
asrt.Equal([]string{"bar", "bar.some.org"}, certSANs.TypedSpec().DNSNames)
})
}

View File

@ -0,0 +1,61 @@
// 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 secrets
import (
"context"
"fmt"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/safe"
"github.com/siderolabs/crypto/x509"
"go.uber.org/zap"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
// MaintenanceRootController manages secrets.Root based on configuration.
type MaintenanceRootController struct{}
// Name implements controller.Controller interface.
func (ctrl *MaintenanceRootController) Name() string {
return "secrets.MaintenanceRootController"
}
// Inputs implements controller.Controller interface.
func (ctrl *MaintenanceRootController) Inputs() []controller.Input {
return nil
}
// Outputs implements controller.Controller interface.
func (ctrl *MaintenanceRootController) Outputs() []controller.Output {
return []controller.Output{
{
Type: secrets.MaintenanceRootType,
Kind: controller.OutputExclusive,
},
}
}
// Run implements controller.Controller interface.
func (ctrl *MaintenanceRootController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
// run this controller only once, as the CA never changes
select {
case <-ctx.Done():
return nil
case <-r.EventCh():
}
return safe.WriterModify(ctx, r, secrets.NewMaintenanceRoot(secrets.MaintenanceRootID), func(root *secrets.MaintenanceRoot) error {
ca, err := x509.NewSelfSignedCertificateAuthority()
if err != nil {
return fmt.Errorf("failed to generate self-signed CA: %w", err)
}
root.TypedSpec().CA = x509.NewCertificateAndKeyFromCertificateAuthority(ca)
return nil
})
}

View File

@ -0,0 +1,39 @@
// 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 secrets_test
import (
"testing"
"github.com/cosi-project/runtime/pkg/resource"
"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"
secretsctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/secrets"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
func TestMaintenanceRootSuite(t *testing.T) {
suite.Run(t, &MaintenanceRootSuite{
DefaultSuite: ctest.DefaultSuite{
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(&secretsctrl.MaintenanceRootController{}))
},
},
})
}
type MaintenanceRootSuite struct {
ctest.DefaultSuite
}
func (suite *MaintenanceRootSuite) TestReconcile() {
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.MaintenanceRootID},
func(root *secrets.MaintenanceRoot, asrt *assert.Assertions) {
asrt.NotEmpty(root.TypedSpec().CA)
})
}

View File

@ -0,0 +1,88 @@
// 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 secrets_test
import (
stdlibx509 "crypto/x509"
"fmt"
"testing"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/rtestutils"
"github.com/siderolabs/crypto/x509"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
secretsctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/secrets"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
func TestMaintenanceSuite(t *testing.T) {
suite.Run(t, &MaintenanceSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 2 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(&secretsctrl.MaintenanceController{}))
},
},
})
}
type MaintenanceSuite struct {
ctest.DefaultSuite
}
func (suite *MaintenanceSuite) TestReconcile() {
rootSecrets := secrets.NewMaintenanceRoot(secrets.MaintenanceRootID)
rootCA, err := x509.NewSelfSignedCertificateAuthority(
x509.Organization("talos"),
)
suite.Require().NoError(err)
rootSecrets.TypedSpec().CA = &x509.PEMEncodedCertificateAndKey{
Crt: rootCA.CrtPEM,
Key: rootCA.KeyPEM,
}
suite.Require().NoError(suite.State().Create(suite.Ctx(), rootSecrets))
certSANs := secrets.NewCertSAN(secrets.NamespaceName, secrets.CertSANMaintenanceID)
certSANs.TypedSpec().Append(
"example.com",
"foo",
"10.2.1.3",
)
certSANs.TypedSpec().FQDN = "maintenance-service"
suite.Require().NoError(suite.State().Create(suite.Ctx(), certSANs))
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.MaintenanceServiceCertsID},
func(certs *secrets.MaintenanceServiceCerts, asrt *assert.Assertions) {
spec := certs.TypedSpec()
asrt.Equal(rootCA.CrtPEM, spec.CA.Crt)
asrt.Nil(spec.CA.Key)
serverCert, err := spec.Server.GetCert()
asrt.NoError(err)
if err != nil {
return
}
asrt.Equal([]string{"example.com", "foo"}, serverCert.DNSNames)
asrt.Equal("[10.2.1.3]", fmt.Sprintf("%v", serverCert.IPAddresses))
asrt.Equal("maintenance-service", serverCert.Subject.CommonName)
asrt.Empty(serverCert.Subject.Organization)
asrt.Equal(
stdlibx509.KeyUsageDigitalSignature,
serverCert.KeyUsage,
)
asrt.Equal([]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageServerAuth}, serverCert.ExtKeyUsage)
})
}

View File

@ -53,7 +53,6 @@ import (
"github.com/siderolabs/talos/internal/app/machined/pkg/system"
"github.com/siderolabs/talos/internal/app/machined/pkg/system/events"
"github.com/siderolabs/talos/internal/app/machined/pkg/system/services"
"github.com/siderolabs/talos/internal/app/maintenance"
"github.com/siderolabs/talos/internal/pkg/console"
"github.com/siderolabs/talos/internal/pkg/cri"
"github.com/siderolabs/talos/internal/pkg/environment"
@ -76,6 +75,7 @@ import (
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/kernel"
metamachinery "github.com/siderolabs/talos/pkg/machinery/meta"
resourceconfig "github.com/siderolabs/talos/pkg/machinery/resources/config"
resourcefiles "github.com/siderolabs/talos/pkg/machinery/resources/files"
"github.com/siderolabs/talos/pkg/machinery/resources/k8s"
resourceruntime "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
@ -472,7 +472,7 @@ func LoadConfig(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
},
)
b, e = receiveConfigViaMaintenanceService(ctx, logger, r)
b, e = receiveConfigViaMaintenanceService(ctx, r)
if e != nil {
return fmt.Errorf("failed to receive config via maintenance service: %w", e)
}
@ -604,7 +604,8 @@ func fetchConfig(ctx context.Context, r runtime.Runtime) (out []byte, err error)
return b, nil
}
func receiveConfigViaMaintenanceService(ctx context.Context, logger *log.Logger, r runtime.Runtime) ([]byte, error) {
//nolint:gocyclo
func receiveConfigViaMaintenanceService(ctx context.Context, r runtime.Runtime) ([]byte, error) {
// add "fake" events to signal when Talos enters and leaves maintenance mode
r.Events().Publish(ctx, &machineapi.TaskEvent{
Action: machineapi.TaskEvent_START,
@ -616,28 +617,84 @@ func receiveConfigViaMaintenanceService(ctx context.Context, logger *log.Logger,
Task: "runningMaintenance",
})
cfgBytes, err := maintenance.Run(ctx, logger)
if err != nil {
return nil, fmt.Errorf("maintenance service failed: %w", err)
// NOTE: this code is temporary, until the config acquisition is completely rewritten to be controller-based
// so this code looks a bit messy, as it's not conreoller-based
// start watching for maintenance service generated machine config
ctx, cancel := context.WithCancel(ctx)
defer cancel()
watchCh := make(chan state.Event)
if err := r.State().V1Alpha2().Resources().Watch(ctx, resourceconfig.NewMachineConfigWithID(nil, resourceconfig.MaintenanceID).Metadata(), watchCh); err != nil {
return nil, fmt.Errorf("failed to watch for maintenance service generated machine config: %w", err)
}
provider, err := configloader.NewFromBytes(cfgBytes)
if err != nil {
return nil, fmt.Errorf("failed to create config provider: %w", err)
// consume the first watch event, it's either Destroyed (if the config is missing), or Created (if the config is there from the previous run)
select {
case ev := <-watchCh:
switch ev.Type { //nolint:exhaustive
case state.Created, state.Destroyed:
// expected
case state.Errored:
return nil, fmt.Errorf("failed to watch for maintenance service generated machine config: %w", ev.Error)
default:
return nil, fmt.Errorf("unexpected event type: %v", ev.Type)
}
case <-ctx.Done():
return nil, ctx.Err()
}
warnings, err := provider.Validate(r.State().Platform().Mode())
for _, w := range warnings {
logger.Printf("WARNING:\n%s", w)
// create request for maintenance service
req := resourceruntime.NewMaintenanceServiceRequest()
if err := r.State().V1Alpha2().Resources().Create(ctx, req); err != nil {
return nil, fmt.Errorf("failed to create maintenance service request: %w", err)
}
if err != nil {
return nil, fmt.Errorf("failed to validate config: %w", err)
// wait for an update from the maintenance service
var processedBytes []byte
waitForConfig:
for {
select {
case ev := <-watchCh:
switch ev.Type { //nolint:exhaustive
case state.Created, state.Updated:
var err error
configContainer := ev.Resource.(*resourceconfig.MachineConfig).Container()
processedBytes, err = configContainer.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to get machine config bytes: %w", err)
}
// wait for v1alpha1 config to appear
// we should refactor this to do a proper check for "complete" config
if configContainer.RawV1Alpha1() != nil {
break waitForConfig
}
case state.Errored:
return nil, fmt.Errorf("failed to watch for maintenance service generated machine config: %w", ev.Error)
default:
return nil, fmt.Errorf("unexpected event type: %v", ev.Type)
}
case <-ctx.Done():
return nil, ctx.Err()
}
}
processedBytes, err := provider.Bytes()
if err != nil {
return nil, fmt.Errorf("failed to export validated config: %w", err)
// tear down and destroy the maintenance service
if _, err := r.State().V1Alpha2().Resources().Teardown(ctx, req.Metadata()); err != nil {
return nil, fmt.Errorf("failed to teardown maintenance service: %w", err)
}
if _, err := r.State().V1Alpha2().Resources().WatchFor(ctx, req.Metadata(), state.WithFinalizerEmpty()); err != nil {
return nil, fmt.Errorf("failed to watch for teardown of maintenance service: %w", err)
}
if err := r.State().V1Alpha2().Resources().Destroy(ctx, req.Metadata()); err != nil {
return nil, fmt.Errorf("failed to destroy maintenance service: %w", err)
}
return processedBytes, nil

View File

@ -252,6 +252,8 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
&runtimecontrollers.KmsgLogDeliveryController{
Drainer: drainer,
},
&runtimecontrollers.MaintenanceConfigController{},
&runtimecontrollers.MaintenanceServiceController{},
&runtimecontrollers.MachineStatusController{
V1Alpha1Events: ctrl.v1alpha1Runtime.Events(),
},
@ -265,6 +267,9 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
&secrets.KubernetesCertSANsController{},
&secrets.KubernetesDynamicCertsController{},
&secrets.KubernetesController{},
&secrets.MaintenanceController{},
&secrets.MaintenanceCertSANsController{},
&secrets.MaintenanceRootController{},
&secrets.RootController{},
&secrets.TrustdController{},
&siderolink.ConfigController{

View File

@ -177,6 +177,8 @@ func NewState() (*State, error) {
&runtime.KernelParamDefaultSpec{},
&runtime.KernelParamStatus{},
&runtime.KmsgLogConfig{},
&runtime.MaintenanceServiceConfig{},
&runtime.MaintenanceServiceRequest{},
&runtime.MachineStatus{},
&runtime.MetaKey{},
&runtime.MountStatus{},
@ -189,6 +191,8 @@ func NewState() (*State, error) {
&secrets.Kubernetes{},
&secrets.KubernetesDynamicCerts{},
&secrets.KubernetesRoot{},
&secrets.MaintenanceServiceCerts{},
&secrets.MaintenanceRoot{},
&secrets.OSRoot{},
&secrets.Trustd{},
&siderolink.Config{},

View File

@ -0,0 +1,14 @@
// 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 maintenance
import "github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
var runtimeController runtime.Controller
// InjectController is used to pass the controller into the maintenance service.
func InjectController(c runtime.Controller) {
runtimeController = c
}

View File

@ -1,245 +0,0 @@
// 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 maintenance
import (
"context"
"crypto/tls"
"fmt"
"log"
"net"
"net/netip"
"time"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/state"
ttls "github.com/siderolabs/crypto/tls"
"github.com/siderolabs/crypto/x509"
"github.com/siderolabs/gen/slices"
"github.com/siderolabs/gen/value"
"github.com/siderolabs/go-procfs/procfs"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
"github.com/siderolabs/talos/internal/app/maintenance/server"
"github.com/siderolabs/talos/pkg/grpc/factory"
"github.com/siderolabs/talos/pkg/grpc/gen"
"github.com/siderolabs/talos/pkg/grpc/middleware/authz"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
)
var ctrl runtime.Controller
// InjectController is used to pass the controller into the maintenance service.
func InjectController(c runtime.Controller) {
ctrl = c
}
// Run executes the configuration receiver, returning any configuration it receives.
//
//nolint:gocyclo
func Run(ctx context.Context, logger *log.Logger) ([]byte, error) {
if ctrl == nil {
return nil, fmt.Errorf("controller is not injected")
}
logger.Println("waiting for network address to be ready")
if err := network.NewReadyCondition(ctrl.Runtime().State().V1Alpha2().Resources(), network.AddressReady).Wait(ctx); err != nil {
return nil, fmt.Errorf("error waiting for the network to be ready: %w", err)
}
var sideroLinkAddress netip.Addr
currentAddresses, err := ctrl.Runtime().State().V1Alpha2().Resources().WatchFor(ctx,
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, network.NodeAddressCurrentID, resource.VersionUndefined),
sideroLinkAddressFinder(&sideroLinkAddress, logger),
)
if err != nil {
return nil, fmt.Errorf("error getting node addresses: %w", err)
}
ips := currentAddresses.(*network.NodeAddress).TypedSpec().IPs()
// hostname might not be available yet, so use it only if it is available
hostnameStatus, err := ctrl.Runtime().State().V1Alpha2().Resources().Get(ctx, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, network.HostnameID, resource.VersionUndefined))
if err != nil && !state.IsNotFoundError(err) {
return nil, fmt.Errorf("error getting node hostname: %w", err)
}
var dnsNames []string
if hostnameStatus != nil {
dnsNames = hostnameStatus.(*network.HostnameStatus).TypedSpec().DNSNames()
}
tlsConfig, provider, err := genTLSConfig(ips, dnsNames)
if err != nil {
return nil, err
}
cert, err := provider.GetCertificate(nil)
if err != nil {
return nil, err
}
certFingerprint, err := x509.SPKIFingerprintFromDER(cert.Certificate[0])
if err != nil {
return nil, err
}
cfgCh := make(chan []byte)
s := server.New(ctrl, logger, cfgCh)
injector := &authz.Injector{
Mode: authz.ReadOnly,
Logger: log.New(logger.Writer(), "machined/authz/injector ", log.Flags()).Printf,
}
// Start the server.
server := factory.NewServer(
s,
factory.WithDefaultLog(),
factory.ServerOptions(
grpc.Creds(
credentials.NewTLS(tlsConfig),
),
),
factory.WithUnaryInterceptor(injector.UnaryInterceptor()),
factory.WithStreamInterceptor(injector.StreamInterceptor()),
)
listener, err := factory.NewListener(factory.Address(formatIP(sideroLinkAddress)), factory.Port(constants.ApidPort))
if err != nil {
return nil, err
}
defer func() {
shutdownCtx, shutdownCancel := context.WithTimeout(ctx, 5*time.Second)
defer shutdownCancel()
factory.ServerGracefulStop(server, shutdownCtx)
}()
go func() {
//nolint:errcheck
server.Serve(listener)
}()
if !value.IsZero(sideroLinkAddress) {
ips = []netip.Addr{sideroLinkAddress}
}
logger.Println("this machine is reachable at:")
for _, ip := range ips {
logger.Printf("\t%s", ip.String())
}
firstIP := "<IP>"
if len(ips) > 0 {
firstIP = ips[0].String()
}
logger.Println("server certificate fingerprint:")
logger.Printf("\t%s", certFingerprint)
logger.Println()
logger.Println("upload configuration using talosctl:")
logger.Printf("\ttalosctl apply-config --insecure --nodes %s --file <config.yaml>", firstIP)
logger.Println("or apply configuration using talosctl interactive installer:")
logger.Printf("\ttalosctl apply-config --insecure --nodes %s --mode=interactive", firstIP)
logger.Println("optionally with node fingerprint check:")
logger.Printf("\ttalosctl apply-config --insecure --nodes %s --cert-fingerprint '%s' --file <config.yaml>", firstIP, certFingerprint)
select {
case cfg := <-cfgCh:
return cfg, nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func formatIP(addr netip.Addr) string {
if value.IsZero(addr) {
return ""
}
return addr.String()
}
func genTLSConfig(ips []netip.Addr, dnsNames []string) (tlsConfig *tls.Config, provider ttls.CertificateProvider, err error) {
ca, err := x509.NewSelfSignedCertificateAuthority()
if err != nil {
return nil, nil, fmt.Errorf("failed to generate self-signed CA: %w", err)
}
ips = append(ips, netip.MustParseAddr("127.0.0.1"), netip.MustParseAddr("::1"))
netIPs := slices.Map(ips, func(ip netip.Addr) net.IP { return ip.AsSlice() })
var generator ttls.Generator
generator, err = gen.NewLocalGenerator(ca.KeyPEM, ca.CrtPEM)
if err != nil {
return nil, nil, fmt.Errorf("failed to create local generator provider: %w", err)
}
provider, err = ttls.NewRenewingCertificateProvider(generator, x509.DNSNames(dnsNames), x509.IPAddresses(netIPs))
if err != nil {
return nil, nil, fmt.Errorf("failed to create local certificate provider: %w", err)
}
caCertPEM, err := provider.GetCA()
if err != nil {
return nil, nil, fmt.Errorf("failed to get CA: %w", err)
}
tlsConfig, err = ttls.New(
ttls.WithClientAuthType(ttls.ServerOnly),
ttls.WithCACertPEM(caCertPEM),
ttls.WithServerCertificateProvider(provider),
)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate tlsconfig: %w", err)
}
return tlsConfig, provider, nil
}
func sideroLinkAddressFinder(address *netip.Addr, logger *log.Logger) state.WatchForConditionFunc {
sideroLinkEnabled := false
if procfs.ProcCmdline().Get(constants.KernelParamSideroLink).First() != nil {
sideroLinkEnabled = true
logger.Println(constants.KernelParamSideroLink + " is enabled, waiting for address")
}
return state.WithCondition(func(r resource.Resource) (bool, error) {
if resource.IsTombstone(r) {
return false, nil
}
if !sideroLinkEnabled {
return true, nil
}
ips := r.(*network.NodeAddress).TypedSpec().IPs()
for _, ip := range ips {
if network.IsULA(ip, network.ULASideroLink) {
*address = ip
return true, nil
}
}
return false, nil
})
}

View File

@ -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 server
package maintenance
import (
"context"

View File

@ -0,0 +1,62 @@
// 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 maintenance
import (
stdlibtls "crypto/tls"
"fmt"
"sync/atomic"
"github.com/siderolabs/crypto/tls"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
// NewTLSProvider creates a new TLS provider for maintenance service.
//
// The provider expects that the certificates are pushed to it.
func NewTLSProvider() *TLSProvider {
return &TLSProvider{}
}
// TLSProvider provides TLS configuration for maintenance service.
type TLSProvider struct {
serverCert atomic.Pointer[stdlibtls.Certificate]
}
// TLSConfig generates server-side tls.Config.
func (provider *TLSProvider) TLSConfig() (*stdlibtls.Config, error) {
return tls.New(
tls.WithClientAuthType(tls.ServerOnly),
tls.WithServerCertificateProvider(provider),
)
}
// Update the certificate in the provider.
func (provider *TLSProvider) Update(maintenanceCerts *secrets.MaintenanceServiceCerts) error {
serverCert, err := stdlibtls.X509KeyPair(maintenanceCerts.TypedSpec().Server.Crt, maintenanceCerts.TypedSpec().Server.Key)
if err != nil {
return fmt.Errorf("failed to parse server cert and key into a TLS Certificate: %w", err)
}
provider.serverCert.Store(&serverCert)
return nil
}
// GetCA implements tls.CertificateProvider interface.
func (provider *TLSProvider) GetCA() ([]byte, error) {
return nil, nil
}
// GetCertificate implements tls.CertificateProvider interface.
func (provider *TLSProvider) GetCertificate(h *stdlibtls.ClientHelloInfo) (*stdlibtls.Certificate, error) {
return provider.serverCert.Load(), nil
}
// GetClientCertificate implements tls.CertificateProvider interface.
func (provider *TLSProvider) GetClientCertificate(*stdlibtls.CertificateRequestInfo) (*stdlibtls.Certificate, error) {
return nil, nil
}

View File

@ -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 server
package maintenance
import (
"context"
@ -27,6 +27,7 @@ import (
"github.com/siderolabs/talos/internal/pkg/configuration"
"github.com/siderolabs/talos/pkg/machinery/api/machine"
"github.com/siderolabs/talos/pkg/machinery/api/storage"
"github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/config/configloader"
v1alpha1machine "github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/constants"
@ -38,16 +39,18 @@ type Server struct {
machine.UnimplementedMachineServiceServer
controller runtime.Controller
logger *log.Logger
cfgCh chan<- []byte
cfgCh chan<- config.Provider
server *grpc.Server
}
// New initializes and returns a `Server`.
func New(c runtime.Controller, logger *log.Logger, cfgCh chan<- []byte) *Server {
func New(cfgCh chan<- config.Provider) *Server {
if runtimeController == nil {
panic("runtime controller is not set")
}
return &Server{
controller: c,
logger: logger,
controller: runtimeController,
cfgCh: cfgCh,
}
}
@ -104,7 +107,7 @@ Node is running in maintenance mode and does not have a config yet.`
return reply, nil
}
s.cfgCh <- in.GetData()
s.cfgCh <- cfgProvider
return reply, nil
}

View File

@ -456,6 +456,62 @@ func (x *MachineStatusStatus) GetUnmetConditions() []*UnmetCondition {
return nil
}
// MaintenanceServiceConfigSpec describes configuration for maintenance service API.
type MaintenanceServiceConfigSpec struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
ListenAddress string `protobuf:"bytes,1,opt,name=listen_address,json=listenAddress,proto3" json:"listen_address,omitempty"`
ReachableAddresses []*common.NetIP `protobuf:"bytes,2,rep,name=reachable_addresses,json=reachableAddresses,proto3" json:"reachable_addresses,omitempty"`
}
func (x *MaintenanceServiceConfigSpec) Reset() {
*x = MaintenanceServiceConfigSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MaintenanceServiceConfigSpec) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MaintenanceServiceConfigSpec) ProtoMessage() {}
func (x *MaintenanceServiceConfigSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MaintenanceServiceConfigSpec.ProtoReflect.Descriptor instead.
func (*MaintenanceServiceConfigSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{8}
}
func (x *MaintenanceServiceConfigSpec) GetListenAddress() string {
if x != nil {
return x.ListenAddress
}
return ""
}
func (x *MaintenanceServiceConfigSpec) GetReachableAddresses() []*common.NetIP {
if x != nil {
return x.ReachableAddresses
}
return nil
}
// MetaKeySpec describes status of the defined sysctls.
type MetaKeySpec struct {
state protoimpl.MessageState
@ -468,7 +524,7 @@ type MetaKeySpec struct {
func (x *MetaKeySpec) Reset() {
*x = MetaKeySpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -481,7 +537,7 @@ func (x *MetaKeySpec) String() string {
func (*MetaKeySpec) ProtoMessage() {}
func (x *MetaKeySpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[8]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -494,7 +550,7 @@ func (x *MetaKeySpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use MetaKeySpec.ProtoReflect.Descriptor instead.
func (*MetaKeySpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{8}
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{9}
}
func (x *MetaKeySpec) GetValue() string {
@ -520,7 +576,7 @@ type MountStatusSpec struct {
func (x *MountStatusSpec) Reset() {
*x = MountStatusSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -533,7 +589,7 @@ func (x *MountStatusSpec) String() string {
func (*MountStatusSpec) ProtoMessage() {}
func (x *MountStatusSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[9]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -546,7 +602,7 @@ func (x *MountStatusSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use MountStatusSpec.ProtoReflect.Descriptor instead.
func (*MountStatusSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{9}
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{10}
}
func (x *MountStatusSpec) GetSource() string {
@ -603,7 +659,7 @@ type PlatformMetadataSpec struct {
func (x *PlatformMetadataSpec) Reset() {
*x = PlatformMetadataSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -616,7 +672,7 @@ func (x *PlatformMetadataSpec) String() string {
func (*PlatformMetadataSpec) ProtoMessage() {}
func (x *PlatformMetadataSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[10]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -629,7 +685,7 @@ func (x *PlatformMetadataSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use PlatformMetadataSpec.ProtoReflect.Descriptor instead.
func (*PlatformMetadataSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{10}
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{11}
}
func (x *PlatformMetadataSpec) GetPlatform() string {
@ -701,7 +757,7 @@ type UnmetCondition struct {
func (x *UnmetCondition) Reset() {
*x = UnmetCondition{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -714,7 +770,7 @@ func (x *UnmetCondition) String() string {
func (*UnmetCondition) ProtoMessage() {}
func (x *UnmetCondition) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[11]
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -727,7 +783,7 @@ func (x *UnmetCondition) ProtoReflect() protoreflect.Message {
// Deprecated: Use UnmetCondition.ProtoReflect.Descriptor instead.
func (*UnmetCondition) Descriptor() ([]byte, []int) {
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{11}
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12}
}
func (x *UnmetCondition) GetName() string {
@ -803,44 +859,52 @@ var file_resource_definitions_runtime_runtime_proto_rawDesc = []byte{
0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e,
0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f,
0x75, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
0x23, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x22, 0xa2, 0x01, 0x0a, 0x0f, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65,
0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70,
0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03,
0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x65,
0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,
0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x22, 0xf5, 0x01, 0x0a, 0x14, 0x50, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x70,
0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1a,
0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65,
0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69,
0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69,
0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69,
0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b,
0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a,
0x04, 0x73, 0x70, 0x6f, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f,
0x74, 0x22, 0x3c, 0x0a, 0x0e, 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f,
0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42,
0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69,
0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70,
0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x85, 0x01, 0x0a, 0x1c, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x70, 0x65, 0x63,
0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, 0x13, 0x72, 0x65, 0x61, 0x63, 0x68,
0x61, 0x62, 0x6c, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65,
0x74, 0x49, 0x50, 0x52, 0x12, 0x72, 0x65, 0x61, 0x63, 0x68, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x64,
0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x0b, 0x4d, 0x65, 0x74, 0x61, 0x4b,
0x65, 0x79, 0x53, 0x70, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xa2, 0x01, 0x0a,
0x0f, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67,
0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74,
0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x69, 0x6c, 0x65, 0x73,
0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65,
0x64, 0x22, 0xf5, 0x01, 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c,
0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61,
0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x7a, 0x6f,
0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x23,
0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x54,
0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
0x63, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69,
0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x18, 0x08, 0x20,
0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x22, 0x3c, 0x0a, 0x0e, 0x55, 0x6e, 0x6d,
0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73,
0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69,
0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x75,
0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -855,33 +919,36 @@ func file_resource_definitions_runtime_runtime_proto_rawDescGZIP() []byte {
return file_resource_definitions_runtime_runtime_proto_rawDescData
}
var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
var file_resource_definitions_runtime_runtime_proto_goTypes = []interface{}{
(*DevicesStatusSpec)(nil), // 0: talos.resource.definitions.runtime.DevicesStatusSpec
(*EventSinkConfigSpec)(nil), // 1: talos.resource.definitions.runtime.EventSinkConfigSpec
(*KernelModuleSpecSpec)(nil), // 2: talos.resource.definitions.runtime.KernelModuleSpecSpec
(*KernelParamSpecSpec)(nil), // 3: talos.resource.definitions.runtime.KernelParamSpecSpec
(*KernelParamStatusSpec)(nil), // 4: talos.resource.definitions.runtime.KernelParamStatusSpec
(*KmsgLogConfigSpec)(nil), // 5: talos.resource.definitions.runtime.KmsgLogConfigSpec
(*MachineStatusSpec)(nil), // 6: talos.resource.definitions.runtime.MachineStatusSpec
(*MachineStatusStatus)(nil), // 7: talos.resource.definitions.runtime.MachineStatusStatus
(*MetaKeySpec)(nil), // 8: talos.resource.definitions.runtime.MetaKeySpec
(*MountStatusSpec)(nil), // 9: talos.resource.definitions.runtime.MountStatusSpec
(*PlatformMetadataSpec)(nil), // 10: talos.resource.definitions.runtime.PlatformMetadataSpec
(*UnmetCondition)(nil), // 11: talos.resource.definitions.runtime.UnmetCondition
(*common.URL)(nil), // 12: common.URL
(enums.RuntimeMachineStage)(0), // 13: talos.resource.definitions.enums.RuntimeMachineStage
(*DevicesStatusSpec)(nil), // 0: talos.resource.definitions.runtime.DevicesStatusSpec
(*EventSinkConfigSpec)(nil), // 1: talos.resource.definitions.runtime.EventSinkConfigSpec
(*KernelModuleSpecSpec)(nil), // 2: talos.resource.definitions.runtime.KernelModuleSpecSpec
(*KernelParamSpecSpec)(nil), // 3: talos.resource.definitions.runtime.KernelParamSpecSpec
(*KernelParamStatusSpec)(nil), // 4: talos.resource.definitions.runtime.KernelParamStatusSpec
(*KmsgLogConfigSpec)(nil), // 5: talos.resource.definitions.runtime.KmsgLogConfigSpec
(*MachineStatusSpec)(nil), // 6: talos.resource.definitions.runtime.MachineStatusSpec
(*MachineStatusStatus)(nil), // 7: talos.resource.definitions.runtime.MachineStatusStatus
(*MaintenanceServiceConfigSpec)(nil), // 8: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec
(*MetaKeySpec)(nil), // 9: talos.resource.definitions.runtime.MetaKeySpec
(*MountStatusSpec)(nil), // 10: talos.resource.definitions.runtime.MountStatusSpec
(*PlatformMetadataSpec)(nil), // 11: talos.resource.definitions.runtime.PlatformMetadataSpec
(*UnmetCondition)(nil), // 12: talos.resource.definitions.runtime.UnmetCondition
(*common.URL)(nil), // 13: common.URL
(enums.RuntimeMachineStage)(0), // 14: talos.resource.definitions.enums.RuntimeMachineStage
(*common.NetIP)(nil), // 15: common.NetIP
}
var file_resource_definitions_runtime_runtime_proto_depIdxs = []int32{
12, // 0: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL
13, // 1: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage
13, // 0: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL
14, // 1: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage
7, // 2: talos.resource.definitions.runtime.MachineStatusSpec.status:type_name -> talos.resource.definitions.runtime.MachineStatusStatus
11, // 3: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
12, // 3: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition
15, // 4: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_resource_definitions_runtime_runtime_proto_init() }
@ -987,7 +1054,7 @@ func file_resource_definitions_runtime_runtime_proto_init() {
}
}
file_resource_definitions_runtime_runtime_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MetaKeySpec); i {
switch v := v.(*MaintenanceServiceConfigSpec); i {
case 0:
return &v.state
case 1:
@ -999,7 +1066,7 @@ func file_resource_definitions_runtime_runtime_proto_init() {
}
}
file_resource_definitions_runtime_runtime_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MountStatusSpec); i {
switch v := v.(*MetaKeySpec); i {
case 0:
return &v.state
case 1:
@ -1011,7 +1078,7 @@ func file_resource_definitions_runtime_runtime_proto_init() {
}
}
file_resource_definitions_runtime_runtime_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PlatformMetadataSpec); i {
switch v := v.(*MountStatusSpec); i {
case 0:
return &v.state
case 1:
@ -1023,6 +1090,18 @@ func file_resource_definitions_runtime_runtime_proto_init() {
}
}
file_resource_definitions_runtime_runtime_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PlatformMetadataSpec); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_resource_definitions_runtime_runtime_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UnmetCondition); i {
case 0:
return &v.state
@ -1041,7 +1120,7 @@ func file_resource_definitions_runtime_runtime_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_resource_definitions_runtime_runtime_proto_rawDesc,
NumEnums: 0,
NumMessages: 12,
NumMessages: 13,
NumExtensions: 0,
NumServices: 0,
},

View File

@ -422,6 +422,70 @@ func (m *MachineStatusStatus) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *MaintenanceServiceConfigSpec) 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 *MaintenanceServiceConfigSpec) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *MaintenanceServiceConfigSpec) 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 len(m.ReachableAddresses) > 0 {
for iNdEx := len(m.ReachableAddresses) - 1; iNdEx >= 0; iNdEx-- {
if vtmsg, ok := interface{}(m.ReachableAddresses[iNdEx]).(interface {
MarshalToSizedBufferVT([]byte) (int, error)
}); ok {
size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarint(dAtA, i, uint64(size))
} else {
encoded, err := proto.Marshal(m.ReachableAddresses[iNdEx])
if err != nil {
return 0, err
}
i -= len(encoded)
copy(dAtA[i:], encoded)
i = encodeVarint(dAtA, i, uint64(len(encoded)))
}
i--
dAtA[i] = 0x12
}
}
if len(m.ListenAddress) > 0 {
i -= len(m.ListenAddress)
copy(dAtA[i:], m.ListenAddress)
i = encodeVarint(dAtA, i, uint64(len(m.ListenAddress)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *MetaKeySpec) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
@ -828,6 +892,32 @@ func (m *MachineStatusStatus) SizeVT() (n int) {
return n
}
func (m *MaintenanceServiceConfigSpec) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.ListenAddress)
if l > 0 {
n += 1 + l + sov(uint64(l))
}
if len(m.ReachableAddresses) > 0 {
for _, e := range m.ReachableAddresses {
if size, ok := interface{}(e).(interface {
SizeVT() int
}); ok {
l = size.SizeVT()
} else {
l = proto.Size(e)
}
n += 1 + l + sov(uint64(l))
}
}
n += len(m.unknownFields)
return n
}
func (m *MetaKeySpec) SizeVT() (n int) {
if m == nil {
return 0
@ -1749,6 +1839,131 @@ func (m *MachineStatusStatus) UnmarshalVT(dAtA []byte) error {
}
return nil
}
func (m *MaintenanceServiceConfigSpec) 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 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: MaintenanceServiceConfigSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MaintenanceServiceConfigSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ListenAddress", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ListenAddress = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ReachableAddresses", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ReachableAddresses = append(m.ReachableAddresses, &common.NetIP{})
if unmarshal, ok := interface{}(m.ReachableAddresses[len(m.ReachableAddresses)-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.ReachableAddresses[len(m.ReachableAddresses)-1]); err != nil {
return err
}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return 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 *MetaKeySpec) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@ -623,6 +623,110 @@ func (x *KubernetesRootSpec) GetApiServerIps() []*common.NetIP {
return nil
}
// MaintenanceRootSpec describes maintenance service CA.
type MaintenanceRootSpec struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ca *common.PEMEncodedCertificateAndKey `protobuf:"bytes,1,opt,name=ca,proto3" json:"ca,omitempty"`
}
func (x *MaintenanceRootSpec) Reset() {
*x = MaintenanceRootSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MaintenanceRootSpec) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MaintenanceRootSpec) ProtoMessage() {}
func (x *MaintenanceRootSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MaintenanceRootSpec.ProtoReflect.Descriptor instead.
func (*MaintenanceRootSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_secrets_secrets_proto_rawDescGZIP(), []int{8}
}
func (x *MaintenanceRootSpec) GetCa() *common.PEMEncodedCertificateAndKey {
if x != nil {
return x.Ca
}
return nil
}
// MaintenanceServiceCertsSpec describes maintenance service certs secrets.
type MaintenanceServiceCertsSpec struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ca *common.PEMEncodedCertificateAndKey `protobuf:"bytes,1,opt,name=ca,proto3" json:"ca,omitempty"`
Server *common.PEMEncodedCertificateAndKey `protobuf:"bytes,2,opt,name=server,proto3" json:"server,omitempty"`
}
func (x *MaintenanceServiceCertsSpec) Reset() {
*x = MaintenanceServiceCertsSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *MaintenanceServiceCertsSpec) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*MaintenanceServiceCertsSpec) ProtoMessage() {}
func (x *MaintenanceServiceCertsSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use MaintenanceServiceCertsSpec.ProtoReflect.Descriptor instead.
func (*MaintenanceServiceCertsSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_secrets_secrets_proto_rawDescGZIP(), []int{9}
}
func (x *MaintenanceServiceCertsSpec) GetCa() *common.PEMEncodedCertificateAndKey {
if x != nil {
return x.Ca
}
return nil
}
func (x *MaintenanceServiceCertsSpec) GetServer() *common.PEMEncodedCertificateAndKey {
if x != nil {
return x.Server
}
return nil
}
// OSRootSpec describes operating system CA.
type OSRootSpec struct {
state protoimpl.MessageState
@ -638,7 +742,7 @@ type OSRootSpec struct {
func (x *OSRootSpec) Reset() {
*x = OSRootSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[8]
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -651,7 +755,7 @@ func (x *OSRootSpec) String() string {
func (*OSRootSpec) ProtoMessage() {}
func (x *OSRootSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[8]
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -664,7 +768,7 @@ func (x *OSRootSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use OSRootSpec.ProtoReflect.Descriptor instead.
func (*OSRootSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_secrets_secrets_proto_rawDescGZIP(), []int{8}
return file_resource_definitions_secrets_secrets_proto_rawDescGZIP(), []int{10}
}
func (x *OSRootSpec) GetCa() *common.PEMEncodedCertificateAndKey {
@ -708,7 +812,7 @@ type TrustdCertsSpec struct {
func (x *TrustdCertsSpec) Reset() {
*x = TrustdCertsSpec{}
if protoimpl.UnsafeEnabled {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[9]
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -721,7 +825,7 @@ func (x *TrustdCertsSpec) String() string {
func (*TrustdCertsSpec) ProtoMessage() {}
func (x *TrustdCertsSpec) ProtoReflect() protoreflect.Message {
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[9]
mi := &file_resource_definitions_secrets_secrets_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -734,7 +838,7 @@ func (x *TrustdCertsSpec) ProtoReflect() protoreflect.Message {
// Deprecated: Use TrustdCertsSpec.ProtoReflect.Descriptor instead.
func (*TrustdCertsSpec) Descriptor() ([]byte, []int) {
return file_resource_definitions_secrets_secrets_proto_rawDescGZIP(), []int{9}
return file_resource_definitions_secrets_secrets_proto_rawDescGZIP(), []int{11}
}
func (x *TrustdCertsSpec) GetCa() *common.PEMEncodedCertificateAndKey {
@ -887,32 +991,46 @@ var file_resource_definitions_secrets_secrets_proto_rawDesc = []byte{
0x6f, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x0e, 0x61, 0x70, 0x69, 0x5f,
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x70, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52,
0x0c, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x70, 0x73, 0x22, 0xb4, 0x01,
0x0a, 0x0a, 0x4f, 0x53, 0x52, 0x6f, 0x6f, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x33, 0x0a, 0x02,
0x63, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
0x6e, 0x2e, 0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x02, 0x63,
0x61, 0x12, 0x2f, 0x0a, 0x0c, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6e, 0x69, 0x5f, 0x70,
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e,
0x2e, 0x4e, 0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x63, 0x65, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x69,
0x50, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x6e,
0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x63,
0x65, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x14,
0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x64, 0x43,
0x65, 0x72, 0x74, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x33, 0x0a, 0x02, 0x63, 0x61, 0x18, 0x01,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x45,
0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x02, 0x63, 0x61, 0x12, 0x3b, 0x0a,
0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b,
0x65, 0x79, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c,
0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61,
0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x2f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x0c, 0x61, 0x70, 0x69, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x49, 0x70, 0x73, 0x22, 0x4a, 0x0a,
0x13, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x6f, 0x6f, 0x74,
0x53, 0x70, 0x65, 0x63, 0x12, 0x33, 0x0a, 0x02, 0x63, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63,
0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41,
0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x02, 0x63, 0x61, 0x22, 0x8f, 0x01, 0x0a, 0x1b, 0x4d, 0x61,
0x69, 0x6e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
0x43, 0x65, 0x72, 0x74, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x33, 0x0a, 0x02, 0x63, 0x61, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50,
0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x02, 0x63, 0x61, 0x12, 0x3b,
0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64,
0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64,
0x4b, 0x65, 0x79, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xb4, 0x01, 0x0a, 0x0a,
0x4f, 0x53, 0x52, 0x6f, 0x6f, 0x74, 0x53, 0x70, 0x65, 0x63, 0x12, 0x33, 0x0a, 0x02, 0x63, 0x61,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66,
0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x02, 0x63, 0x61, 0x12,
0x2f, 0x0a, 0x0c, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6e, 0x69, 0x5f, 0x70, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4e,
0x65, 0x74, 0x49, 0x50, 0x52, 0x0a, 0x63, 0x65, 0x72, 0x74, 0x53, 0x61, 0x6e, 0x69, 0x50, 0x73,
0x12, 0x2a, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x6e, 0x73, 0x5f,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x65, 0x72,
0x74, 0x53, 0x61, 0x6e, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05,
0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x22, 0x83, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x64, 0x43, 0x65, 0x72,
0x74, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x33, 0x0a, 0x02, 0x63, 0x61, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x45, 0x4d, 0x45,
0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x02, 0x63, 0x61, 0x12, 0x3b, 0x0a, 0x06, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x45, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43,
0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x4b, 0x65, 0x79,
0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62,
0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68,
0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73,
0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -927,7 +1045,7 @@ func file_resource_definitions_secrets_secrets_proto_rawDescGZIP() []byte {
return file_resource_definitions_secrets_secrets_proto_rawDescData
}
var file_resource_definitions_secrets_secrets_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_resource_definitions_secrets_secrets_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
var file_resource_definitions_secrets_secrets_proto_goTypes = []interface{}{
(*APICertsSpec)(nil), // 0: talos.resource.definitions.secrets.APICertsSpec
(*CertSANSpec)(nil), // 1: talos.resource.definitions.secrets.CertSANSpec
@ -937,43 +1055,48 @@ var file_resource_definitions_secrets_secrets_proto_goTypes = []interface{}{
(*KubernetesCertsSpec)(nil), // 5: talos.resource.definitions.secrets.KubernetesCertsSpec
(*KubernetesDynamicCertsSpec)(nil), // 6: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec
(*KubernetesRootSpec)(nil), // 7: talos.resource.definitions.secrets.KubernetesRootSpec
(*OSRootSpec)(nil), // 8: talos.resource.definitions.secrets.OSRootSpec
(*TrustdCertsSpec)(nil), // 9: talos.resource.definitions.secrets.TrustdCertsSpec
(*common.PEMEncodedCertificateAndKey)(nil), // 10: common.PEMEncodedCertificateAndKey
(*common.NetIP)(nil), // 11: common.NetIP
(*common.URL)(nil), // 12: common.URL
(*common.PEMEncodedKey)(nil), // 13: common.PEMEncodedKey
(*MaintenanceRootSpec)(nil), // 8: talos.resource.definitions.secrets.MaintenanceRootSpec
(*MaintenanceServiceCertsSpec)(nil), // 9: talos.resource.definitions.secrets.MaintenanceServiceCertsSpec
(*OSRootSpec)(nil), // 10: talos.resource.definitions.secrets.OSRootSpec
(*TrustdCertsSpec)(nil), // 11: talos.resource.definitions.secrets.TrustdCertsSpec
(*common.PEMEncodedCertificateAndKey)(nil), // 12: common.PEMEncodedCertificateAndKey
(*common.NetIP)(nil), // 13: common.NetIP
(*common.URL)(nil), // 14: common.URL
(*common.PEMEncodedKey)(nil), // 15: common.PEMEncodedKey
}
var file_resource_definitions_secrets_secrets_proto_depIdxs = []int32{
10, // 0: talos.resource.definitions.secrets.APICertsSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
10, // 1: talos.resource.definitions.secrets.APICertsSpec.client:type_name -> common.PEMEncodedCertificateAndKey
10, // 2: talos.resource.definitions.secrets.APICertsSpec.server:type_name -> common.PEMEncodedCertificateAndKey
11, // 3: talos.resource.definitions.secrets.CertSANSpec.i_ps:type_name -> common.NetIP
10, // 4: talos.resource.definitions.secrets.EtcdCertsSpec.etcd:type_name -> common.PEMEncodedCertificateAndKey
10, // 5: talos.resource.definitions.secrets.EtcdCertsSpec.etcd_peer:type_name -> common.PEMEncodedCertificateAndKey
10, // 6: talos.resource.definitions.secrets.EtcdCertsSpec.etcd_admin:type_name -> common.PEMEncodedCertificateAndKey
10, // 7: talos.resource.definitions.secrets.EtcdCertsSpec.etcd_api_server:type_name -> common.PEMEncodedCertificateAndKey
10, // 8: talos.resource.definitions.secrets.EtcdRootSpec.etcd_ca:type_name -> common.PEMEncodedCertificateAndKey
12, // 9: talos.resource.definitions.secrets.KubeletSpec.endpoint:type_name -> common.URL
10, // 10: talos.resource.definitions.secrets.KubeletSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
10, // 11: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec.api_server:type_name -> common.PEMEncodedCertificateAndKey
10, // 12: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec.api_server_kubelet_client:type_name -> common.PEMEncodedCertificateAndKey
10, // 13: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec.front_proxy:type_name -> common.PEMEncodedCertificateAndKey
12, // 14: talos.resource.definitions.secrets.KubernetesRootSpec.endpoint:type_name -> common.URL
12, // 15: talos.resource.definitions.secrets.KubernetesRootSpec.local_endpoint:type_name -> common.URL
10, // 16: talos.resource.definitions.secrets.KubernetesRootSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
13, // 17: talos.resource.definitions.secrets.KubernetesRootSpec.service_account:type_name -> common.PEMEncodedKey
10, // 18: talos.resource.definitions.secrets.KubernetesRootSpec.aggregator_ca:type_name -> common.PEMEncodedCertificateAndKey
11, // 19: talos.resource.definitions.secrets.KubernetesRootSpec.api_server_ips:type_name -> common.NetIP
10, // 20: talos.resource.definitions.secrets.OSRootSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
11, // 21: talos.resource.definitions.secrets.OSRootSpec.cert_sani_ps:type_name -> common.NetIP
10, // 22: talos.resource.definitions.secrets.TrustdCertsSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
10, // 23: talos.resource.definitions.secrets.TrustdCertsSpec.server:type_name -> common.PEMEncodedCertificateAndKey
24, // [24:24] is the sub-list for method output_type
24, // [24:24] is the sub-list for method input_type
24, // [24:24] is the sub-list for extension type_name
24, // [24:24] is the sub-list for extension extendee
0, // [0:24] is the sub-list for field type_name
12, // 0: talos.resource.definitions.secrets.APICertsSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
12, // 1: talos.resource.definitions.secrets.APICertsSpec.client:type_name -> common.PEMEncodedCertificateAndKey
12, // 2: talos.resource.definitions.secrets.APICertsSpec.server:type_name -> common.PEMEncodedCertificateAndKey
13, // 3: talos.resource.definitions.secrets.CertSANSpec.i_ps:type_name -> common.NetIP
12, // 4: talos.resource.definitions.secrets.EtcdCertsSpec.etcd:type_name -> common.PEMEncodedCertificateAndKey
12, // 5: talos.resource.definitions.secrets.EtcdCertsSpec.etcd_peer:type_name -> common.PEMEncodedCertificateAndKey
12, // 6: talos.resource.definitions.secrets.EtcdCertsSpec.etcd_admin:type_name -> common.PEMEncodedCertificateAndKey
12, // 7: talos.resource.definitions.secrets.EtcdCertsSpec.etcd_api_server:type_name -> common.PEMEncodedCertificateAndKey
12, // 8: talos.resource.definitions.secrets.EtcdRootSpec.etcd_ca:type_name -> common.PEMEncodedCertificateAndKey
14, // 9: talos.resource.definitions.secrets.KubeletSpec.endpoint:type_name -> common.URL
12, // 10: talos.resource.definitions.secrets.KubeletSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
12, // 11: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec.api_server:type_name -> common.PEMEncodedCertificateAndKey
12, // 12: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec.api_server_kubelet_client:type_name -> common.PEMEncodedCertificateAndKey
12, // 13: talos.resource.definitions.secrets.KubernetesDynamicCertsSpec.front_proxy:type_name -> common.PEMEncodedCertificateAndKey
14, // 14: talos.resource.definitions.secrets.KubernetesRootSpec.endpoint:type_name -> common.URL
14, // 15: talos.resource.definitions.secrets.KubernetesRootSpec.local_endpoint:type_name -> common.URL
12, // 16: talos.resource.definitions.secrets.KubernetesRootSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
15, // 17: talos.resource.definitions.secrets.KubernetesRootSpec.service_account:type_name -> common.PEMEncodedKey
12, // 18: talos.resource.definitions.secrets.KubernetesRootSpec.aggregator_ca:type_name -> common.PEMEncodedCertificateAndKey
13, // 19: talos.resource.definitions.secrets.KubernetesRootSpec.api_server_ips:type_name -> common.NetIP
12, // 20: talos.resource.definitions.secrets.MaintenanceRootSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
12, // 21: talos.resource.definitions.secrets.MaintenanceServiceCertsSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
12, // 22: talos.resource.definitions.secrets.MaintenanceServiceCertsSpec.server:type_name -> common.PEMEncodedCertificateAndKey
12, // 23: talos.resource.definitions.secrets.OSRootSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
13, // 24: talos.resource.definitions.secrets.OSRootSpec.cert_sani_ps:type_name -> common.NetIP
12, // 25: talos.resource.definitions.secrets.TrustdCertsSpec.ca:type_name -> common.PEMEncodedCertificateAndKey
12, // 26: talos.resource.definitions.secrets.TrustdCertsSpec.server:type_name -> common.PEMEncodedCertificateAndKey
27, // [27:27] is the sub-list for method output_type
27, // [27:27] is the sub-list for method input_type
27, // [27:27] is the sub-list for extension type_name
27, // [27:27] is the sub-list for extension extendee
0, // [0:27] is the sub-list for field type_name
}
func init() { file_resource_definitions_secrets_secrets_proto_init() }
@ -1079,7 +1202,7 @@ func file_resource_definitions_secrets_secrets_proto_init() {
}
}
file_resource_definitions_secrets_secrets_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OSRootSpec); i {
switch v := v.(*MaintenanceRootSpec); i {
case 0:
return &v.state
case 1:
@ -1091,6 +1214,30 @@ func file_resource_definitions_secrets_secrets_proto_init() {
}
}
file_resource_definitions_secrets_secrets_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*MaintenanceServiceCertsSpec); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_resource_definitions_secrets_secrets_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OSRootSpec); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_resource_definitions_secrets_secrets_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TrustdCertsSpec); i {
case 0:
return &v.state
@ -1109,7 +1256,7 @@ func file_resource_definitions_secrets_secrets_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_resource_definitions_secrets_secrets_proto_rawDesc,
NumEnums: 0,
NumMessages: 10,
NumMessages: 12,
NumExtensions: 0,
NumServices: 0,
},

View File

@ -839,6 +839,138 @@ func (m *KubernetesRootSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *MaintenanceRootSpec) 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 *MaintenanceRootSpec) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *MaintenanceRootSpec) 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.Ca != nil {
if vtmsg, ok := interface{}(m.Ca).(interface {
MarshalToSizedBufferVT([]byte) (int, error)
}); ok {
size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarint(dAtA, i, uint64(size))
} else {
encoded, err := proto.Marshal(m.Ca)
if err != nil {
return 0, err
}
i -= len(encoded)
copy(dAtA[i:], encoded)
i = encodeVarint(dAtA, i, uint64(len(encoded)))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *MaintenanceServiceCertsSpec) 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 *MaintenanceServiceCertsSpec) MarshalToVT(dAtA []byte) (int, error) {
size := m.SizeVT()
return m.MarshalToSizedBufferVT(dAtA[:size])
}
func (m *MaintenanceServiceCertsSpec) 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.Server != nil {
if vtmsg, ok := interface{}(m.Server).(interface {
MarshalToSizedBufferVT([]byte) (int, error)
}); ok {
size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarint(dAtA, i, uint64(size))
} else {
encoded, err := proto.Marshal(m.Server)
if err != nil {
return 0, err
}
i -= len(encoded)
copy(dAtA[i:], encoded)
i = encodeVarint(dAtA, i, uint64(len(encoded)))
}
i--
dAtA[i] = 0x12
}
if m.Ca != nil {
if vtmsg, ok := interface{}(m.Ca).(interface {
MarshalToSizedBufferVT([]byte) (int, error)
}); ok {
size, err := vtmsg.MarshalToSizedBufferVT(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarint(dAtA, i, uint64(size))
} else {
encoded, err := proto.Marshal(m.Ca)
if err != nil {
return 0, err
}
i -= len(encoded)
copy(dAtA[i:], encoded)
i = encodeVarint(dAtA, i, uint64(len(encoded)))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *OSRootSpec) MarshalVT() (dAtA []byte, err error) {
if m == nil {
return nil, nil
@ -1370,6 +1502,56 @@ func (m *KubernetesRootSpec) SizeVT() (n int) {
return n
}
func (m *MaintenanceRootSpec) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Ca != nil {
if size, ok := interface{}(m.Ca).(interface {
SizeVT() int
}); ok {
l = size.SizeVT()
} else {
l = proto.Size(m.Ca)
}
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func (m *MaintenanceServiceCertsSpec) SizeVT() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Ca != nil {
if size, ok := interface{}(m.Ca).(interface {
SizeVT() int
}); ok {
l = size.SizeVT()
} else {
l = proto.Size(m.Ca)
}
n += 1 + l + sov(uint64(l))
}
if m.Server != nil {
if size, ok := interface{}(m.Server).(interface {
SizeVT() int
}); ok {
l = size.SizeVT()
} else {
l = proto.Size(m.Server)
}
n += 1 + l + sov(uint64(l))
}
n += len(m.unknownFields)
return n
}
func (m *OSRootSpec) SizeVT() (n int) {
if m == nil {
return 0
@ -3212,6 +3394,240 @@ func (m *KubernetesRootSpec) UnmarshalVT(dAtA []byte) error {
}
return nil
}
func (m *MaintenanceRootSpec) 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 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: MaintenanceRootSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MaintenanceRootSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Ca", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Ca == nil {
m.Ca = &common.PEMEncodedCertificateAndKey{}
}
if unmarshal, ok := interface{}(m.Ca).(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.Ca); err != nil {
return err
}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return 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 *MaintenanceServiceCertsSpec) 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 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: MaintenanceServiceCertsSpec: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: MaintenanceServiceCertsSpec: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Ca", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Ca == nil {
m.Ca = &common.PEMEncodedCertificateAndKey{}
}
if unmarshal, ok := interface{}(m.Ca).(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.Ca); err != nil {
return err
}
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Server", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLength
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLength
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Server == nil {
m.Server = &common.PEMEncodedCertificateAndKey{}
}
if unmarshal, ok := interface{}(m.Server).(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.Server); err != nil {
return err
}
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skip(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return 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 *OSRootSpec) UnmarshalVT(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@ -226,16 +226,22 @@ func (container *Container) Validate(mode validation.RuntimeMode, opt ...validat
warnings, err = container.v1alpha1Config.Validate(mode, opt...)
}
var multiErr *multierror.Error
if err != nil {
multiErr = multierror.Append(multiErr, err)
}
for _, doc := range container.documents {
if validatableDoc, ok := doc.(config.Validator); ok {
docWarnings, docErr := validatableDoc.Validate(mode, opt...)
warnings = append(warnings, docWarnings...)
err = multierror.Append(err, docErr)
multiErr = multierror.Append(multiErr, docErr)
}
}
return warnings, err
return warnings, multiErr.ErrorOrNil()
}
// RedactSecrets returns a copy of the Provider with all secrets replaced with the given string.

View File

@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/siderolabs/talos/pkg/machinery/config/config"
"github.com/siderolabs/talos/pkg/machinery/config/configloader"
"github.com/siderolabs/talos/pkg/machinery/config/container"
"github.com/siderolabs/talos/pkg/machinery/config/types/siderolink"
@ -19,6 +20,8 @@ import (
)
func TestNew(t *testing.T) {
t.Parallel()
v1alpha1Cfg := &v1alpha1.Config{
MachineConfig: &v1alpha1.MachineConfig{
MachineFeatures: &v1alpha1.FeaturesConfig{
@ -42,6 +45,7 @@ func TestNew(t *testing.T) {
assert.Equal(t, "topsecret", cfg.Cluster().Secret())
assert.Equal(t, "https://siderolink.api/join?jointoken=secret&user=alice", cfg.SideroLink().APIUrl().String())
assert.Same(t, v1alpha1Cfg, cfg.RawV1Alpha1())
assert.Equal(t, []config.Document{v1alpha1Cfg, sideroLinkCfg}, cfg.Documents())
bytes, err := cfg.Bytes()
require.NoError(t, err)
@ -58,6 +62,8 @@ func TestNew(t *testing.T) {
}
func TestNewDuplicate(t *testing.T) {
t.Parallel()
v1alpha1Cfg1 := &v1alpha1.Config{}
v1alpha1Cfg2 := &v1alpha1.Config{}
@ -71,6 +77,88 @@ func TestNewDuplicate(t *testing.T) {
assert.EqualError(t, err, "duplicate document: SideroLinkConfig/")
}
func TestValidate(t *testing.T) {
t.Parallel()
sideroLinkCfg := siderolink.NewConfigV1Alpha1()
sideroLinkCfg.APIUrlConfig.URL = must(url.Parse("https://siderolink.api/?jointoken=secret&user=alice"))
invalidSideroLinkCfg := siderolink.NewConfigV1Alpha1()
v1alpha1Cfg := &v1alpha1.Config{
ClusterConfig: &v1alpha1.ClusterConfig{
ControlPlane: &v1alpha1.ControlPlaneConfig{
Endpoint: &v1alpha1.Endpoint{
URL: must(url.Parse("https://localhost:6443")),
},
},
},
MachineConfig: &v1alpha1.MachineConfig{
MachineType: "worker",
},
}
invalidV1alpha1Config := &v1alpha1.Config{}
for _, tt := range []struct {
name string
documents []config.Document
expectedError string
expecetedWarnings []string
}{
{
name: "empty",
},
{
name: "multi-doc",
documents: []config.Document{sideroLinkCfg, v1alpha1Cfg},
},
{
name: "only siderolink",
documents: []config.Document{sideroLinkCfg},
},
{
name: "only v1alpha1",
documents: []config.Document{v1alpha1Cfg},
},
{
name: "invalid siderolink",
documents: []config.Document{invalidSideroLinkCfg},
expectedError: "1 error occurred:\n\t* apiUrl is required\n\n",
},
{
name: "invalid v1alpha1",
documents: []config.Document{invalidV1alpha1Config},
expectedError: "1 error occurred:\n\t* machine instructions are required\n\n",
},
{
name: "invalid multi-doc",
documents: []config.Document{invalidSideroLinkCfg, invalidV1alpha1Config},
expectedError: "2 errors occurred:\n\t* machine instructions are required\n\t* apiUrl is required\n\n",
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
ctr, err := container.New(tt.documents...)
require.NoError(t, err)
warnings, err := ctr.Validate(validationMode{})
if tt.expectedError == "" {
require.NoError(t, err)
} else {
require.EqualError(t, err, tt.expectedError)
}
require.Equal(t, tt.expecetedWarnings, warnings)
})
}
}
func must[T any](t T, err error) T {
if err != nil {
panic(err)
@ -78,3 +166,13 @@ func must[T any](t T, err error) T {
return t
}
type validationMode struct{}
func (validationMode) String() string {
return ""
}
func (validationMode) RequiresInstall() bool {
return false
}

View File

@ -866,6 +866,9 @@ const (
// MetaValuesEnvVar is the name of the environment variable to store encoded meta values for the disk image (installer).
MetaValuesEnvVar = "INSTALLER_META_BASE64"
// MaintenanceServiceCommonName is the CN of the maintenance service server certificate.
MaintenanceServiceCommonName = "maintenance-service.talos.dev"
)
// See https://linux.die.net/man/3/klogctl

View File

@ -21,6 +21,9 @@ const MachineConfigType = resource.Type("MachineConfigs.config.talos.dev")
// V1Alpha1ID is the ID of V1Alpha1 resource (singleton).
const V1Alpha1ID = resource.ID("v1alpha1")
// MaintenanceID is the ID of the config submitted in the maintenance mode.
const MaintenanceID = resource.ID("maintenance")
// MachineConfig resource holds v1alpha Talos configuration.
type MachineConfig struct {
md resource.Metadata
@ -38,8 +41,13 @@ func (s *v1alpha1Spec) MarshalYAMLBytes() ([]byte, error) {
// NewMachineConfig initializes a V1Alpha1 resource.
func NewMachineConfig(spec config.Provider) *MachineConfig {
return NewMachineConfigWithID(spec, V1Alpha1ID)
}
// NewMachineConfigWithID initializes a MachineConfig resource.
func NewMachineConfigWithID(spec config.Provider, id resource.ID) *MachineConfig {
r := &MachineConfig{
md: resource.NewMetadata(NamespaceName, MachineConfigType, V1Alpha1ID, resource.VersionUndefined),
md: resource.NewMetadata(NamespaceName, MachineConfigType, id, resource.VersionUndefined),
spec: &v1alpha1Spec{
cfg: spec,
},

View File

@ -2,11 +2,12 @@
// 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 DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
// Code generated by "deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
package runtime
import (
"net/netip"
"net/url"
)
@ -64,6 +65,22 @@ func (o KmsgLogConfigSpec) DeepCopy() KmsgLogConfigSpec {
return cp
}
// DeepCopy generates a deep copy of MaintenanceServiceConfigSpec.
func (o MaintenanceServiceConfigSpec) DeepCopy() MaintenanceServiceConfigSpec {
var cp MaintenanceServiceConfigSpec = o
if o.ReachableAddresses != nil {
cp.ReachableAddresses = make([]netip.Addr, len(o.ReachableAddresses))
copy(cp.ReachableAddresses, o.ReachableAddresses)
}
return cp
}
// DeepCopy generates a deep copy of MaintenanceServiceRequestSpec.
func (o MaintenanceServiceRequestSpec) DeepCopy() MaintenanceServiceRequestSpec {
var cp MaintenanceServiceRequestSpec = o
return cp
}
// DeepCopy generates a deep copy of MachineStatusSpec.
func (o MachineStatusSpec) DeepCopy() MachineStatusSpec {
var cp MachineStatusSpec = o

View File

@ -0,0 +1,62 @@
// 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 runtime
import (
"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"
"github.com/siderolabs/talos/pkg/machinery/proto"
)
// MaintenanceServiceConfigType is type of MaintenanceConfig resource.
const MaintenanceServiceConfigType = resource.Type("MaintenanceServiceConfigs.runtime.talos.dev")
// MaintenanceServiceConfig resource holds configuration for maintenance service API.
type MaintenanceServiceConfig = typed.Resource[MaintenanceServiceConfigSpec, MaintenanceServiceConfigExtension]
// MaintenanceServiceConfigID is a resource ID for MaintenanceConfig.
const MaintenanceServiceConfigID resource.ID = "maintenance"
// MaintenanceServiceConfigSpec describes configuration for maintenance service API.
//
//gotagsrewrite:gen
type MaintenanceServiceConfigSpec struct {
ListenAddress string `yaml:"listenAddress" protobuf:"1"`
ReachableAddresses []netip.Addr `yaml:"reachableAddresses" protobuf:"2"`
}
// NewMaintenanceServiceConfig initializes a MaintenanceConfig resource.
func NewMaintenanceServiceConfig() *MaintenanceServiceConfig {
return typed.NewResource[MaintenanceServiceConfigSpec, MaintenanceServiceConfigExtension](
resource.NewMetadata(NamespaceName, MaintenanceServiceConfigType, MaintenanceServiceConfigID, resource.VersionUndefined),
MaintenanceServiceConfigSpec{},
)
}
// MaintenanceServiceConfigExtension is auxiliary resource data for MaintenanceConfig.
type MaintenanceServiceConfigExtension struct{}
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (MaintenanceServiceConfigExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: MaintenanceServiceConfigType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
}
}
func init() {
proto.RegisterDefaultTypes()
err := protobuf.RegisterDynamic[MaintenanceServiceConfigSpec](MaintenanceServiceConfigType, &MaintenanceServiceConfig{})
if err != nil {
panic(err)
}
}

View File

@ -0,0 +1,57 @@
// 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 runtime
import (
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/meta"
"github.com/cosi-project/runtime/pkg/resource/protobuf"
"github.com/cosi-project/runtime/pkg/resource/typed"
"github.com/siderolabs/talos/pkg/machinery/proto"
)
// MaintenanceServiceRequestType is type of MaintenanceServiceConfig resource.
const MaintenanceServiceRequestType = resource.Type("MaintenanceServiceRequests.runtime.talos.dev")
// MaintenanceServiceRequest resource indicates that the maintenance service should run.
type MaintenanceServiceRequest = typed.Resource[MaintenanceServiceRequestSpec, MaintenanceServiceRequestExtension]
// MaintenanceServiceRequestID is a resource ID for MaintenanceConfig.
const MaintenanceServiceRequestID resource.ID = "maintenance"
// MaintenanceServiceRequestSpec indicates that maintenance service API should be started.
//
//gotagsrewrite:gen
type MaintenanceServiceRequestSpec struct{}
// NewMaintenanceServiceRequest initializes a MaintenanceConfig resource.
func NewMaintenanceServiceRequest() *MaintenanceServiceRequest {
return typed.NewResource[MaintenanceServiceRequestSpec, MaintenanceServiceRequestExtension](
resource.NewMetadata(NamespaceName, MaintenanceServiceRequestType, MaintenanceServiceRequestID, resource.VersionUndefined),
MaintenanceServiceRequestSpec{},
)
}
// MaintenanceServiceRequestExtension is auxiliary resource data for MaintenanceConfig.
type MaintenanceServiceRequestExtension struct{}
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (MaintenanceServiceRequestExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: MaintenanceServiceRequestType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
}
}
func init() {
proto.RegisterDefaultTypes()
err := protobuf.RegisterDynamic[MaintenanceServiceRequestSpec](MaintenanceServiceRequestType, &MaintenanceServiceRequest{})
if err != nil {
panic(err)
}
}

View File

@ -5,4 +5,4 @@
package runtime
//nolint:lll
//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .

View File

@ -33,6 +33,8 @@ func TestRegisterResource(t *testing.T) {
&runtime.KernelParamStatus{},
&runtime.KmsgLogConfig{},
&runtime.MachineStatus{},
&runtime.MaintenanceServiceConfig{},
&runtime.MaintenanceServiceRequest{},
&runtime.MetaKey{},
&runtime.MountStatus{},
&runtime.PlatformMetadata{},

View File

@ -24,6 +24,9 @@ const CertSANType = resource.Type("CertSANs.secrets.talos.dev")
// CertSANAPIID is a resource ID of singleton instance for the Talos API.
const CertSANAPIID = resource.ID("api")
// CertSANMaintenanceID is a resource ID of singleton instance for the Talos Maintenance API.
const CertSANMaintenanceID = resource.ID("maintenance")
// CertSANKubernetesID is a resource ID of singleton instance for the Kubernetes API Server.
const CertSANKubernetesID = resource.ID("k8s")

View File

@ -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 APICertsSpec -type CertSANSpec -type EtcdCertsSpec -type EtcdRootSpec -type KubeletSpec -type KubernetesCertsSpec -type KubernetesDynamicCertsSpec -type KubernetesRootSpec -type OSRootSpec -type TrustdCertsSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
// Code generated by "deep-copy -type APICertsSpec -type CertSANSpec -type EtcdCertsSpec -type EtcdRootSpec -type KubeletSpec -type KubernetesCertsSpec -type KubernetesDynamicCertsSpec -type KubernetesRootSpec -type MaintenanceServiceCertsSpec -type MaintenanceRootSpec -type OSRootSpec -type TrustdCertsSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
package secrets
@ -144,6 +144,27 @@ func (o KubernetesRootSpec) DeepCopy() KubernetesRootSpec {
return cp
}
// DeepCopy generates a deep copy of MaintenanceServiceCertsSpec.
func (o MaintenanceServiceCertsSpec) DeepCopy() MaintenanceServiceCertsSpec {
var cp MaintenanceServiceCertsSpec = o
if o.CA != nil {
cp.CA = o.CA.DeepCopy()
}
if o.Server != nil {
cp.Server = o.Server.DeepCopy()
}
return cp
}
// DeepCopy generates a deep copy of MaintenanceRootSpec.
func (o MaintenanceRootSpec) DeepCopy() MaintenanceRootSpec {
var cp MaintenanceRootSpec = o
if o.CA != nil {
cp.CA = o.CA.DeepCopy()
}
return cp
}
// DeepCopy generates a deep copy of OSRootSpec.
func (o OSRootSpec) DeepCopy() OSRootSpec {
var cp OSRootSpec = o

View File

@ -0,0 +1,61 @@
// 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 secrets //nolint:dupl
import (
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/meta"
"github.com/cosi-project/runtime/pkg/resource/protobuf"
"github.com/cosi-project/runtime/pkg/resource/typed"
"github.com/siderolabs/crypto/x509"
"github.com/siderolabs/talos/pkg/machinery/proto"
)
// MaintenanceServiceCertsType is type of MaintenanceCerts resource.
const MaintenanceServiceCertsType = resource.Type("MaintenanceServiceCertificates.secrets.talos.dev")
// MaintenanceServiceCertsID is a resource ID of singleton instance.
const MaintenanceServiceCertsID = resource.ID("maintenance")
// MaintenanceServiceCerts contains Maintenance Service generated secrets.
type MaintenanceServiceCerts = typed.Resource[MaintenanceServiceCertsSpec, MaintenanceCertsExtension]
// MaintenanceServiceCertsSpec describes maintenance service certs secrets.
//
//gotagsrewrite:gen
type MaintenanceServiceCertsSpec struct {
CA *x509.PEMEncodedCertificateAndKey `yaml:"ca" protobuf:"1"` // only cert is passed, without key
Server *x509.PEMEncodedCertificateAndKey `yaml:"server" protobuf:"2"`
}
// NewMaintenanceServiceCerts initializes an MaintenanceCerts resource.
func NewMaintenanceServiceCerts() *MaintenanceServiceCerts {
return typed.NewResource[MaintenanceServiceCertsSpec, MaintenanceCertsExtension](
resource.NewMetadata(NamespaceName, MaintenanceServiceCertsType, MaintenanceServiceCertsID, resource.VersionUndefined),
MaintenanceServiceCertsSpec{},
)
}
// MaintenanceCertsExtension provides auxiliary methods for MaintenanceCerts.
type MaintenanceCertsExtension struct{}
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (MaintenanceCertsExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: MaintenanceServiceCertsType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
Sensitivity: meta.Sensitive,
}
}
func init() {
proto.RegisterDefaultTypes()
if err := protobuf.RegisterDynamic[MaintenanceServiceCertsSpec](MaintenanceServiceCertsType, &MaintenanceServiceCerts{}); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,60 @@
// 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 secrets
import (
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/meta"
"github.com/cosi-project/runtime/pkg/resource/protobuf"
"github.com/cosi-project/runtime/pkg/resource/typed"
"github.com/siderolabs/crypto/x509"
"github.com/siderolabs/talos/pkg/machinery/proto"
)
// MaintenanceRootType is type of MaintenanceRoot secret resource.
const MaintenanceRootType = resource.Type("MaintenanceRootSecrets.secrets.talos.dev")
// MaintenanceRootID is the Resource ID for MaintenanceRoot.
const MaintenanceRootID = resource.ID("maintenance")
// MaintenanceRoot contains root secrets for the maintenance service.
type MaintenanceRoot = typed.Resource[MaintenanceRootSpec, MaintenanceRootExtension]
// MaintenanceRootSpec describes maintenance service CA.
//
//gotagsrewrite:gen
type MaintenanceRootSpec struct {
CA *x509.PEMEncodedCertificateAndKey `yaml:"ca" protobuf:"1"`
}
// NewMaintenanceRoot initializes a MaintenanceRoot resource.
func NewMaintenanceRoot(id resource.ID) *MaintenanceRoot {
return typed.NewResource[MaintenanceRootSpec, MaintenanceRootExtension](
resource.NewMetadata(NamespaceName, MaintenanceRootType, id, resource.VersionUndefined),
MaintenanceRootSpec{},
)
}
// MaintenanceRootExtension provides auxiliary methods for MaintenanceRoot.
type MaintenanceRootExtension struct{}
// ResourceDefinition implements meta.ResourceDefinitionProvider interface.
func (MaintenanceRootExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
return meta.ResourceDefinitionSpec{
Type: MaintenanceRootType,
Aliases: []resource.Type{},
DefaultNamespace: NamespaceName,
Sensitivity: meta.Sensitive,
}
}
func init() {
proto.RegisterDefaultTypes()
if err := protobuf.RegisterDynamic[MaintenanceRootSpec](MaintenanceRootType, &MaintenanceRoot{}); err != nil {
panic(err)
}
}

View File

@ -11,4 +11,4 @@ import "github.com/cosi-project/runtime/pkg/resource"
const NamespaceName resource.Namespace = "secrets"
//nolint:lll
//go:generate deep-copy -type APICertsSpec -type CertSANSpec -type EtcdCertsSpec -type EtcdRootSpec -type KubeletSpec -type KubernetesCertsSpec -type KubernetesDynamicCertsSpec -type KubernetesRootSpec -type OSRootSpec -type TrustdCertsSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
//go:generate deep-copy -type APICertsSpec -type CertSANSpec -type EtcdCertsSpec -type EtcdRootSpec -type KubeletSpec -type KubernetesCertsSpec -type KubernetesDynamicCertsSpec -type KubernetesRootSpec -type MaintenanceServiceCertsSpec -type MaintenanceRootSpec -type OSRootSpec -type TrustdCertsSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .

View File

@ -33,6 +33,8 @@ func TestRegisterResource(t *testing.T) {
&secrets.Kubernetes{},
&secrets.KubernetesDynamicCerts{},
&secrets.KubernetesRoot{},
&secrets.MaintenanceServiceCerts{},
&secrets.MaintenanceRoot{},
&secrets.OSRoot{},
&secrets.Trustd{},
} {

View File

@ -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 secrets
package secrets //nolint:dupl
import (
"github.com/cosi-project/runtime/pkg/resource"

View File

@ -57,6 +57,7 @@ func (ConfigExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
JSONPath: `{.apiEndpoint}`,
},
},
Sensitivity: meta.Sensitive,
}
}

View File

@ -195,6 +195,7 @@ description: Talos gRPC API reference.
- [KmsgLogConfigSpec](#talos.resource.definitions.runtime.KmsgLogConfigSpec)
- [MachineStatusSpec](#talos.resource.definitions.runtime.MachineStatusSpec)
- [MachineStatusStatus](#talos.resource.definitions.runtime.MachineStatusStatus)
- [MaintenanceServiceConfigSpec](#talos.resource.definitions.runtime.MaintenanceServiceConfigSpec)
- [MetaKeySpec](#talos.resource.definitions.runtime.MetaKeySpec)
- [MountStatusSpec](#talos.resource.definitions.runtime.MountStatusSpec)
- [PlatformMetadataSpec](#talos.resource.definitions.runtime.PlatformMetadataSpec)
@ -209,6 +210,8 @@ description: Talos gRPC API reference.
- [KubernetesCertsSpec](#talos.resource.definitions.secrets.KubernetesCertsSpec)
- [KubernetesDynamicCertsSpec](#talos.resource.definitions.secrets.KubernetesDynamicCertsSpec)
- [KubernetesRootSpec](#talos.resource.definitions.secrets.KubernetesRootSpec)
- [MaintenanceRootSpec](#talos.resource.definitions.secrets.MaintenanceRootSpec)
- [MaintenanceServiceCertsSpec](#talos.resource.definitions.secrets.MaintenanceServiceCertsSpec)
- [OSRootSpec](#talos.resource.definitions.secrets.OSRootSpec)
- [TrustdCertsSpec](#talos.resource.definitions.secrets.TrustdCertsSpec)
@ -3549,6 +3552,22 @@ MachineStatusStatus describes machine current status at the stage.
<a name="talos.resource.definitions.runtime.MaintenanceServiceConfigSpec"></a>
### MaintenanceServiceConfigSpec
MaintenanceServiceConfigSpec describes configuration for maintenance service API.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| listen_address | [string](#string) | | |
| reachable_addresses | [common.NetIP](#common.NetIP) | repeated | |
<a name="talos.resource.definitions.runtime.MetaKeySpec"></a>
### MetaKeySpec
@ -3784,6 +3803,37 @@ KubernetesRootSpec describes root Kubernetes secrets.
<a name="talos.resource.definitions.secrets.MaintenanceRootSpec"></a>
### MaintenanceRootSpec
MaintenanceRootSpec describes maintenance service CA.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| ca | [common.PEMEncodedCertificateAndKey](#common.PEMEncodedCertificateAndKey) | | |
<a name="talos.resource.definitions.secrets.MaintenanceServiceCertsSpec"></a>
### MaintenanceServiceCertsSpec
MaintenanceServiceCertsSpec describes maintenance service certs secrets.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| ca | [common.PEMEncodedCertificateAndKey](#common.PEMEncodedCertificateAndKey) | | |
| server | [common.PEMEncodedCertificateAndKey](#common.PEMEncodedCertificateAndKey) | | |
<a name="talos.resource.definitions.secrets.OSRootSpec"></a>
### OSRootSpec