Andrey Smirnov 7a68504b6b
feat: support rotating Kubernetes CA
Fixes #8440

Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com>
2024-04-01 22:08:02 +04:00

122 lines
3.7 KiB
Go

// 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"
"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"
talosconfig "github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/config/generate"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/secrets"
)
func TestRootSuite(t *testing.T) {
t.Parallel()
suite.Run(t, &RootSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 10 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(secretsctrl.NewRootEtcdController()))
suite.Require().NoError(suite.Runtime().RegisterController(secretsctrl.NewRootKubernetesController()))
suite.Require().NoError(suite.Runtime().RegisterController(secretsctrl.NewRootOSController()))
},
},
})
}
type RootSuite struct {
ctest.DefaultSuite
}
func (suite *RootSuite) genConfig(controlplane bool) talosconfig.Config {
input, err := generate.NewInput("test-cluster", "http://localhost:6443", "")
suite.Require().NoError(err)
var cfg talosconfig.Provider
if controlplane {
cfg, err = input.Config(machine.TypeControlPlane)
} else {
cfg, err = input.Config(machine.TypeWorker)
}
suite.Require().NoError(err)
machineCfg := config.NewMachineConfig(cfg)
suite.Require().NoError(suite.State().Create(suite.Ctx(), machineCfg))
return cfg
}
func (suite *RootSuite) TestReconcileControlPlane() {
cfg := suite.genConfig(true)
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.EtcdRootID},
func(res *secrets.EtcdRoot, asrt *assert.Assertions) {
asrt.Equal(res.TypedSpec().EtcdCA, cfg.Cluster().Etcd().CA())
},
)
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.KubernetesRootID},
func(res *secrets.KubernetesRoot, asrt *assert.Assertions) {
asrt.Equal(res.TypedSpec().IssuingCA, cfg.Cluster().IssuingCA())
asrt.Equal(
[]*x509.PEMEncodedCertificate{
{
Crt: cfg.Cluster().IssuingCA().Crt,
},
},
res.TypedSpec().AcceptedCAs,
)
},
)
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.OSRootID},
func(res *secrets.OSRoot, asrt *assert.Assertions) {
asrt.Equal(res.TypedSpec().IssuingCA, cfg.Machine().Security().IssuingCA())
asrt.Equal(
[]*x509.PEMEncodedCertificate{
{
Crt: cfg.Machine().Security().IssuingCA().Crt,
},
},
res.TypedSpec().AcceptedCAs,
)
},
)
}
func (suite *RootSuite) TestReconcileWorker() {
cfg := suite.genConfig(false)
rtestutils.AssertResources(suite.Ctx(), suite.T(), suite.State(), []resource.ID{secrets.OSRootID},
func(res *secrets.OSRoot, asrt *assert.Assertions) {
asrt.Nil(res.TypedSpec().IssuingCA)
asrt.Equal(
[]*x509.PEMEncodedCertificate{
{
Crt: cfg.Machine().Security().IssuingCA().Crt,
},
},
res.TypedSpec().AcceptedCAs,
)
},
)
rtestutils.AssertNoResource[*secrets.Etcd](suite.Ctx(), suite.T(), suite.State(), secrets.EtcdRootID)
rtestutils.AssertNoResource[*secrets.Kubernetes](suite.Ctx(), suite.T(), suite.State(), secrets.KubernetesRootID)
}