From 2e64e9e4e026817f844765b4c8a7d346d85bf983 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 23 May 2024 15:40:40 +0400 Subject: [PATCH] fix: require accepted CAs on worker nodes Note: this issue never happens with default Talos worker configuration (generated by Omni, `talosctl gen config` or CABPT). Before change https://github.com/siderolabs/talos/pull/4294 3 years ago, worker nodes connected to trustd in "insecure" mode (without validating the trustd server certificate). The change kept backwards compatibility, so it still allowed insecure mode on upgrades. Now it's time to break this compatibility promise, and require accepted CAs to be always present. Adds validation for machine configuration, so if upgrade is attempeted, it would not validate the machine config without accepted CAs. Now lack of accepted CAs would lead to failure to connect to trustd. Signed-off-by: Andrey Smirnov --- .../machined/pkg/controllers/secrets/api.go | 2 +- internal/integration/api/apply-config.go | 10 +- pkg/grpc/gen/remote.go | 4 +- pkg/grpc/middleware/auth/basic/basic.go | 20 +- .../config/container/container_test.go | 4 + .../types/v1alpha1/v1alpha1_validation.go | 19 +- .../v1alpha1/v1alpha1_validation_test.go | 253 +++++++++++++++++- 7 files changed, 297 insertions(+), 15 deletions(-) diff --git a/internal/app/machined/pkg/controllers/secrets/api.go b/internal/app/machined/pkg/controllers/secrets/api.go index 72791fa2b..1d2a0c931 100644 --- a/internal/app/machined/pkg/controllers/secrets/api.go +++ b/internal/app/machined/pkg/controllers/secrets/api.go @@ -337,7 +337,7 @@ func (ctrl *APIController) generateControlPlane(ctx context.Context, r controlle func (ctrl *APIController) generateWorker(ctx context.Context, r controller.Runtime, logger *zap.Logger, rootSpec *secrets.OSRootSpec, endpointsStr []string, certSANs *secrets.CertSANSpec, ) error { - remoteGen, err := gen.NewRemoteGenerator(rootSpec.Token, endpointsStr, rootSpec.IssuingCA) + remoteGen, err := gen.NewRemoteGenerator(rootSpec.Token, endpointsStr, rootSpec.AcceptedCAs) if err != nil { return fmt.Errorf("failed creating trustd client: %w", err) } diff --git a/internal/integration/api/apply-config.go b/internal/integration/api/apply-config.go index 95144e558..b3b22a20a 100644 --- a/internal/integration/api/apply-config.go +++ b/internal/integration/api/apply-config.go @@ -8,6 +8,7 @@ package api import ( "context" + "os" "sort" "testing" "time" @@ -397,7 +398,14 @@ func (suite *ApplyConfigSuite) TestApplyDryRun() { cfgDataOut := suite.PatchV1Alpha1Config(provider, func(cfg *v1alpha1.Config) { // this won't be possible without a reboot - cfg.MachineConfig.MachineType = "controlplane" + cfg.MachineConfig.MachineFiles = append(cfg.MachineConfig.MachineFiles, + &v1alpha1.MachineFile{ + FileContent: "test", + FilePermissions: v1alpha1.FileMode(os.ModePerm), + FilePath: "/var/lib/test", + FileOp: "create", + }, + ) }) reply, err := suite.Client.ApplyConfiguration( diff --git a/pkg/grpc/gen/remote.go b/pkg/grpc/gen/remote.go index 1797c6580..533d811f4 100644 --- a/pkg/grpc/gen/remote.go +++ b/pkg/grpc/gen/remote.go @@ -28,7 +28,7 @@ type RemoteGenerator struct { } // NewRemoteGenerator initializes a RemoteGenerator with a preconfigured grpc.ClientConn. -func NewRemoteGenerator(token string, endpoints []string, ca *x509.PEMEncodedCertificateAndKey) (g *RemoteGenerator, err error) { +func NewRemoteGenerator(token string, endpoints []string, acceptedCAs []*x509.PEMEncodedCertificate) (g *RemoteGenerator, err error) { if len(endpoints) == 0 { return nil, errors.New("at least one root of trust endpoint is required") } @@ -37,7 +37,7 @@ func NewRemoteGenerator(token string, endpoints []string, ca *x509.PEMEncodedCer g = &RemoteGenerator{} - conn, err := basic.NewConnection(fmt.Sprintf("%s:///%s", resolver.RoundRobinResolverScheme, strings.Join(endpoints, ",")), basic.NewTokenCredentials(token), ca) + conn, err := basic.NewConnection(fmt.Sprintf("%s:///%s", resolver.RoundRobinResolverScheme, strings.Join(endpoints, ",")), basic.NewTokenCredentials(token), acceptedCAs) if err != nil { return nil, err } diff --git a/pkg/grpc/middleware/auth/basic/basic.go b/pkg/grpc/middleware/auth/basic/basic.go index 0b6aae608..1dee1fe4c 100644 --- a/pkg/grpc/middleware/auth/basic/basic.go +++ b/pkg/grpc/middleware/auth/basic/basic.go @@ -5,10 +5,12 @@ package basic import ( + "bytes" "crypto/tls" stdx509 "crypto/x509" "github.com/siderolabs/crypto/x509" + "github.com/siderolabs/gen/xslices" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) @@ -22,15 +24,19 @@ type Credentials interface { // NewConnection initializes a grpc.ClientConn configured for basic // authentication. -func NewConnection(address string, creds credentials.PerRPCCredentials, ca *x509.PEMEncodedCertificateAndKey) (conn *grpc.ClientConn, err error) { +func NewConnection(address string, creds credentials.PerRPCCredentials, acceptedCAs []*x509.PEMEncodedCertificate) (conn *grpc.ClientConn, err error) { tlsConfig := &tls.Config{} - if ca == nil { - tlsConfig.InsecureSkipVerify = true - } else { - tlsConfig.RootCAs = stdx509.NewCertPool() - tlsConfig.RootCAs.AppendCertsFromPEM(ca.Crt) - } + tlsConfig.RootCAs = stdx509.NewCertPool() + tlsConfig.RootCAs.AppendCertsFromPEM(bytes.Join( + xslices.Map( + acceptedCAs, + func(cert *x509.PEMEncodedCertificate) []byte { + return cert.Crt + }, + ), + nil, + )) grpcOpts := []grpc.DialOption{ grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), diff --git a/pkg/machinery/config/container/container_test.go b/pkg/machinery/config/container/container_test.go index e34dd16e2..a9f30968b 100644 --- a/pkg/machinery/config/container/container_test.go +++ b/pkg/machinery/config/container/container_test.go @@ -8,6 +8,7 @@ import ( "net/url" "testing" + "github.com/siderolabs/crypto/x509" "github.com/siderolabs/gen/xtesting/must" "github.com/siderolabs/go-pointer" "github.com/stretchr/testify/assert" @@ -137,6 +138,9 @@ func TestValidate(t *testing.T) { }, MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("cert"), + }, }, } diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go index bdf4978e3..e3d70681c 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation.go @@ -131,12 +131,21 @@ func (c *Config) Validate(mode validation.RuntimeMode, options ...validation.Opt warnings = append(warnings, fmt.Sprintf("use %q instead of %q for machine type", t.String(), c.MachineConfig.MachineType)) } + if c.Machine().Security().IssuingCA() == nil && len(c.Machine().Security().AcceptedCAs()) == 0 { + result = multierror.Append(result, errors.New("issuing CA or some accepted CAs are required (.machine.ca, machine.acceptedCAs)")) + } + switch c.Machine().Type() { case machine.TypeInit, machine.TypeControlPlane: warn, err := ValidateCNI(c.Cluster().Network().CNI()) warnings = append(warnings, warn...) result = multierror.Append(result, err) + if c.Machine().Security().IssuingCA() == nil { + result = multierror.Append(result, errors.New("issuing CA is required (.machine.ca)")) + } else if len(c.Machine().Security().IssuingCA().Key) == 0 { + result = multierror.Append(result, errors.New("issuing CA key is required for controlplane nodes (.machine.ca.key)")) + } case machine.TypeWorker: for _, d := range c.Machine().Network().Devices() { if d.VIPConfig() != nil { @@ -150,8 +159,14 @@ func (c *Config) Validate(mode validation.RuntimeMode, options ...validation.Opt } } - if c.Machine().Security().IssuingCA() != nil && len(c.Machine().Security().IssuingCA().Key) > 0 { - result = multierror.Append(result, errors.New("issuing Talos API CA key is not allowed on non-controlplane nodes (.machine.ca)")) + if c.Machine().Security().IssuingCA() != nil { + if len(c.Machine().Security().IssuingCA().Key) > 0 { + result = multierror.Append(result, errors.New("issuing Talos API CA key is not allowed on non-controlplane nodes (.machine.ca)")) + } + + if len(c.Machine().Security().IssuingCA().Crt) == 0 && len(c.Machine().Security().AcceptedCAs()) == 0 { + result = multierror.Append(result, errors.New("trusted CA certificates are required on non-controlplane nodes (.machine.ca.crt, .machine.acceptedCAs)")) + } } if c.Cluster().IssuingCA() != nil && len(c.Cluster().IssuingCA().Key) > 0 { diff --git a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go index 249714357..b665bac9e 100644 --- a/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go +++ b/pkg/machinery/config/types/v1alpha1/v1alpha1_validation_test.go @@ -61,7 +61,11 @@ func TestValidate(t *testing.T) { name: "NoMachineType", config: &v1alpha1.Config{ ConfigVersion: "v1alpha1", - MachineConfig: &v1alpha1.MachineConfig{}, + MachineConfig: &v1alpha1.MachineConfig{ + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, + }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ Endpoint: &v1alpha1.Endpoint{ @@ -80,6 +84,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "join", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -97,7 +104,11 @@ func TestValidate(t *testing.T) { name: "NoMachineTypeStrict", config: &v1alpha1.Config{ ConfigVersion: "v1alpha1", - MachineConfig: &v1alpha1.MachineConfig{}, + MachineConfig: &v1alpha1.MachineConfig{ + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, + }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ Endpoint: &v1alpha1.Endpoint{ @@ -109,12 +120,77 @@ func TestValidate(t *testing.T) { strict: true, expectedError: "1 error occurred:\n\t* warning: use \"worker\" instead of \"\" for machine type\n\n", }, + { + name: "WorkerNoAcceptedCAs", + config: &v1alpha1.Config{ + ConfigVersion: "v1alpha1", + MachineConfig: &v1alpha1.MachineConfig{ + MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{}, + }, + ClusterConfig: &v1alpha1.ClusterConfig{ + ControlPlane: &v1alpha1.ControlPlaneConfig{ + Endpoint: &v1alpha1.Endpoint{ + endpointURL, + }, + }, + }, + }, + strict: true, + expectedError: "1 error occurred:\n\t* trusted CA certificates are required on non-controlplane nodes (.machine.ca.crt, .machine.acceptedCAs)\n\n", + }, + { + name: "WorkerOnlyAcceptedCAs", + config: &v1alpha1.Config{ + ConfigVersion: "v1alpha1", + MachineConfig: &v1alpha1.MachineConfig{ + MachineType: "worker", + MachineAcceptedCAs: []*x509.PEMEncodedCertificate{ + { + Crt: []byte("foo"), + }, + }, + }, + ClusterConfig: &v1alpha1.ClusterConfig{ + ControlPlane: &v1alpha1.ControlPlaneConfig{ + Endpoint: &v1alpha1.Endpoint{ + endpointURL, + }, + }, + }, + }, + strict: true, + }, + { + name: "ControlplaneNoCAKey", + config: &v1alpha1.Config{ + ConfigVersion: "v1alpha1", + MachineConfig: &v1alpha1.MachineConfig{ + MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, + }, + ClusterConfig: &v1alpha1.ClusterConfig{ + ControlPlane: &v1alpha1.ControlPlaneConfig{ + Endpoint: &v1alpha1.Endpoint{ + endpointURL, + }, + }, + }, + }, + strict: true, + expectedError: "1 error occurred:\n\t* issuing CA key is required for controlplane nodes (.machine.ca.key)\n\n", + }, { name: "NoMachineInstall", config: &v1alpha1.Config{ ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -131,6 +207,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -149,6 +228,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineInstall: &v1alpha1.InstallConfig{ InstallDisk: "/dev/vda", }, @@ -169,6 +251,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineInstall: &v1alpha1.InstallConfig{ InstallDisk: "/dev/vda", InstallExtensions: []v1alpha1.InstallExtensionConfig{ @@ -201,6 +286,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -224,6 +312,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -243,6 +334,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -260,6 +354,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -283,6 +380,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -306,6 +406,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -337,6 +441,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -354,6 +462,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -380,6 +492,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -409,6 +525,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -438,6 +558,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -468,6 +592,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -502,6 +630,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -535,6 +667,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -559,6 +695,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -593,6 +733,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -628,6 +772,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -667,6 +815,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -724,6 +876,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -763,6 +919,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -799,6 +959,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -838,6 +1002,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -884,6 +1052,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -943,6 +1115,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkKubeSpan: &v1alpha1.NetworkKubeSpan{ KubeSpanEnabled: pointer.To(true), @@ -967,6 +1143,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ClusterID: "foo", @@ -994,6 +1174,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -1014,6 +1198,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -1032,6 +1220,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -1050,6 +1241,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -1078,6 +1273,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{ @@ -1104,6 +1303,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineKubelet: &v1alpha1.KubeletConfig{ KubeletNodeIP: &v1alpha1.KubeletNodeIPConfig{ KubeletNodeIPValidSubnets: []string{ @@ -1130,6 +1332,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineKubelet: &v1alpha1.KubeletConfig{ KubeletNodeIP: &v1alpha1.KubeletNodeIPConfig{ KubeletNodeIPValidSubnets: []string{ @@ -1158,6 +1363,11 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineAcceptedCAs: []*x509.PEMEncodedCertificate{ + { + Crt: []byte("foo"), + }, + }, MachineKubelet: &v1alpha1.KubeletConfig{ KubeletExtraConfig: v1alpha1.Unstructured{ Object: map[string]interface{}{ @@ -1182,6 +1392,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ {}, @@ -1204,6 +1418,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -1231,6 +1449,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkInterfaces: []*v1alpha1.Device{ { @@ -1255,6 +1477,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineFeatures: &v1alpha1.FeaturesConfig{ KubernetesTalosAPIAccessConfig: &v1alpha1.KubernetesTalosAPIAccessConfig{ AccessEnabled: pointer.To(true), @@ -1277,6 +1503,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineFeatures: &v1alpha1.FeaturesConfig{ RBAC: pointer.To(true), KubernetesTalosAPIAccessConfig: &v1alpha1.KubernetesTalosAPIAccessConfig{ @@ -1300,6 +1529,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, MachineFeatures: &v1alpha1.FeaturesConfig{ RBAC: pointer.To(true), KubernetesTalosAPIAccessConfig: &v1alpha1.KubernetesTalosAPIAccessConfig{ @@ -1331,6 +1564,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineNodeLabels: map[string]string{ "/foo": "bar", "key": "value", @@ -1356,6 +1592,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkKubeSpan: &v1alpha1.NetworkKubeSpan{ KubeSpanEnabled: pointer.To(true), @@ -1390,6 +1629,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkKubeSpan: &v1alpha1.NetworkKubeSpan{ KubeSpanEnabled: pointer.To(true), @@ -1423,6 +1665,9 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "worker", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + }, MachineNetwork: &v1alpha1.NetworkConfig{ NetworkKubeSpan: &v1alpha1.NetworkKubeSpan{ KubeSpanEnabled: pointer.To(true), @@ -1451,6 +1696,10 @@ func TestValidate(t *testing.T) { ConfigVersion: "v1alpha1", MachineConfig: &v1alpha1.MachineConfig{ MachineType: "controlplane", + MachineCA: &x509.PEMEncodedCertificateAndKey{ + Crt: []byte("foo"), + Key: []byte("bar"), + }, }, ClusterConfig: &v1alpha1.ClusterConfig{ ControlPlane: &v1alpha1.ControlPlaneConfig{