mirror of
https://github.com/siderolabs/talos.git
synced 2026-05-05 04:16:21 +02:00
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:
parent
d23d04de2a
commit
bdb96189fa
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
143
internal/app/machined/pkg/controllers/secrets/maintenance.go
Normal file
143
internal/app/machined/pkg/controllers/secrets/maintenance.go
Normal 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()
|
||||
}
|
||||
}
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
@ -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)
|
||||
})
|
||||
}
|
||||
@ -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
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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{},
|
||||
|
||||
14
internal/app/maintenance/controller.go
Normal file
14
internal/app/maintenance/controller.go
Normal 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
|
||||
}
|
||||
@ -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
|
||||
})
|
||||
}
|
||||
@ -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"
|
||||
62
internal/app/maintenance/provider.go
Normal file
62
internal/app/maintenance/provider.go
Normal 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
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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,
|
||||
},
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
},
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
},
|
||||
|
||||
@ -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
|
||||
|
||||
62
pkg/machinery/resources/runtime/maintenance_config.go
Normal file
62
pkg/machinery/resources/runtime/maintenance_config.go
Normal 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)
|
||||
}
|
||||
}
|
||||
57
pkg/machinery/resources/runtime/maintenance_request.go
Normal file
57
pkg/machinery/resources/runtime/maintenance_request.go
Normal 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)
|
||||
}
|
||||
}
|
||||
@ -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 .
|
||||
|
||||
@ -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{},
|
||||
|
||||
@ -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")
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
61
pkg/machinery/resources/secrets/maintenance.go
Normal file
61
pkg/machinery/resources/secrets/maintenance.go
Normal 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)
|
||||
}
|
||||
}
|
||||
60
pkg/machinery/resources/secrets/maintenance_root.go
Normal file
60
pkg/machinery/resources/secrets/maintenance_root.go
Normal 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)
|
||||
}
|
||||
}
|
||||
@ -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 .
|
||||
|
||||
@ -33,6 +33,8 @@ func TestRegisterResource(t *testing.T) {
|
||||
&secrets.Kubernetes{},
|
||||
&secrets.KubernetesDynamicCerts{},
|
||||
&secrets.KubernetesRoot{},
|
||||
&secrets.MaintenanceServiceCerts{},
|
||||
&secrets.MaintenanceRoot{},
|
||||
&secrets.OSRoot{},
|
||||
&secrets.Trustd{},
|
||||
} {
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -57,6 +57,7 @@ func (ConfigExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
|
||||
JSONPath: `{.apiEndpoint}`,
|
||||
},
|
||||
},
|
||||
Sensitivity: meta.Sensitive,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user