Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/siderolabs/talos/pkg/machinery/config/generate"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/config/types/siderolink"
"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/provision"
)
Expand Down Expand Up @@ -452,9 +451,9 @@ func (m *Maker[T]) initGenOps() error {

if m.Ops.EnableKubeSpan {
genOptions = slices.Concat(genOptions,
[]generate.Option{generate.WithNetworkOptions(
v1alpha1.WithKubeSpan(),
)},
Comment thread
smira marked this conversation as resolved.
[]generate.Option{
generate.WithKubeSpanEnabled(m.Ops.EnableKubeSpan),
},
)
}

Expand Down
6 changes: 2 additions & 4 deletions cmd/talosctl/cmd/mgmt/gen/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
"github.com/siderolabs/talos/pkg/machinery/config/generate"
"github.com/siderolabs/talos/pkg/machinery/config/generate/secrets"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
"github.com/siderolabs/talos/pkg/machinery/constants"
)

Expand Down Expand Up @@ -204,11 +203,10 @@ func writeConfig(args []string) error {
genOptions = append(genOptions, generate.WithVersionContract(versionContract))
}

// Add KubeSpan configuration based on version
if genConfigCmdFlags.withKubeSpan {
genOptions = append(genOptions,
generate.WithNetworkOptions(
v1alpha1.WithKubeSpan(),
),
generate.WithKubeSpanEnabled(genConfigCmdFlags.withKubeSpan),
)
}

Expand Down
9 changes: 9 additions & 0 deletions hack/release.toml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ It replaces and deprecates the previous method of setting environment variables
Multiple values for the same environment variable will replace previous values, with the last one taking precedence.

To remove an environment variable, remove it from the `EnvironmentConfig` document and restart the node.
"""

[notes.kubespan]
title = "KubeSpan Configuration"
description = """\
A new `KubeSpanConfig` document has been introduced to configure KubeSpan settings.
It replaces and deprecates the previous method of configuring KubeSpan via the `.machine.network.kubespan` field.

