mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-15 17:41:31 +02:00
Fixes #4138 When KubeSpan is enabled, Talos automatically generates or loads KubeSpan identity which consists of Wireguard key pair. ULA address is calculated based on ClusterID and first NIC MAC address. Some code was borrowed from #3577. Example: ``` $ talosctl -n 172.20.0.2 get ksi NODE NAMESPACE TYPE ID VERSION ADDRESS PUBLICKEY 172.20.0.2 kubespan KubeSpanIdentity local 1 fd71:6e1d:86be:6302:e871:1bff:feb2:ccee/128 Oak2fBEWngBhwslBxDVgnRNHXs88OAp4kjroSX0uqUE= ``` Additional changes: * `--with-kubespan` flag for `talosctl cluster create` for quick testing * validate that cluster discovery (and KubeSpan) requires ClusterID and ClusterSecret. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com> Signed-off-by: Seán C McCord <ulexus@gmail.com> Co-authored-by: Seán C McCord <ulexus@gmail.com>
142 lines
4.7 KiB
Go
142 lines
4.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 kubespan_test
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cosi-project/runtime/pkg/resource"
|
|
"github.com/stretchr/testify/suite"
|
|
"github.com/talos-systems/go-retry/retry"
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
|
|
kubespanctrl "github.com/talos-systems/talos/internal/app/machined/pkg/controllers/kubespan"
|
|
"github.com/talos-systems/talos/pkg/machinery/constants"
|
|
"github.com/talos-systems/talos/pkg/machinery/nethelpers"
|
|
"github.com/talos-systems/talos/pkg/resources/config"
|
|
"github.com/talos-systems/talos/pkg/resources/kubespan"
|
|
"github.com/talos-systems/talos/pkg/resources/network"
|
|
runtimeres "github.com/talos-systems/talos/pkg/resources/runtime"
|
|
"github.com/talos-systems/talos/pkg/resources/v1alpha1"
|
|
)
|
|
|
|
type IdentitySuite struct {
|
|
KubeSpanSuite
|
|
|
|
statePath string
|
|
}
|
|
|
|
func (suite *IdentitySuite) TestGenerate() {
|
|
suite.statePath = suite.T().TempDir()
|
|
|
|
suite.Require().NoError(suite.runtime.RegisterController(&kubespanctrl.IdentityController{
|
|
StatePath: suite.statePath,
|
|
}))
|
|
|
|
suite.startRuntime()
|
|
|
|
stateMount := runtimeres.NewMountStatus(v1alpha1.NamespaceName, constants.StatePartitionLabel)
|
|
|
|
suite.Assert().NoError(suite.state.Create(suite.ctx, stateMount))
|
|
|
|
cfg := kubespan.NewConfig(config.NamespaceName, kubespan.ConfigID)
|
|
cfg.TypedSpec().Enabled = true
|
|
cfg.TypedSpec().ClusterID = "8XuV9TZHW08DOk3bVxQjH9ih_TBKjnh-j44tsCLSBzo="
|
|
|
|
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
|
|
|
|
firstMac := network.NewHardwareAddr(network.NamespaceName, network.FirstHardwareAddr)
|
|
mac, err := net.ParseMAC("ea:71:1b:b2:cc:ee")
|
|
suite.Require().NoError(err)
|
|
|
|
firstMac.TypedSpec().HardwareAddr = nethelpers.HardwareAddr(mac)
|
|
|
|
suite.Require().NoError(suite.state.Create(suite.ctx, firstMac))
|
|
|
|
specMD := resource.NewMetadata(kubespan.NamespaceName, kubespan.IdentityType, kubespan.LocalIdentity, resource.VersionUndefined)
|
|
|
|
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
|
|
suite.assertResource(
|
|
specMD,
|
|
func(res resource.Resource) error {
|
|
spec := res.(*kubespan.Identity).TypedSpec()
|
|
|
|
_, err := wgtypes.ParseKey(spec.PrivateKey)
|
|
suite.Assert().NoError(err)
|
|
|
|
_, err = wgtypes.ParseKey(spec.PublicKey)
|
|
suite.Assert().NoError(err)
|
|
|
|
suite.Assert().Equal("fd7f:175a:b97c:5602:e871:1bff:feb2:ccee/128", spec.Address.String())
|
|
suite.Assert().Equal("fd7f:175a:b97c:5602::/64", spec.Subnet.String())
|
|
|
|
return nil
|
|
},
|
|
),
|
|
))
|
|
}
|
|
|
|
func (suite *IdentitySuite) TestLoad() {
|
|
// using verbatim data here to make sure nodeId representation is supported in future version fo Talos
|
|
const identityYaml = `address: ""
|
|
subnet: ""
|
|
privateKey: sF45u5ePau58WeeCUY3T8D9foEKaQ8Opx4cGC8g4XE4=
|
|
publicKey: Oak2fBEWngBhwslBxDVgnRNHXs88OAp4kjroSX0uqUE=
|
|
`
|
|
|
|
suite.statePath = suite.T().TempDir()
|
|
|
|
suite.Require().NoError(suite.runtime.RegisterController(&kubespanctrl.IdentityController{
|
|
StatePath: suite.statePath,
|
|
}))
|
|
|
|
suite.startRuntime()
|
|
|
|
suite.Require().NoError(os.WriteFile(filepath.Join(suite.statePath, constants.KubeSpanIdentityFilename), []byte(identityYaml), 0o600))
|
|
|
|
stateMount := runtimeres.NewMountStatus(v1alpha1.NamespaceName, constants.StatePartitionLabel)
|
|
|
|
suite.Assert().NoError(suite.state.Create(suite.ctx, stateMount))
|
|
|
|
cfg := kubespan.NewConfig(config.NamespaceName, kubespan.ConfigID)
|
|
cfg.TypedSpec().Enabled = true
|
|
cfg.TypedSpec().ClusterID = "8XuV9TZHW08DOk3bVxQjH9ih_TBKjnh-j44tsCLSBzo="
|
|
|
|
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
|
|
|
|
firstMac := network.NewHardwareAddr(network.NamespaceName, network.FirstHardwareAddr)
|
|
mac, err := net.ParseMAC("ea:71:1b:b2:cc:ee")
|
|
suite.Require().NoError(err)
|
|
|
|
firstMac.TypedSpec().HardwareAddr = nethelpers.HardwareAddr(mac)
|
|
|
|
suite.Require().NoError(suite.state.Create(suite.ctx, firstMac))
|
|
|
|
specMD := resource.NewMetadata(kubespan.NamespaceName, kubespan.IdentityType, kubespan.LocalIdentity, resource.VersionUndefined)
|
|
|
|
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
|
|
suite.assertResource(
|
|
specMD,
|
|
func(res resource.Resource) error {
|
|
spec := res.(*kubespan.Identity).TypedSpec()
|
|
|
|
suite.Assert().Equal("sF45u5ePau58WeeCUY3T8D9foEKaQ8Opx4cGC8g4XE4=", spec.PrivateKey)
|
|
suite.Assert().Equal("Oak2fBEWngBhwslBxDVgnRNHXs88OAp4kjroSX0uqUE=", spec.PublicKey)
|
|
suite.Assert().Equal("fd7f:175a:b97c:5602:e871:1bff:feb2:ccee/128", spec.Address.String())
|
|
suite.Assert().Equal("fd7f:175a:b97c:5602::/64", spec.Subnet.String())
|
|
|
|
return nil
|
|
},
|
|
),
|
|
))
|
|
}
|
|
|
|
func TestIdentitySuite(t *testing.T) {
|
|
suite.Run(t, new(IdentitySuite))
|
|
}
|