mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-10 07:01:12 +02:00
This introduces new configuration settings to configure advertised/listen subnets. For backwards compatibility when using no settings or old 'subnet' argument, etcd still listens on all addresses. If new `advertisedSubnets` is being used, this automatically limits etcd listen addresses to the same value. `listenSubnets` can be configured also explicitly e.g. to listen on additional addresses for some other scenarios (e.g. accessing etcd from outside of the cluster). See #5668 One more thing left (for a separate PR) is to update etcd advertised URLs on the fly. Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
160 lines
4.4 KiB
Go
160 lines
4.4 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 etcd_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/cosi-project/runtime/pkg/safe"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
"inet.af/netaddr"
|
|
|
|
"github.com/talos-systems/talos/internal/app/machined/pkg/controllers/ctest"
|
|
etcdctrl "github.com/talos-systems/talos/internal/app/machined/pkg/controllers/etcd"
|
|
"github.com/talos-systems/talos/pkg/machinery/resources/etcd"
|
|
"github.com/talos-systems/talos/pkg/machinery/resources/k8s"
|
|
"github.com/talos-systems/talos/pkg/machinery/resources/network"
|
|
)
|
|
|
|
func TestSpecSuite(t *testing.T) {
|
|
suite.Run(t, &SpecSuite{
|
|
DefaultSuite: ctest.DefaultSuite{
|
|
AfterSetup: func(suite *ctest.DefaultSuite) {
|
|
suite.Require().NoError(suite.Runtime().RegisterController(&etcdctrl.SpecController{}))
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
type SpecSuite struct {
|
|
ctest.DefaultSuite
|
|
}
|
|
|
|
func (suite *SpecSuite) TestReconcile() {
|
|
hostnameStatus := network.NewHostnameStatus(network.NamespaceName, network.HostnameID)
|
|
hostnameStatus.TypedSpec().Hostname = "worker1"
|
|
hostnameStatus.TypedSpec().Domainname = "some.domain"
|
|
suite.Require().NoError(suite.State().Create(suite.Ctx(), hostnameStatus))
|
|
|
|
addresses := network.NewNodeAddress(
|
|
network.NamespaceName,
|
|
network.FilteredNodeAddressID(network.NodeAddressRoutedID, k8s.NodeAddressFilterNoK8s),
|
|
)
|
|
|
|
addresses.TypedSpec().Addresses = []netaddr.IPPrefix{
|
|
netaddr.MustParseIPPrefix("10.0.0.5/24"),
|
|
netaddr.MustParseIPPrefix("192.168.1.1/24"),
|
|
netaddr.MustParseIPPrefix("2001:0db8:85a3:0000:0000:8a2e:0370:7334/64"),
|
|
netaddr.MustParseIPPrefix("2002:0db8:85a3:0000:0000:8a2e:0370:7335/64"),
|
|
}
|
|
|
|
suite.Require().NoError(suite.State().Create(suite.Ctx(), addresses))
|
|
|
|
for _, tt := range []struct {
|
|
name string
|
|
cfg etcd.ConfigSpec
|
|
expected etcd.SpecSpec
|
|
}{
|
|
{
|
|
name: "defaults",
|
|
cfg: etcd.ConfigSpec{
|
|
Image: "foo/bar:v1.0.0",
|
|
ExtraArgs: map[string]string{
|
|
"arg": "value",
|
|
},
|
|
},
|
|
expected: etcd.SpecSpec{
|
|
Name: "worker1",
|
|
Image: "foo/bar:v1.0.0",
|
|
ExtraArgs: map[string]string{
|
|
"arg": "value",
|
|
},
|
|
AdvertisedAddresses: []netaddr.IP{
|
|
netaddr.MustParseIP("10.0.0.5"),
|
|
},
|
|
ListenPeerAddresses: []netaddr.IP{
|
|
netaddr.IPv6Unspecified(),
|
|
},
|
|
ListenClientAddresses: []netaddr.IP{
|
|
netaddr.IPv6Unspecified(),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "only advertised",
|
|
cfg: etcd.ConfigSpec{
|
|
Image: "foo/bar:v1.0.0",
|
|
AdvertiseValidSubnets: []string{
|
|
"192.168.0.0/16",
|
|
},
|
|
},
|
|
expected: etcd.SpecSpec{
|
|
Name: "worker1",
|
|
Image: "foo/bar:v1.0.0",
|
|
AdvertisedAddresses: []netaddr.IP{
|
|
netaddr.MustParseIP("192.168.1.1"),
|
|
},
|
|
ListenPeerAddresses: []netaddr.IP{
|
|
netaddr.IPv6Unspecified(),
|
|
},
|
|
ListenClientAddresses: []netaddr.IP{
|
|
netaddr.IPv6Unspecified(),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "advertised and listen",
|
|
cfg: etcd.ConfigSpec{
|
|
Image: "foo/bar:v1.0.0",
|
|
AdvertiseValidSubnets: []string{
|
|
"192.168.0.0/16",
|
|
"2001::/16",
|
|
},
|
|
ListenValidSubnets: []string{
|
|
"192.168.0.0/16",
|
|
},
|
|
},
|
|
expected: etcd.SpecSpec{
|
|
Name: "worker1",
|
|
Image: "foo/bar:v1.0.0",
|
|
AdvertisedAddresses: []netaddr.IP{
|
|
netaddr.MustParseIP("192.168.1.1"),
|
|
netaddr.MustParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334"),
|
|
},
|
|
ListenPeerAddresses: []netaddr.IP{
|
|
netaddr.MustParseIP("192.168.1.1"),
|
|
},
|
|
ListenClientAddresses: []netaddr.IP{
|
|
netaddr.MustParseIP("::1"),
|
|
netaddr.MustParseIP("192.168.1.1"),
|
|
},
|
|
},
|
|
},
|
|
} {
|
|
suite.Run(tt.name, func() {
|
|
etcdConfig := etcd.NewConfig(etcd.NamespaceName, etcd.ConfigID)
|
|
*etcdConfig.TypedSpec() = tt.cfg
|
|
|
|
suite.Require().NoError(suite.State().Create(suite.Ctx(), etcdConfig))
|
|
|
|
suite.AssertWithin(3*time.Second, 100*time.Millisecond, ctest.WrapRetry(func(assert *assert.Assertions, require *require.Assertions) {
|
|
etcdSpec, err := safe.StateGet[*etcd.Spec](suite.Ctx(), suite.State(), etcd.NewSpec(etcd.NamespaceName, etcd.SpecID).Metadata())
|
|
if err != nil {
|
|
assert.NoError(err)
|
|
|
|
return
|
|
}
|
|
|
|
assert.Equal(tt.expected, *etcdSpec.TypedSpec())
|
|
}))
|
|
|
|
suite.Require().NoError(suite.State().Destroy(suite.Ctx(), etcdConfig.Metadata()))
|
|
})
|
|
}
|
|
}
|