The old configuration field will continue to work for backward compatibility.
"""

[make_deps]
Expand Down
2 changes: 1 addition & 1 deletion internal/app/machined/pkg/controllers/etcd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (suite *ConfigSuite) TestReconcile() {
},
MachineConfig: &v1alpha1.MachineConfig{
MachineType: "controlplane",
MachineNetwork: &v1alpha1.NetworkConfig{
MachineNetwork: &v1alpha1.NetworkConfig{ //nolint:staticcheck // legacy config
NetworkInterfaces: tt.networkConfig,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (suite *NodeIPConfigSuite) TestReconcileWithSubnets() {
KubeletNodeIPValidSubnets: []string{"10.0.0.0/24"},
},
},
MachineNetwork: &v1alpha1.NetworkConfig{
MachineNetwork: &v1alpha1.NetworkConfig{ //nolint:staticcheck // legacy controller
NetworkInterfaces: []*v1alpha1.Device{
{
DeviceVIPConfig: &v1alpha1.DeviceVIPConfig{
Expand Down
18 changes: 12 additions & 6 deletions internal/app/machined/pkg/controllers/kubespan/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,20 @@ func NewConfigController() *ConfigController {
if cfg != nil && cfg.Config().Machine() != nil {
c := cfg.Config()

res.TypedSpec().Enabled = c.Machine().Network().KubeSpan().Enabled()
if c.NetworkKubeSpanConfig() != nil {
res.TypedSpec().Enabled = c.NetworkKubeSpanConfig().Enabled()
res.TypedSpec().ForceRouting = c.NetworkKubeSpanConfig().ForceRouting()
res.TypedSpec().AdvertiseKubernetesNetworks = c.NetworkKubeSpanConfig().AdvertiseKubernetesNetworks()
res.TypedSpec().HarvestExtraEndpoints = c.NetworkKubeSpanConfig().HarvestExtraEndpoints()
res.TypedSpec().MTU = c.NetworkKubeSpanConfig().MTU()

if c.NetworkKubeSpanConfig().Filters() != nil {
res.TypedSpec().EndpointFilters = c.NetworkKubeSpanConfig().Filters().Endpoints()
}
}

res.TypedSpec().ClusterID = c.Cluster().ID()
res.TypedSpec().SharedSecret = c.Cluster().Secret()
res.TypedSpec().ForceRouting = c.Machine().Network().KubeSpan().ForceRouting()
res.TypedSpec().AdvertiseKubernetesNetworks = c.Machine().Network().KubeSpan().AdvertiseKubernetesNetworks()
res.TypedSpec().HarvestExtraEndpoints = c.Machine().Network().KubeSpan().HarvestExtraEndpoints()
res.TypedSpec().MTU = c.Machine().Network().KubeSpan().MTU()
res.TypedSpec().EndpointFilters = c.Machine().Network().KubeSpan().Filters().Endpoints()
res.TypedSpec().ExtraEndpoints = c.KubespanConfig().ExtraAnnouncedEndpoints()
}

Expand Down
110 changes: 62 additions & 48 deletions internal/app/machined/pkg/controllers/kubespan/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"testing"
"time"

"github.com/cosi-project/runtime/pkg/resource"
"github.com/siderolabs/go-pointer"
"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"
kubespanctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/kubespan"
"github.com/siderolabs/talos/pkg/machinery/config/container"
"github.com/siderolabs/talos/pkg/machinery/config/types/network"
Expand All @@ -23,20 +23,16 @@ import (
)

type ConfigSuite struct {
KubeSpanSuite
ctest.DefaultSuite
}

func (suite *ConfigSuite) TestReconcileConfig() {
suite.Require().NoError(suite.runtime.RegisterController(kubespanctrl.NewConfigController()))

suite.startRuntime()

ctr, err := container.New(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
NetworkKubeSpan: &v1alpha1.NetworkKubeSpan{
MachineNetwork: &v1alpha1.NetworkConfig{ //nolint:staticcheck // legacy config
NetworkKubeSpan: &v1alpha1.NetworkKubeSpan{ //nolint:staticcheck // legacy config
KubeSpanEnabled: pointer.To(true),
},
},
Expand All @@ -54,65 +50,83 @@ func (suite *ConfigSuite) TestReconcileConfig() {
)
suite.Require().NoError(err)

cfg := config.NewMachineConfig(ctr)

suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Create(config.NewMachineConfig(ctr))

specMD := resource.NewMetadata(config.NamespaceName, kubespan.ConfigType, kubespan.ConfigID, resource.VersionUndefined)
ctest.AssertResource(suite, kubespan.ConfigID, func(res *kubespan.Config, asrt *assert.Assertions) {
spec := res.TypedSpec()

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.Config).TypedSpec()

suite.Assert().True(spec.Enabled)
suite.Assert().Equal("8XuV9TZHW08DOk3bVxQjH9ih_TBKjnh-j44tsCLSBzo=", spec.ClusterID)
suite.Assert().Equal("I+1In7fLnpcRIjUmEoeugZnSyFoTF6MztLxICL5Yu0s=", spec.SharedSecret)
suite.Assert().True(spec.ForceRouting)
suite.Assert().False(spec.AdvertiseKubernetesNetworks)
suite.Assert().False(spec.HarvestExtraEndpoints)
suite.Assert().Equal("[\"192.168.33.11:1001\"]", fmt.Sprintf("%q", spec.ExtraEndpoints))

return nil
},
),
))
asrt.True(spec.Enabled)
asrt.Equal("8XuV9TZHW08DOk3bVxQjH9ih_TBKjnh-j44tsCLSBzo=", spec.ClusterID)
asrt.Equal("I+1In7fLnpcRIjUmEoeugZnSyFoTF6MztLxICL5Yu0s=", spec.SharedSecret)
asrt.True(spec.ForceRouting)
asrt.False(spec.AdvertiseKubernetesNetworks)
asrt.False(spec.HarvestExtraEndpoints)
asrt.Equal("[\"192.168.33.11:1001\"]", fmt.Sprintf("%q", spec.ExtraEndpoints))
})
}

func (suite *ConfigSuite) TestReconcileDisabled() {
suite.Require().NoError(suite.runtime.RegisterController(kubespanctrl.NewConfigController()))

suite.startRuntime()

cfg := config.NewMachineConfig(
container.NewV1Alpha1(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{},
}))
suite.Create(cfg)

suite.Require().NoError(suite.state.Create(suite.ctx, cfg))

specMD := resource.NewMetadata(config.NamespaceName, kubespan.ConfigType, kubespan.ConfigID, resource.VersionUndefined)
ctest.AssertResource(suite, kubespan.ConfigID, func(res *kubespan.Config, asrt *assert.Assertions) {
spec := res.TypedSpec()

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.Config).TypedSpec()
asrt.False(spec.Enabled)
})
}

suite.Assert().False(spec.Enabled)
func (suite *ConfigSuite) TestReconcileMultiDoc() {
kubeSpanCfg := network.NewKubeSpanV1Alpha1()
kubeSpanCfg.ConfigEnabled = pointer.To(true)
kubeSpanCfg.ConfigMTU = pointer.To(uint32(1380))
kubeSpanCfg.ConfigFilters = &network.KubeSpanFiltersConfig{
ConfigEndpoints: []string{"0.0.0.0/0", "::/0"},
}

return nil
ctr, err := container.New(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
ClusterID: "test-cluster-id-multi-doc",
ClusterSecret: "test-cluster-secret-multi-doc",
},
),
))
},
kubeSpanCfg,
)
suite.Require().NoError(err)

suite.Create(config.NewMachineConfig(ctr))

ctest.AssertResource(suite, kubespan.ConfigID,
func(res *kubespan.Config, asrt *assert.Assertions) {
spec := res.TypedSpec()

asrt.True(spec.Enabled)
asrt.Equal("test-cluster-id-multi-doc", spec.ClusterID)
asrt.Equal("test-cluster-secret-multi-doc", spec.SharedSecret)
asrt.Equal(uint32(1380), spec.MTU)
asrt.Equal([]string{"0.0.0.0/0", "::/0"}, spec.EndpointFilters)
},
)
}

func TestConfigSuite(t *testing.T) {
t.Parallel()

suite.Run(t, new(ConfigSuite))
suite.Run(t, &ConfigSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 5 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(kubespanctrl.NewConfigController()))
},
},
})
}
79 changes: 27 additions & 52 deletions internal/app/machined/pkg/controllers/kubespan/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import (
"testing"
"time"

"github.com/cosi-project/runtime/pkg/resource"
"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"
kubespanctrl "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/kubespan"
"github.com/siderolabs/talos/pkg/machinery/config/machine"
"github.com/siderolabs/talos/pkg/machinery/resources/cluster"
Expand All @@ -20,17 +20,13 @@ import (
)

type EndpointSuite struct {
KubeSpanSuite
ctest.DefaultSuite
}

func (suite *EndpointSuite) TestReconcile() {
suite.Require().NoError(suite.runtime.RegisterController(&kubespanctrl.EndpointController{}))

suite.startRuntime()

cfg := kubespan.NewConfig(config.NamespaceName, kubespan.ConfigID)
cfg.TypedSpec().HarvestExtraEndpoints = true
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Create(cfg)

// create some affiliates and peer statuses
affiliate1 := cluster.NewAffiliate(cluster.NamespaceName, "7x1SuC8Ege5BGXdAfTEff5iQnlWZLfv9h1LGMxA2pYkC")
Expand Down Expand Up @@ -59,8 +55,8 @@ func (suite *EndpointSuite) TestReconcile() {
},
}

suite.Require().NoError(suite.state.Create(suite.ctx, affiliate1))
suite.Require().NoError(suite.state.Create(suite.ctx, affiliate2))
suite.Create(affiliate1)
suite.Create(affiliate2)

peerStatus1 := kubespan.NewPeerStatus(kubespan.NamespaceName, affiliate1.TypedSpec().KubeSpan.PublicKey)
*peerStatus1.TypedSpec() = kubespan.PeerStatusSpec{
Expand All @@ -80,57 +76,36 @@ func (suite *EndpointSuite) TestReconcile() {
State: kubespan.PeerStateUp,
}

suite.Require().NoError(suite.state.Create(suite.ctx, peerStatus1))
suite.Require().NoError(suite.state.Create(suite.ctx, peerStatus2))
suite.Require().NoError(suite.state.Create(suite.ctx, peerStatus3))
suite.Create(peerStatus1)
suite.Create(peerStatus2)
suite.Create(peerStatus3)

// peer1 is up and has matching affiliate
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(
kubespan.NamespaceName,
kubespan.EndpointType,
peerStatus1.Metadata().ID(),
resource.VersionUndefined,
),
func(res resource.Resource) error {
spec := res.(*kubespan.Endpoint).TypedSpec()

suite.Assert().Equal(peerStatus1.TypedSpec().Endpoint, spec.Endpoint)
suite.Assert().Equal(affiliate1.TypedSpec().NodeID, spec.AffiliateID)

return nil
},
),
))
ctest.AssertResource(suite, peerStatus1.Metadata().ID(),
func(res *kubespan.Endpoint, asrt *assert.Assertions) {
spec := res.TypedSpec()

asrt.Equal(peerStatus1.TypedSpec().Endpoint, spec.Endpoint)
asrt.Equal(affiliate1.TypedSpec().NodeID, spec.AffiliateID)
},
)

// peer2 is not up, it shouldn't be published as an endpoint
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResource(
resource.NewMetadata(
kubespan.NamespaceName,
kubespan.EndpointType,
peerStatus2.Metadata().ID(),
resource.VersionUndefined,
),
),
))
ctest.AssertNoResource[*kubespan.Endpoint](suite, peerStatus2.Metadata().ID())

// peer3 is up, but has not matching affiliate
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResource(
resource.NewMetadata(
kubespan.NamespaceName,
kubespan.EndpointType,
peerStatus3.Metadata().ID(),
resource.VersionUndefined,
),
),
))
ctest.AssertNoResource[*kubespan.Endpoint](suite, peerStatus3.Metadata().ID())
}

func TestEndpointSuite(t *testing.T) {
t.Parallel()

suite.Run(t, new(EndpointSuite))
suite.Run(t, &EndpointSuite{
DefaultSuite: ctest.DefaultSuite{
Timeout: 5 * time.Second,
AfterSetup: func(suite *ctest.DefaultSuite) {
suite.Require().NoError(suite.Runtime().RegisterController(&kubespanctrl.EndpointController{}))
},
},
})
}
Loading
Loading