feat: update golangci-lint to 1.45.0 and gofumpt to 0.3.0

- Update golangci-lint to 1.45.0
- Update gofumpt to 0.3.0
- Fix gofumpt errors
- Add goimports and format imports since gofumports is removed
- Update Dockerfile
- Fix .golangci.yml configuration
- Fix linting errors

Signed-off-by: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com>
This commit is contained in:
Dmitriy Matrenichev 2022-03-23 11:49:07 +04:00
parent a92c614b2f
commit e06e1473b0
No known key found for this signature in database
GPG Key ID: D3363CF894E68892
127 changed files with 7058 additions and 5010 deletions

View File

@ -119,7 +119,10 @@ linters-settings:
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
gci:
local-prefixes: github.com/talos-systems/talos
sections:
- standard # Captures all standard packages if they do not match another section.
- default # Contains all imports that could not be matched to another section type.
- prefix(github.com/talos-systems/talos) # Groups all imports with the specified Prefix.
cyclop:
# the maximal code complexity to report
max-complexity: 20
@ -138,6 +141,7 @@ linters:
- errorlint
- exhaustivestruct
- forbidigo
- forcetypeassert
- funlen
- gas
- gochecknoglobals
@ -148,6 +152,7 @@ linters:
- gomnd
- ifshort
- ireturn # we return interfaces
- maintidx
- nestif
- nilnil # we return "nil, nil"
- paralleltest
@ -199,10 +204,10 @@ issues:
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-per-linter: 0
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same: 0
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.

View File

@ -96,9 +96,12 @@ RUN ["/toolchain/bin/ln", "-svf", "/toolchain/bin/bash", "/bin/sh"]
RUN ["/toolchain/bin/ln", "-svf", "/toolchain/etc/ssl", "/etc/ssl"]
ARG GOLANGCILINT_VERSION
RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/${GOLANGCILINT_VERSION}/install.sh | bash -s -- -b /toolchain/bin ${GOLANGCILINT_VERSION}
ARG GOIMPORTS_VERSION
RUN go install golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION} \
&& mv /go/bin/goimports /toolchain/go/bin/goimports
ARG GOFUMPT_VERSION
RUN go install mvdan.cc/gofumpt/gofumports@${GOFUMPT_VERSION} \
&& mv /go/bin/gofumports /toolchain/go/bin/gofumports
RUN go install mvdan.cc/gofumpt@${GOFUMPT_VERSION} \
&& mv /go/bin/gofumpt /toolchain/go/bin/gofumpt
ARG STRINGER_VERSION
RUN go install golang.org/x/tools/cmd/stringer@${STRINGER_VERSION} \
&& mv /go/bin/stringer /toolchain/go/bin/stringer
@ -190,18 +193,21 @@ COPY ./api/resource/secrets/secrets.proto /api/resource/secrets/secrets.proto
RUN protoc -I/api -I/api/vendor/ --go_out=paths=source_relative:/api --go-grpc_out=paths=source_relative:/api --go-vtproto_out=paths=source_relative:/api --go-vtproto_opt=features=marshal+unmarshal+size resource/secrets/secrets.proto
COPY ./api/inspect/inspect.proto /api/inspect/inspect.proto
RUN protoc -I/api -I/api/vendor/ --go_out=paths=source_relative:/api --go-grpc_out=paths=source_relative:/api --go-vtproto_out=paths=source_relative:/api --go-vtproto_opt=features=marshal+unmarshal+size inspect/inspect.proto
# Gofumports generated files to adjust import order
RUN gofumports -w -local github.com/talos-systems/talos /api/
# Goimports and gofumpt generated files to adjust import order
RUN goimports -w -local github.com/talos-systems/talos /api/
RUN gofumpt -w /api/
# run docgen for machinery config
FROM build-go AS go-generate
COPY ./pkg ./pkg
COPY ./hack/boilerplate.txt ./hack/boilerplate.txt
RUN --mount=type=cache,target=/.cache go generate ./pkg/...
RUN gofumports -w -local github.com/talos-systems/talos ./pkg/
RUN goimports -w -local github.com/talos-systems/talos ./pkg/
RUN gofumpt -w ./pkg/
WORKDIR /src/pkg/machinery
RUN --mount=type=cache,target=/.cache go generate ./...
RUN gofumports -w -local github.com/talos-systems/talos ./
RUN goimports -w -local github.com/talos-systems/talos ./
RUN gofumpt -w ./
FROM --platform=${BUILDPLATFORM} scratch AS generate
COPY --from=proto-format-build /src/api /api/
@ -660,8 +666,6 @@ WORKDIR /src/pkg/machinery
RUN --mount=type=cache,target=/.cache golangci-lint run --config ../../.golangci.yml
WORKDIR /src
RUN --mount=type=cache,target=/.cache importvet github.com/talos-systems/talos/...
RUN find . -name '*.pb.go' -o -name '*_string_*.go' | xargs rm
RUN --mount=type=cache,target=/.cache FILES="$(gofumports -l -local github.com/talos-systems/talos .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'gofumports -w -local github.com/talos-systems/talos .':\n${FILES}"; exit 1)
# The protolint target performs linting on protobuf files.

View File

@ -16,8 +16,9 @@ TOOLS ?= ghcr.io/siderolabs/tools:v1.1.0-alpha.0-1-g99be089
PKGS ?= v1.1.0-alpha.0-5-g58603ba
EXTRAS ?= v1.0.0
GO_VERSION ?= 1.17
GOFUMPT_VERSION ?= v0.1.1
GOLANGCILINT_VERSION ?= v1.43.0
GOIMPORTS_VERSION ?= v0.1.10
GOFUMPT_VERSION ?= v0.3.0
GOLANGCILINT_VERSION ?= v1.45.0
STRINGER_VERSION ?= v0.1.5
ENUMER_VERSION ?= v1.1.2
DEEPCOPY_GEN_VERSION ?= v0.21.3
@ -85,6 +86,7 @@ COMMON_ARGS += --build-arg=TOOLS=$(TOOLS)
COMMON_ARGS += --build-arg=PKGS=$(PKGS)
COMMON_ARGS += --build-arg=EXTRAS=$(EXTRAS)
COMMON_ARGS += --build-arg=GOFUMPT_VERSION=$(GOFUMPT_VERSION)
COMMON_ARGS += --build-arg=GOIMPORTS_VERSION=$(GOIMPORTS_VERSION)
COMMON_ARGS += --build-arg=STRINGER_VERSION=$(STRINGER_VERSION)
COMMON_ARGS += --build-arg=ENUMER_VERSION=$(ENUMER_VERSION)
COMMON_ARGS += --build-arg=DEEPCOPY_GEN_VERSION=$(DEEPCOPY_GEN_VERSION)
@ -272,7 +274,7 @@ api-descriptors: ## Generates API descriptors used to detect breaking API change
@$(MAKE) local-api-descriptors DEST=./ PLATFORM=linux/amd64
fmt-go: ## Formats the source code.
@docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) bash -c "go install mvdan.cc/gofumpt/gofumports@$(GOFUMPT_VERSION) && gofumports -w -local github.com/talos-systems/talos ."
@docker run --rm -it -v $(PWD):/src -w /src golang:$(GO_VERSION) bash -c "go install golang.org/x/tools/cmd/goimports@$(GOIMPORTS_VERSION) && goimports -w -local github.com/talos-systems/talos . && go install mvdan.cc/gofumpt@$(GOFUMPT_VERSION) && gofumpt -w ."
fmt-protobuf: ## Formats protobuf files.
@$(MAKE) local-fmt-protobuf DEST=./ PLATFORM=linux/amd64

View File

@ -123,7 +123,8 @@ func GenV1Alpha1Config(genOptions []generate.GenOption,
kubernetesVersion string,
configPatch []string,
configPatchControlPlane []string,
configPatchWorker []string) (*v1alpha1.ConfigBundle, error) {
configPatchWorker []string,
) (*v1alpha1.ConfigBundle, error) {
configBundleOpts := []bundle.Option{
bundle.WithInputOptions(
&bundle.InputOptions{

View File

@ -22,7 +22,7 @@ type APISource struct {
Interval time.Duration
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
wg sync.WaitGroup

View File

@ -20,7 +20,7 @@ import (
"google.golang.org/grpc/peer"
"github.com/talos-systems/talos/pkg/cli"
_ "github.com/talos-systems/talos/pkg/grpc/codec" //nolint:gci // register codec
_ "github.com/talos-systems/talos/pkg/grpc/codec" // register codec
"github.com/talos-systems/talos/pkg/machinery/api/common"
machineapi "github.com/talos-systems/talos/pkg/machinery/api/machine"
"github.com/talos-systems/talos/pkg/machinery/client"
@ -44,7 +44,8 @@ const pathAutoCompleteLimit = 500
//
// WithClientNoNodes doesn't set any node information on request context.
func WithClientNoNodes(action func(context.Context, *client.Client) error) error {
return cli.WithContext(context.Background(), func(ctx context.Context) error {
return cli.WithContext(
context.Background(), func(ctx context.Context) error {
cfg, err := clientconfig.Open(Talosconfig)
if err != nil {
return fmt.Errorf("failed to open config file %q: %w", Talosconfig, err)
@ -71,12 +72,14 @@ func WithClientNoNodes(action func(context.Context, *client.Client) error) error
defer c.Close()
return action(ctx, c)
})
},
)
}
// WithClient builds upon WithClientNoNodes to provide set of nodes on request context based on config & flags.
func WithClient(action func(context.Context, *client.Client) error) error {
return WithClientNoNodes(func(ctx context.Context, c *client.Client) error {
return WithClientNoNodes(
func(ctx context.Context, c *client.Client) error {
if len(Nodes) < 1 {
configContext := c.GetConfigContext()
if configContext == nil {
@ -93,12 +96,14 @@ func WithClient(action func(context.Context, *client.Client) error) error {
ctx = client.WithNodes(ctx, Nodes...)
return action(ctx, c)
})
},
)
}
// WithClientMaintenance wraps common code to initialize Talos client in maintenance (insecure mode).
func WithClientMaintenance(enforceFingerprints []string, action func(context.Context, *client.Client) error) error {
return cli.WithContext(context.Background(), func(ctx context.Context) error {
return cli.WithContext(
context.Background(), func(ctx context.Context) error {
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}
@ -127,7 +132,8 @@ func WithClientMaintenance(enforceFingerprints []string, action func(context.Con
defer c.Close()
return action(ctx, c)
})
},
)
}
// Commands is a list of commands published by the package.
@ -170,13 +176,17 @@ func completePathFromNode(inputPath string) []string {
func getPathFromNode(path, filter string) map[string]struct{} {
paths := make(map[string]struct{})
WithClient(func(ctx context.Context, c *client.Client) error { //nolint:errcheck
//nolint:errcheck
WithClient(
func(ctx context.Context, c *client.Client) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
stream, err := c.LS(ctx, &machineapi.ListRequest{
stream, err := c.LS(
ctx, &machineapi.ListRequest{
Root: path,
})
},
)
if err != nil {
return err
}
@ -224,7 +234,8 @@ func getPathFromNode(path, filter string) map[string]struct{} {
}
}
}
})
},
)
return paths
}
@ -232,7 +243,9 @@ func getPathFromNode(path, filter string) map[string]struct{} {
func getServiceFromNode() []string {
var svcIds []string
WithClient(func(ctx context.Context, c *client.Client) error { //nolint:errcheck
//nolint:errcheck
WithClient(
func(ctx context.Context, c *client.Client) error {
var remotePeer peer.Peer
resp, err := c.ServiceList(ctx, grpc.Peer(&remotePeer))
@ -248,7 +261,8 @@ func getServiceFromNode() []string {
}
return nil
})
},
)
return svcIds
}
@ -256,7 +270,9 @@ func getServiceFromNode() []string {
func getContainersFromNode(kubernetes bool) []string {
var containerIds []string
WithClient(func(ctx context.Context, c *client.Client) error { //nolint:errcheck
//nolint:errcheck
WithClient(
func(ctx context.Context, c *client.Client) error {
var (
namespace string
driver common.ContainerDriver
@ -290,7 +306,8 @@ func getContainersFromNode(kubernetes bool) []string {
}
return nil
})
},
)
return containerIds
}

View File

@ -17,7 +17,7 @@ import (
"github.com/talos-systems/grpc-proxy/proxy"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
protobuf "google.golang.org/protobuf/proto" //nolint:depguard,gci
protobuf "google.golang.org/protobuf/proto" //nolint:depguard
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/descriptorpb"
@ -71,7 +71,8 @@ func (suite *APIDSuite) TestGetConnection() {
suite.Assert().Equal([]string{"127.0.0.2"}, mdOut1.Get("proxyfrom"))
suite.Assert().Equal([]string{"os:admin"}, mdOut1.Get("talos-role"))
suite.Run("Same context", func() {
suite.Run(
"Same context", func() {
ctx2 := ctx1
outCtx2, conn2, err2 := suite.b.GetConnection(ctx2)
suite.Require().NoError(err2)
@ -83,14 +84,19 @@ func (suite *APIDSuite) TestGetConnection() {
suite.Assert().Equal([]string{"value1", "value2"}, mdOut2.Get("key"))
suite.Assert().Equal([]string{"127.0.0.2"}, mdOut2.Get("proxyfrom"))
suite.Assert().Equal([]string{"os:admin"}, mdOut2.Get("talos-role"))
})
},
)
suite.Run("Other context", func() {
suite.Run(
"Other context", func() {
md3 := metadata.New(nil)
md3.Set(":authority", "127.0.0.2")
md3.Set("nodes", "127.0.0.1")
md3.Set("key", "value3", "value4")
ctx3 := metadata.NewIncomingContext(authz.ContextWithRoles(context.Background(), role.MakeSet(role.Reader)), md3)
ctx3 := metadata.NewIncomingContext(
authz.ContextWithRoles(context.Background(), role.MakeSet(role.Reader)),
md3,
)
outCtx3, conn3, err3 := suite.b.GetConnection(ctx3)
suite.Require().NoError(err3)
@ -102,7 +108,8 @@ func (suite *APIDSuite) TestGetConnection() {
suite.Assert().Equal([]string{"value3", "value4"}, mdOut3.Get("key"))
suite.Assert().Equal([]string{"127.0.0.2"}, mdOut3.Get("proxyfrom"))
suite.Assert().Equal([]string{"os:reader"}, mdOut3.Get("talos-role"))
})
},
)
}
func (suite *APIDSuite) TestAppendInfoUnary() {
@ -221,7 +228,8 @@ func TestAPIIdiosyncrasies(t *testing.T) {
for j := 0; j < methods.Len(); j++ {
method := methods.Get(j)
t.Run(string(method.FullName()), func(t *testing.T) {
t.Run(
string(method.FullName()), func(t *testing.T) {
response := method.Output()
responseFields := response.Fields()
@ -238,13 +246,19 @@ func TestAPIIdiosyncrasies(t *testing.T) {
reply := messages.Message()
replyFields := reply.Fields()
require.GreaterOrEqual(t, replyFields.Len(), 1, "unary replies should have at least one field")
require.GreaterOrEqual(
t,
replyFields.Len(),
1,
"unary replies should have at least one field",
)
metadata := replyFields.Get(0)
assert.Equal(t, "metadata", metadata.TextName())
assert.Equal(t, 1, int(metadata.Number()))
}
})
},
)
}
}
}
@ -294,8 +308,10 @@ func getOptions(t *testing.T, descriptor protoreflect.Descriptor) (deprecated bo
func testDeprecated(t *testing.T, descriptor protoreflect.Descriptor, currentVersion *config.VersionContract) {
deprecated, version := getOptions(t, descriptor)
assert.Equal(t, deprecated, version != "",
"%s: `deprecated` and `remove_deprecated_XXX_in` options should be used together", descriptor.FullName())
assert.Equal(
t, deprecated, version != "",
"%s: `deprecated` and `remove_deprecated_XXX_in` options should be used together", descriptor.FullName(),
)
if !deprecated || version == "" {
return

View File

@ -47,7 +47,6 @@ func (s *InspectServer) ControllerRuntimeDependencies(ctx context.Context, in *e
}
edges = append(edges, &inspectapi.ControllerDependencyEdge{
ControllerName: graph.Edges[i].ControllerName,
EdgeType: edgeType,

View File

@ -263,7 +263,9 @@ func run() error {
}
// Watch and handle runtime events.
_ = c.Runtime().Events().Watch(func(events <-chan runtime.EventInfo) { //nolint:errcheck
//nolint:errcheck
_ = c.Runtime().Events().Watch(
func(events <-chan runtime.EventInfo) {
for {
for event := range events {
switch msg := event.Payload.(type) {
@ -274,14 +276,19 @@ func run() error {
continue
}
errCh <- fmt.Errorf("fatal sequencer error in %q sequence: %v", msg.GetSequence(), msg.GetError().String())
errCh <- fmt.Errorf(
"fatal sequencer error in %q sequence: %v",
msg.GetSequence(),
msg.GetError().String(),
)
}
case *machine.RestartEvent:
errCh <- runtime.RebootError{Cmd: int(msg.Cmd)}
}
}
}
})
},
)
return <-errCh
}

View File

@ -31,7 +31,7 @@ type ClusterSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -96,10 +96,14 @@ func (suite *ClusterSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -38,6 +38,7 @@ type K8sAddressFilterSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
//nolint:containedctx
ctx context.Context
ctxCancel context.CancelFunc
}
@ -67,7 +68,10 @@ func (suite *K8sAddressFilterSuite) startRuntime() {
}()
}
func (suite *K8sAddressFilterSuite) assertResource(md resource.Metadata, check func(res resource.Resource) error) func() error {
func (suite *K8sAddressFilterSuite) assertResource(
md resource.Metadata,
check func(res resource.Resource) error,
) func() error {
return func() error {
r, err := suite.state.Get(suite.ctx, md)
if err != nil {
@ -86,7 +90,8 @@ func (suite *K8sAddressFilterSuite) TestReconcile() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -106,36 +111,57 @@ func (suite *K8sAddressFilterSuite) TestReconcile() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(network.NamespaceName, network.NodeAddressFilterType, k8s.NodeAddressFilterOnlyK8s, resource.VersionUndefined),
resource.NewMetadata(
network.NamespaceName,
network.NodeAddressFilterType,
k8s.NodeAddressFilterOnlyK8s,
resource.VersionUndefined,
),
func(res resource.Resource) error {
spec := res.(*network.NodeAddressFilter).TypedSpec()
suite.Assert().Equal("[10.32.0.0/12 fd00:10:32::/102 10.200.0.0/22 fd40:10:200::/112]", fmt.Sprintf("%s", spec.IncludeSubnets))
suite.Assert().Equal(
"[10.32.0.0/12 fd00:10:32::/102 10.200.0.0/22 fd40:10:200::/112]",
fmt.Sprintf("%s", spec.IncludeSubnets),
)
suite.Assert().Empty(spec.ExcludeSubnets)
return nil
},
),
))
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(network.NamespaceName, network.NodeAddressFilterType, k8s.NodeAddressFilterNoK8s, resource.VersionUndefined),
resource.NewMetadata(
network.NamespaceName,
network.NodeAddressFilterType,
k8s.NodeAddressFilterNoK8s,
resource.VersionUndefined,
),
func(res resource.Resource) error {
spec := res.(*network.NodeAddressFilter).TypedSpec()
suite.Assert().Empty(spec.IncludeSubnets)
suite.Assert().Equal("[10.32.0.0/12 fd00:10:32::/102 10.200.0.0/22 fd40:10:200::/112]", fmt.Sprintf("%s", spec.ExcludeSubnets))
suite.Assert().Equal(
"[10.32.0.0/12 fd00:10:32::/102 10.200.0.0/22 fd40:10:200::/112]",
fmt.Sprintf("%s", spec.ExcludeSubnets),
)
return nil
},
),
))
),
)
}
func (suite *K8sAddressFilterSuite) TearDownTest() {

View File

@ -40,7 +40,7 @@ type K8sControlPlaneSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -70,7 +70,10 @@ func (suite *K8sControlPlaneSuite) startRuntime() {
}
func (suite *K8sControlPlaneSuite) assertK8sControlPlanes(manifests []string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(config.NamespaceName, config.K8sControlPlaneType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(config.NamespaceName, config.K8sControlPlaneType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -97,7 +100,8 @@ func (suite *K8sControlPlaneSuite) setupMachine(cfg *config.MachineConfig) confi
suite.Require().NoError(suite.state.Create(suite.ctx, machineType))
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertK8sControlPlanes(
[]string{
@ -110,7 +114,8 @@ func (suite *K8sControlPlaneSuite) setupMachine(cfg *config.MachineConfig) confi
},
)
},
))
),
)
r, err := suite.state.Get(suite.ctx, config.NewK8sControlPlaneAPIServer().Metadata())
suite.Require().NoError(err)
@ -125,7 +130,8 @@ func (suite *K8sControlPlaneSuite) TestReconcileDefaults() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -135,7 +141,8 @@ func (suite *K8sControlPlaneSuite) TestReconcileDefaults() {
},
},
},
})
},
)
apiServerCfg := suite.setupMachine(cfg)
suite.Assert().Empty(apiServerCfg.CloudProvider)
@ -149,7 +156,8 @@ func (suite *K8sControlPlaneSuite) TestReconcileExtraVolumes() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -167,24 +175,28 @@ func (suite *K8sControlPlaneSuite) TestReconcileExtraVolumes() {
},
},
},
})
},
)
apiServerCfg := suite.setupMachine(cfg)
suite.Assert().Equal([]config.K8sExtraVolume{
suite.Assert().Equal(
[]config.K8sExtraVolume{
{
Name: "var-foo",
HostPath: "/var/lib",
MountPath: "/var/foo/",
ReadOnly: false,
},
}, apiServerCfg.ExtraVolumes)
}, apiServerCfg.ExtraVolumes,
)
}
func (suite *K8sControlPlaneSuite) TestReconcileEnvironment() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -199,19 +211,23 @@ func (suite *K8sControlPlaneSuite) TestReconcileEnvironment() {
},
},
},
})
},
)
apiServerCfg := suite.setupMachine(cfg)
suite.Assert().Equal(map[string]string{
suite.Assert().Equal(
map[string]string{
"HTTP_PROXY": "foo",
}, apiServerCfg.EnvironmentVariables)
}, apiServerCfg.EnvironmentVariables,
)
}
func (suite *K8sControlPlaneSuite) TestReconcileExternalCloudProvider() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -228,7 +244,8 @@ func (suite *K8sControlPlaneSuite) TestReconcileExternalCloudProvider() {
},
},
},
})
},
)
apiServerCfg := suite.setupMachine(cfg)
suite.Assert().Equal("external", apiServerCfg.CloudProvider)
@ -240,7 +257,8 @@ func (suite *K8sControlPlaneSuite) TestReconcileExternalCloudProvider() {
r, err = suite.state.Get(suite.ctx, config.NewK8sExtraManifests().Metadata())
suite.Require().NoError(err)
suite.Assert().Equal(config.K8sExtraManifestsSpec{
suite.Assert().Equal(
config.K8sExtraManifestsSpec{
ExtraManifests: []config.ExtraManifest{
{
Name: "https://raw.githubusercontent.com/kubernetes/cloud-provider-aws/v1.20.0-alpha.0/manifests/rbac.yaml",
@ -253,14 +271,16 @@ func (suite *K8sControlPlaneSuite) TestReconcileExternalCloudProvider() {
Priority: "30",
},
},
}, r.(*config.K8sControlPlane).ExtraManifests())
}, r.(*config.K8sControlPlane).ExtraManifests(),
)
}
func (suite *K8sControlPlaneSuite) TestReconcileInlineManifests() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -272,23 +292,27 @@ func (suite *K8sControlPlaneSuite) TestReconcileInlineManifests() {
ClusterInlineManifests: v1alpha1.ClusterInlineManifests{
{
InlineManifestName: "namespace-ci",
InlineManifestContents: strings.TrimSpace(`
InlineManifestContents: strings.TrimSpace(
`
apiVersion: v1
kind: Namespace
metadata:
name: ci
`),
`,
),
},
},
},
})
},
)
suite.setupMachine(cfg)
r, err := suite.state.Get(suite.ctx, config.NewK8sExtraManifests().Metadata())
suite.Require().NoError(err)
suite.Assert().Equal(config.K8sExtraManifestsSpec{
suite.Assert().Equal(
config.K8sExtraManifestsSpec{
ExtraManifests: []config.ExtraManifest{
{
Name: "namespace-ci",
@ -296,7 +320,8 @@ metadata:
InlineManifest: "apiVersion: v1\nkind: Namespace\nmetadata:\n\tname: ci",
},
},
}, r.(*config.K8sControlPlane).ExtraManifests())
}, r.(*config.K8sControlPlane).ExtraManifests(),
)
}
func (suite *K8sControlPlaneSuite) TearDownTest() {
@ -307,8 +332,19 @@ func (suite *K8sControlPlaneSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), k8s.NewSecretsStatus(k8s.ControlPlaneNamespaceName, "-")))
suite.Assert().NoError(suite.state.Destroy(context.Background(), config.NewK8sControlPlaneAPIServer().Metadata(), state.WithDestroyOwner("config.K8sControlPlaneController")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
k8s.NewSecretsStatus(k8s.ControlPlaneNamespaceName, "-"),
),
)
suite.Assert().NoError(
suite.state.Destroy(
context.Background(),
config.NewK8sControlPlaneAPIServer().Metadata(),
state.WithDestroyOwner("config.K8sControlPlaneController"),
),
)
}
func TestK8sControlPlaneSuite(t *testing.T) {

View File

@ -35,7 +35,7 @@ type EtcFileSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
etcPath string
@ -57,10 +57,14 @@ func (suite *EtcFileSuite) SetupTest() {
suite.etcPath = suite.T().TempDir()
suite.shadowPath = suite.T().TempDir()
suite.Require().NoError(suite.runtime.RegisterController(&filesctrl.EtcFileController{
suite.Require().NoError(
suite.runtime.RegisterController(
&filesctrl.EtcFileController{
EtcPath: suite.etcPath,
ShadowPath: suite.shadowPath,
}))
},
),
)
}
func (suite *EtcFileSuite) startRuntime() {
@ -83,7 +87,10 @@ func (suite *EtcFileSuite) assertEtcFile(filename, contents string, expectedVers
return retry.ExpectedErrorf("contents don't match %q != %q", string(b), contents)
}
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(files.NamespaceName, files.EtcFileStatusType, filename, resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(files.NamespaceName, files.EtcFileStatusType, filename, resource.VersionUndefined),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -118,10 +125,13 @@ func (suite *EtcFileSuite) TestFiles() {
suite.Require().NoError(suite.state.Create(suite.ctx, etcFileSpec))
suite.Assert().NoError(retry.Constant(5*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(5*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertEtcFile("test1", "foo", etcFileSpec.Metadata().Version())
}))
},
),
)
for _, r := range []resource.Resource{etcFileSpec} {
for {

View File

@ -276,7 +276,8 @@ func envVars(environment map[string]string) []v1.EnvVar {
}
func (ctrl *ControlPlaneStaticPodController) manageAPIServer(ctx context.Context, r controller.Runtime, logger *zap.Logger,
configResource *config.K8sControlPlane, secretsVersion, configVersion string) (string, error) {
configResource *config.K8sControlPlane, secretsVersion, configVersion string,
) (string, error) {
cfg := configResource.APIServer()
enabledAdmissionPlugins := []string{"NodeRestriction"}
@ -465,7 +466,8 @@ func (ctrl *ControlPlaneStaticPodController) manageAPIServer(ctx context.Context
}
func (ctrl *ControlPlaneStaticPodController) manageControllerManager(ctx context.Context, r controller.Runtime,
logger *zap.Logger, configResource *config.K8sControlPlane, secretsVersion, configVersion string) (string, error) {
logger *zap.Logger, configResource *config.K8sControlPlane, secretsVersion, configVersion string,
) (string, error) {
cfg := configResource.ControllerManager()
if !cfg.Enabled {
@ -594,7 +596,8 @@ func (ctrl *ControlPlaneStaticPodController) manageControllerManager(ctx context
}
func (ctrl *ControlPlaneStaticPodController) manageScheduler(ctx context.Context, r controller.Runtime,
logger *zap.Logger, configResource *config.K8sControlPlane, secretsVersion, configVersion string) (string, error) {
logger *zap.Logger, configResource *config.K8sControlPlane, secretsVersion, configVersion string,
) (string, error) {
cfg := configResource.Scheduler()
if !cfg.Enabled {

View File

@ -41,7 +41,7 @@ type ControlPlaneStaticPodSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -78,7 +78,10 @@ func (suite *ControlPlaneStaticPodSuite) startRuntime() {
//nolint:dupl
func (suite *ControlPlaneStaticPodSuite) assertControlPlaneStaticPods(manifests []string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -109,7 +112,8 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileDefaults() {
suite.Require().NoError(suite.state.Create(suite.ctx, configControllerManager))
suite.Require().NoError(suite.state.Create(suite.ctx, configScheduler))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertControlPlaneStaticPods(
[]string{
@ -119,14 +123,19 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileDefaults() {
},
)
},
))
),
)
// tear down etcd service
suite.Require().NoError(suite.state.Destroy(suite.ctx, v1alpha1.NewService("etcd").Metadata()))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
list, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined))
list, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -137,14 +146,16 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileDefaults() {
return nil
},
))
),
)
}
func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraMounts() {
secretStatus := k8s.NewSecretsStatus(k8s.ControlPlaneNamespaceName, k8s.StaticPodSecretsStaticPodID)
configStatus := k8s.NewConfigStatus(k8s.ControlPlaneNamespaceName, k8s.ConfigStatusStaticPodID)
configAPIServer := config.NewK8sControlPlaneAPIServer()
configAPIServer.SetAPIServer(config.K8sControlPlaneAPIServerSpec{
configAPIServer.SetAPIServer(
config.K8sControlPlaneAPIServerSpec{
ExtraVolumes: []config.K8sExtraVolume{
{
Name: "foo",
@ -153,7 +164,8 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraMounts() {
ReadOnly: true,
},
},
})
},
)
configControllerManager := config.NewK8sControlPlaneControllerManager()
configScheduler := config.NewK8sControlPlaneScheduler()
@ -164,7 +176,8 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraMounts() {
suite.Require().NoError(suite.state.Create(suite.ctx, configControllerManager))
suite.Require().NoError(suite.state.Create(suite.ctx, configScheduler))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertControlPlaneStaticPods(
[]string{
@ -174,9 +187,13 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraMounts() {
},
)
},
))
),
)
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined),
)
suite.Require().NoError(err)
apiServerPod, err := k8sadapter.StaticPod(r.(*k8s.StaticPod)).Pod()
@ -185,65 +202,81 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraMounts() {
suite.Assert().Len(apiServerPod.Spec.Volumes, 4)
suite.Assert().Len(apiServerPod.Spec.Containers[0].VolumeMounts, 4)
suite.Assert().Equal(v1.Volume{
suite.Assert().Equal(
v1.Volume{
Name: "secrets",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: constants.KubernetesAPIServerSecretsDir,
},
},
}, apiServerPod.Spec.Volumes[0])
}, apiServerPod.Spec.Volumes[0],
)
suite.Assert().Equal(v1.Volume{
suite.Assert().Equal(
v1.Volume{
Name: "config",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: constants.KubernetesAPIServerConfigDir,
},
},
}, apiServerPod.Spec.Volumes[1])
}, apiServerPod.Spec.Volumes[1],
)
suite.Assert().Equal(v1.Volume{
suite.Assert().Equal(
v1.Volume{
Name: "audit",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: constants.KubernetesAuditLogDir,
},
},
}, apiServerPod.Spec.Volumes[2])
}, apiServerPod.Spec.Volumes[2],
)
suite.Assert().Equal(v1.Volume{
suite.Assert().Equal(
v1.Volume{
Name: "foo",
VolumeSource: v1.VolumeSource{
HostPath: &v1.HostPathVolumeSource{
Path: "/var/lib",
},
},
}, apiServerPod.Spec.Volumes[3])
}, apiServerPod.Spec.Volumes[3],
)
suite.Assert().Equal(v1.VolumeMount{
suite.Assert().Equal(
v1.VolumeMount{
Name: "secrets",
MountPath: constants.KubernetesAPIServerSecretsDir,
ReadOnly: true,
}, apiServerPod.Spec.Containers[0].VolumeMounts[0])
}, apiServerPod.Spec.Containers[0].VolumeMounts[0],
)
suite.Assert().Equal(v1.VolumeMount{
suite.Assert().Equal(
v1.VolumeMount{
Name: "config",
MountPath: constants.KubernetesAPIServerConfigDir,
ReadOnly: true,
}, apiServerPod.Spec.Containers[0].VolumeMounts[1])
}, apiServerPod.Spec.Containers[0].VolumeMounts[1],
)
suite.Assert().Equal(v1.VolumeMount{
suite.Assert().Equal(
v1.VolumeMount{
Name: "audit",
MountPath: constants.KubernetesAuditLogDir,
ReadOnly: false,
}, apiServerPod.Spec.Containers[0].VolumeMounts[2])
}, apiServerPod.Spec.Containers[0].VolumeMounts[2],
)
suite.Assert().Equal(v1.VolumeMount{
suite.Assert().Equal(
v1.VolumeMount{
Name: "foo",
MountPath: "/var/foo",
ReadOnly: true,
}, apiServerPod.Spec.Containers[0].VolumeMounts[3])
}, apiServerPod.Spec.Containers[0].VolumeMounts[3],
)
}
func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraArgs() {
@ -278,9 +311,11 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraArgs() {
secretStatus := k8s.NewSecretsStatus(k8s.ControlPlaneNamespaceName, k8s.StaticPodSecretsStaticPodID)
configAPIServer := config.NewK8sControlPlaneAPIServer()
configAPIServer.SetAPIServer(config.K8sControlPlaneAPIServerSpec{
configAPIServer.SetAPIServer(
config.K8sControlPlaneAPIServerSpec{
ExtraArgs: test.args,
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, configStatus))
suite.Require().NoError(suite.state.Create(suite.ctx, secretStatus))
@ -290,13 +325,17 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraArgs() {
// wait for some time to ensure that controller has picked the input
time.Sleep(500 * time.Millisecond)
_, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined))
_, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined),
)
suite.Require().Error(err)
continue
}
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertControlPlaneStaticPods(
[]string{
@ -304,9 +343,13 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraArgs() {
},
)
},
))
),
)
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined),
)
suite.Require().NoError(err)
apiServerPod, err := k8sadapter.StaticPod(r.(*k8s.StaticPod)).Pod()
@ -332,9 +375,13 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraArgs() {
suite.Require().NoError(suite.state.Destroy(suite.ctx, secretStatus.Metadata()))
suite.Require().NoError(suite.state.Destroy(suite.ctx, configAPIServer.Metadata()))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
list, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined))
list, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -345,7 +392,8 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileExtraArgs() {
return nil
},
))
),
)
}
}
@ -401,13 +449,16 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileEnvironmentVariables() {
for _, test := range tests {
configAPIServer := config.NewK8sControlPlaneAPIServer()
configAPIServer.SetAPIServer(config.K8sControlPlaneAPIServerSpec{
configAPIServer.SetAPIServer(
config.K8sControlPlaneAPIServerSpec{
EnvironmentVariables: test.env,
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, configAPIServer))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertControlPlaneStaticPods(
[]string{
@ -415,9 +466,13 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileEnvironmentVariables() {
},
)
},
))
),
)
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "kube-apiserver", resource.VersionUndefined),
)
suite.Require().NoError(err)
apiServerPod, err := k8sadapter.StaticPod(r.(*k8s.StaticPod)).Pod()
@ -429,9 +484,13 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileEnvironmentVariables() {
suite.Require().NoError(suite.state.Destroy(suite.ctx, configAPIServer.Metadata()))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
list, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined))
list, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.StaticPodType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -442,7 +501,8 @@ func (suite *ControlPlaneStaticPodSuite) TestReconcileEnvironmentVariables() {
return nil
},
))
),
)
}
}
@ -459,7 +519,8 @@ func (suite *ControlPlaneStaticPodSuite) TestControlPlaneStaticPodsExceptSchedul
suite.Require().NoError(suite.state.Create(suite.ctx, configControllerManager))
suite.Require().NoError(suite.state.Create(suite.ctx, configScheduler))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertControlPlaneStaticPods(
[]string{
@ -469,21 +530,25 @@ func (suite *ControlPlaneStaticPodSuite) TestControlPlaneStaticPodsExceptSchedul
},
)
},
))
),
)
// flip enabled to disable scheduler
_, err := suite.state.UpdateWithConflicts(suite.ctx, configScheduler.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, configScheduler.Metadata(), func(r resource.Resource) error {
spec := r.(*config.K8sControlPlane).Scheduler()
spec.Enabled = false
r.(*config.K8sControlPlane).SetScheduler(spec)
return nil
})
},
)
suite.Require().NoError(err)
configScheduler.SetScheduler(config.K8sControlPlaneSchedulerSpec{Enabled: false})
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertControlPlaneStaticPods(
[]string{
@ -492,7 +557,8 @@ func (suite *ControlPlaneStaticPodSuite) TestControlPlaneStaticPodsExceptSchedul
},
)
},
))
),
)
}
func (suite *ControlPlaneStaticPodSuite) TearDownTest() {
@ -503,7 +569,12 @@ func (suite *ControlPlaneStaticPodSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), k8s.NewSecretsStatus(k8s.ControlPlaneNamespaceName, "-")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
k8s.NewSecretsStatus(k8s.ControlPlaneNamespaceName, "-"),
),
)
suite.Assert().NoError(suite.state.Create(context.Background(), config.NewK8sManifests()))
}

View File

@ -40,7 +40,7 @@ type ExtraManifestSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -71,7 +71,10 @@ func (suite *ExtraManifestSuite) startRuntime() {
//nolint:dupl
func (suite *ExtraManifestSuite) assertExtraManifests(manifests []string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -91,12 +94,14 @@ func (suite *ExtraManifestSuite) assertExtraManifests(manifests []string) error
func (suite *ExtraManifestSuite) TestReconcileInlineManifests() {
configExtraManifests := config.NewK8sExtraManifests()
configExtraManifests.SetExtraManifests(config.K8sExtraManifestsSpec{
configExtraManifests.SetExtraManifests(
config.K8sExtraManifestsSpec{
ExtraManifests: []config.ExtraManifest{
{
Name: "namespaces",
Priority: "99",
InlineManifest: strings.TrimSpace(`
InlineManifest: strings.TrimSpace(
`
apiVersion: v1
kind: Namespace
metadata:
@ -106,10 +111,12 @@ apiVersion: v1
kind: Namespace
metadata:
name: build
`),
`,
),
},
},
})
},
)
statusNetwork := network.NewStatus(network.NamespaceName, network.StatusID)
statusNetwork.TypedSpec().AddressReady = true
@ -118,7 +125,8 @@ metadata:
suite.Require().NoError(suite.state.Create(suite.ctx, configExtraManifests))
suite.Require().NoError(suite.state.Create(suite.ctx, statusNetwork))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertExtraManifests(
[]string{
@ -126,9 +134,18 @@ metadata:
},
)
},
))
),
)
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "99-namespaces", resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.ControlPlaneNamespaceName,
k8s.ManifestType,
"99-namespaces",
resource.VersionUndefined,
),
)
suite.Require().NoError(err)
manifest := r.(*k8s.Manifest) //nolint:errcheck,forcetypeassert

View File

@ -38,7 +38,7 @@ type KubeletConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -71,7 +71,8 @@ func (suite *KubeletConfigSuite) TestReconcile() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineKubelet: &v1alpha1.KubeletConfig{
@ -109,13 +110,23 @@ func (suite *KubeletConfigSuite) TestReconcile() {
DNSDomain: "service.svc",
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
kubeletConfig, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.KubeletConfigType, k8s.KubeletID, resource.VersionUndefined))
kubeletConfig, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.KubeletConfigType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -133,7 +144,8 @@ func (suite *KubeletConfigSuite) TestReconcile() {
map[string]string{
"enable-feature": "foo",
},
spec.ExtraArgs)
spec.ExtraArgs,
)
suite.Assert().Equal(
[]specs.Mount{
{
@ -142,7 +154,8 @@ func (suite *KubeletConfigSuite) TestReconcile() {
Type: "tmpfs",
},
},
spec.ExtraMounts)
spec.ExtraMounts,
)
suite.Assert().Equal(
map[string]interface{}{
"serverTLSBootstrap": true,
@ -153,14 +166,16 @@ func (suite *KubeletConfigSuite) TestReconcile() {
return nil
},
))
),
)
}
func (suite *KubeletConfigSuite) TestReconcileDefaults() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineKubelet: &v1alpha1.KubeletConfig{
@ -177,13 +192,23 @@ func (suite *KubeletConfigSuite) TestReconcileDefaults() {
ServiceSubnet: []string{constants.DefaultIPv4ServiceNet},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
kubeletConfig, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.KubeletConfigType, k8s.KubeletID, resource.VersionUndefined))
kubeletConfig, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.KubeletConfigType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -203,7 +228,8 @@ func (suite *KubeletConfigSuite) TestReconcileDefaults() {
return nil
},
))
),
)
}
func (suite *KubeletConfigSuite) TearDownTest() {

View File

@ -43,7 +43,7 @@ type KubeletSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -99,9 +99,18 @@ func (suite *KubeletSpecSuite) TestReconcileDefault() {
suite.Require().NoError(suite.state.Create(suite.ctx, nodename))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
kubeletSpec, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined))
kubeletSpec, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.KubeletSpecType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -125,7 +134,8 @@ func (suite *KubeletSpecSuite) TestReconcileDefault() {
"--hostname-override=example.com",
"--kubeconfig=/etc/kubernetes/kubeconfig-kubelet",
"--node-ip=172.20.0.2",
}, spec.Args)
}, spec.Args,
)
suite.Assert().Equal(cfg.TypedSpec().ExtraMounts, spec.ExtraMounts)
suite.Assert().Equal([]interface{}{"10.96.0.10"}, spec.Config["clusterDNS"])
@ -133,7 +143,8 @@ func (suite *KubeletSpecSuite) TestReconcileDefault() {
return nil
},
))
),
)
}
func (suite *KubeletSpecSuite) TestReconcileWithExplicitNodeIP() {
@ -150,9 +161,18 @@ func (suite *KubeletSpecSuite) TestReconcileWithExplicitNodeIP() {
suite.Require().NoError(suite.state.Create(suite.ctx, nodename))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
kubeletSpec, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined))
kubeletSpec, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.KubeletSpecType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -174,11 +194,13 @@ func (suite *KubeletSpecSuite) TestReconcileWithExplicitNodeIP() {
"--hostname-override=example.com",
"--kubeconfig=/etc/kubernetes/kubeconfig-kubelet",
"--node-ip=10.0.0.1",
}, spec.Args)
}, spec.Args,
)
return nil
},
))
),
)
}
func (suite *KubeletSpecSuite) TestReconcileWithExtraConfig() {
@ -202,9 +224,18 @@ func (suite *KubeletSpecSuite) TestReconcileWithExtraConfig() {
suite.Require().NoError(suite.state.Create(suite.ctx, nodeIP))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
kubeletSpec, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.KubeletSpecType, k8s.KubeletID, resource.VersionUndefined))
kubeletSpec, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.KubeletSpecType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -217,7 +248,10 @@ func (suite *KubeletSpecSuite) TestReconcileWithExtraConfig() {
var kubeletConfiguration kubeletconfig.KubeletConfiguration
if err := k8sruntime.DefaultUnstructuredConverter.FromUnstructured(spec.Config, &kubeletConfiguration); err != nil {
if err := k8sruntime.DefaultUnstructuredConverter.FromUnstructured(
spec.Config,
&kubeletConfiguration,
); err != nil {
return err
}
@ -227,7 +261,8 @@ func (suite *KubeletSpecSuite) TestReconcileWithExtraConfig() {
return nil
},
))
),
)
}
func (suite *KubeletSpecSuite) TearDownTest() {
@ -276,23 +311,28 @@ func TestNewKubeletConfigurationFail(t *testing.T) {
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Run(
tt.name, func(t *testing.T) {
_, err := k8sctrl.NewKubeletConfiguration([]string{"10.96.0.10"}, "cluster.svc", tt.extraConfig)
require.Error(t, err)
assert.EqualError(t, err, tt.expectedErr)
})
},
)
}
}
func TestNewKubeletConfigurationSuccess(t *testing.T) {
config, err := k8sctrl.NewKubeletConfiguration([]string{"10.0.0.5"}, "cluster.local", map[string]interface{}{
config, err := k8sctrl.NewKubeletConfiguration(
[]string{"10.0.0.5"}, "cluster.local", map[string]interface{}{
"oomScoreAdj": -300,
"enableDebuggingHandlers": true,
})
},
)
require.NoError(t, err)
assert.Equal(t, &kubeletconfig.KubeletConfiguration{
assert.Equal(
t, &kubeletconfig.KubeletConfiguration{
TypeMeta: metav1.TypeMeta{
APIVersion: kubeletconfig.SchemeGroupVersion.String(),
Kind: "KubeletConfiguration",
@ -339,5 +379,6 @@ func TestNewKubeletConfigurationSuccess(t *testing.T) {
TLSMinVersion: "VersionTLS13",
EnableDebuggingHandlers: pointer.ToBool(true),
},
config)
config,
)
}

View File

@ -39,7 +39,7 @@ type ManifestSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -70,7 +70,10 @@ func (suite *ManifestSuite) startRuntime() {
//nolint:dupl
func (suite *ManifestSuite) assertManifests(manifests []string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -124,7 +127,8 @@ func (suite *ManifestSuite) TestReconcileDefaults() {
suite.Require().NoError(suite.state.Create(suite.ctx, rootSecrets))
suite.Require().NoError(suite.state.Create(suite.ctx, manifestConfig))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertManifests(
[]string{
@ -142,7 +146,8 @@ func (suite *ManifestSuite) TestReconcileDefaults() {
},
)
},
))
),
)
}
func (suite *ManifestSuite) TestReconcileDisableKubeProxy() {
@ -155,7 +160,8 @@ func (suite *ManifestSuite) TestReconcileDisableKubeProxy() {
suite.Require().NoError(suite.state.Create(suite.ctx, rootSecrets))
suite.Require().NoError(suite.state.Create(suite.ctx, manifestConfig))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertManifests(
[]string{
@ -172,7 +178,8 @@ func (suite *ManifestSuite) TestReconcileDisableKubeProxy() {
},
)
},
))
),
)
}
func (suite *ManifestSuite) TestReconcileKubeProxyExtraArgs() {
@ -185,7 +192,8 @@ func (suite *ManifestSuite) TestReconcileKubeProxyExtraArgs() {
suite.Require().NoError(suite.state.Create(suite.ctx, rootSecrets))
suite.Require().NoError(suite.state.Create(suite.ctx, manifestConfig))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertManifests(
[]string{
@ -203,9 +211,18 @@ func (suite *ManifestSuite) TestReconcileKubeProxyExtraArgs() {
},
)
},
))
),
)
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.ControlPlaneNamespaceName, k8s.ManifestType, "10-kube-proxy", resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.ControlPlaneNamespaceName,
k8s.ManifestType,
"10-kube-proxy",
resource.VersionUndefined,
),
)
suite.Require().NoError(err)
manifest := r.(*k8s.Manifest) //nolint:errcheck,forcetypeassert
@ -230,7 +247,8 @@ func (suite *ManifestSuite) TestReconcileDisablePSP() {
suite.Require().NoError(suite.state.Create(suite.ctx, rootSecrets))
suite.Require().NoError(suite.state.Create(suite.ctx, manifestConfig))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertManifests(
[]string{
@ -247,7 +265,8 @@ func (suite *ManifestSuite) TestReconcileDisablePSP() {
},
)
},
))
),
)
}
func (suite *ManifestSuite) TearDownTest() {

View File

@ -37,7 +37,7 @@ type NodeIPConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -70,7 +70,8 @@ func (suite *NodeIPConfigSuite) TestReconcileWithSubnets() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineKubelet: &v1alpha1.KubeletConfig{
@ -107,13 +108,23 @@ func (suite *NodeIPConfigSuite) TestReconcileWithSubnets() {
PodSubnet: []string{constants.DefaultIPv4PodNet},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
NodeIPConfig, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.NodeIPConfigType, k8s.KubeletID, resource.VersionUndefined))
NodeIPConfig, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.NodeIPConfigType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -125,18 +136,23 @@ func (suite *NodeIPConfigSuite) TestReconcileWithSubnets() {
spec := NodeIPConfig.(*k8s.NodeIPConfig).TypedSpec()
suite.Assert().Equal([]string{"10.0.0.0/24"}, spec.ValidSubnets)
suite.Assert().Equal([]string{"10.244.0.0/16", "10.96.0.0/12", "1.2.3.4", "5.6.7.8"}, spec.ExcludeSubnets)
suite.Assert().Equal(
[]string{"10.244.0.0/16", "10.96.0.0/12", "1.2.3.4", "5.6.7.8"},
spec.ExcludeSubnets,
)
return nil
},
))
),
)
}
func (suite *NodeIPConfigSuite) TestReconcileDefaults() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -150,13 +166,23 @@ func (suite *NodeIPConfigSuite) TestReconcileDefaults() {
PodSubnet: []string{constants.DefaultIPv4PodNet, constants.DefaultIPv6PodNet},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
NodeIPConfig, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.NodeIPConfigType, k8s.KubeletID, resource.VersionUndefined))
NodeIPConfig, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
k8s.NamespaceName,
k8s.NodeIPConfigType,
k8s.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -168,11 +194,15 @@ func (suite *NodeIPConfigSuite) TestReconcileDefaults() {
spec := NodeIPConfig.(*k8s.NodeIPConfig).TypedSpec()
suite.Assert().Equal([]string{"0.0.0.0/0", "::/0"}, spec.ValidSubnets)
suite.Assert().Equal([]string{"10.244.0.0/16", "fc00:db8:10::/56", "10.96.0.0/12", "fc00:db8:20::/112"}, spec.ExcludeSubnets)
suite.Assert().Equal(
[]string{"10.244.0.0/16", "fc00:db8:10::/56", "10.96.0.0/12", "fc00:db8:20::/112"},
spec.ExcludeSubnets,
)
return nil
},
))
),
)
}
func (suite *NodeIPConfigSuite) TearDownTest() {

View File

@ -36,7 +36,7 @@ type NodeIPSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -75,7 +75,10 @@ func (suite *NodeIPSuite) TestReconcileIPv4() {
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
addresses := network.NewNodeAddress(network.NamespaceName, network.FilteredNodeAddressID(network.NodeAddressCurrentID, k8s.NodeAddressFilterNoK8s))
addresses := network.NewNodeAddress(
network.NamespaceName,
network.FilteredNodeAddressID(network.NodeAddressCurrentID, k8s.NodeAddressFilterNoK8s),
)
addresses.TypedSpec().Addresses = []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("10.0.0.2/32"), // excluded explicitly
@ -85,9 +88,13 @@ func (suite *NodeIPSuite) TestReconcileIPv4() {
suite.Require().NoError(suite.state.Create(suite.ctx, addresses))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
NodeIP, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.NodeIPType, k8s.KubeletID, resource.VersionUndefined))
NodeIP, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.NodeIPType, k8s.KubeletID, resource.VersionUndefined),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -102,7 +109,8 @@ func (suite *NodeIPSuite) TestReconcileIPv4() {
return nil
},
))
),
)
}
func (suite *NodeIPSuite) TestReconcileDefaultSubnets() {
@ -114,7 +122,10 @@ func (suite *NodeIPSuite) TestReconcileDefaultSubnets() {
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
addresses := network.NewNodeAddress(network.NamespaceName, network.FilteredNodeAddressID(network.NodeAddressCurrentID, k8s.NodeAddressFilterNoK8s))
addresses := network.NewNodeAddress(
network.NamespaceName,
network.FilteredNodeAddressID(network.NodeAddressCurrentID, k8s.NodeAddressFilterNoK8s),
)
addresses.TypedSpec().Addresses = []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("10.0.0.5/24"),
@ -125,9 +136,13 @@ func (suite *NodeIPSuite) TestReconcileDefaultSubnets() {
suite.Require().NoError(suite.state.Create(suite.ctx, addresses))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
NodeIP, err := suite.state.Get(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.NodeIPType, k8s.KubeletID, resource.VersionUndefined))
NodeIP, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.NodeIPType, k8s.KubeletID, resource.VersionUndefined),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -142,7 +157,8 @@ func (suite *NodeIPSuite) TestReconcileDefaultSubnets() {
return nil
},
))
),
)
}
func (suite *NodeIPSuite) TearDownTest() {

View File

@ -38,7 +38,7 @@ type NodenameSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -69,7 +69,10 @@ func (suite *NodenameSuite) startRuntime() {
//nolint:dupl
func (suite *NodenameSuite) assertNodename(expected string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(k8s.NamespaceName, k8s.NodenameType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(k8s.NamespaceName, k8s.NodenameType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -83,7 +86,11 @@ func (suite *NodenameSuite) assertNodename(expected string) error {
}
if resources.Items[0].(*k8s.Nodename).TypedSpec().Nodename != expected {
return retry.ExpectedErrorf("expected %q, got %q", expected, resources.Items[0].(*k8s.Nodename).TypedSpec().Nodename)
return retry.ExpectedErrorf(
"expected %q, got %q",
expected,
resources.Items[0].(*k8s.Nodename).TypedSpec().Nodename,
)
}
return nil
@ -93,7 +100,8 @@ func (suite *NodenameSuite) TestDefault() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -103,7 +111,8 @@ func (suite *NodenameSuite) TestDefault() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
@ -113,18 +122,21 @@ func (suite *NodenameSuite) TestDefault() {
suite.Require().NoError(suite.state.Create(suite.ctx, hostnameStatus))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNodename("foo")
},
))
),
)
}
func (suite *NodenameSuite) TestFQDN() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineKubelet: &v1alpha1.KubeletConfig{
@ -138,7 +150,8 @@ func (suite *NodenameSuite) TestFQDN() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
@ -148,11 +161,13 @@ func (suite *NodenameSuite) TestFQDN() {
suite.Require().NoError(suite.state.Create(suite.ctx, hostnameStatus))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNodename("foo.bar.ltd")
},
))
),
)
}
func (suite *NodenameSuite) TearDownTest() {
@ -163,17 +178,26 @@ func (suite *NodenameSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}
suite.Require().NoError(err)
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewHostnameStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewHostnameStatus(network.NamespaceName, "bar"),
),
)
}
func TestNodenameSuite(t *testing.T) {

View File

@ -36,7 +36,7 @@ type StaticPodConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -65,7 +65,10 @@ func (suite *StaticPodConfigSuite) startRuntime() {
}()
}
func (suite *StaticPodConfigSuite) assertResource(md resource.Metadata, check func(res resource.Resource) error) func() error {
func (suite *StaticPodConfigSuite) assertResource(
md resource.Metadata,
check func(res resource.Resource) error,
) func() error {
return func() error {
r, err := suite.state.Get(suite.ctx, md)
if err != nil {
@ -96,7 +99,8 @@ func (suite *StaticPodConfigSuite) assertNoResource(md resource.Metadata) func()
}
func (suite *StaticPodConfigSuite) TestReconcile() {
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachinePods: []v1alpha1.Unstructured{
@ -120,11 +124,13 @@ func (suite *StaticPodConfigSuite) TestReconcile() {
},
},
ClusterConfig: &v1alpha1.ClusterConfig{},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
*k8s.NewStaticPod(k8s.NamespaceName, "default-nginx").Metadata(),
func(res resource.Resource) error {
@ -136,7 +142,8 @@ func (suite *StaticPodConfigSuite) TestReconcile() {
return nil
},
),
))
),
)
// update the pod changing the namespace
cfg.Config().Raw().(*v1alpha1.Config).MachineConfig.MachinePods[0].Object["metadata"].(map[string]interface{})["namespace"] = "custom"
@ -144,16 +151,23 @@ func (suite *StaticPodConfigSuite) TestReconcile() {
cfg.Metadata().BumpVersion()
suite.Require().NoError(suite.state.Update(suite.ctx, oldVersion, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResource(
*k8s.NewStaticPod(k8s.NamespaceName, "default-nginx").Metadata(),
),
))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
),
)
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
*k8s.NewStaticPod(k8s.NamespaceName, "custom-nginx").Metadata(),
func(res resource.Resource) error {
v, ok, err := unstructured.NestedString(res.(*k8s.StaticPod).TypedSpec().Pod, "metadata", "namespace")
v, ok, err := unstructured.NestedString(
res.(*k8s.StaticPod).TypedSpec().Pod,
"metadata",
"namespace",
)
suite.Require().NoError(err)
suite.Assert().True(ok)
suite.Assert().Equal("custom", v)
@ -161,7 +175,8 @@ func (suite *StaticPodConfigSuite) TestReconcile() {
return nil
},
),
))
),
)
// remove all pods
cfg.Config().Raw().(*v1alpha1.Config).MachineConfig.MachinePods = nil
@ -169,11 +184,13 @@ func (suite *StaticPodConfigSuite) TestReconcile() {
cfg.Metadata().BumpVersion()
suite.Require().NoError(suite.state.Update(suite.ctx, oldVersion, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResource(
*k8s.NewStaticPod(k8s.NamespaceName, "custom-nginx").Metadata(),
),
))
),
)
}
func (suite *StaticPodConfigSuite) TearDownTest() {

View File

@ -33,7 +33,7 @@ type KubeSpanSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -136,10 +136,14 @@ func (suite *KubeSpanSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -40,10 +40,12 @@ func (suite *ManagerSuite) TestDisabled() {
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResourceType(
resource.NewMetadata(kubespan.NamespaceName, kubespan.PeerStatusType, "", resource.VersionUndefined),
)),
),
),
)
}
@ -114,7 +116,9 @@ func (suite *ManagerSuite) TestReconcile() {
mockWireguard := &mockWireguardClient{}
mockNfTables := &mockNftablesManager{}
suite.Require().NoError(suite.runtime.RegisterController(&kubespanctrl.ManagerController{
suite.Require().NoError(
suite.runtime.RegisterController(
&kubespanctrl.ManagerController{
WireguardClientFactory: func() (kubespanctrl.WireguardClient, error) {
return mockWireguard, nil
},
@ -125,7 +129,9 @@ func (suite *ManagerSuite) TestReconcile() {
return mockNfTables
},
PeerReconcileInterval: time.Second,
}))
},
),
)
suite.startRuntime()
@ -140,11 +146,17 @@ func (suite *ManagerSuite) TestReconcile() {
localIdentity := kubespan.NewIdentity(kubespan.NamespaceName, kubespan.LocalIdentity)
suite.Require().NoError(kubespanadapter.IdentitySpec(localIdentity.TypedSpec()).GenerateKey())
suite.Require().NoError(kubespanadapter.IdentitySpec(localIdentity.TypedSpec()).UpdateAddress("v16UCWpO2iOm82n6F8dGCJ41ZXXBvDrjRDs2su7C_zs=", mac))
suite.Require().NoError(
kubespanadapter.IdentitySpec(localIdentity.TypedSpec()).UpdateAddress(
"v16UCWpO2iOm82n6F8dGCJ41ZXXBvDrjRDs2su7C_zs=",
mac,
),
)
suite.Require().NoError(suite.state.Create(suite.ctx, localIdentity))
// initial setup: link should be created without any peers
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(
network.ConfigNamespaceName,
@ -170,14 +182,19 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
),
))
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(
network.ConfigNamespaceName,
network.AddressSpecType,
network.LayeredID(network.ConfigOperator, network.AddressID(constants.KubeSpanLinkName, localIdentity.TypedSpec().Address)),
network.LayeredID(
network.ConfigOperator,
network.AddressID(constants.KubeSpanLinkName, localIdentity.TypedSpec().Address),
),
resource.VersionUndefined,
),
func(res resource.Resource) error {
@ -194,9 +211,11 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
),
))
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResourceIDs(
resource.NewMetadata(
network.ConfigNamespaceName,
@ -205,17 +224,38 @@ func (suite *ManagerSuite) TestReconcile() {
resource.VersionUndefined,
),
[]resource.ID{
network.LayeredID(network.ConfigOperator, network.RouteID(constants.KubeSpanDefaultRoutingTable, nethelpers.FamilyInet4, netaddr.IPPrefix{}, netaddr.IP{}, 1)),
network.LayeredID(network.ConfigOperator, network.RouteID(constants.KubeSpanDefaultRoutingTable, nethelpers.FamilyInet6, netaddr.IPPrefix{}, netaddr.IP{}, 1)),
network.LayeredID(
network.ConfigOperator,
network.RouteID(
constants.KubeSpanDefaultRoutingTable,
nethelpers.FamilyInet4,
netaddr.IPPrefix{},
netaddr.IP{},
1,
),
),
network.LayeredID(
network.ConfigOperator,
network.RouteID(
constants.KubeSpanDefaultRoutingTable,
nethelpers.FamilyInet6,
netaddr.IPPrefix{},
netaddr.IP{},
1,
),
),
},
),
))
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResourceType(
resource.NewMetadata(kubespan.NamespaceName, kubespan.PeerStatusType, "", resource.VersionUndefined),
),
))
),
)
// add two peers, they should be added to the wireguard link spec and should be tracked in peer statuses
peer1 := kubespan.NewPeerSpec(kubespan.NamespaceName, "3FxU7UuwektMjbyuJBs7i1hDj2rQA6tHnbNB6WrQxww=")
@ -246,7 +286,8 @@ func (suite *ManagerSuite) TestReconcile() {
key2, err := wgtypes.ParseKey(peer2.Metadata().ID())
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(
network.ConfigNamespaceName,
@ -271,14 +312,21 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
),
))
),
)
for _, peer := range []*kubespan.PeerSpec{peer1, peer2} {
peer := peer
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(kubespan.NamespaceName, kubespan.PeerStatusType, peer.Metadata().ID(), resource.VersionUndefined),
resource.NewMetadata(
kubespan.NamespaceName,
kubespan.PeerStatusType,
peer.Metadata().ID(),
resource.VersionUndefined,
),
func(res resource.Resource) error {
spec := res.(*kubespan.PeerStatus).TypedSpec()
@ -291,10 +339,12 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
),
))
),
)
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
ipSet := mockNfTables.IPSet()
@ -311,7 +361,8 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
))
),
)
// update config and disable force routing, nothing should be routed
oldVersion := cfg.Metadata().Version()
@ -319,7 +370,8 @@ func (suite *ManagerSuite) TestReconcile() {
cfg.Metadata().BumpVersion()
suite.Require().NoError(suite.state.Update(suite.ctx, oldVersion, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
ipSet := mockNfTables.IPSet()
@ -333,10 +385,12 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
))
),
)
// report up status via wireguard mock
mockWireguard.update(&wgtypes.Device{
mockWireguard.update(
&wgtypes.Device{
Peers: []wgtypes.Peer{
{
PublicKey: key1,
@ -349,14 +403,21 @@ func (suite *ManagerSuite) TestReconcile() {
LastHandshakeTime: time.Now(),
},
},
})
},
)
for _, peer := range []*kubespan.PeerSpec{peer1, peer2} {
peer := peer
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertResource(
resource.NewMetadata(kubespan.NamespaceName, kubespan.PeerStatusType, peer.Metadata().ID(), resource.VersionUndefined),
resource.NewMetadata(
kubespan.NamespaceName,
kubespan.PeerStatusType,
peer.Metadata().ID(),
resource.VersionUndefined,
),
func(res resource.Resource) error {
spec := res.(*kubespan.PeerStatus).TypedSpec()
@ -367,11 +428,13 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
),
))
),
)
}
// as the peers are now up, all traffic should be routed via KubeSpan
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
ipSet := mockNfTables.IPSet()
@ -388,7 +451,8 @@ func (suite *ManagerSuite) TestReconcile() {
return nil
},
))
),
)
// update config and disable wireguard, everything should be cleaned up
oldVersion = cfg.Metadata().Version()
@ -396,11 +460,18 @@ func (suite *ManagerSuite) TestReconcile() {
cfg.Metadata().BumpVersion()
suite.Require().NoError(suite.state.Update(suite.ctx, oldVersion, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.assertNoResource(
resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, network.LayeredID(network.ConfigOperator, network.LinkID(constants.KubeSpanLinkName)), resource.VersionUndefined),
resource.NewMetadata(
network.ConfigNamespaceName,
network.LinkSpecType,
network.LayeredID(network.ConfigOperator, network.LinkID(constants.KubeSpanLinkName)),
resource.VersionUndefined,
),
))
),
),
)
}
func TestManagerSuite(t *testing.T) {

View File

@ -41,7 +41,7 @@ type AddressConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -73,7 +73,10 @@ func (suite *AddressConfigSuite) assertAddresses(requiredIDs []string, check fun
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.AddressSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.AddressSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -103,42 +106,60 @@ func (suite *AddressConfigSuite) TestLoopback() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
"default/lo/127.0.0.1/8",
}, func(r *network.AddressSpec) error {
suite.Assert().Equal("lo", r.TypedSpec().LinkName)
suite.Assert().Equal(nethelpers.ScopeHost, r.TypedSpec().Scope)
return nil
})
}))
},
)
},
),
)
}
func (suite *AddressConfigSuite) TestCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.AddressConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.AddressConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2::172.20.0.1:255.255.255.0::eth1:::::"),
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
"cmdline/eth1/172.20.0.2/24",
}, func(r *network.AddressSpec) error {
suite.Assert().Equal("eth1", r.TypedSpec().LinkName)
return nil
})
}))
},
)
},
),
)
}
func (suite *AddressConfigSuite) TestCmdlineNoNetmask() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.AddressConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.AddressConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2::172.20.0.1"),
}))
},
),
)
suite.startRuntime()
@ -160,17 +181,22 @@ func (suite *AddressConfigSuite) TestCmdlineNoNetmask() {
suite.Assert().NotEmpty(ifaceName)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
fmt.Sprintf("cmdline/%s/172.20.0.2/32", ifaceName),
}, func(r *network.AddressSpec) error {
suite.Assert().Equal(ifaceName, r.TypedSpec().LinkName)
suite.Assert().Equal(network.ConfigCmdline, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *AddressConfigSuite) TestMachineConfiguration() {
@ -181,7 +207,8 @@ func (suite *AddressConfigSuite) TestMachineConfiguration() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -235,13 +262,16 @@ func (suite *AddressConfigSuite) TestMachineConfiguration() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
"configuration/eth2/2001:470:6d:30e:8ed2:b60c:9d2f:803a/64",
"configuration/eth3/192.168.0.24/28",
"configuration/eth5/10.5.0.7/32",
@ -251,8 +281,11 @@ func (suite *AddressConfigSuite) TestMachineConfiguration() {
"configuration/eth0.25/11.0.0.1/8",
}, func(r *network.AddressSpec) error {
return nil
})
}))
},
)
},
),
)
}
func (suite *AddressConfigSuite) TearDownTest() {
@ -263,10 +296,14 @@ func (suite *AddressConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -49,7 +49,7 @@ type AddressEventsSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -67,9 +67,13 @@ func (suite *AddressEventsSuite) SetupTest() {
suite.runtime, err = runtime.NewRuntime(suite.state, logging.Wrap(log.Writer()))
suite.Require().NoError(err)
suite.Require().NoError(suite.runtime.RegisterController(&network.AddressEventController{
suite.Require().NoError(
suite.runtime.RegisterController(
&network.AddressEventController{
V1Alpha1Events: suite.events,
}))
},
),
)
suite.startRuntime()
}
@ -92,7 +96,8 @@ func (suite *AddressEventsSuite) TestReconcile() {
var event *machine.AddressEvent
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
suite.events.messagesMu.Lock()
defer suite.events.messagesMu.Unlock()
@ -116,14 +121,17 @@ func (suite *AddressEventsSuite) TestReconcile() {
return nil
},
))
),
)
suite.Require().Equal(hostname.TypedSpec().Hostname, event.Hostname)
suite.Require().Empty(event.Addresses)
nodeAddress := networkresource.NewNodeAddress(networkresource.NamespaceName, networkresource.FilteredNodeAddressID(
nodeAddress := networkresource.NewNodeAddress(
networkresource.NamespaceName, networkresource.FilteredNodeAddressID(
networkresource.NodeAddressCurrentID,
k8s.NodeAddressFilterNoK8s),
k8s.NodeAddressFilterNoK8s,
),
)
addrs := []string{
@ -139,7 +147,8 @@ func (suite *AddressEventsSuite) TestReconcile() {
suite.Require().NoError(suite.state.Create(suite.ctx, nodeAddress))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
suite.events.messagesMu.Lock()
defer suite.events.messagesMu.Unlock()
@ -163,7 +172,8 @@ func (suite *AddressEventsSuite) TestReconcile() {
return nil
},
))
),
)
suite.Require().Equal(addrs, event.Addresses)
}

View File

@ -37,7 +37,7 @@ type AddressMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -73,7 +73,10 @@ func (suite *AddressMergeSuite) assertAddresses(requiredIDs []string, check func
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -99,7 +102,10 @@ func (suite *AddressMergeSuite) assertAddresses(requiredIDs []string, check func
}
func (suite *AddressMergeSuite) assertNoAddress(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -154,9 +160,11 @@ func (suite *AddressMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
"lo/127.0.0.1/8",
"eth0/10.0.0.1/8",
"eth0/10.0.0.35/32",
@ -171,24 +179,35 @@ func (suite *AddressMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, static.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
"lo/127.0.0.1/8",
"eth0/10.0.0.35/32",
}, func(r *network.AddressSpec) error {
return nil
})
}))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
},
)
},
),
)
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoAddress("eth0/10.0.0.35/32")
}))
},
),
)
}
//nolint:gocyclo
@ -236,10 +255,20 @@ func (suite *AddressMergeSuite) TestMergeFlapping() {
eg.Go(flipflop(0))
eg.Go(flipflop(1))
eg.Go(func() error {
eg.Go(
func() error {
// add/remove finalizer to the merged resource
for i := 0; i < 1000; i++ {
if err := suite.state.AddFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "eth0/10.0.0.1/8", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.AddFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.AddressSpecType,
"eth0/10.0.0.1/8",
resource.VersionUndefined,
),
"foo",
); err != nil {
if !state.IsNotFoundError(err) {
return err
}
@ -251,7 +280,16 @@ func (suite *AddressMergeSuite) TestMergeFlapping() {
time.Sleep(10 * time.Millisecond)
if err := suite.state.RemoveFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.AddressSpecType, "eth0/10.0.0.1/8", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.RemoveFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.AddressSpecType,
"eth0/10.0.0.1/8",
resource.VersionUndefined,
),
"foo",
); err != nil {
if err != nil && !state.IsNotFoundError(err) {
return err
}
@ -259,13 +297,16 @@ func (suite *AddressMergeSuite) TestMergeFlapping() {
}
return nil
})
},
)
suite.Require().NoError(eg.Wait())
suite.Assert().NoError(retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
"eth0/10.0.0.1/8",
}, func(r *network.AddressSpec) error {
if r.Metadata().Phase() != resource.PhaseRunning {
@ -278,8 +319,11 @@ func (suite *AddressMergeSuite) TestMergeFlapping() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *AddressMergeSuite) TearDownTest() {
@ -290,7 +334,12 @@ func (suite *AddressMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewAddressSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewAddressSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestAddressMergeSuite(t *testing.T) {

View File

@ -146,7 +146,8 @@ func findAddress(addrs []rtnetlink.AddressMessage, linkIndex uint32, ipPrefix ne
//nolint:gocyclo
func (ctrl *AddressSpecController) syncAddress(ctx context.Context, r controller.Runtime, logger *zap.Logger, conn *rtnetlink.Conn,
links []rtnetlink.LinkMessage, addrs []rtnetlink.AddressMessage, address *network.AddressSpec) error {
links []rtnetlink.LinkMessage, addrs []rtnetlink.AddressMessage, address *network.AddressSpec,
) error {
linkIndex := resolveLinkName(links, address.TypedSpec().LinkName)
switch address.Metadata().Phase() {

View File

@ -40,7 +40,7 @@ type AddressSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -144,10 +144,13 @@ func (suite *AddressSpecSuite) TestLoopback() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinkAddress("lo", "127.11.0.1/32")
}))
},
),
)
// teardown the address
for {
@ -191,7 +194,9 @@ func (suite *AddressSpecSuite) TestDummy() {
}
// create dummy interface
suite.Require().NoError(conn.Link.New(&rtnetlink.LinkMessage{
suite.Require().NoError(
conn.Link.New(
&rtnetlink.LinkMessage{
Type: unix.ARPHRD_ETHER,
Attributes: &rtnetlink.LinkAttributes{
Name: dummyInterface,
@ -200,17 +205,22 @@ func (suite *AddressSpecSuite) TestDummy() {
Kind: "dummy",
},
},
}))
},
),
)
iface, err := net.InterfaceByName(dummyInterface)
suite.Require().NoError(err)
defer conn.Link.Delete(uint32(iface.Index)) //nolint:errcheck
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinkAddress(dummyInterface, "10.0.0.1/8")
}))
},
),
)
// delete dummy interface, address should be unassigned automatically
suite.Require().NoError(conn.Link.Delete(uint32(iface.Index)))
@ -236,7 +246,12 @@ func (suite *AddressSpecSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewAddressSpec(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewAddressSpec(network.NamespaceName, "bar"),
),
)
}
func TestAddressSpecSuite(t *testing.T) {

View File

@ -34,7 +34,7 @@ type AddressStatusSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -70,7 +70,10 @@ func (suite *AddressStatusSuite) assertAddresses(requiredIDs []string, check fun
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.AddressStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.AddressStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -96,12 +99,17 @@ func (suite *AddressStatusSuite) assertAddresses(requiredIDs []string, check fun
}
func (suite *AddressStatusSuite) TestLoopback() {
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{"lo/127.0.0.1/8"}, func(r *network.AddressStatus) error {
return suite.assertAddresses(
[]string{"lo/127.0.0.1/8"}, func(r *network.AddressStatus) error {
return nil
})
}))
},
)
},
),
)
}
func (suite *AddressStatusSuite) TearDownTest() {

View File

@ -39,7 +39,7 @@ type EtcFileConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
cfg *config.MachineConfig
@ -65,7 +65,8 @@ func (suite *EtcFileConfigSuite) SetupTest() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
suite.cfg = config.NewMachineConfig(&v1alpha1.Config{
suite.cfg = config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -88,7 +89,8 @@ func (suite *EtcFileConfigSuite) SetupTest() {
},
},
},
})
},
)
suite.defaultAddress = network.NewNodeAddress(network.NamespaceName, network.NodeAddressDefaultID)
suite.defaultAddress.TypedSpec().Addresses = []netaddr.IPPrefix{netaddr.MustParseIPPrefix("33.11.22.44/32")}
@ -98,7 +100,12 @@ func (suite *EtcFileConfigSuite) SetupTest() {
suite.hostnameStatus.TypedSpec().Domainname = "example.com"
suite.resolverStatus = network.NewResolverStatus(network.NamespaceName, network.ResolverID)
suite.resolverStatus.TypedSpec().DNSServers = []netaddr.IP{netaddr.MustParseIP("1.1.1.1"), netaddr.MustParseIP("2.2.2.2"), netaddr.MustParseIP("3.3.3.3"), netaddr.MustParseIP("4.4.4.4")}
suite.resolverStatus.TypedSpec().DNSServers = []netaddr.IP{
netaddr.MustParseIP("1.1.1.1"),
netaddr.MustParseIP("2.2.2.2"),
netaddr.MustParseIP("3.3.3.3"),
netaddr.MustParseIP("4.4.4.4"),
}
}
func (suite *EtcFileConfigSuite) startRuntime() {
@ -118,7 +125,10 @@ func (suite *EtcFileConfigSuite) assertEtcFiles(requiredIDs []string, check func
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(files.NamespaceName, files.EtcFileSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(files.NamespaceName, files.EtcFileSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -144,7 +154,10 @@ func (suite *EtcFileConfigSuite) assertEtcFiles(requiredIDs []string, check func
}
func (suite *EtcFileConfigSuite) assertNoEtcFile(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(files.NamespaceName, files.EtcFileSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(files.NamespaceName, files.EtcFileSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -177,7 +190,8 @@ func (suite *EtcFileConfigSuite) testFiles(resources []resource.Resource, resolv
unexpectedIds = append(unexpectedIds, "hosts")
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertEtcFiles(
expectedIds,
@ -190,28 +204,36 @@ func (suite *EtcFileConfigSuite) testFiles(resources []resource.Resource, resolv
}
return nil
})
}))
},
)
},
),
)
for _, id := range unexpectedIds {
id := id
suite.Assert().NoError(retry.Constant(1*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(1*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoEtcFile(id)
}))
},
),
)
}
}
func (suite *EtcFileConfigSuite) TestComplete() {
suite.testFiles([]resource.Resource{suite.cfg, suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus},
suite.testFiles(
[]resource.Resource{suite.cfg, suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus},
"nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n\nsearch example.com\n",
"127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters\n\n10.0.0.1 a b \n10.0.0.2 c d ", //nolint:lll
)
}
func (suite *EtcFileConfigSuite) TestNoExtraHosts() {
suite.testFiles([]resource.Resource{suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus},
suite.testFiles(
[]resource.Resource{suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus},
"nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n\nsearch example.com\n",
"127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters",
)
@ -220,21 +242,24 @@ func (suite *EtcFileConfigSuite) TestNoExtraHosts() {
func (suite *EtcFileConfigSuite) TestNoDomainname() {
suite.hostnameStatus.TypedSpec().Domainname = ""
suite.testFiles([]resource.Resource{suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus},
suite.testFiles(
[]resource.Resource{suite.defaultAddress, suite.hostnameStatus, suite.resolverStatus},
"nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n",
"127.0.0.1 localhost\n33.11.22.44 foo \n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters",
)
}
func (suite *EtcFileConfigSuite) TestOnlyResolvers() {
suite.testFiles([]resource.Resource{suite.resolverStatus},
suite.testFiles(
[]resource.Resource{suite.resolverStatus},
"nameserver 1.1.1.1\nnameserver 2.2.2.2\nnameserver 3.3.3.3\n",
"",
)
}
func (suite *EtcFileConfigSuite) TestOnlyHostname() {
suite.testFiles([]resource.Resource{suite.defaultAddress, suite.hostnameStatus},
suite.testFiles(
[]resource.Resource{suite.defaultAddress, suite.hostnameStatus},
"",
"127.0.0.1 localhost\n33.11.22.44 foo.example.com foo\n::1 localhost ip6-localhost ip6-loopback\nff02::1 ip6-allnodes\nff02::2 ip6-allrouters",
)
@ -248,19 +273,38 @@ func (suite *EtcFileConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}
suite.Require().NoError(err)
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewHostnameStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewResolverStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewNodeAddress(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewHostnameStatus(network.NamespaceName, "bar"),
),
)
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewResolverStatus(network.NamespaceName, "bar"),
),
)
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewNodeAddress(network.NamespaceName, "bar"),
),
)
}
func TestEtcFileConfigSuite(t *testing.T) {

View File

@ -36,7 +36,7 @@ type HardwareAddrSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *HardwareAddrSuite) assertHWAddr(requiredIDs []string, check func(*n
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.HardwareAddrType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.HardwareAddrType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -98,7 +101,10 @@ func (suite *HardwareAddrSuite) assertHWAddr(requiredIDs []string, check func(*n
}
func (suite *HardwareAddrSuite) assertNoHWAddr(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.HardwareAddrType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.HardwareAddrType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -136,37 +142,50 @@ func (suite *HardwareAddrSuite) TestFirst() {
suite.Require().NoError(suite.state.Create(suite.ctx, bond0))
suite.Require().NoError(suite.state.Create(suite.ctx, eth1))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHWAddr([]string{network.FirstHardwareAddr}, func(r *network.HardwareAddr) error {
return suite.assertHWAddr(
[]string{network.FirstHardwareAddr}, func(r *network.HardwareAddr) error {
if r.TypedSpec().Name != eth1.Metadata().ID() && net.HardwareAddr(r.TypedSpec().HardwareAddr).String() != "6a:2b:bd:b2:fc:e0" {
return retry.ExpectedErrorf("should be eth1")
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Create(suite.ctx, eth0))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHWAddr([]string{network.FirstHardwareAddr}, func(r *network.HardwareAddr) error {
return suite.assertHWAddr(
[]string{network.FirstHardwareAddr}, func(r *network.HardwareAddr) error {
if r.TypedSpec().Name != eth0.Metadata().ID() && net.HardwareAddr(r.TypedSpec().HardwareAddr).String() != "56:a0:a0:87:1c:fa" {
return retry.ExpectedErrorf("should be eth0")
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, eth0.Metadata()))
suite.Require().NoError(suite.state.Destroy(suite.ctx, eth1.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoHWAddr(network.FirstHardwareAddr)
}))
},
),
)
}
func (suite *HardwareAddrSuite) TearDownTest() {
@ -177,7 +196,12 @@ func (suite *HardwareAddrSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkStatus(network.NamespaceName, "bar"),
),
)
}
func TestHardwareAddrSuite(t *testing.T) {

View File

@ -40,7 +40,7 @@ type HostnameConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *HostnameConfigSuite) assertHostnames(requiredIDs []string, check fu
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.HostnameSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.HostnameSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -98,7 +101,10 @@ func (suite *HostnameConfigSuite) assertHostnames(requiredIDs []string, check fu
}
func (suite *HostnameConfigSuite) assertNoHostname(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.HostnameSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.HostnameSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -122,9 +128,11 @@ func (suite *HostnameConfigSuite) TestDefaults() {
suite.Require().NoError(suite.state.Create(suite.ctx, defaultAddress))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHostnames([]string{
return suite.assertHostnames(
[]string{
"default/hostname",
}, func(r *network.HostnameSpec) error {
suite.Assert().Equal("talos-33-11-22-44", r.TypedSpec().Hostname)
@ -132,20 +140,29 @@ func (suite *HostnameConfigSuite) TestDefaults() {
suite.Assert().Equal(network.ConfigDefault, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *HostnameConfigSuite) TestCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.HostnameConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.HostnameConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2:172.21.0.1:172.20.0.1:255.255.255.0:master1.domain.tld:eth1::10.0.0.1:10.0.0.2:10.0.0.1"),
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHostnames([]string{
return suite.assertHostnames(
[]string{
"cmdline/hostname",
}, func(r *network.HostnameSpec) error {
suite.Assert().Equal("master1", r.TypedSpec().Hostname)
@ -153,8 +170,11 @@ func (suite *HostnameConfigSuite) TestCmdline() {
suite.Assert().Equal(network.ConfigCmdline, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *HostnameConfigSuite) TestMachineConfiguration() {
@ -165,7 +185,8 @@ func (suite *HostnameConfigSuite) TestMachineConfiguration() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -179,13 +200,16 @@ func (suite *HostnameConfigSuite) TestMachineConfiguration() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHostnames([]string{
return suite.assertHostnames(
[]string{
"configuration/hostname",
}, func(r *network.HostnameSpec) error {
suite.Assert().Equal("foo", r.TypedSpec().Hostname)
@ -193,20 +217,31 @@ func (suite *HostnameConfigSuite) TestMachineConfiguration() {
suite.Assert().Equal(network.ConfigMachineConfiguration, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
_, err = suite.state.UpdateWithConflicts(suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
r.(*config.MachineConfig).Config().(*v1alpha1.Config).MachineConfig.MachineNetwork.NetworkHostname = strings.Repeat("a", 128)
_, err = suite.state.UpdateWithConflicts(
suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
r.(*config.MachineConfig).Config().(*v1alpha1.Config).MachineConfig.MachineNetwork.NetworkHostname = strings.Repeat(
"a",
128,
)
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoHostname("configuration/hostname")
}))
},
),
)
}
func (suite *HostnameConfigSuite) TearDownTest() {
@ -217,17 +252,26 @@ func (suite *HostnameConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}
suite.Require().NoError(err)
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewNodeAddress(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewNodeAddress(network.NamespaceName, "bar"),
),
)
}
func TestHostnameConfigSuite(t *testing.T) {

View File

@ -34,7 +34,7 @@ type HostnameMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -70,7 +70,10 @@ func (suite *HostnameMergeSuite) assertHostnames(requiredIDs []string, check fun
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.HostnameSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.HostnameSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -126,9 +129,11 @@ func (suite *HostnameMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHostnames([]string{
return suite.assertHostnames(
[]string{
"hostname",
}, func(r *network.HostnameSpec) error {
suite.Assert().Equal("bar.com", r.TypedSpec().FQDN())
@ -136,14 +141,19 @@ func (suite *HostnameMergeSuite) TestMerge() {
suite.Assert().Equal("com", r.TypedSpec().Domainname)
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, static.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertHostnames([]string{
return suite.assertHostnames(
[]string{
"hostname",
}, func(r *network.HostnameSpec) error {
if r.TypedSpec().FQDN() != "eth-0" {
@ -151,8 +161,11 @@ func (suite *HostnameMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *HostnameMergeSuite) TearDownTest() {
@ -163,7 +176,12 @@ func (suite *HostnameMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewHostnameSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewHostnameSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestHostnameMergeSuite(t *testing.T) {

View File

@ -33,7 +33,7 @@ type HostnameSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -47,9 +47,13 @@ func (suite *HostnameSpecSuite) SetupTest() {
suite.runtime, err = runtime.NewRuntime(suite.state, logging.Wrap(log.Writer()))
suite.Require().NoError(err)
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.HostnameSpecController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.HostnameSpecController{
V1Alpha1Mode: v1alpha1runtime.ModeContainer, // run in container mode to skip _actually_ setting hostname
}))
},
),
)
suite.startRuntime()
}
@ -65,7 +69,10 @@ func (suite *HostnameSpecSuite) startRuntime() {
}
func (suite *HostnameSpecSuite) assertStatus(id string, fqdn string) error {
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, id, resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.HostnameStatusType, id, resource.VersionUndefined),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -95,10 +102,13 @@ func (suite *HostnameSpecSuite) TestSpec() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus("hostname", "foo.bar")
}))
},
),
)
}
func (suite *HostnameSpecSuite) TearDownTest() {
@ -109,7 +119,12 @@ func (suite *HostnameSpecSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewHostnameSpec(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewHostnameSpec(network.NamespaceName, "bar"),
),
)
}
func TestHostnameSpecSuite(t *testing.T) {

View File

@ -40,7 +40,7 @@ type LinkConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *LinkConfigSuite) assertLinks(requiredIDs []string, check func(*netw
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -104,7 +107,10 @@ func (suite *LinkConfigSuite) assertNoLinks(unexpectedIDs []string) error {
unexpIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.LinkSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -124,9 +130,11 @@ func (suite *LinkConfigSuite) TestLoopback() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"default/lo",
}, func(r *network.LinkSpec) error {
suite.Assert().Equal("lo", r.TypedSpec().Name)
@ -135,20 +143,29 @@ func (suite *LinkConfigSuite) TestLoopback() {
suite.Assert().Equal(network.ConfigDefault, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *LinkConfigSuite) TestCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.LinkConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.LinkConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2::172.20.0.1:255.255.255.0::eth1:::::"),
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"cmdline/eth1",
}, func(r *network.LinkSpec) error {
suite.Assert().Equal("eth1", r.TypedSpec().Name)
@ -157,8 +174,11 @@ func (suite *LinkConfigSuite) TestCmdline() {
suite.Assert().Equal(network.ConfigCmdline, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *LinkConfigSuite) TestMachineConfiguration() {
@ -169,7 +189,8 @@ func (suite *LinkConfigSuite) TestMachineConfiguration() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -245,13 +266,16 @@ func (suite *LinkConfigSuite) TestMachineConfiguration() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"configuration/eth0",
"configuration/eth0.24",
"configuration/eth0.48",
@ -305,7 +329,8 @@ func (suite *LinkConfigSuite) TestMachineConfiguration() {
suite.Assert().True(r.TypedSpec().Logical)
suite.Assert().Equal(nethelpers.LinkNone, r.TypedSpec().Type)
suite.Assert().Equal(network.LinkKindWireguard, r.TypedSpec().Kind)
suite.Assert().Equal(network.WireguardSpec{
suite.Assert().Equal(
network.WireguardSpec{
PrivateKey: "ABC",
Peers: []network.WireguardPeer{
{
@ -317,18 +342,26 @@ func (suite *LinkConfigSuite) TestMachineConfiguration() {
},
},
},
}, r.TypedSpec().Wireguard)
}, r.TypedSpec().Wireguard,
)
}
return nil
})
}))
},
)
},
),
)
}
func (suite *LinkConfigSuite) TestDefaultUp() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.LinkConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.LinkConfigController{
Cmdline: procfs.NewCmdline("talos.network.interface.ignore=eth2"),
}))
},
),
)
for _, link := range []string{"eth0", "eth1", "eth2", "eth3", "eth4"} {
linkStatus := network.NewLinkStatus(network.NamespaceName, link)
@ -341,7 +374,8 @@ func (suite *LinkConfigSuite) TestDefaultUp() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -382,33 +416,44 @@ func (suite *LinkConfigSuite) TestDefaultUp() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"default/eth1",
}, func(r *network.LinkSpec) error {
suite.Assert().Equal(network.ConfigDefault, r.TypedSpec().ConfigLayer)
suite.Assert().True(r.TypedSpec().Up)
return nil
})
}))
},
)
},
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoLinks([]string{
return suite.assertNoLinks(
[]string{
"default/eth0",
"default/eth2",
"default/eth3",
"default/eth4",
})
}))
},
)
},
),
)
}
func (suite *LinkConfigSuite) TearDownTest() {
@ -419,17 +464,26 @@ func (suite *LinkConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}
suite.Require().NoError(err)
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkStatus(network.NamespaceName, "bar"),
),
)
}
func TestLinkConfigSuite(t *testing.T) {

View File

@ -36,7 +36,7 @@ type LinkMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *LinkMergeSuite) assertLinks(requiredIDs []string, check func(*netwo
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.LinkSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -98,7 +101,10 @@ func (suite *LinkMergeSuite) assertLinks(requiredIDs []string, check func(*netwo
}
func (suite *LinkMergeSuite) assertNoLinks(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.AddressStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.AddressStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -140,9 +146,11 @@ func (suite *LinkMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"lo",
"eth0",
}, func(r *network.LinkSpec) error {
@ -154,14 +162,19 @@ func (suite *LinkMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, static.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"lo",
"eth0",
}, func(r *network.LinkSpec) error {
@ -176,15 +189,21 @@ func (suite *LinkMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, loopback.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoLinks("lo")
}))
},
),
)
}
func (suite *LinkMergeSuite) TestMergeLogicalLink() {
@ -211,9 +230,11 @@ func (suite *LinkMergeSuite) TestMergeLogicalLink() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"bond0",
}, func(r *network.LinkSpec) error {
if r.TypedSpec().MTU != 1450 {
@ -224,8 +245,11 @@ func (suite *LinkMergeSuite) TestMergeLogicalLink() {
suite.Assert().EqualValues(1450, r.TypedSpec().MTU)
return nil
})
}))
},
)
},
),
)
}
//nolint:gocyclo
@ -271,10 +295,20 @@ func (suite *LinkMergeSuite) TestMergeFlapping() {
eg.Go(flipflop(0))
eg.Go(flipflop(1))
eg.Go(func() error {
eg.Go(
func() error {
// add/remove finalizer to the merged resource
for i := 0; i < 1000; i++ {
if err := suite.state.AddFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkSpecType, "eth0", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.AddFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.LinkSpecType,
"eth0",
resource.VersionUndefined,
),
"foo",
); err != nil {
if !state.IsNotFoundError(err) {
return err
}
@ -286,7 +320,16 @@ func (suite *LinkMergeSuite) TestMergeFlapping() {
time.Sleep(10 * time.Millisecond)
if err := suite.state.RemoveFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkSpecType, "eth0", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.RemoveFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.LinkSpecType,
"eth0",
resource.VersionUndefined,
),
"foo",
); err != nil {
if err != nil && !state.IsNotFoundError(err) {
return err
}
@ -294,13 +337,16 @@ func (suite *LinkMergeSuite) TestMergeFlapping() {
}
return nil
})
},
)
suite.Require().NoError(eg.Wait())
suite.Assert().NoError(retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"eth0",
}, func(r *network.LinkSpec) error {
if r.Metadata().Phase() != resource.PhaseRunning {
@ -312,8 +358,11 @@ func (suite *LinkMergeSuite) TestMergeFlapping() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *LinkMergeSuite) TestMergeWireguard() {
@ -352,12 +401,17 @@ func (suite *LinkMergeSuite) TestMergeWireguard() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertLinks([]string{
return suite.assertLinks(
[]string{
"kubespan",
}, func(r *network.LinkSpec) error {
suite.Assert().Equal("IG9MqCII7z54Ysof1fQ9a7WcMNG+qNJRMyRCQz3JTUY=", r.TypedSpec().Wireguard.PrivateKey)
suite.Assert().Equal(
"IG9MqCII7z54Ysof1fQ9a7WcMNG+qNJRMyRCQz3JTUY=",
r.TypedSpec().Wireguard.PrivateKey,
)
suite.Assert().Equal(1234, r.TypedSpec().Wireguard.ListenPort)
suite.Assert().Len(r.TypedSpec().Wireguard.Peers, 2)
@ -378,15 +432,21 @@ func (suite *LinkMergeSuite) TestMergeWireguard() {
)
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, kubespanOperator.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoLinks("kubespan")
}))
},
),
)
}
func (suite *LinkMergeSuite) TearDownTest() {
@ -397,7 +457,12 @@ func (suite *LinkMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestLinkMergeSuite(t *testing.T) {

View File

@ -160,7 +160,8 @@ func findLink(links []rtnetlink.LinkMessage, name string) *rtnetlink.LinkMessage
//
//nolint:gocyclo,cyclop
func (ctrl *LinkSpecController) syncLink(ctx context.Context, r controller.Runtime, logger *zap.Logger, conn *rtnetlink.Conn, wgClient *wgctrl.Client,
links *[]rtnetlink.LinkMessage, link *network.LinkSpec) error {
links *[]rtnetlink.LinkMessage, link *network.LinkSpec,
) error {
logger = logger.With(zap.String("link", link.TypedSpec().Name))
switch link.Metadata().Phase() {

View File

@ -39,7 +39,7 @@ type LinkSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -78,7 +78,10 @@ func (suite *LinkSpecSuite) assertInterfaces(requiredIDs []string, check func(*n
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -104,7 +107,10 @@ func (suite *LinkSpecSuite) assertInterfaces(requiredIDs []string, check func(*n
}
func (suite *LinkSpecSuite) assertNoInterface(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -134,12 +140,17 @@ func (suite *LinkSpecSuite) TestLoopback() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{"lo"}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{"lo"}, func(r *network.LinkStatus) error {
return nil
})
}))
},
)
},
),
)
}
func (suite *LinkSpecSuite) TestDummy() {
@ -160,9 +171,11 @@ func (suite *LinkSpecSuite) TestDummy() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{dummyInterface}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{dummyInterface}, func(r *network.LinkStatus) error {
suite.Assert().Equal("dummy", r.TypedSpec().Kind)
if r.TypedSpec().OperationalState != nethelpers.OperStateUnknown && r.TypedSpec().OperationalState != nethelpers.OperStateUp {
@ -174,8 +187,11 @@ func (suite *LinkSpecSuite) TestDummy() {
}
return nil
})
}))
},
)
},
),
)
// teardown the link
for {
@ -189,10 +205,13 @@ func (suite *LinkSpecSuite) TestDummy() {
time.Sleep(100 * time.Millisecond)
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoInterface(dummyInterface)
}))
},
),
)
}
//nolint:gocyclo
@ -245,9 +264,11 @@ func (suite *LinkSpecSuite) TestVLAN() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{dummyInterface, vlanName1, vlanName2}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{dummyInterface, vlanName1, vlanName2}, func(r *network.LinkStatus) error {
switch r.Metadata().ID() {
case dummyInterface:
suite.Assert().Equal("dummy", r.TypedSpec().Kind)
@ -267,27 +288,37 @@ func (suite *LinkSpecSuite) TestVLAN() {
}
return nil
})
}))
},
)
},
),
)
// attempt to change VLAN ID
_, err := suite.state.UpdateWithConflicts(suite.ctx, vlan1.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, vlan1.Metadata(), func(r resource.Resource) error {
r.(*network.LinkSpec).TypedSpec().VLAN.VID = 42
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{vlanName1}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{vlanName1}, func(r *network.LinkStatus) error {
if r.TypedSpec().VLAN.VID != 42 {
return retry.ExpectedErrorf("vlan ID is not 42: %d", r.TypedSpec().VLAN.VID)
}
return nil
})
}))
},
)
},
),
)
// teardown the links
for _, r := range []resource.Resource{vlan1, vlan2, dummy} {
@ -303,10 +334,13 @@ func (suite *LinkSpecSuite) TestVLAN() {
}
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoInterface(dummyInterface)
}))
},
),
)
}
//nolint:gocyclo
@ -362,9 +396,11 @@ func (suite *LinkSpecSuite) TestBond() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{dummy0Name, dummy1Name, bondName}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{dummy0Name, dummy1Name, bondName}, func(r *network.LinkStatus) error {
switch r.Metadata().ID() {
case bondName:
suite.Assert().Equal(network.LinkKindBond, r.TypedSpec().Kind)
@ -385,46 +421,67 @@ func (suite *LinkSpecSuite) TestBond() {
}
return nil
})
}))
},
)
},
),
)
// attempt to change bond type
_, err := suite.state.UpdateWithConflicts(suite.ctx, bond.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, bond.Metadata(), func(r resource.Resource) error {
r.(*network.LinkSpec).TypedSpec().BondMaster.Mode = nethelpers.BondModeRoundrobin
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{bondName}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{bondName}, func(r *network.LinkStatus) error {
if r.TypedSpec().BondMaster.Mode != nethelpers.BondModeRoundrobin {
return retry.ExpectedErrorf("bond mode is not %s: %s", nethelpers.BondModeRoundrobin, r.TypedSpec().BondMaster.Mode)
return retry.ExpectedErrorf(
"bond mode is not %s: %s",
nethelpers.BondModeRoundrobin,
r.TypedSpec().BondMaster.Mode,
)
}
return nil
})
}))
},
)
},
),
)
// unslave one of the interfaces
_, err = suite.state.UpdateWithConflicts(suite.ctx, dummy0.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, dummy0.Metadata(), func(r resource.Resource) error {
r.(*network.LinkSpec).TypedSpec().MasterName = ""
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{dummy0Name}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{dummy0Name}, func(r *network.LinkStatus) error {
if r.TypedSpec().MasterIndex != 0 {
return retry.ExpectedErrorf("iface not unslaved yet")
}
return nil
})
}))
},
)
},
),
)
// teardown the links
for _, r := range []resource.Resource{dummy0, dummy1, bond} {
@ -440,10 +497,13 @@ func (suite *LinkSpecSuite) TestBond() {
}
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoInterface(bondName)
}))
},
),
)
}
//nolint:gocyclo
@ -490,9 +550,11 @@ func (suite *LinkSpecSuite) TestBond8023ad() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces(append(dummyNames, bondName), func(r *network.LinkStatus) error {
return suite.assertInterfaces(
append(dummyNames, bondName), func(r *network.LinkStatus) error {
if r.Metadata().ID() == bondName {
// master
suite.Assert().Equal(network.LinkKindBond, r.TypedSpec().Kind)
@ -514,8 +576,11 @@ func (suite *LinkSpecSuite) TestBond8023ad() {
}
return nil
})
}))
},
)
},
),
)
// teardown the links
for _, r := range append(dummies, bond) {
@ -531,10 +596,13 @@ func (suite *LinkSpecSuite) TestBond8023ad() {
}
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoInterface(bondName)
}))
},
),
)
}
func (suite *LinkSpecSuite) TestWireguard() {
@ -583,9 +651,11 @@ func (suite *LinkSpecSuite) TestWireguard() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{wgInterface}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{wgInterface}, func(r *network.LinkStatus) error {
suite.Assert().Equal("wireguard", r.TypedSpec().Kind)
if r.TypedSpec().Wireguard.PublicKey != priv.PublicKey().String() {
@ -601,30 +671,40 @@ func (suite *LinkSpecSuite) TestWireguard() {
}
return nil
})
}))
},
)
},
),
)
// attempt to change wireguard private key
priv2, err := wgtypes.GeneratePrivateKey()
suite.Require().NoError(err)
_, err = suite.state.UpdateWithConflicts(suite.ctx, wg.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, wg.Metadata(), func(r resource.Resource) error {
r.(*network.LinkSpec).TypedSpec().Wireguard.PrivateKey = priv2.String()
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{wgInterface}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{wgInterface}, func(r *network.LinkStatus) error {
if r.TypedSpec().Wireguard.PublicKey != priv2.PublicKey().String() {
return retry.ExpectedErrorf("private key was not updated")
}
return nil
})
}))
},
)
},
),
)
// teardown the links
for _, r := range []resource.Resource{wg} {
@ -640,10 +720,13 @@ func (suite *LinkSpecSuite) TestWireguard() {
}
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoInterface(wgInterface)
}))
},
),
)
}
func (suite *LinkSpecSuite) TearDownTest() {

View File

@ -39,7 +39,7 @@ type LinkStatusSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -79,7 +79,10 @@ func (suite *LinkStatusSuite) assertInterfaces(requiredIDs []string, check func(
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -105,7 +108,10 @@ func (suite *LinkStatusSuite) assertInterfaces(requiredIDs []string, check func(
}
func (suite *LinkStatusSuite) assertNoInterface(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -120,15 +126,20 @@ func (suite *LinkStatusSuite) assertNoInterface(id string) error {
}
func (suite *LinkStatusSuite) TestLoopbackInterface() {
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{"lo"}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{"lo"}, func(r *network.LinkStatus) error {
suite.Assert().Equal("loopback", r.TypedSpec().Type.String())
suite.Assert().EqualValues(65536, r.TypedSpec().MTU)
return nil
})
}))
},
)
},
),
)
}
func (suite *LinkStatusSuite) TestDummyInterface() {
@ -139,7 +150,9 @@ func (suite *LinkStatusSuite) TestDummyInterface() {
defer conn.Close() //nolint:errcheck
suite.Require().NoError(conn.Link.New(&rtnetlink.LinkMessage{
suite.Require().NoError(
conn.Link.New(
&rtnetlink.LinkMessage{
Type: unix.ARPHRD_ETHER,
Attributes: &rtnetlink.LinkAttributes{
Name: dummyInterface,
@ -148,48 +161,72 @@ func (suite *LinkStatusSuite) TestDummyInterface() {
Kind: "dummy",
},
},
}))
},
),
)
iface, err := net.InterfaceByName(dummyInterface)
suite.Require().NoError(err)
defer conn.Link.Delete(uint32(iface.Index)) //nolint:errcheck
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{dummyInterface}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{dummyInterface}, func(r *network.LinkStatus) error {
suite.Assert().Equal("ether", r.TypedSpec().Type.String())
suite.Assert().EqualValues(1400, r.TypedSpec().MTU)
suite.Assert().Equal(nethelpers.OperStateDown, r.TypedSpec().OperationalState)
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(conn.Link.Set(&rtnetlink.LinkMessage{
suite.Require().NoError(
conn.Link.Set(
&rtnetlink.LinkMessage{
Type: unix.ARPHRD_ETHER,
Index: uint32(iface.Index),
Flags: unix.IFF_UP,
Change: unix.IFF_UP,
}))
},
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertInterfaces([]string{dummyInterface}, func(r *network.LinkStatus) error {
return suite.assertInterfaces(
[]string{dummyInterface}, func(r *network.LinkStatus) error {
if r.TypedSpec().OperationalState != nethelpers.OperStateUp && r.TypedSpec().OperationalState != nethelpers.OperStateUnknown {
return retry.ExpectedError(fmt.Errorf("operational state is not up: %s", r.TypedSpec().OperationalState))
return retry.ExpectedError(
fmt.Errorf(
"operational state is not up: %s",
r.TypedSpec().OperationalState,
),
)
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(conn.Link.Delete(uint32(iface.Index)))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoInterface(dummyInterface)
}))
},
),
)
}
func (suite *LinkStatusSuite) TearDownTest() {
@ -200,7 +237,12 @@ func (suite *LinkStatusSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkRefresh(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkRefresh(network.NamespaceName, "bar"),
),
)
}
func TestLinkStatusSuite(t *testing.T) {

View File

@ -39,7 +39,7 @@ type NodeAddressSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -75,7 +75,10 @@ func (suite *NodeAddressSuite) assertAddresses(requiredIDs []string, check func(
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.NodeAddressType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.NodeAddressType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -104,9 +107,11 @@ func (suite *NodeAddressSuite) TestDefaults() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.AddressStatusController{}))
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.LinkStatusController{}))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
network.NodeAddressDefaultID,
network.NodeAddressCurrentID,
network.NodeAddressAccumulativeID,
@ -115,9 +120,13 @@ func (suite *NodeAddressSuite) TestDefaults() {
suite.T().Logf("id %q val %s", r.Metadata().ID(), addrs)
suite.Assert().True(sort.SliceIsSorted(addrs, func(i, j int) bool {
suite.Assert().True(
sort.SliceIsSorted(
addrs, func(i, j int) bool {
return addrs[i].IP().Compare(addrs[j].IP()) < 0
}), "addresses %s", addrs)
},
), "addresses %s", addrs,
)
if r.Metadata().ID() == network.NodeAddressDefaultID {
if len(addrs) != 1 {
@ -130,8 +139,11 @@ func (suite *NodeAddressSuite) TestDefaults() {
}
return nil
})
}))
},
)
},
),
)
}
//nolint:gocyclo
@ -158,17 +170,34 @@ func (suite *NodeAddressSuite) TestFilters() {
addressStatus.TypedSpec().Address = addr
addressStatus.TypedSpec().LinkName = link.Metadata().ID()
addressStatus.TypedSpec().LinkIndex = link.TypedSpec().Index
suite.Require().NoError(suite.state.Create(suite.ctx, addressStatus, state.WithCreateOwner(addressStatusController.Name())))
suite.Require().NoError(
suite.state.Create(
suite.ctx,
addressStatus,
state.WithCreateOwner(addressStatusController.Name()),
),
)
}
newExternalAddress := func(addr netaddr.IPPrefix) {
addressStatus := network.NewAddressStatus(network.NamespaceName, network.AddressID("external", addr))
addressStatus.TypedSpec().Address = addr
addressStatus.TypedSpec().LinkName = "external"
suite.Require().NoError(suite.state.Create(suite.ctx, addressStatus, state.WithCreateOwner(platformConfigController.Name())))
suite.Require().NoError(
suite.state.Create(
suite.ctx,
addressStatus,
state.WithCreateOwner(platformConfigController.Name()),
),
)
}
for _, addr := range []string{"10.0.0.1/8", "25.3.7.9/32", "2001:470:6d:30e:4a62:b3ba:180b:b5b8/64", "127.0.0.1/8"} {
for _, addr := range []string{
"10.0.0.1/8",
"25.3.7.9/32",
"2001:470:6d:30e:4a62:b3ba:180b:b5b8/64",
"127.0.0.1/8",
} {
newAddress(netaddr.MustParseIPPrefix(addr), linkUp)
}
@ -185,12 +214,17 @@ func (suite *NodeAddressSuite) TestFilters() {
suite.Require().NoError(suite.state.Create(suite.ctx, filter1))
filter2 := network.NewNodeAddressFilter(network.NamespaceName, "only-k8s")
filter2.TypedSpec().IncludeSubnets = []netaddr.IPPrefix{netaddr.MustParseIPPrefix("10.0.0.0/8"), netaddr.MustParseIPPrefix("192.168.0.0/16")}
filter2.TypedSpec().IncludeSubnets = []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("10.0.0.0/8"),
netaddr.MustParseIPPrefix("192.168.0.0/16"),
}
suite.Require().NoError(suite.state.Create(suite.ctx, filter2))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertAddresses([]string{
return suite.assertAddresses(
[]string{
network.NodeAddressDefaultID,
network.NodeAddressCurrentID,
network.NodeAddressAccumulativeID,
@ -207,19 +241,31 @@ func (suite *NodeAddressSuite) TestFilters() {
return fmt.Errorf("unexpected %q: %s", r.Metadata().ID(), addrs)
}
case network.NodeAddressCurrentID:
if !reflect.DeepEqual(addrs, ipList("1.2.3.4/32 10.0.0.1/8 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64")) {
if !reflect.DeepEqual(
addrs,
ipList("1.2.3.4/32 10.0.0.1/8 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64"),
) {
return fmt.Errorf("unexpected %q: %s", r.Metadata().ID(), addrs)
}
case network.NodeAddressAccumulativeID:
if !reflect.DeepEqual(addrs, ipList("1.2.3.4/32 10.0.0.1/8 10.0.0.2/8 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64")) {
if !reflect.DeepEqual(
addrs,
ipList("1.2.3.4/32 10.0.0.1/8 10.0.0.2/8 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64"),
) {
return fmt.Errorf("unexpected %q: %s", r.Metadata().ID(), addrs)
}
case network.FilteredNodeAddressID(network.NodeAddressCurrentID, filter1.Metadata().ID()):
if !reflect.DeepEqual(addrs, ipList("1.2.3.4/32 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64")) {
if !reflect.DeepEqual(
addrs,
ipList("1.2.3.4/32 25.3.7.9/32 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64"),
) {
return fmt.Errorf("unexpected %q: %s", r.Metadata().ID(), addrs)
}
case network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, filter1.Metadata().ID()):
if !reflect.DeepEqual(addrs, ipList("1.2.3.4/32 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64")) {
if !reflect.DeepEqual(
addrs,
ipList("1.2.3.4/32 25.3.7.9/32 192.168.3.7/24 2001:470:6d:30e:4a62:b3ba:180b:b5b8/64"),
) {
return fmt.Errorf("unexpected %q: %s", r.Metadata().ID(), addrs)
}
case network.FilteredNodeAddressID(network.NodeAddressCurrentID, filter2.Metadata().ID()):
@ -233,8 +279,11 @@ func (suite *NodeAddressSuite) TestFilters() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *NodeAddressSuite) TearDownTest() {
@ -245,8 +294,18 @@ func (suite *NodeAddressSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewAddressStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewAddressStatus(network.NamespaceName, "bar"),
),
)
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkStatus(network.NamespaceName, "bar"),
),
)
}
func TestNodeAddressSuite(t *testing.T) {

View File

@ -40,7 +40,7 @@ type OperatorConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *OperatorConfigSuite) assertOperators(requiredIDs []string, check fu
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.OperatorSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.OperatorSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -104,7 +107,10 @@ func (suite *OperatorConfigSuite) assertNoOperators(unexpectedIDs []string) erro
unexpIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.OperatorSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.OperatorSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -120,9 +126,13 @@ func (suite *OperatorConfigSuite) assertNoOperators(unexpectedIDs []string) erro
}
func (suite *OperatorConfigSuite) TestDefaultDHCP() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.OperatorConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.OperatorConfigController{
Cmdline: procfs.NewCmdline("talos.network.interface.ignore=eth2"),
}))
},
),
)
suite.startRuntime()
@ -134,9 +144,11 @@ func (suite *OperatorConfigSuite) TestDefaultDHCP() {
suite.Require().NoError(suite.state.Create(suite.ctx, linkStatus))
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"default/dhcp4/eth0",
"default/dhcp4/eth1",
}, func(r *network.OperatorSpec) error {
@ -152,14 +164,21 @@ func (suite *OperatorConfigSuite) TestDefaultDHCP() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *OperatorConfigSuite) TestDefaultDHCPCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.OperatorConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.OperatorConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2::172.20.0.1:255.255.255.0::eth1:::::"),
}))
},
),
)
suite.startRuntime()
@ -171,9 +190,11 @@ func (suite *OperatorConfigSuite) TestDefaultDHCPCmdline() {
suite.Require().NoError(suite.state.Create(suite.ctx, linkStatus))
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"default/dhcp4/eth0",
"default/dhcp4/eth2",
}, func(r *network.OperatorSpec) error {
@ -189,28 +210,49 @@ func (suite *OperatorConfigSuite) TestDefaultDHCPCmdline() {
}
return nil
})
}))
},
)
},
),
)
// remove link
suite.Require().NoError(suite.state.Destroy(suite.ctx, resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "eth2", resource.VersionUndefined)))
suite.Require().NoError(
suite.state.Destroy(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.LinkStatusType, "eth2", resource.VersionUndefined),
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoOperators([]string{
return suite.assertNoOperators(
[]string{
"default/dhcp4/eth2",
})
}))
},
)
},
),
)
}
func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP4() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.OperatorConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.OperatorConfigController{
Cmdline: procfs.NewCmdline("talos.network.interface.ignore=eth5"),
}))
},
),
)
// add LinkConfig controller to produce link specs based on machine configuration
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.LinkConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.LinkConfigController{
Cmdline: procfs.NewCmdline("talos.network.interface.ignore=eth5"),
}))
},
),
)
suite.startRuntime()
@ -225,7 +267,8 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP4() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -276,13 +319,16 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP4() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"configuration/dhcp4/eth1",
"configuration/dhcp4/eth3",
"configuration/dhcp4/eth4.25",
@ -303,19 +349,27 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP4() {
}
return nil
})
}))
},
)
},
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoOperators([]string{
return suite.assertNoOperators(
[]string{
"configuration/dhcp4/eth0",
"default/dhcp4/eth0",
"configuration/dhcp4/eth2",
"default/dhcp4/eth2",
"configuration/dhcp4/eth4.26",
})
}))
},
)
},
),
)
}
func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP6() {
@ -326,7 +380,8 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP6() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -363,13 +418,16 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP6() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"configuration/dhcp6/eth2",
"configuration/dhcp6/eth3",
}, func(r *network.OperatorSpec) error {
@ -386,15 +444,23 @@ func (suite *OperatorConfigSuite) TestMachineConfigurationDHCP6() {
}
return nil
})
}))
},
)
},
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoOperators([]string{
return suite.assertNoOperators(
[]string{
"configuration/dhcp6/eth1",
})
}))
},
)
},
),
)
}
func (suite *OperatorConfigSuite) TearDownTest() {
@ -405,17 +471,26 @@ func (suite *OperatorConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}
suite.Require().NoError(err)
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkStatus(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkStatus(network.ConfigNamespaceName, "bar"),
),
)
}
func TestOperatorConfigSuite(t *testing.T) {

View File

@ -35,7 +35,7 @@ type OperatorMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -71,7 +71,10 @@ func (suite *OperatorMergeSuite) assertOperators(requiredIDs []string, check fun
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.OperatorSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.OperatorSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -97,7 +100,10 @@ func (suite *OperatorMergeSuite) assertOperators(requiredIDs []string, check fun
}
func (suite *OperatorMergeSuite) assertNoOperator(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.OperatorSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.OperatorSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -139,9 +145,11 @@ func (suite *OperatorMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"dhcp4/eth0",
"dhcp6/eth0",
}, func(r *network.OperatorSpec) error {
@ -153,23 +161,34 @@ func (suite *OperatorMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, dhcp6.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"dhcp4/eth0",
}, func(r *network.OperatorSpec) error {
return nil
})
}))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
},
)
},
),
)
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoOperator("dhcp6/eth0")
}))
},
),
)
}
//nolint:gocyclo
@ -214,10 +233,20 @@ func (suite *OperatorMergeSuite) TestMergeFlapping() {
eg.Go(flipflop(0))
eg.Go(flipflop(1))
eg.Go(func() error {
eg.Go(
func() error {
// add/remove finalizer to the merged resource
for i := 0; i < 1000; i++ {
if err := suite.state.AddFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.OperatorSpecType, "dhcp4/eth0", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.AddFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.OperatorSpecType,
"dhcp4/eth0",
resource.VersionUndefined,
),
"foo",
); err != nil {
if !state.IsNotFoundError(err) {
return err
}
@ -229,7 +258,16 @@ func (suite *OperatorMergeSuite) TestMergeFlapping() {
time.Sleep(10 * time.Millisecond)
if err := suite.state.RemoveFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.OperatorSpecType, "dhcp4/eth0", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.RemoveFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.OperatorSpecType,
"dhcp4/eth0",
resource.VersionUndefined,
),
"foo",
); err != nil {
if err != nil && !state.IsNotFoundError(err) {
return err
}
@ -237,13 +275,16 @@ func (suite *OperatorMergeSuite) TestMergeFlapping() {
}
return nil
})
},
)
suite.Require().NoError(eg.Wait())
suite.Assert().NoError(retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"dhcp4/eth0",
}, func(r *network.OperatorSpec) error {
if r.Metadata().Phase() != resource.PhaseRunning {
@ -256,8 +297,11 @@ func (suite *OperatorMergeSuite) TestMergeFlapping() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *OperatorMergeSuite) TearDownTest() {
@ -268,7 +312,12 @@ func (suite *OperatorMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewOperatorSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewOperatorSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestOperatorMergeSuite(t *testing.T) {

View File

@ -37,7 +37,7 @@ type OperatorSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -155,9 +155,13 @@ func (suite *OperatorSpecSuite) SetupTest() {
runningOperators = map[string]*mockOperator{}
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.OperatorSpecController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.OperatorSpecController{
Factory: suite.newOperator,
}))
},
),
)
suite.startRuntime()
}
@ -214,7 +218,10 @@ func (suite *OperatorSpecSuite) assertResources(resourceType resource.Type, requ
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, resourceType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, resourceType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -255,12 +262,17 @@ func (suite *OperatorSpecSuite) TestScheduling() {
suite.Require().NoError(suite.state.Create(suite.ctx, specVIP))
// operators shouldn't be running yet, as link state is not known yet
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning(nil, func(op *mockOperator) error {
return suite.assertRunning(
nil, func(op *mockOperator) error {
return nil
})
}))
},
)
},
),
)
linkState := network.NewLinkStatus(network.NamespaceName, "eth0")
*linkState.TypedSpec() = network.LinkStatusSpec{
@ -270,26 +282,35 @@ func (suite *OperatorSpecSuite) TestScheduling() {
suite.Require().NoError(suite.state.Create(suite.ctx, linkState))
// vip operator should be scheduled now, as VIP operator doesn't require link to be up
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning([]string{"vip/eth0"}, func(op *mockOperator) error {
return suite.assertRunning(
[]string{"vip/eth0"}, func(op *mockOperator) error {
suite.Assert().Equal(netaddr.MustParseIP("1.2.3.4"), op.spec.VIP.IP)
return nil
})
}))
},
)
},
),
)
_, err := suite.state.UpdateWithConflicts(suite.ctx, linkState.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, linkState.Metadata(), func(r resource.Resource) error {
r.(*network.LinkStatus).TypedSpec().OperationalState = nethelpers.OperStateUp
return nil
})
},
)
suite.Require().NoError(err)
// now all operators should be scheduled
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning([]string{"dhcp4/eth0", "vip/eth0"}, func(op *mockOperator) error {
return suite.assertRunning(
[]string{"dhcp4/eth0", "vip/eth0"}, func(op *mockOperator) error {
switch op.spec.Operator { //nolint:exhaustive
case network.OperatorDHCP4:
suite.Assert().EqualValues(1024, op.spec.DHCP4.RouteMetric)
@ -300,20 +321,27 @@ func (suite *OperatorSpecSuite) TestScheduling() {
}
return nil
})
}))
},
)
},
),
)
// change the spec, operator should be rescheduled
_, err = suite.state.UpdateWithConflicts(suite.ctx, specVIP.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, specVIP.Metadata(), func(r resource.Resource) error {
r.(*network.OperatorSpec).TypedSpec().VIP.IP = netaddr.MustParseIP("3.4.5.6")
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning([]string{"dhcp4/eth0", "vip/eth0"}, func(op *mockOperator) error {
return suite.assertRunning(
[]string{"dhcp4/eth0", "vip/eth0"}, func(op *mockOperator) error {
switch op.spec.Operator { //nolint:exhaustive
case network.OperatorDHCP4:
suite.Assert().EqualValues(1024, op.spec.DHCP4.RouteMetric)
@ -326,23 +354,33 @@ func (suite *OperatorSpecSuite) TestScheduling() {
}
return nil
})
}))
},
)
},
),
)
// bring down the interface, operator should be stopped
_, err = suite.state.UpdateWithConflicts(suite.ctx, linkState.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, linkState.Metadata(), func(r resource.Resource) error {
r.(*network.LinkStatus).TypedSpec().OperationalState = nethelpers.OperStateDown
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning([]string{"vip/eth0"}, func(op *mockOperator) error {
return suite.assertRunning(
[]string{"vip/eth0"}, func(op *mockOperator) error {
return nil
})
}))
},
)
},
),
)
}
func (suite *OperatorSpecSuite) TestPanic() {
@ -366,25 +404,35 @@ func (suite *OperatorSpecSuite) TestPanic() {
suite.Require().NoError(suite.state.Create(suite.ctx, linkState))
// DHCP6 operator should panic and then restart
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning([]string{"dhcp6/eth0"}, func(op *mockOperator) error { return nil })
}))
},
),
)
// bring down the interface, operator should be stopped
_, err := suite.state.UpdateWithConflicts(suite.ctx, linkState.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, linkState.Metadata(), func(r resource.Resource) error {
r.(*network.LinkStatus).TypedSpec().OperationalState = nethelpers.OperStateDown
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning(nil, func(op *mockOperator) error {
return suite.assertRunning(
nil, func(op *mockOperator) error {
return nil
})
}))
},
)
},
),
)
}
func (suite *OperatorSpecSuite) TestOperatorOutputs() {
@ -407,12 +455,17 @@ func (suite *OperatorSpecSuite) TestOperatorOutputs() {
suite.Require().NoError(suite.state.Create(suite.ctx, linkState))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRunning([]string{"dhcp4/eth0"}, func(op *mockOperator) error {
return suite.assertRunning(
[]string{"dhcp4/eth0"}, func(op *mockOperator) error {
return nil
})
}))
},
)
},
),
)
// pretend dhcp has some specs ready
runningOperatorsMu.Lock()
@ -447,18 +500,27 @@ func (suite *OperatorSpecSuite) TestOperatorOutputs() {
dhcpMock.notify()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.AddressSpecType, []string{"dhcp4/eth0/eth0/10.5.0.2/24"})
}))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
},
),
)
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.LinkSpecType, []string{"dhcp4/eth0/eth0"})
}))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
},
),
)
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.HostnameSpecType, []string{"dhcp4/eth0/hostname"})
}))
},
),
)
// update specs
dhcpMock.mu.Lock()
@ -476,10 +538,13 @@ func (suite *OperatorSpecSuite) TestOperatorOutputs() {
dhcpMock.notify()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.AddressSpecType, []string{"dhcp4/eth0/eth0/10.5.0.3/24"})
}))
},
),
)
}
func (suite *OperatorSpecSuite) TearDownTest() {
@ -490,7 +555,12 @@ func (suite *OperatorSpecSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewOperatorSpec(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewOperatorSpec(network.NamespaceName, "bar"),
),
)
}
func TestOperatorSpecSuite(t *testing.T) {

View File

@ -38,7 +38,7 @@ type OperatorVIPConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -63,14 +63,20 @@ func (suite *OperatorVIPConfigSuite) startRuntime() {
}()
}
func (suite *OperatorVIPConfigSuite) assertOperators(requiredIDs []string, check func(*network.OperatorSpec) error) error {
func (suite *OperatorVIPConfigSuite) assertOperators(
requiredIDs []string,
check func(*network.OperatorSpec) error,
) error {
missingIDs := make(map[string]struct{}, len(requiredIDs))
for _, id := range requiredIDs {
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.OperatorSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.OperatorSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -103,7 +109,8 @@ func (suite *OperatorVIPConfigSuite) TestMachineConfigurationVIP() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -144,13 +151,16 @@ func (suite *OperatorVIPConfigSuite) TestMachineConfigurationVIP() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertOperators([]string{
return suite.assertOperators(
[]string{
"configuration/vip/eth1",
"configuration/vip/eth2",
"configuration/vip/eth3.26",
@ -164,15 +174,21 @@ func (suite *OperatorVIPConfigSuite) TestMachineConfigurationVIP() {
suite.Assert().EqualValues(netaddr.MustParseIP("2.3.4.5"), r.TypedSpec().VIP.IP)
case "configuration/vip/eth2":
suite.Assert().Equal("eth2", r.TypedSpec().LinkName)
suite.Assert().EqualValues(netaddr.MustParseIP("fd7a:115c:a1e0:ab12:4843:cd96:6277:2302"), r.TypedSpec().VIP.IP)
suite.Assert().EqualValues(
netaddr.MustParseIP("fd7a:115c:a1e0:ab12:4843:cd96:6277:2302"),
r.TypedSpec().VIP.IP,
)
case "configuration/vip/eth3.26":
suite.Assert().Equal("eth3.26", r.TypedSpec().LinkName)
suite.Assert().EqualValues(netaddr.MustParseIP("5.5.4.4"), r.TypedSpec().VIP.IP)
}
return nil
})
}))
},
)
},
),
)
}
func (suite *OperatorVIPConfigSuite) TearDownTest() {
@ -183,17 +199,26 @@ func (suite *OperatorVIPConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}
suite.Require().NoError(err)
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewLinkStatus(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewLinkStatus(network.ConfigNamespaceName, "bar"),
),
)
}
func TestOperatorVIPConfigSuite(t *testing.T) {

View File

@ -45,7 +45,7 @@ type PlatformConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,14 +72,22 @@ func (suite *PlatformConfigSuite) startRuntime() {
}()
}
func (suite *PlatformConfigSuite) assertResources(resourceNamespace resource.Namespace, resourceType resource.Type, requiredIDs []string, check func(resource.Resource) error) error {
func (suite *PlatformConfigSuite) assertResources(
resourceNamespace resource.Namespace,
resourceType resource.Type,
requiredIDs []string,
check func(resource.Resource) error,
) error {
missingIDs := make(map[string]struct{}, len(requiredIDs))
for _, id := range requiredIDs {
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(resourceNamespace, resourceType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(resourceNamespace, resourceType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -102,7 +110,10 @@ func (suite *PlatformConfigSuite) assertResources(resourceNamespace resource.Nam
}
func (suite *PlatformConfigSuite) assertNoResource(resourceType resource.Type, id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, resourceType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, resourceType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -121,23 +132,32 @@ func (suite *PlatformConfigSuite) TestNoPlatform() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoResource(network.HostnameSpecType, "platform/hostname")
}))
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockHostname() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl.c.talos-testbed.internal")},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.HostnameSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.HostnameSpecType, []string{
"platform/hostname",
}, func(r resource.Resource) error {
spec := r.(*network.HostnameSpec).TypedSpec()
@ -147,21 +167,30 @@ func (suite *PlatformConfigSuite) TestPlatformMockHostname() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockHostnameNoDomain() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl")},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.HostnameSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.HostnameSpecType, []string{
"platform/hostname",
}, func(r resource.Resource) error {
spec := r.(*network.HostnameSpec).TypedSpec()
@ -171,23 +200,35 @@ func (suite *PlatformConfigSuite) TestPlatformMockHostnameNoDomain() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockAddresses() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
addresses: []netaddr.IPPrefix{netaddr.MustParseIPPrefix("192.168.1.24/24"), netaddr.MustParseIPPrefix("2001:fd::3/64")},
addresses: []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("192.168.1.24/24"),
netaddr.MustParseIPPrefix("2001:fd::3/64"),
},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.AddressSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.AddressSpecType, []string{
"platform/eth0/192.168.1.24/24",
"platform/eth0/2001:fd::3/64",
}, func(r resource.Resource) error {
@ -205,23 +246,32 @@ func (suite *PlatformConfigSuite) TestPlatformMockAddresses() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockLinks() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
linksUp: []string{"eth0", "eth1"},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.LinkSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.LinkSpecType, []string{
"platform/eth0",
"platform/eth1",
}, func(r resource.Resource) error {
@ -231,23 +281,32 @@ func (suite *PlatformConfigSuite) TestPlatformMockLinks() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockRoutes() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
defaultRoutes: []netaddr.IP{netaddr.MustParseIP("10.0.0.1")},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.RouteSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.RouteSpecType, []string{
"platform/inet4/10.0.0.1//1024",
}, func(r resource.Resource) error {
spec := r.(*network.RouteSpec).TypedSpec()
@ -256,23 +315,32 @@ func (suite *PlatformConfigSuite) TestPlatformMockRoutes() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockOperators() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
dhcp4Links: []string{"eth1", "eth2"},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.OperatorSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.OperatorSpecType, []string{
"platform/dhcp4/eth1",
"platform/dhcp4/eth2",
}, func(r resource.Resource) error {
@ -282,23 +350,32 @@ func (suite *PlatformConfigSuite) TestPlatformMockOperators() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockResolvers() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
resolvers: []netaddr.IP{netaddr.MustParseIP("1.1.1.1")},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.ResolverSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.ResolverSpecType, []string{
"platform/resolvers",
}, func(r resource.Resource) error {
spec := r.(*network.ResolverSpec).TypedSpec()
@ -307,23 +384,32 @@ func (suite *PlatformConfigSuite) TestPlatformMockResolvers() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockTimeServers() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
timeServers: []string{"pool.ntp.org"},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.TimeServerSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.TimeServerSpecType, []string{
"platform/timeservers",
}, func(r resource.Resource) error {
spec := r.(*network.TimeServerSpec).TypedSpec()
@ -332,21 +418,35 @@ func (suite *PlatformConfigSuite) TestPlatformMockTimeServers() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TestPlatformMockExternalIPs() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{externalIPs: []netaddr.IP{netaddr.MustParseIP("10.3.4.5"), netaddr.MustParseIP("2001:470:6d:30e:96f4:4219:5733:b860")}},
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
externalIPs: []netaddr.IP{
netaddr.MustParseIP("10.3.4.5"),
netaddr.MustParseIP("2001:470:6d:30e:96f4:4219:5733:b860"),
},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.NamespaceName, network.AddressStatusType, []string{
return suite.assertResources(
network.NamespaceName, network.AddressStatusType, []string{
"external/10.3.4.5/32",
"external/2001:470:6d:30e:96f4:4219:5733:b860/128",
}, func(r resource.Resource) error {
@ -362,20 +462,30 @@ func (suite *PlatformConfigSuite) TestPlatformMockExternalIPs() {
}
return nil
})
}))
},
)
},
),
)
}
const sampleStoredConfig = "addresses: []\nlinks: []\nroutes: []\nhostnames:\n - hostname: talos-e2e-897b4e49-gcp-controlplane-jvcnl\n domainname: \"\"\n layer: default\nresolvers: []\ntimeServers: []\noperators: []\nexternalIPs:\n - 10.3.4.5\n - 2001:470:6d:30e:96f4:4219:5733:b860\n" //nolint:lll
func (suite *PlatformConfigSuite) TestStoreConfig() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
hostname: []byte("talos-e2e-897b4e49-gcp-controlplane-jvcnl"),
externalIPs: []netaddr.IP{netaddr.MustParseIP("10.3.4.5"), netaddr.MustParseIP("2001:470:6d:30e:96f4:4219:5733:b860")},
externalIPs: []netaddr.IP{
netaddr.MustParseIP("10.3.4.5"),
netaddr.MustParseIP("2001:470:6d:30e:96f4:4219:5733:b860"),
},
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
@ -383,7 +493,8 @@ func (suite *PlatformConfigSuite) TestStoreConfig() {
suite.Assert().NoError(suite.state.Create(suite.ctx, stateMount))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
contents, err := os.ReadFile(filepath.Join(suite.statePath, constants.PlatformNetworkConfigFilename))
if err != nil {
@ -397,29 +508,43 @@ func (suite *PlatformConfigSuite) TestStoreConfig() {
suite.Assert().Equal(sampleStoredConfig, string(contents))
return nil
}))
},
),
)
}
func (suite *PlatformConfigSuite) TestLoadConfig() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.PlatformConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.PlatformConfigController{
V1alpha1Platform: &platformMock{
noData: true,
},
StatePath: suite.statePath,
}))
},
),
)
suite.startRuntime()
suite.Require().NoError(os.WriteFile(filepath.Join(suite.statePath, constants.PlatformNetworkConfigFilename), []byte(sampleStoredConfig), 0o400))
suite.Require().NoError(
os.WriteFile(
filepath.Join(suite.statePath, constants.PlatformNetworkConfigFilename),
[]byte(sampleStoredConfig),
0o400,
),
)
stateMount := runtimeres.NewMountStatus(v1alpha1.NamespaceName, constants.StatePartitionLabel)
suite.Assert().NoError(suite.state.Create(suite.ctx, stateMount))
// controller should pick up cached network configuration
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.NamespaceName, network.AddressStatusType, []string{
return suite.assertResources(
network.NamespaceName, network.AddressStatusType, []string{
"external/10.3.4.5/32",
"external/2001:470:6d:30e:96f4:4219:5733:b860/128",
}, func(r resource.Resource) error {
@ -435,12 +560,17 @@ func (suite *PlatformConfigSuite) TestLoadConfig() {
}
return nil
})
}))
},
)
},
),
)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResources(network.ConfigNamespaceName, network.HostnameSpecType, []string{
return suite.assertResources(
network.ConfigNamespaceName, network.HostnameSpecType, []string{
"platform/hostname",
}, func(r resource.Resource) error {
spec := r.(*network.HostnameSpec).TypedSpec()
@ -450,8 +580,11 @@ func (suite *PlatformConfigSuite) TestLoadConfig() {
suite.Assert().Equal(network.ConfigPlatform, spec.ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *PlatformConfigSuite) TearDownTest() {
@ -496,7 +629,10 @@ func (mock *platformMock) KernelArgs() procfs.Parameters {
}
//nolint:gocyclo
func (mock *platformMock) NetworkConfiguration(ctx context.Context, ch chan<- *v1alpha1runtime.PlatformNetworkConfig) error {
func (mock *platformMock) NetworkConfiguration(
ctx context.Context,
ch chan<- *v1alpha1runtime.PlatformNetworkConfig,
) error {
if mock.noData {
return nil
}
@ -520,7 +656,8 @@ func (mock *platformMock) NetworkConfiguration(ctx context.Context, ch chan<- *v
family = nethelpers.FamilyInet6
}
networkConfig.Addresses = append(networkConfig.Addresses,
networkConfig.Addresses = append(
networkConfig.Addresses,
network.AddressSpecSpec{
ConfigLayer: network.ConfigPlatform,
LinkName: "eth0",
@ -528,7 +665,8 @@ func (mock *platformMock) NetworkConfiguration(ctx context.Context, ch chan<- *v
Scope: nethelpers.ScopeGlobal,
Flags: nethelpers.AddressFlags(nethelpers.AddressPermanent),
Family: family,
})
},
)
}
for _, gw := range mock.defaultRoutes {
@ -554,34 +692,42 @@ func (mock *platformMock) NetworkConfiguration(ctx context.Context, ch chan<- *v
}
for _, link := range mock.linksUp {
networkConfig.Links = append(networkConfig.Links, network.LinkSpecSpec{
networkConfig.Links = append(
networkConfig.Links, network.LinkSpecSpec{
ConfigLayer: network.ConfigPlatform,
Name: link,
Up: true,
})
},
)
}
if len(mock.resolvers) > 0 {
networkConfig.Resolvers = append(networkConfig.Resolvers, network.ResolverSpecSpec{
networkConfig.Resolvers = append(
networkConfig.Resolvers, network.ResolverSpecSpec{
ConfigLayer: network.ConfigPlatform,
DNSServers: mock.resolvers,
})
},
)
}
if len(mock.timeServers) > 0 {
networkConfig.TimeServers = append(networkConfig.TimeServers, network.TimeServerSpecSpec{
networkConfig.TimeServers = append(
networkConfig.TimeServers, network.TimeServerSpecSpec{
ConfigLayer: network.ConfigPlatform,
NTPServers: mock.timeServers,
})
},
)
}
for _, link := range mock.dhcp4Links {
networkConfig.Operators = append(networkConfig.Operators, network.OperatorSpecSpec{
networkConfig.Operators = append(
networkConfig.Operators, network.OperatorSpecSpec{
ConfigLayer: network.ConfigPlatform,
LinkName: link,
Operator: network.OperatorDHCP4,
DHCP4: network.DHCP4OperatorSpec{},
})
},
)
}
select {

View File

@ -40,7 +40,7 @@ type ResolverConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *ResolverConfigSuite) assertResolvers(requiredIDs []string, check fu
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.ResolverSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.ResolverSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -98,7 +101,10 @@ func (suite *ResolverConfigSuite) assertResolvers(requiredIDs []string, check fu
}
func (suite *ResolverConfigSuite) assertNoResolver(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.ResolverSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.ResolverSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -117,36 +123,60 @@ func (suite *ResolverConfigSuite) TestDefaults() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResolvers([]string{
return suite.assertResolvers(
[]string{
"default/resolvers",
}, func(r *network.ResolverSpec) error {
suite.Assert().Equal([]netaddr.IP{netaddr.MustParseIP(constants.DefaultPrimaryResolver), netaddr.MustParseIP(constants.DefaultSecondaryResolver)}, r.TypedSpec().DNSServers)
suite.Assert().Equal(
[]netaddr.IP{
netaddr.MustParseIP(constants.DefaultPrimaryResolver),
netaddr.MustParseIP(constants.DefaultSecondaryResolver),
}, r.TypedSpec().DNSServers,
)
suite.Assert().Equal(network.ConfigDefault, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *ResolverConfigSuite) TestCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.ResolverConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.ResolverConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2:172.21.0.1:172.20.0.1:255.255.255.0:master1:eth1::10.0.0.1:10.0.0.2:10.0.0.1"),
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResolvers([]string{
return suite.assertResolvers(
[]string{
"cmdline/resolvers",
}, func(r *network.ResolverSpec) error {
suite.Assert().Equal([]netaddr.IP{netaddr.MustParseIP("10.0.0.1"), netaddr.MustParseIP("10.0.0.2")}, r.TypedSpec().DNSServers)
suite.Assert().Equal(
[]netaddr.IP{
netaddr.MustParseIP("10.0.0.1"),
netaddr.MustParseIP("10.0.0.2"),
}, r.TypedSpec().DNSServers,
)
return nil
})
}))
},
)
},
),
)
}
func (suite *ResolverConfigSuite) TestMachineConfiguration() {
@ -157,7 +187,8 @@ func (suite *ResolverConfigSuite) TestMachineConfiguration() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -171,32 +202,48 @@ func (suite *ResolverConfigSuite) TestMachineConfiguration() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResolvers([]string{
return suite.assertResolvers(
[]string{
"configuration/resolvers",
}, func(r *network.ResolverSpec) error {
suite.Assert().Equal([]netaddr.IP{netaddr.MustParseIP("2.2.2.2"), netaddr.MustParseIP("3.3.3.3")}, r.TypedSpec().DNSServers)
suite.Assert().Equal(
[]netaddr.IP{
netaddr.MustParseIP("2.2.2.2"),
netaddr.MustParseIP("3.3.3.3"),
}, r.TypedSpec().DNSServers,
)
return nil
})
}))
},
)
},
),
)
_, err = suite.state.UpdateWithConflicts(suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
r.(*config.MachineConfig).Config().(*v1alpha1.Config).MachineConfig.MachineNetwork.NameServers = nil
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoResolver("configuration/resolvers")
}))
},
),
)
}
func (suite *ResolverConfigSuite) TearDownTest() {
@ -207,10 +254,14 @@ func (suite *ResolverConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -37,7 +37,7 @@ type ResolverMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -73,7 +73,10 @@ func (suite *ResolverMergeSuite) assertResolvers(requiredIDs []string, check fun
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.ResolverSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.ResolverSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -101,7 +104,10 @@ func (suite *ResolverMergeSuite) assertResolvers(requiredIDs []string, check fun
func (suite *ResolverMergeSuite) TestMerge() {
def := network.NewResolverSpec(network.ConfigNamespaceName, "default/resolvers")
*def.TypedSpec() = network.ResolverSpecSpec{
DNSServers: []netaddr.IP{netaddr.MustParseIP(constants.DefaultPrimaryResolver), netaddr.MustParseIP(constants.DefaultSecondaryResolver)},
DNSServers: []netaddr.IP{
netaddr.MustParseIP(constants.DefaultPrimaryResolver),
netaddr.MustParseIP(constants.DefaultSecondaryResolver),
},
ConfigLayer: network.ConfigDefault,
}
@ -127,31 +133,44 @@ func (suite *ResolverMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResolvers([]string{
return suite.assertResolvers(
[]string{
"resolvers",
}, func(r *network.ResolverSpec) error {
suite.Assert().Equal(*static.TypedSpec(), *r.TypedSpec())
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, static.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertResolvers([]string{
return suite.assertResolvers(
[]string{
"resolvers",
}, func(r *network.ResolverSpec) error {
if !reflect.DeepEqual(r.TypedSpec().DNSServers, []netaddr.IP{netaddr.MustParseIP("1.1.2.0"), netaddr.MustParseIP("1.1.2.1")}) {
if !reflect.DeepEqual(
r.TypedSpec().DNSServers,
[]netaddr.IP{netaddr.MustParseIP("1.1.2.0"), netaddr.MustParseIP("1.1.2.1")},
) {
return retry.ExpectedErrorf("unexpected servers %q", r.TypedSpec().DNSServers)
}
return nil
})
}))
},
)
},
),
)
}
func (suite *ResolverMergeSuite) TearDownTest() {
@ -162,7 +181,12 @@ func (suite *ResolverMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewResolverSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewResolverSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestResolverMergeSuite(t *testing.T) {

View File

@ -36,7 +36,7 @@ type ResolverSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -66,7 +66,10 @@ func (suite *ResolverSpecSuite) startRuntime() {
}
func (suite *ResolverSpecSuite) assertStatus(id string, servers ...netaddr.IP) error {
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(network.NamespaceName, network.ResolverStatusType, id, resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.ResolverStatusType, id, resource.VersionUndefined),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -95,10 +98,13 @@ func (suite *ResolverSpecSuite) TestSpec() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus("resolvers", netaddr.MustParseIP(constants.DefaultPrimaryResolver))
}))
},
),
)
}
func (suite *ResolverSpecSuite) TearDownTest() {
@ -109,7 +115,12 @@ func (suite *ResolverSpecSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewResolverSpec(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewResolverSpec(network.NamespaceName, "bar"),
),
)
}
func TestResolverSpecSuite(t *testing.T) {

View File

@ -40,7 +40,7 @@ type RouteConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -72,7 +72,10 @@ func (suite *RouteConfigSuite) assertRoutes(requiredIDs []string, check func(*ne
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.RouteSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.RouteSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -98,15 +101,21 @@ func (suite *RouteConfigSuite) assertRoutes(requiredIDs []string, check func(*ne
}
func (suite *RouteConfigSuite) TestCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.RouteConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.RouteConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2::172.20.0.1:255.255.255.0::eth1:::::"),
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoutes([]string{
return suite.assertRoutes(
[]string{
"cmdline/inet4/172.20.0.1//1024",
}, func(r *network.RouteSpec) error {
suite.Assert().Equal("eth1", r.TypedSpec().OutLinkName)
@ -115,8 +124,11 @@ func (suite *RouteConfigSuite) TestCmdline() {
suite.Assert().EqualValues(netctrl.DefaultRouteMetric, r.TypedSpec().Priority)
return nil
})
}))
},
)
},
),
)
}
func (suite *RouteConfigSuite) TestMachineConfiguration() {
@ -127,7 +139,8 @@ func (suite *RouteConfigSuite) TestMachineConfiguration() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineNetwork: &v1alpha1.NetworkConfig{
@ -204,13 +217,16 @@ func (suite *RouteConfigSuite) TestMachineConfiguration() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoutes([]string{
return suite.assertRoutes(
[]string{
"configuration/inet6/2001:470:6d:30e:8ed2:b60c:9d2f:803b//1024",
"configuration/inet4/10.0.3.1/10.0.3.0/24/1024",
"configuration/inet4/192.168.0.25/192.168.0.0/18/25",
@ -246,8 +262,11 @@ func (suite *RouteConfigSuite) TestMachineConfiguration() {
suite.Assert().Equal(network.ConfigMachineConfiguration, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *RouteConfigSuite) TearDownTest() {
@ -258,10 +277,14 @@ func (suite *RouteConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -37,7 +37,7 @@ type RouteMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -73,7 +73,10 @@ func (suite *RouteMergeSuite) assertRoutes(requiredIDs []string, check func(*net
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.RouteSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.RouteSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -99,7 +102,10 @@ func (suite *RouteMergeSuite) assertRoutes(requiredIDs []string, check func(*net
}
func (suite *RouteMergeSuite) assertNoRoute(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.RouteSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.RouteSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -155,9 +161,11 @@ func (suite *RouteMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoutes([]string{
return suite.assertRoutes(
[]string{
"inet4/10.5.0.3//50",
"inet4/10.0.0.34/10.0.0.35/32/1024",
}, func(r *network.RouteSpec) error {
@ -171,14 +179,19 @@ func (suite *RouteMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, dhcp.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoutes([]string{
return suite.assertRoutes(
[]string{
"inet4/10.5.0.3//50",
"inet4/10.0.0.34/10.0.0.35/32/1024",
}, func(r *network.RouteSpec) error {
@ -195,15 +208,21 @@ func (suite *RouteMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, static.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoRoute("inet4/10.0.0.34/10.0.0.35/32/1024")
}))
},
),
)
}
//nolint:gocyclo
@ -257,10 +276,20 @@ func (suite *RouteMergeSuite) TestMergeFlapping() {
eg.Go(flipflop(0))
eg.Go(flipflop(1))
eg.Go(func() error {
eg.Go(
func() error {
// add/remove finalizer to the merged resource
for i := 0; i < 1000; i++ {
if err := suite.state.AddFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.RouteSpecType, "inet4/10.5.0.3//50", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.AddFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.RouteSpecType,
"inet4/10.5.0.3//50",
resource.VersionUndefined,
),
"foo",
); err != nil {
if !state.IsNotFoundError(err) {
return err
}
@ -272,7 +301,16 @@ func (suite *RouteMergeSuite) TestMergeFlapping() {
time.Sleep(10 * time.Millisecond)
if err := suite.state.RemoveFinalizer(suite.ctx, resource.NewMetadata(network.NamespaceName, network.RouteSpecType, "inet4/10.5.0.3//50", resource.VersionUndefined), "foo"); err != nil {
if err := suite.state.RemoveFinalizer(
suite.ctx,
resource.NewMetadata(
network.NamespaceName,
network.RouteSpecType,
"inet4/10.5.0.3//50",
resource.VersionUndefined,
),
"foo",
); err != nil {
if err != nil && !state.IsNotFoundError(err) {
return err
}
@ -280,13 +318,16 @@ func (suite *RouteMergeSuite) TestMergeFlapping() {
}
return nil
})
},
)
suite.Require().NoError(eg.Wait())
suite.Assert().NoError(retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(15*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoutes([]string{
return suite.assertRoutes(
[]string{
"inet4/10.5.0.3//50",
}, func(r *network.RouteSpec) error {
if r.Metadata().Phase() != resource.PhaseRunning {
@ -299,8 +340,11 @@ func (suite *RouteMergeSuite) TestMergeFlapping() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *RouteMergeSuite) TearDownTest() {
@ -311,7 +355,12 @@ func (suite *RouteMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewRouteSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewRouteSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestRouteMergeSuite(t *testing.T) {

View File

@ -149,7 +149,8 @@ func findRoutes(routes []rtnetlink.RouteMessage, family nethelpers.Family, desti
//nolint:gocyclo,cyclop
func (ctrl *RouteSpecController) syncRoute(ctx context.Context, r controller.Runtime, logger *zap.Logger, conn *rtnetlink.Conn,
links []rtnetlink.LinkMessage, routes []rtnetlink.RouteMessage, route *network.RouteSpec) error {
links []rtnetlink.LinkMessage, routes []rtnetlink.RouteMessage, route *network.RouteSpec,
) error {
linkIndex := resolveLinkName(links, route.TypedSpec().OutLinkName)
destinationStr := route.TypedSpec().Destination.String()

View File

@ -40,7 +40,7 @@ type RouteSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -73,7 +73,11 @@ func (suite *RouteSpecSuite) startRuntime() {
}()
}
func (suite *RouteSpecSuite) assertRoute(destination netaddr.IPPrefix, gateway netaddr.IP, check func(rtnetlink.RouteMessage) error) error {
func (suite *RouteSpecSuite) assertRoute(
destination netaddr.IPPrefix,
gateway netaddr.IP,
check func(rtnetlink.RouteMessage) error,
) error {
conn, err := rtnetlink.Dial(nil)
suite.Require().NoError(err)
@ -150,14 +154,21 @@ func (suite *RouteSpecSuite) TestLoopback() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoute(netaddr.MustParseIPPrefix("127.0.11.0/24"), netaddr.MustParseIP("127.0.11.1"), func(route rtnetlink.RouteMessage) error {
return suite.assertRoute(
netaddr.MustParseIPPrefix("127.0.11.0/24"),
netaddr.MustParseIP("127.0.11.1"),
func(route rtnetlink.RouteMessage) error {
suite.Assert().EqualValues(0, route.Attributes.Priority)
return nil
})
}))
},
)
},
),
)
// teardown the route
for {
@ -172,7 +183,12 @@ func (suite *RouteSpecSuite) TestLoopback() {
}
// torn down address should be removed immediately
suite.Assert().NoError(suite.assertNoRoute(netaddr.MustParseIPPrefix("127.0.11.0/24"), netaddr.MustParseIP("127.0.11.1")))
suite.Assert().NoError(
suite.assertNoRoute(
netaddr.MustParseIPPrefix("127.0.11.0/24"),
netaddr.MustParseIP("127.0.11.1"),
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, loopback.Metadata()))
}
@ -197,29 +213,38 @@ func (suite *RouteSpecSuite) TestDefaultRoute() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoute(netaddr.IPPrefix{}, netaddr.MustParseIP("127.0.11.2"), func(route rtnetlink.RouteMessage) error {
return suite.assertRoute(
netaddr.IPPrefix{}, netaddr.MustParseIP("127.0.11.2"), func(route rtnetlink.RouteMessage) error {
suite.Assert().Nil(route.Attributes.Dst)
suite.Assert().EqualValues(1048576, route.Attributes.Priority)
return nil
})
}))
},
)
},
),
)
// update the route metric
_, err := suite.state.UpdateWithConflicts(suite.ctx, def.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, def.Metadata(), func(r resource.Resource) error {
defR := r.(*network.RouteSpec) //nolint:forcetypeassert,errcheck
defR.TypedSpec().Priority = 1048577
return nil
})
},
)
suite.Assert().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoute(netaddr.IPPrefix{}, netaddr.MustParseIP("127.0.11.2"), func(route rtnetlink.RouteMessage) error {
return suite.assertRoute(
netaddr.IPPrefix{}, netaddr.MustParseIP("127.0.11.2"), func(route rtnetlink.RouteMessage) error {
suite.Assert().Nil(route.Attributes.Dst)
if route.Attributes.Priority != 1048577 {
@ -227,8 +252,11 @@ func (suite *RouteSpecSuite) TestDefaultRoute() {
}
return nil
})
}))
},
)
},
),
)
// teardown the route
for {
@ -256,7 +284,9 @@ func (suite *RouteSpecSuite) TestDefaultAndInterfaceRoutes() {
defer conn.Close() //nolint:errcheck
suite.Require().NoError(conn.Link.New(&rtnetlink.LinkMessage{
suite.Require().NoError(
conn.Link.New(
&rtnetlink.LinkMessage{
Type: unix.ARPHRD_ETHER,
Flags: unix.IFF_UP,
Change: unix.IFF_UP,
@ -267,7 +297,9 @@ func (suite *RouteSpecSuite) TestDefaultAndInterfaceRoutes() {
Kind: "dummy",
},
},
}))
},
),
)
iface, err := net.InterfaceByName(dummyInterface)
suite.Require().NoError(err)
@ -276,7 +308,9 @@ func (suite *RouteSpecSuite) TestDefaultAndInterfaceRoutes() {
localIP := net.ParseIP("10.28.0.27").To4()
suite.Require().NoError(conn.Address.New(&rtnetlink.AddressMessage{
suite.Require().NoError(
conn.Address.New(
&rtnetlink.AddressMessage{
Family: unix.AF_INET,
PrefixLength: 32,
Scope: unix.RT_SCOPE_UNIVERSE,
@ -285,7 +319,9 @@ func (suite *RouteSpecSuite) TestDefaultAndInterfaceRoutes() {
Address: localIP,
Local: localIP,
},
}))
},
),
)
def := network.NewRouteSpec(network.NamespaceName, "default")
*def.TypedSpec() = network.RouteSpecSpec{
@ -321,24 +357,31 @@ func (suite *RouteSpecSuite) TestDefaultAndInterfaceRoutes() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
if err := suite.assertRoute(netaddr.IPPrefix{}, netaddr.MustParseIP("10.28.0.1"), func(route rtnetlink.RouteMessage) error {
if err := suite.assertRoute(
netaddr.IPPrefix{}, netaddr.MustParseIP("10.28.0.1"), func(route rtnetlink.RouteMessage) error {
suite.Assert().Nil(route.Attributes.Dst)
suite.Assert().EqualValues(1048576, route.Attributes.Priority)
return nil
}); err != nil {
},
); err != nil {
return err
}
return suite.assertRoute(netaddr.MustParseIPPrefix("10.28.0.1/32"), netaddr.IP{}, func(route rtnetlink.RouteMessage) error {
return suite.assertRoute(
netaddr.MustParseIPPrefix("10.28.0.1/32"), netaddr.IP{}, func(route rtnetlink.RouteMessage) error {
suite.Assert().Nil(route.Attributes.Gateway)
suite.Assert().EqualValues(1048576, route.Attributes.Priority)
return nil
})
}))
},
)
},
),
)
// teardown the routes
for {
@ -378,7 +421,9 @@ func (suite *RouteSpecSuite) TestLinkLocalRoute() {
defer conn.Close() //nolint:errcheck
suite.Require().NoError(conn.Link.New(&rtnetlink.LinkMessage{
suite.Require().NoError(
conn.Link.New(
&rtnetlink.LinkMessage{
Type: unix.ARPHRD_ETHER,
Flags: unix.IFF_UP,
Change: unix.IFF_UP,
@ -389,7 +434,9 @@ func (suite *RouteSpecSuite) TestLinkLocalRoute() {
Kind: "dummy",
},
},
}))
},
),
)
iface, err := net.InterfaceByName(dummyInterface)
suite.Require().NoError(err)
@ -398,7 +445,9 @@ func (suite *RouteSpecSuite) TestLinkLocalRoute() {
localIP := net.ParseIP("10.28.0.27").To4()
suite.Require().NoError(conn.Address.New(&rtnetlink.AddressMessage{
suite.Require().NoError(
conn.Address.New(
&rtnetlink.AddressMessage{
Family: unix.AF_INET,
PrefixLength: 24,
Scope: unix.RT_SCOPE_UNIVERSE,
@ -407,7 +456,9 @@ func (suite *RouteSpecSuite) TestLinkLocalRoute() {
Address: localIP,
Local: localIP,
},
}))
},
),
)
ll := network.NewRouteSpec(network.NamespaceName, "ll")
*ll.TypedSpec() = network.RouteSpecSpec{
@ -428,14 +479,21 @@ func (suite *RouteSpecSuite) TestLinkLocalRoute() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoute(netaddr.MustParseIPPrefix("169.254.169.254/32"), netaddr.MustParseIP("10.28.0.1"), func(route rtnetlink.RouteMessage) error {
return suite.assertRoute(
netaddr.MustParseIPPrefix("169.254.169.254/32"),
netaddr.MustParseIP("10.28.0.1"),
func(route rtnetlink.RouteMessage) error {
suite.Assert().EqualValues(1048576, route.Attributes.Priority)
return nil
})
}))
},
)
},
),
)
// teardown the routes
for {
@ -450,7 +508,12 @@ func (suite *RouteSpecSuite) TestLinkLocalRoute() {
}
// torn down route should be removed immediately
suite.Assert().NoError(suite.assertNoRoute(netaddr.MustParseIPPrefix("169.254.169.254/32"), netaddr.MustParseIP("10.28.0.1")))
suite.Assert().NoError(
suite.assertNoRoute(
netaddr.MustParseIPPrefix("169.254.169.254/32"),
netaddr.MustParseIP("10.28.0.1"),
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, ll.Metadata()))
}

View File

@ -35,7 +35,7 @@ type RouteStatusSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -71,7 +71,10 @@ func (suite *RouteStatusSuite) assertRoutes(requiredIDs []string, check func(*ne
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.RouteStatusType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.RouteStatusType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -97,9 +100,11 @@ func (suite *RouteStatusSuite) assertRoutes(requiredIDs []string, check func(*ne
}
func (suite *RouteStatusSuite) TestRoutes() {
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertRoutes([]string{"local/inet4//127.0.0.0/8/0"}, func(r *network.RouteStatus) error {
return suite.assertRoutes(
[]string{"local/inet4//127.0.0.0/8/0"}, func(r *network.RouteStatus) error {
suite.Assert().True(r.TypedSpec().Source.IsLoopback())
suite.Assert().Equal("lo", r.TypedSpec().OutLinkName)
suite.Assert().Equal(nethelpers.TableLocal, r.TypedSpec().Table)
@ -108,8 +113,11 @@ func (suite *RouteStatusSuite) TestRoutes() {
suite.Assert().Equal(nethelpers.ProtocolKernel, r.TypedSpec().Protocol)
return nil
})
}))
},
)
},
),
)
}
func (suite *RouteStatusSuite) TearDownTest() {

View File

@ -35,7 +35,7 @@ type StatusSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -65,7 +65,10 @@ func (suite *StatusSuite) startRuntime() {
}
func (suite *StatusSuite) assertStatus(expected network.StatusSpec) error {
status, err := suite.state.Get(suite.ctx, resource.NewMetadata(network.NamespaceName, network.StatusType, network.StatusID, resource.VersionUndefined))
status, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.StatusType, network.StatusID, resource.VersionUndefined),
)
if err != nil {
if !state.IsNotFoundError(err) {
suite.Require().NoError(err)
@ -82,10 +85,13 @@ func (suite *StatusSuite) assertStatus(expected network.StatusSpec) error {
}
func (suite *StatusSuite) TestNone() {
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus(network.StatusSpec{})
}))
},
),
)
}
func (suite *StatusSuite) TestAddresses() {
@ -94,10 +100,13 @@ func (suite *StatusSuite) TestAddresses() {
suite.Require().NoError(suite.state.Create(suite.ctx, nodeAddress))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus(network.StatusSpec{AddressReady: true})
}))
},
),
)
}
func (suite *StatusSuite) TestRoutes() {
@ -106,10 +115,13 @@ func (suite *StatusSuite) TestRoutes() {
suite.Require().NoError(suite.state.Create(suite.ctx, route))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus(network.StatusSpec{ConnectivityReady: true})
}))
},
),
)
}
func (suite *StatusSuite) TestHostname() {
@ -118,10 +130,13 @@ func (suite *StatusSuite) TestHostname() {
suite.Require().NoError(suite.state.Create(suite.ctx, hostname))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus(network.StatusSpec{HostnameReady: true})
}))
},
),
)
}
func (suite *StatusSuite) TestEtcFiles() {
@ -131,10 +146,13 @@ func (suite *StatusSuite) TestEtcFiles() {
suite.Require().NoError(suite.state.Create(suite.ctx, hosts))
suite.Require().NoError(suite.state.Create(suite.ctx, resolv))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus(network.StatusSpec{EtcFilesReady: true})
}))
},
),
)
}
func (suite *StatusSuite) TearDownTest() {
@ -145,9 +163,24 @@ func (suite *StatusSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewNodeAddress(network.NamespaceName, "bar")))
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewResolverStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewHostnameStatus(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewNodeAddress(network.NamespaceName, "bar"),
),
)
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewResolverStatus(network.NamespaceName, "bar"),
),
)
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewHostnameStatus(network.NamespaceName, "bar"),
),
)
suite.Assert().NoError(suite.state.Create(context.Background(), files.NewEtcFileStatus(files.NamespaceName, "bar")))
}

View File

@ -39,7 +39,7 @@ type TimeServerConfigSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -64,14 +64,20 @@ func (suite *TimeServerConfigSuite) startRuntime() {
}()
}
func (suite *TimeServerConfigSuite) assertTimeServers(requiredIDs []string, check func(*network.TimeServerSpec) error) error {
func (suite *TimeServerConfigSuite) assertTimeServers(
requiredIDs []string,
check func(*network.TimeServerSpec) error,
) error {
missingIDs := make(map[string]struct{}, len(requiredIDs))
for _, id := range requiredIDs {
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.TimeServerSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.TimeServerSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -97,7 +103,10 @@ func (suite *TimeServerConfigSuite) assertTimeServers(requiredIDs []string, chec
}
func (suite *TimeServerConfigSuite) assertNoTimeServer(id string) error {
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.ConfigNamespaceName, network.TimeServerSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.ConfigNamespaceName, network.TimeServerSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -116,36 +125,50 @@ func (suite *TimeServerConfigSuite) TestDefaults() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeServers([]string{
return suite.assertTimeServers(
[]string{
"default/timeservers",
}, func(r *network.TimeServerSpec) error {
suite.Assert().Equal([]string{constants.DefaultNTPServer}, r.TypedSpec().NTPServers)
suite.Assert().Equal(network.ConfigDefault, r.TypedSpec().ConfigLayer)
return nil
})
}))
},
)
},
),
)
}
func (suite *TimeServerConfigSuite) TestCmdline() {
suite.Require().NoError(suite.runtime.RegisterController(&netctrl.TimeServerConfigController{
suite.Require().NoError(
suite.runtime.RegisterController(
&netctrl.TimeServerConfigController{
Cmdline: procfs.NewCmdline("ip=172.20.0.2:172.21.0.1:172.20.0.1:255.255.255.0:master1:eth1::10.0.0.1:10.0.0.2:10.0.0.1"),
}))
},
),
)
suite.startRuntime()
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeServers([]string{
return suite.assertTimeServers(
[]string{
"cmdline/timeservers",
}, func(r *network.TimeServerSpec) error {
suite.Assert().Equal([]string{"10.0.0.1"}, r.TypedSpec().NTPServers)
return nil
})
}))
},
)
},
),
)
}
func (suite *TimeServerConfigSuite) TestMachineConfiguration() {
@ -156,7 +179,8 @@ func (suite *TimeServerConfigSuite) TestMachineConfiguration() {
u, err := url.Parse("https://foo:6443")
suite.Require().NoError(err)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineTime: &v1alpha1.TimeConfig{
@ -170,32 +194,43 @@ func (suite *TimeServerConfigSuite) TestMachineConfiguration() {
},
},
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeServers([]string{
return suite.assertTimeServers(
[]string{
"configuration/timeservers",
}, func(r *network.TimeServerSpec) error {
suite.Assert().Equal([]string{"za.pool.ntp.org", "pool.ntp.org"}, r.TypedSpec().NTPServers)
return nil
})
}))
},
)
},
),
)
_, err = suite.state.UpdateWithConflicts(suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
r.(*config.MachineConfig).Config().(*v1alpha1.Config).MachineConfig.MachineTime = nil
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertNoTimeServer("configuration/timeservers")
}))
},
),
)
}
func (suite *TimeServerConfigSuite) TearDownTest() {
@ -206,10 +241,14 @@ func (suite *TimeServerConfigSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -36,7 +36,7 @@ type TimeServerMergeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -65,14 +65,20 @@ func (suite *TimeServerMergeSuite) startRuntime() {
}()
}
func (suite *TimeServerMergeSuite) assertTimeServers(requiredIDs []string, check func(*network.TimeServerSpec) error) error {
func (suite *TimeServerMergeSuite) assertTimeServers(
requiredIDs []string,
check func(*network.TimeServerSpec) error,
) error {
missingIDs := make(map[string]struct{}, len(requiredIDs))
for _, id := range requiredIDs {
missingIDs[id] = struct{}{}
}
resources, err := suite.state.List(suite.ctx, resource.NewMetadata(network.NamespaceName, network.TimeServerSpecType, "", resource.VersionUndefined))
resources, err := suite.state.List(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.TimeServerSpecType, "", resource.VersionUndefined),
)
if err != nil {
return err
}
@ -126,22 +132,29 @@ func (suite *TimeServerMergeSuite) TestMerge() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeServers([]string{
return suite.assertTimeServers(
[]string{
"timeservers",
}, func(r *network.TimeServerSpec) error {
suite.Assert().Equal(*static.TypedSpec(), *r.TypedSpec())
return nil
})
}))
},
)
},
),
)
suite.Require().NoError(suite.state.Destroy(suite.ctx, static.Metadata()))
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeServers([]string{
return suite.assertTimeServers(
[]string{
"timeservers",
}, func(r *network.TimeServerSpec) error {
if !reflect.DeepEqual(r.TypedSpec().NTPServers, []string{"ntp.eth0", "ntp.eth1"}) {
@ -149,8 +162,11 @@ func (suite *TimeServerMergeSuite) TestMerge() {
}
return nil
})
}))
},
)
},
),
)
}
func (suite *TimeServerMergeSuite) TearDownTest() {
@ -161,7 +177,12 @@ func (suite *TimeServerMergeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewTimeServerSpec(network.ConfigNamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewTimeServerSpec(network.ConfigNamespaceName, "bar"),
),
)
}
func TestTimeServerMergeSuite(t *testing.T) {

View File

@ -35,7 +35,7 @@ type TimeServerSpecSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -65,7 +65,10 @@ func (suite *TimeServerSpecSuite) startRuntime() {
}
func (suite *TimeServerSpecSuite) assertStatus(id string, servers ...string) error {
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(network.NamespaceName, network.TimeServerStatusType, id, resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(network.NamespaceName, network.TimeServerStatusType, id, resource.VersionUndefined),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -94,10 +97,13 @@ func (suite *TimeServerSpecSuite) TestSpec() {
suite.Require().NoError(suite.state.Create(suite.ctx, res), "%v", res.Spec())
}
suite.Assert().NoError(retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(3*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertStatus("timeservers", constants.DefaultNTPServer)
}))
},
),
)
}
func (suite *TimeServerSpecSuite) TearDownTest() {
@ -108,7 +114,12 @@ func (suite *TimeServerSpecSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
suite.Assert().NoError(suite.state.Create(context.Background(), network.NewTimeServerSpec(network.NamespaceName, "bar")))
suite.Assert().NoError(
suite.state.Create(
context.Background(),
network.NewTimeServerSpec(network.NamespaceName, "bar"),
),
)
}
func TestTimeServerSpecSuite(t *testing.T) {

View File

@ -33,6 +33,7 @@ type PerfSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
//nolint:containedctx
ctx context.Context
ctxCancel context.CancelFunc
}
@ -65,9 +66,18 @@ func (suite *PerfSuite) TestReconcile() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
cpu, err := suite.state.Get(suite.ctx, resource.NewMetadata(perfresource.NamespaceName, perfresource.CPUType, perfresource.CPUID, resource.VersionUndefined))
cpu, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
perfresource.NamespaceName,
perfresource.CPUType,
perfresource.CPUID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -76,7 +86,15 @@ func (suite *PerfSuite) TestReconcile() {
return err
}
mem, err := suite.state.Get(suite.ctx, resource.NewMetadata(perfresource.NamespaceName, perfresource.MemoryType, perfresource.MemoryID, resource.VersionUndefined))
mem, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
perfresource.NamespaceName,
perfresource.MemoryType,
perfresource.MemoryID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -94,7 +112,8 @@ func (suite *PerfSuite) TestReconcile() {
return nil
},
))
),
)
}
func (suite *PerfSuite) TearDownTest() {

View File

@ -38,7 +38,7 @@ type RuntimeSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -92,10 +92,14 @@ func (suite *RuntimeSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -64,7 +64,7 @@ type EventsSinkSuite struct {
wg sync.WaitGroup
eg errgroup.Group
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -84,11 +84,15 @@ func (suite *EventsSinkSuite) SetupTest() {
suite.cmdline = procfs.NewCmdline(fmt.Sprintf("%s=%s", constants.KernelParamEventsSink, "localhost"))
suite.drainer = talosruntime.NewDrainer()
suite.Require().NoError(suite.runtime.RegisterController(&controllerruntime.EventsSinkController{
suite.Require().NoError(
suite.runtime.RegisterController(
&controllerruntime.EventsSinkController{
V1Alpha1Events: suite.events,
Cmdline: suite.cmdline,
Drainer: suite.drainer,
}))
},
),
)
suite.startRuntime()
}
@ -121,37 +125,46 @@ func (suite *EventsSinkSuite) startServer(ctx context.Context) {
suite.server = grpc.NewServer()
eventsapi.RegisterEventSinkServiceServer(suite.server, suite.sink)
suite.eg.Go(func() error {
suite.eg.Go(
func() error {
<-ctx.Done()
suite.server.Stop()
return nil
})
},
)
suite.eg.Go(func() error {
suite.eg.Go(
func() error {
return suite.server.Serve(lis)
})
},
)
}
func (suite *EventsSinkSuite) TestPublish() {
ctx, cancel := context.WithCancel(suite.ctx)
defer cancel()
suite.events.Publish(&machine.AddressEvent{
suite.events.Publish(
&machine.AddressEvent{
Hostname: "localhost",
})
},
)
suite.events.Publish(&machine.PhaseEvent{
suite.events.Publish(
&machine.PhaseEvent{
Phase: "test",
Action: machine.PhaseEvent_START,
})
},
)
suite.Require().Equal(0, len(suite.handler.events))
suite.startServer(ctx)
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(func() error {
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(
func() error {
suite.handler.eventsMu.Lock()
defer suite.handler.eventsMu.Unlock()
@ -160,7 +173,8 @@ func (suite *EventsSinkSuite) TestPublish() {
}
return nil
})
},
)
suite.Require().NoError(err)
}
@ -169,14 +183,18 @@ func (suite *EventsSinkSuite) TestDrain() {
defer cancel()
for i := 0; i < 10; i++ {
suite.events.Publish(&machine.PhaseEvent{
suite.events.Publish(
&machine.PhaseEvent{
Phase: "test",
Action: machine.PhaseEvent_START,
})
suite.events.Publish(&machine.PhaseEvent{
},
)
suite.events.Publish(
&machine.PhaseEvent{
Phase: "test",
Action: machine.PhaseEvent_STOP,
})
},
)
}
suite.Require().Equal(0, len(suite.handler.events))
@ -188,19 +206,24 @@ func (suite *EventsSinkSuite) TestDrain() {
var eg errgroup.Group
eg.Go(func() error {
eg.Go(
func() error {
return suite.drainer.Drain(c)
})
},
)
eg.Go(func() error {
eg.Go(
func() error {
time.Sleep(time.Millisecond * 300)
suite.startServer(ctx)
return nil
})
},
)
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(func() error {
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(
func() error {
suite.handler.eventsMu.Lock()
defer suite.handler.eventsMu.Unlock()
@ -209,7 +232,8 @@ func (suite *EventsSinkSuite) TestDrain() {
}
return nil
})
},
)
suite.Require().NoError(err)
suite.Require().NoError(eg.Wait())

View File

@ -60,7 +60,7 @@ type KmsgLogDeliverySuite struct {
drainer *talosruntime.Drainer
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
handler *logHandler
@ -92,13 +92,23 @@ func (suite *KmsgLogDeliverySuite) SetupTest() {
suite.srv.Serve() //nolint:errcheck
}()
suite.cmdline = procfs.NewCmdline(fmt.Sprintf("%s=%s", constants.KernelParamLoggingKernel, fmt.Sprintf("tcp://%s", listener.Addr())))
suite.cmdline = procfs.NewCmdline(
fmt.Sprintf(
"%s=%s",
constants.KernelParamLoggingKernel,
fmt.Sprintf("tcp://%s", listener.Addr()),
),
)
suite.drainer = talosruntime.NewDrainer()
suite.Require().NoError(suite.runtime.RegisterController(&controllerruntime.KmsgLogDeliveryController{
suite.Require().NoError(
suite.runtime.RegisterController(
&controllerruntime.KmsgLogDeliveryController{
Cmdline: suite.cmdline,
Drainer: suite.drainer,
}))
},
),
)
status := network.NewStatus(network.NamespaceName, network.StatusID)
status.TypedSpec().AddressReady = true
@ -120,13 +130,15 @@ func (suite *KmsgLogDeliverySuite) TestDelivery() {
suite.startRuntime()
// controller should deliver some kernel logs from host's kmsg buffer
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(func() error {
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(
func() error {
if suite.handler.getCount() == 0 {
return retry.ExpectedErrorf("no logs received")
}
return nil
})
},
)
suite.Require().NoError(err)
}
@ -134,13 +146,15 @@ func (suite *KmsgLogDeliverySuite) TestDrain() {
suite.startRuntime()
// wait for controller to start delivering some logs
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(func() error {
err := retry.Constant(time.Second*5, retry.WithUnits(time.Millisecond*100)).Retry(
func() error {
if suite.handler.getCount() == 0 {
return retry.ExpectedErrorf("no logs received")
}
return nil
})
},
)
suite.Require().NoError(err)
// drain should be successful, i.e. controller should stop on its own before context is canceled

View File

@ -332,7 +332,8 @@ func (ctrl *APIController) generateControlPlane(ctx context.Context, r controlle
}
func (ctrl *APIController) generateJoin(ctx context.Context, r controller.Runtime, logger *zap.Logger,
rootSpec *secrets.OSRootSpec, endpointsStr []string, certSANs *secrets.CertSANSpec) error {
rootSpec *secrets.OSRootSpec, endpointsStr []string, certSANs *secrets.CertSANSpec,
) error {
remoteGen, err := gen.NewRemoteGenerator(rootSpec.Token, endpointsStr, rootSpec.CA)
if err != nil {
return fmt.Errorf("failed creating trustd client: %w", err)

View File

@ -37,7 +37,7 @@ type APICertSANsSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -78,13 +78,28 @@ func (suite *APICertSANsSuite) TestReconcileControlPlane() {
hostnameStatus.TypedSpec().Domainname = "some.org"
suite.Require().NoError(suite.state.Create(suite.ctx, hostnameStatus))
nodeAddresses := network.NewNodeAddress(network.NamespaceName, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s))
nodeAddresses.TypedSpec().Addresses = []netaddr.IPPrefix{netaddr.MustParseIPPrefix("10.2.1.3/24"), netaddr.MustParseIPPrefix("172.16.0.1/32")}
nodeAddresses := network.NewNodeAddress(
network.NamespaceName,
network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s),
)
nodeAddresses.TypedSpec().Addresses = []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("10.2.1.3/24"),
netaddr.MustParseIPPrefix("172.16.0.1/32"),
}
suite.Require().NoError(suite.state.Create(suite.ctx, nodeAddresses))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
certSANs, err := suite.state.Get(suite.ctx, resource.NewMetadata(secrets.NamespaceName, secrets.CertSANType, secrets.CertSANAPIID, resource.VersionUndefined))
certSANs, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
secrets.NamespaceName,
secrets.CertSANType,
secrets.CertSANAPIID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -101,7 +116,8 @@ func (suite *APICertSANsSuite) TestReconcileControlPlane() {
return nil
},
))
),
)
}
func (suite *APICertSANsSuite) TearDownTest() {

View File

@ -41,7 +41,7 @@ type APISuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -110,9 +110,18 @@ func (suite *APISuite) TestReconcileControlPlane() {
suite.Require().NoError(suite.state.Create(suite.ctx, certSANs))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
certs, err := suite.state.Get(suite.ctx, resource.NewMetadata(secrets.NamespaceName, secrets.APIType, secrets.APIID, resource.VersionUndefined))
certs, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
secrets.NamespaceName,
secrets.APIType,
secrets.APIID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -135,7 +144,10 @@ func (suite *APISuite) TestReconcileControlPlane() {
suite.Assert().Equal("foo.example.com", serverCert.Subject.CommonName)
suite.Assert().Empty(serverCert.Subject.Organization)
suite.Assert().Equal(stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment, serverCert.KeyUsage)
suite.Assert().Equal(
stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment,
serverCert.KeyUsage,
)
suite.Assert().Equal([]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageServerAuth}, serverCert.ExtKeyUsage)
clientCert, err := apiCerts.Client.GetCert()
@ -147,12 +159,16 @@ func (suite *APISuite) TestReconcileControlPlane() {
suite.Assert().Equal("foo.example.com", clientCert.Subject.CommonName)
suite.Assert().Equal([]string{string(role.Impersonator)}, clientCert.Subject.Organization)
suite.Assert().Equal(stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment, clientCert.KeyUsage)
suite.Assert().Equal(
stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment,
clientCert.KeyUsage,
)
suite.Assert().Equal([]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageClientAuth}, clientCert.ExtKeyUsage)
return nil
},
))
),
)
}
func (suite *APISuite) TearDownTest() {

View File

@ -37,7 +37,7 @@ type KubeletSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -75,7 +75,8 @@ func (suite *KubeletSuite) TestReconcile() {
k8sCA := x509.NewCertificateAndKeyFromCertificateAuthority(ca)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{
@ -87,13 +88,23 @@ func (suite *KubeletSuite) TestReconcile() {
ClusterCA: k8sCA,
BootstrapToken: "abc.def",
},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
kubeletSecrets, err := suite.state.Get(suite.ctx, resource.NewMetadata(secrets.NamespaceName, secrets.KubeletType, secrets.KubeletID, resource.VersionUndefined))
kubeletSecrets, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
secrets.NamespaceName,
secrets.KubeletType,
secrets.KubeletID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -111,7 +122,8 @@ func (suite *KubeletSuite) TestReconcile() {
return nil
},
))
),
)
}
func (suite *KubeletSuite) TearDownTest() {

View File

@ -177,7 +177,8 @@ func (ctrl *KubernetesController) Run(ctx context.Context, r controller.Runtime,
}
func (ctrl *KubernetesController) updateSecrets(k8sRoot *secrets.KubernetesRootSpec, k8sSecrets *secrets.KubernetesCertsSpec,
certSANs *secrets.CertSANSpec) error {
certSANs *secrets.CertSANSpec,
) error {
ca, err := x509.NewCertificateAuthorityFromCertificateAndKey(k8sRoot.CA)
if err != nil {
return fmt.Errorf("failed to parse CA certificate: %w", err)

View File

@ -39,7 +39,7 @@ type KubernetesCertSANsSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -86,13 +86,28 @@ func (suite *KubernetesCertSANsSuite) TestReconcile() {
hostnameStatus.TypedSpec().Domainname = "example.com"
suite.Require().NoError(suite.state.Create(suite.ctx, hostnameStatus))
nodeAddresses := network.NewNodeAddress(network.NamespaceName, network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s))
nodeAddresses.TypedSpec().Addresses = []netaddr.IPPrefix{netaddr.MustParseIPPrefix("10.2.1.3/24"), netaddr.MustParseIPPrefix("172.16.0.1/32")}
nodeAddresses := network.NewNodeAddress(
network.NamespaceName,
network.FilteredNodeAddressID(network.NodeAddressAccumulativeID, k8s.NodeAddressFilterNoK8s),
)
nodeAddresses.TypedSpec().Addresses = []netaddr.IPPrefix{
netaddr.MustParseIPPrefix("10.2.1.3/24"),
netaddr.MustParseIPPrefix("172.16.0.1/32"),
}
suite.Require().NoError(suite.state.Create(suite.ctx, nodeAddresses))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
certSANs, err := suite.state.Get(suite.ctx, resource.NewMetadata(secrets.NamespaceName, secrets.CertSANType, secrets.CertSANKubernetesID, resource.VersionUndefined))
certSANs, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
secrets.NamespaceName,
secrets.CertSANType,
secrets.CertSANKubernetesID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -114,12 +129,14 @@ func (suite *KubernetesCertSANsSuite) TestReconcile() {
"kubernetes.default.svc.cluster.remote",
"localhost",
"some.url",
}, spec.DNSNames)
}, spec.DNSNames,
)
suite.Assert().Equal("[10.2.1.3 10.4.3.2 172.16.0.1]", fmt.Sprintf("%v", spec.IPs))
return nil
},
))
),
)
}
func (suite *KubernetesCertSANsSuite) TearDownTest() {

View File

@ -44,7 +44,7 @@ type KubernetesSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -138,14 +138,25 @@ func (suite *KubernetesSuite) TestReconcile() {
suite.Require().NoError(suite.state.Create(suite.ctx, certSANs))
timeSync := timeresource.NewStatus()
timeSync.SetStatus(timeresource.StatusSpec{
timeSync.SetStatus(
timeresource.StatusSpec{
Synced: true,
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, timeSync))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
certs, err := suite.state.Get(suite.ctx, resource.NewMetadata(secrets.NamespaceName, secrets.KubernetesType, secrets.KubernetesID, resource.VersionUndefined))
certs, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
secrets.NamespaceName,
secrets.KubernetesType,
secrets.KubernetesID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -170,13 +181,17 @@ func (suite *KubernetesSuite) TestReconcile() {
"kubernetes.default.svc.cluster.remote",
"localhost",
"some.url",
}, apiCert.DNSNames)
}, apiCert.DNSNames,
)
suite.Assert().Equal("[10.2.1.3 10.4.3.2 172.16.0.1]", fmt.Sprintf("%v", apiCert.IPAddresses))
suite.Assert().Equal("kube-apiserver", apiCert.Subject.CommonName)
suite.Assert().Equal([]string{"kube-master"}, apiCert.Subject.Organization)
suite.Assert().Equal(stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment, apiCert.KeyUsage)
suite.Assert().Equal(
stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment,
apiCert.KeyUsage,
)
suite.Assert().Equal([]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageServerAuth}, apiCert.ExtKeyUsage)
clientCert, err := kubernetesCerts.APIServerKubeletClient.GetCert()
@ -185,10 +200,19 @@ func (suite *KubernetesSuite) TestReconcile() {
suite.Assert().Empty(clientCert.DNSNames)
suite.Assert().Empty(clientCert.IPAddresses)
suite.Assert().Equal(constants.KubernetesAPIServerKubeletClientCommonName, clientCert.Subject.CommonName)
suite.Assert().Equal([]string{constants.KubernetesAdminCertOrganization}, clientCert.Subject.Organization)
suite.Assert().Equal(
constants.KubernetesAPIServerKubeletClientCommonName,
clientCert.Subject.CommonName,
)
suite.Assert().Equal(
[]string{constants.KubernetesAdminCertOrganization},
clientCert.Subject.Organization,
)
suite.Assert().Equal(stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment, clientCert.KeyUsage)
suite.Assert().Equal(
stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment,
clientCert.KeyUsage,
)
suite.Assert().Equal([]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageClientAuth}, clientCert.ExtKeyUsage)
frontProxyCert, err := kubernetesCerts.FrontProxy.GetCert()
@ -200,10 +224,20 @@ func (suite *KubernetesSuite) TestReconcile() {
suite.Assert().Equal("front-proxy-client", frontProxyCert.Subject.CommonName)
suite.Assert().Empty(frontProxyCert.Subject.Organization)
suite.Assert().Equal(stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment, frontProxyCert.KeyUsage)
suite.Assert().Equal([]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageClientAuth}, frontProxyCert.ExtKeyUsage)
suite.Assert().Equal(
stdlibx509.KeyUsageDigitalSignature|stdlibx509.KeyUsageKeyEncipherment,
frontProxyCert.KeyUsage,
)
suite.Assert().Equal(
[]stdlibx509.ExtKeyUsage{stdlibx509.ExtKeyUsageClientAuth},
frontProxyCert.ExtKeyUsage,
)
for _, kubeconfig := range []string{kubernetesCerts.ControllerManagerKubeconfig, kubernetesCerts.SchedulerKubeconfig, kubernetesCerts.AdminKubeconfig} {
for _, kubeconfig := range []string{
kubernetesCerts.ControllerManagerKubeconfig,
kubernetesCerts.SchedulerKubeconfig,
kubernetesCerts.AdminKubeconfig,
} {
config, err := clientcmd.Load([]byte(kubeconfig))
suite.Require().NoError(err)
@ -212,7 +246,8 @@ func (suite *KubernetesSuite) TestReconcile() {
return nil
},
))
),
)
}
func (suite *KubernetesSuite) TearDownTest() {

View File

@ -40,7 +40,7 @@ type ManagerSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
s *grpc.Server
@ -90,9 +90,13 @@ func (suite *ManagerSuite) SetupTest() {
cmdline := procfs.NewCmdline(fmt.Sprintf("%s=%s", constants.KernelParamSideroLink, lis.Addr().String()))
suite.Require().NoError(suite.runtime.RegisterController(&siderolinkctrl.ManagerController{
suite.Require().NoError(
suite.runtime.RegisterController(
&siderolinkctrl.ManagerController{
Cmdline: cmdline,
}))
},
),
)
}
func (suite *ManagerSuite) startRuntime() {
@ -113,14 +117,20 @@ func (suite *ManagerSuite) TestReconcile() {
nodeAddress := netaddr.MustParseIPPrefix(mockNodeAddressPrefix)
suite.Assert().NoError(retry.Constant(5*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(5*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
addressResource, err := suite.state.Get(suite.ctx, resource.NewMetadata(
addressResource, err := suite.state.Get(
suite.ctx, resource.NewMetadata(
network.ConfigNamespaceName,
network.AddressSpecType,
network.LayeredID(network.ConfigOperator, network.AddressID(constants.SideroLinkName, nodeAddress)),
network.LayeredID(
network.ConfigOperator,
network.AddressID(constants.SideroLinkName, nodeAddress),
),
resource.VersionUndefined,
))
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -136,12 +146,14 @@ func (suite *ManagerSuite) TestReconcile() {
suite.Assert().Equal(nethelpers.FamilyInet6, address.Family)
suite.Assert().Equal(constants.SideroLinkName, address.LinkName)
linkResource, err := suite.state.Get(suite.ctx, resource.NewMetadata(
linkResource, err := suite.state.Get(
suite.ctx, resource.NewMetadata(
network.ConfigNamespaceName,
network.LinkSpecType,
network.LayeredID(network.ConfigOperator, network.LinkID(constants.SideroLinkName)),
resource.VersionUndefined,
))
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -158,11 +170,23 @@ func (suite *ManagerSuite) TestReconcile() {
suite.Assert().Len(link.Wireguard.Peers, 1)
suite.Assert().Equal(mockServerEndpoint, link.Wireguard.Peers[0].Endpoint)
suite.Assert().Equal(mockServerPublicKey, link.Wireguard.Peers[0].PublicKey)
suite.Assert().Equal([]netaddr.IPPrefix{netaddr.IPPrefixFrom(netaddr.MustParseIP(mockServerAddress), 128)}, link.Wireguard.Peers[0].AllowedIPs)
suite.Assert().Equal(constants.SideroLinkDefaultPeerKeepalive, link.Wireguard.Peers[0].PersistentKeepaliveInterval)
suite.Assert().Equal(
[]netaddr.IPPrefix{
netaddr.IPPrefixFrom(
netaddr.MustParseIP(mockServerAddress),
128,
),
}, link.Wireguard.Peers[0].AllowedIPs,
)
suite.Assert().Equal(
constants.SideroLinkDefaultPeerKeepalive,
link.Wireguard.Peers[0].PersistentKeepaliveInterval,
)
return nil
}))
},
),
)
}
func (suite *ManagerSuite) TearDownTest() {

View File

@ -41,7 +41,7 @@ type SyncSuite struct {
runtime *runtime.Runtime
wg sync.WaitGroup
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
syncerMu sync.Mutex
@ -72,7 +72,15 @@ func (suite *SyncSuite) startRuntime() {
}
func (suite *SyncSuite) assertTimeStatus(spec timeresource.StatusSpec) error {
r, err := suite.state.Get(suite.ctx, resource.NewMetadata(v1alpha1resource.NamespaceName, timeresource.StatusType, timeresource.StatusID, resource.VersionUndefined))
r, err := suite.state.Get(
suite.ctx,
resource.NewMetadata(
v1alpha1resource.NamespaceName,
timeresource.StatusType,
timeresource.StatusID,
resource.VersionUndefined,
),
)
if err != nil {
if state.IsNotFoundError(err) {
return retry.ExpectedError(err)
@ -91,10 +99,14 @@ func (suite *SyncSuite) assertTimeStatus(spec timeresource.StatusSpec) error {
}
func (suite *SyncSuite) TestReconcileContainerMode() {
suite.Require().NoError(suite.runtime.RegisterController(&timectrl.SyncController{
suite.Require().NoError(
suite.runtime.RegisterController(
&timectrl.SyncController{
V1Alpha1Mode: v1alpha1runtime.ModeContainer,
NewNTPSyncer: suite.newMockSyncer,
}))
},
),
)
timeServers := network.NewTimeServerStatus(network.NamespaceName, network.TimeServerID)
timeServers.TypedSpec().NTPServers = []string{constants.DefaultNTPServer}
@ -102,7 +114,8 @@ func (suite *SyncSuite) TestReconcileContainerMode() {
suite.startRuntime()
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -112,14 +125,19 @@ func (suite *SyncSuite) TestReconcileContainerMode() {
},
)
},
))
),
)
}
func (suite *SyncSuite) TestReconcileSyncDisabled() {
suite.Require().NoError(suite.runtime.RegisterController(&timectrl.SyncController{
suite.Require().NoError(
suite.runtime.RegisterController(
&timectrl.SyncController{
V1Alpha1Mode: v1alpha1runtime.ModeMetal,
NewNTPSyncer: suite.newMockSyncer,
}))
},
),
)
suite.startRuntime()
@ -127,7 +145,8 @@ func (suite *SyncSuite) TestReconcileSyncDisabled() {
timeServers.TypedSpec().NTPServers = []string{constants.DefaultNTPServer}
suite.Require().NoError(suite.state.Create(suite.ctx, timeServers))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -137,9 +156,11 @@ func (suite *SyncSuite) TestReconcileSyncDisabled() {
},
)
},
))
),
)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineTime: &v1alpha1.TimeConfig{
@ -147,11 +168,13 @@ func (suite *SyncSuite) TestReconcileSyncDisabled() {
},
},
ClusterConfig: &v1alpha1.ClusterConfig{},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -161,14 +184,19 @@ func (suite *SyncSuite) TestReconcileSyncDisabled() {
},
)
},
))
),
)
}
func (suite *SyncSuite) TestReconcileSyncDefaultConfig() {
suite.Require().NoError(suite.runtime.RegisterController(&timectrl.SyncController{
suite.Require().NoError(
suite.runtime.RegisterController(
&timectrl.SyncController{
V1Alpha1Mode: v1alpha1runtime.ModeMetal,
NewNTPSyncer: suite.newMockSyncer,
}))
},
),
)
suite.startRuntime()
@ -176,15 +204,18 @@ func (suite *SyncSuite) TestReconcileSyncDefaultConfig() {
timeServers.TypedSpec().NTPServers = []string{constants.DefaultNTPServer}
suite.Require().NoError(suite.state.Create(suite.ctx, timeServers))
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -194,14 +225,19 @@ func (suite *SyncSuite) TestReconcileSyncDefaultConfig() {
},
)
},
))
),
)
}
func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
suite.Require().NoError(suite.runtime.RegisterController(&timectrl.SyncController{
suite.Require().NoError(
suite.runtime.RegisterController(
&timectrl.SyncController{
V1Alpha1Mode: v1alpha1runtime.ModeMetal,
NewNTPSyncer: suite.newMockSyncer,
}))
},
),
)
suite.startRuntime()
@ -209,7 +245,8 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
timeServers.TypedSpec().NTPServers = []string{constants.DefaultNTPServer}
suite.Require().NoError(suite.state.Create(suite.ctx, timeServers))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -219,19 +256,23 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
},
)
},
))
),
)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
ClusterConfig: &v1alpha1.ClusterConfig{},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
var mockSyncer *mockSyncer
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
mockSyncer = suite.getMockSyncer()
@ -241,11 +282,13 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
return nil
},
))
),
)
suite.Assert().Equal([]string{constants.DefaultNTPServer}, mockSyncer.getTimeServers())
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -255,11 +298,13 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
},
)
},
))
),
)
close(mockSyncer.syncedCh)
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -269,16 +314,20 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
},
)
},
))
),
)
_, err := suite.state.UpdateWithConflicts(suite.ctx, timeServers.Metadata(), func(r resource.Resource) error {
_, err := suite.state.UpdateWithConflicts(
suite.ctx, timeServers.Metadata(), func(r resource.Resource) error {
r.(*network.TimeServerStatus).TypedSpec().NTPServers = []string{"127.0.0.1"}
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
if !reflect.DeepEqual(mockSyncer.getTimeServers(), []string{"127.0.0.1"}) {
return retry.ExpectedError(fmt.Errorf("time servers not updated yet"))
@ -286,11 +335,13 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
return nil
},
))
),
)
mockSyncer.epochCh <- struct{}{}
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -300,18 +351,22 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
},
)
},
))
),
)
_, err = suite.state.UpdateWithConflicts(suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
_, err = suite.state.UpdateWithConflicts(
suite.ctx, cfg.Metadata(), func(r resource.Resource) error {
r.(*config.MachineConfig).Config().(*v1alpha1.Config).MachineConfig.MachineTime = &v1alpha1.TimeConfig{
TimeDisabled: true,
}
return nil
})
},
)
suite.Require().NoError(err)
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -321,14 +376,19 @@ func (suite *SyncSuite) TestReconcileSyncChangeConfig() {
},
)
},
))
),
)
}
func (suite *SyncSuite) TestReconcileSyncBootTimeout() {
suite.Require().NoError(suite.runtime.RegisterController(&timectrl.SyncController{
suite.Require().NoError(
suite.runtime.RegisterController(
&timectrl.SyncController{
V1Alpha1Mode: v1alpha1runtime.ModeMetal,
NewNTPSyncer: suite.newMockSyncer,
}))
},
),
)
suite.startRuntime()
@ -336,7 +396,8 @@ func (suite *SyncSuite) TestReconcileSyncBootTimeout() {
timeServers.TypedSpec().NTPServers = []string{constants.DefaultNTPServer}
suite.Require().NoError(suite.state.Create(suite.ctx, timeServers))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -346,9 +407,11 @@ func (suite *SyncSuite) TestReconcileSyncBootTimeout() {
},
)
},
))
),
)
cfg := config.NewMachineConfig(&v1alpha1.Config{
cfg := config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{
MachineTime: &v1alpha1.TimeConfig{
@ -356,11 +419,13 @@ func (suite *SyncSuite) TestReconcileSyncBootTimeout() {
},
},
ClusterConfig: &v1alpha1.ClusterConfig{},
})
},
)
suite.Require().NoError(suite.state.Create(suite.ctx, cfg))
suite.Assert().NoError(retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
suite.Assert().NoError(
retry.Constant(10*time.Second, retry.WithUnits(100*time.Millisecond)).Retry(
func() error {
return suite.assertTimeStatus(
timeresource.StatusSpec{
@ -370,7 +435,8 @@ func (suite *SyncSuite) TestReconcileSyncBootTimeout() {
},
)
},
))
),
)
}
func (suite *SyncSuite) TearDownTest() {
@ -381,10 +447,14 @@ func (suite *SyncSuite) TearDownTest() {
suite.wg.Wait()
// trigger updates in resources to stop watch loops
err := suite.state.Create(context.Background(), config.NewMachineConfig(&v1alpha1.Config{
err := suite.state.Create(
context.Background(), config.NewMachineConfig(
&v1alpha1.Config{
ConfigVersion: "v1alpha1",
MachineConfig: &v1alpha1.MachineConfig{},
}))
},
),
)
if state.IsConflictError(err) {
err = suite.state.Destroy(context.Background(), config.NewMachineConfig(nil).Metadata())
}

View File

@ -5,7 +5,7 @@
package rpi4
import (
_ "embed" //nolint:gci
_ "embed"
"io/ioutil"
"github.com/talos-systems/go-procfs/procfs"

View File

@ -1845,7 +1845,8 @@ func StopDBus(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc
}
func pauseOnFailure(callback func(runtime.Sequence, interface{}) (runtime.TaskExecutionFunc, string),
timeout time.Duration) func(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
timeout time.Duration,
) func(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
return func(seq runtime.Sequence, data interface{}) (runtime.TaskExecutionFunc, string) {
f, name := callback(seq, data)

View File

@ -34,7 +34,7 @@ type containerdRunner struct {
stopped chan struct{}
client *containerd.Client
ctx context.Context
ctx context.Context //nolint:containedctx
container containerd.Container
stdinCloser *StdinCloser
}
@ -196,7 +196,13 @@ func (c *containerdRunner) Run(eventSink events.Recorder) error {
return nil
case <-c.stop:
// graceful stop the task
eventSink(events.StateStopping, "Sending SIGTERM to task %s (PID %d, container %s)", task.ID(), task.Pid(), c.container.ID())
eventSink(
events.StateStopping,
"Sending SIGTERM to task %s (PID %d, container %s)",
task.ID(),
task.Pid(),
c.container.ID(),
)
if err = task.Kill(c.ctx, syscall.SIGTERM, containerd.WithKillAll); err != nil {
return fmt.Errorf("error sending SIGTERM: %w", err)
@ -209,7 +215,13 @@ func (c *containerdRunner) Run(eventSink events.Recorder) error {
return nil
case <-time.After(c.opts.GracefulShutdownTimeout):
// kill the process
eventSink(events.StateStopping, "Sending SIGKILL to task %s (PID %d, container %s)", task.ID(), task.Pid(), c.container.ID())
eventSink(
events.StateStopping,
"Sending SIGKILL to task %s (PID %d, container %s)",
task.ID(),
task.Pid(),
c.container.ID(),
)
if err = task.Kill(c.ctx, syscall.SIGKILL, containerd.WithKillAll); err != nil {
return fmt.Errorf("error sending SIGKILL: %w", err)
@ -233,21 +245,27 @@ func (c *containerdRunner) Stop() error {
return nil
}
func (c *containerdRunner) newContainerOpts(image containerd.Image, specOpts []oci.SpecOpts) []containerd.NewContainerOpts {
func (c *containerdRunner) newContainerOpts(
image containerd.Image,
specOpts []oci.SpecOpts,
) []containerd.NewContainerOpts {
containerOpts := []containerd.NewContainerOpts{}
if image != nil {
containerOpts = append(containerOpts,
containerOpts = append(
containerOpts,
containerd.WithImage(image),
containerd.WithNewSnapshot(c.args.ID, image),
)
}
containerOpts = append(containerOpts,
containerOpts = append(
containerOpts,
containerd.WithNewSpec(specOpts...),
)
containerOpts = append(containerOpts,
containerOpts = append(
containerOpts,
c.opts.ContainerOpts...,
)
@ -258,12 +276,14 @@ func (c *containerdRunner) newOCISpecOpts(image oci.Image) []oci.SpecOpts {
specOpts := []oci.SpecOpts{}
if image != nil {
specOpts = append(specOpts,
specOpts = append(
specOpts,
oci.WithImageConfig(image),
)
}
specOpts = append(specOpts,
specOpts = append(
specOpts,
oci.WithProcessArgs(c.args.ProcessArgs...),
oci.WithEnv(c.opts.Env),
oci.WithHostHostsFile,
@ -272,27 +292,32 @@ func (c *containerdRunner) newOCISpecOpts(image oci.Image) []oci.SpecOpts {
)
if c.opts.OOMScoreAdj != 0 {
specOpts = append(specOpts,
specOpts = append(
specOpts,
WithOOMScoreAdj(c.opts.OOMScoreAdj),
)
}
if c.opts.CgroupPath != "" {
specOpts = append(specOpts,
specOpts = append(
specOpts,
oci.WithCgroup(c.opts.CgroupPath),
)
}
specOpts = append(specOpts,
specOpts = append(
specOpts,
c.opts.OCISpecOpts...,
)
if c.opts.OverrideSeccompProfile != nil {
specOpts = append(specOpts,
specOpts = append(
specOpts,
WithCustomSeccompProfile(c.opts.OverrideSeccompProfile),
)
} else {
specOpts = append(specOpts,
specOpts = append(
specOpts,
seccomp.WithDefaultProfile(), // add seccomp profile last, as it depends on process capabilities
)
}

View File

@ -25,7 +25,7 @@ type goroutineRunner struct {
opts *runner.Options
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
wg sync.WaitGroup

View File

@ -41,7 +41,7 @@ type ServiceRunner struct {
stateSubscribers map[StateEvent][]chan<- struct{}
ctxMu sync.Mutex
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -291,7 +291,12 @@ func (svcrunner *ServiceRunner) run(ctx context.Context, runnr runner.Runner) er
defer healthWg.Done()
//nolint:errcheck
health.Run(ctx, healthSvc.HealthSettings(svcrunner.runtime), &svcrunner.healthState, healthSvc.HealthFunc(svcrunner.runtime))
health.Run(
ctx,
healthSvc.HealthSettings(svcrunner.runtime),
&svcrunner.healthState,
healthSvc.HealthFunc(svcrunner.runtime),
)
}()
notifyCh := make(chan health.StateChange, 2)

View File

@ -51,7 +51,7 @@ const assertRebootedRebootTimeout = 10 * time.Minute
type ApplyConfigSuite struct {
base.K8sSuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -109,30 +109,38 @@ func (suite *ApplyConfigSuite) TestApply() {
cfgDataOut, err := cfg.Bytes()
suite.Assert().Nilf(err, "failed to marshal updated machine config data (node %q): %w", node, err)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
_, err = suite.Client.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
_, err = suite.Client.ApplyConfiguration(
nodeCtx, &machineapi.ApplyConfigurationRequest{
Data: cfgDataOut,
Mode: machineapi.ApplyConfigurationRequest_REBOOT,
})
},
)
if err != nil {
// It is expected that the connection will EOF here, so just log the error
suite.Assert().Nilf("failed to apply configuration (node %q): %w", node, err)
}
return nil
}, assertRebootedRebootTimeout)
}, assertRebootedRebootTimeout,
)
// Verify configuration change
var newProvider config.Provider
suite.Require().Nilf(retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(func() error {
suite.Require().Nilf(
retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(
func() error {
newProvider, err = suite.ReadConfigFromNode(nodeCtx)
if err != nil {
return retry.ExpectedError(err)
}
return nil
}), "failed to read updated configuration from node %q: %w", node, err)
},
), "failed to read updated configuration from node %q: %w", node, err,
)
suite.Assert().Equal(
newProvider.Machine().Sysctls()[applyConfigTestSysctl],
@ -168,10 +176,12 @@ func (suite *ApplyConfigSuite) TestApplyWithoutReboot() {
cfgDataOut, err := cfg.Bytes()
suite.Require().NoError(err, "failed to marshal updated machine config data (node %q)", node)
_, err = suite.Client.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{
_, err = suite.Client.ApplyConfiguration(
nodeCtx, &machineapi.ApplyConfigurationRequest{
Data: cfgDataOut,
Mode: mode,
})
},
)
suite.Require().NoError(err, "failed to apply deferred configuration (node %q): %w", node)
// Verify configuration change
@ -195,10 +205,12 @@ func (suite *ApplyConfigSuite) TestApplyWithoutReboot() {
cfgDataOut, err = cfg.Bytes()
suite.Require().NoError(err, "failed to marshal updated machine config data (node %q)", node)
_, err = suite.Client.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{
_, err = suite.Client.ApplyConfiguration(
nodeCtx, &machineapi.ApplyConfigurationRequest{
Data: cfgDataOut,
Mode: mode,
})
},
)
suite.Require().NoError(err, "failed to apply deferred configuration (node %q): %w", node)
}
}
@ -295,32 +307,40 @@ func (suite *ApplyConfigSuite) TestApplyConfigRotateEncryptionSecrets() {
data, err := machineConfig.Bytes()
suite.Require().NoError(err)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
_, err = suite.Client.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
_, err = suite.Client.ApplyConfiguration(
nodeCtx, &machineapi.ApplyConfigurationRequest{
Data: data,
Mode: machineapi.ApplyConfigurationRequest_REBOOT,
})
},
)
if err != nil {
// It is expected that the connection will EOF here, so just log the error
suite.Assert().Nilf("failed to apply configuration (node %q): %w", node, err)
}
return nil
}, assertRebootedRebootTimeout)
}, assertRebootedRebootTimeout,
)
suite.ClearConnectionRefused(suite.ctx, node)
// Verify configuration change
var newProvider config.Provider
suite.Require().Nilf(retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(func() error {
suite.Require().Nilf(
retry.Constant(time.Minute, retry.WithUnits(time.Second)).Retry(
func() error {
newProvider, err = suite.ReadConfigFromNode(nodeCtx)
if err != nil {
return retry.ExpectedError(err)
}
return nil
}), "failed to read updated configuration from node %q: %w", node, err)
},
), "failed to read updated configuration from node %q: %w", node, err,
)
e := newProvider.Machine().SystemDiskEncryption().Get(constants.EphemeralPartitionLabel)
@ -370,10 +390,12 @@ func (suite *ApplyConfigSuite) TestApplyNoReboot() {
cfgDataOut, err := cfg.Bytes()
suite.Assert().Nilf(err, "failed to marshal updated machine config data (node %q): %w", node, err)
_, err = suite.Client.ApplyConfiguration(nodeCtx, &machineapi.ApplyConfigurationRequest{
_, err = suite.Client.ApplyConfiguration(
nodeCtx, &machineapi.ApplyConfigurationRequest{
Data: cfgDataOut,
Mode: machineapi.ApplyConfigurationRequest_NO_REBOOT,
})
},
)
suite.Require().Error(err)
var (

View File

@ -28,7 +28,7 @@ import (
type DiscoverySuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}

View File

@ -23,10 +23,10 @@ import (
type DiskUsageSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
nodeCtx context.Context
nodeCtx context.Context //nolint:containedctx
}
// SuiteName ...

View File

@ -22,7 +22,7 @@ import (
type DmesgSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}

View File

@ -30,7 +30,7 @@ import (
type EtcdRecoverSuite struct {
base.K8sSuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -112,7 +112,9 @@ func (suite *EtcdRecoverSuite) TestSnapshotRecover() {
return fmt.Errorf("error reading pre-reset boot ID: %w", err)
}
if err = base.IgnoreGRPCUnavailable(suite.Client.ResetGeneric(nodeCtx, &machineapi.ResetRequest{
if err = base.IgnoreGRPCUnavailable(
suite.Client.ResetGeneric(
nodeCtx, &machineapi.ResetRequest{
Reboot: true,
Graceful: false,
SystemPartitionsToWipe: []*machineapi.ResetPartitionSpec{
@ -121,13 +123,16 @@ func (suite *EtcdRecoverSuite) TestSnapshotRecover() {
Wipe: true,
},
},
})); err != nil {
},
),
); err != nil {
return fmt.Errorf("error resetting the node %q: %w", node, err)
}
var bootIDAfter string
return retry.Constant(5 * time.Minute).Retry(func() error {
return retry.Constant(5 * time.Minute).Retry(
func() error {
requestCtx, requestCtxCancel := context.WithTimeout(nodeCtx, 5*time.Second)
defer requestCtxCancel()
@ -140,11 +145,19 @@ func (suite *EtcdRecoverSuite) TestSnapshotRecover() {
if bootIDAfter == bootIDBefore {
// bootID should be different after reboot
return retry.ExpectedError(fmt.Errorf("bootID didn't change for node %q: before %s, after %s", node, bootIDBefore, bootIDAfter))
return retry.ExpectedError(
fmt.Errorf(
"bootID didn't change for node %q: before %s, after %s",
node,
bootIDBefore,
bootIDAfter,
),
)
}
return nil
})
},
)
}()
}()
}
@ -203,7 +216,8 @@ func (suite *EtcdRecoverSuite) recoverEtcd(recoverNode string, src io.ReadSeeker
suite.T().Log("uploading the snapshot")
if err := retry.Constant(time.Minute, retry.WithUnits(time.Millisecond*200)).RetryWithContext(ctx, func(ctx context.Context) error {
if err := retry.Constant(time.Minute, retry.WithUnits(time.Millisecond*200)).RetryWithContext(
ctx, func(ctx context.Context) error {
_, err := src.Seek(0, io.SeekStart)
if err != nil {
return err
@ -216,23 +230,28 @@ func (suite *EtcdRecoverSuite) recoverEtcd(recoverNode string, src io.ReadSeeker
}
return err
}); err != nil {
},
); err != nil {
return fmt.Errorf("error uploading snapshot: %w", err)
}
suite.T().Log("bootstrapping from the snapshot")
return retry.Constant(time.Minute, retry.WithUnits(time.Millisecond*200)).RetryWithContext(ctx, func(ctx context.Context) error {
err := suite.Client.Bootstrap(ctx, &machineapi.BootstrapRequest{
return retry.Constant(time.Minute, retry.WithUnits(time.Millisecond*200)).RetryWithContext(
ctx, func(ctx context.Context) error {
err := suite.Client.Bootstrap(
ctx, &machineapi.BootstrapRequest{
RecoverEtcd: true,
})
},
)
if client.StatusCode(err) == codes.FailedPrecondition || client.StatusCode(err) == codes.DeadlineExceeded {
return retry.ExpectedError(err)
}
return err
})
},
)
}
func init() {

View File

@ -26,7 +26,7 @@ import (
type EtcdSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -67,7 +67,10 @@ func (suite *EtcdSuite) TestEtcdForfeitLeadership() {
var leader string
for _, node := range nodes {
resp, err := suite.Client.EtcdForfeitLeadership(client.WithNodes(suite.ctx, node), &machineapi.EtcdForfeitLeadershipRequest{})
resp, err := suite.Client.EtcdForfeitLeadership(
client.WithNodes(suite.ctx, node),
&machineapi.EtcdForfeitLeadershipRequest{},
)
suite.Require().NoError(err)
if resp.Messages[0].GetMember() != "" {
@ -130,16 +133,21 @@ func (suite *EtcdSuite) TestEtcdLeaveCluster() {
}
}
suite.Assert().Equal("rpc error: code = Unknown desc = lstat /var/lib/etcd: no such file or directory", info.Metadata.Error)
suite.Assert().Equal(
"rpc error: code = Unknown desc = lstat /var/lib/etcd: no such file or directory",
info.Metadata.Error,
)
}
// NB: Reboot the node so that it can rejoin the etcd cluster. This allows us
// to check the cluster health and catch any issues in rejoining.
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
_, err = suite.Client.MachineClient.Reboot(nodeCtx, &machineapi.RebootRequest{})
return err
}, 10*time.Minute)
}, 10*time.Minute,
)
}
func init() {

View File

@ -20,10 +20,10 @@ import (
type EventsSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
nodeCtx context.Context
nodeCtx context.Context //nolint:containedctx
}
// SuiteName ...
@ -54,7 +54,9 @@ func (suite *EventsSuite) TestEventsWatch() {
watchCtx, watchCtxCancel := context.WithCancel(suite.nodeCtx)
defer watchCtxCancel()
suite.Assert().NoError(suite.Client.EventsWatch(watchCtx, func(ch <-chan client.Event) {
suite.Assert().NoError(
suite.Client.EventsWatch(
watchCtx, func(ch <-chan client.Event) {
defer watchCtxCancel()
timer := time.NewTimer(500 * time.Millisecond)
@ -72,7 +74,9 @@ func (suite *EventsSuite) TestEventsWatch() {
return
}
}
}, opts...))
}, opts...,
),
)
return result
}
@ -88,7 +92,10 @@ func (suite *EventsSuite) TestEventsWatch() {
// (as check excludes that event with picked ID)
id := allEvents[len(allEvents)-15].ID
eventsSinceID := receiveEvents(client.WithTailID(id))
suite.Require().GreaterOrEqual(len(eventsSinceID), 14) // there might some new events since allEvents, but at least 15 should be received
suite.Require().GreaterOrEqual(
len(eventsSinceID),
14,
) // there might some new events since allEvents, but at least 15 should be received
}
func init() {

View File

@ -26,7 +26,7 @@ import (
type GenerateConfigSuite struct {
base.K8sSuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -104,9 +104,18 @@ func (suite *GenerateConfigSuite) TestGenerate() {
suite.Require().EqualValues(request.ClusterConfig.Name, config.Cluster().Name())
suite.Require().EqualValues(request.ClusterConfig.ControlPlane.Endpoint, config.Cluster().Endpoint().String())
suite.Require().EqualValues(request.ClusterConfig.ClusterNetwork.DnsDomain, config.Cluster().Network().DNSDomain())
suite.Require().EqualValues(request.ClusterConfig.ClusterNetwork.CniConfig.Name, config.Cluster().Network().CNI().Name())
suite.Require().EqualValues(request.ClusterConfig.ClusterNetwork.CniConfig.Urls, config.Cluster().Network().CNI().URLs())
suite.Require().EqualValues(fmt.Sprintf("%s:v%s", constants.KubeletImage, request.MachineConfig.KubernetesVersion), config.Machine().Kubelet().Image())
suite.Require().EqualValues(
request.ClusterConfig.ClusterNetwork.CniConfig.Name,
config.Cluster().Network().CNI().Name(),
)
suite.Require().EqualValues(
request.ClusterConfig.ClusterNetwork.CniConfig.Urls,
config.Cluster().Network().CNI().URLs(),
)
suite.Require().EqualValues(
fmt.Sprintf("%s:v%s", constants.KubeletImage, request.MachineConfig.KubernetesVersion),
config.Machine().Kubelet().Image(),
)
suite.Require().EqualValues(request.MachineConfig.InstallConfig.InstallDisk, disk)
suite.Require().EqualValues(request.MachineConfig.InstallConfig.InstallImage, config.Machine().Install().Image())
suite.Require().EqualValues(request.MachineConfig.NetworkConfig.Hostname, config.Machine().Network().Hostname())
@ -149,15 +158,30 @@ func (suite *GenerateConfigSuite) TestGenerate() {
suite.Require().EqualValues(request.ConfigVersion, joinedConfig.Version())
suite.Require().EqualValues(request.ClusterConfig.Name, joinedConfig.Cluster().Name())
suite.Require().EqualValues(request.ClusterConfig.ControlPlane.Endpoint, joinedConfig.Cluster().Endpoint().String())
suite.Require().EqualValues(request.ClusterConfig.ClusterNetwork.DnsDomain, joinedConfig.Cluster().Network().DNSDomain())
suite.Require().EqualValues(fmt.Sprintf("%s:v%s", constants.KubeletImage, request.MachineConfig.KubernetesVersion), joinedConfig.Machine().Kubelet().Image())
suite.Require().EqualValues(
request.ClusterConfig.ClusterNetwork.DnsDomain,
joinedConfig.Cluster().Network().DNSDomain(),
)
suite.Require().EqualValues(
fmt.Sprintf("%s:v%s", constants.KubeletImage, request.MachineConfig.KubernetesVersion),
joinedConfig.Machine().Kubelet().Image(),
)
suite.Require().EqualValues(request.MachineConfig.InstallConfig.InstallDisk, disk)
suite.Require().EqualValues(request.MachineConfig.InstallConfig.InstallImage, joinedConfig.Machine().Install().Image())
suite.Require().EqualValues(request.MachineConfig.NetworkConfig.Hostname, joinedConfig.Machine().Network().Hostname())
suite.Require().EqualValues(
request.MachineConfig.InstallConfig.InstallImage,
joinedConfig.Machine().Install().Image(),
)
suite.Require().EqualValues(
request.MachineConfig.NetworkConfig.Hostname,
joinedConfig.Machine().Network().Hostname(),
)
suite.Require().EqualValues(config.Machine().Security().CA(), joinedConfig.Machine().Security().CA())
suite.Require().EqualValues(config.Machine().Security().Token(), joinedConfig.Machine().Security().Token())
suite.Require().EqualValues(config.Cluster().AESCBCEncryptionSecret(), joinedConfig.Cluster().AESCBCEncryptionSecret())
suite.Require().EqualValues(
config.Cluster().AESCBCEncryptionSecret(),
joinedConfig.Cluster().AESCBCEncryptionSecret(),
)
suite.Require().EqualValues(config.Cluster().CA(), joinedConfig.Cluster().CA())
suite.Require().EqualValues(config.Cluster().Token(), joinedConfig.Cluster().Token())
suite.Require().EqualValues(config.Cluster().Etcd().CA(), config.Cluster().Etcd().CA())

View File

@ -25,10 +25,10 @@ import (
type LogsSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
nodeCtx context.Context
nodeCtx context.Context //nolint:containedctx
}
// SuiteName ...
@ -167,7 +167,11 @@ func (suite *LogsSuite) testStreaming(tailLines int32) {
// invoke machined enough times to generate
// some logs
for i := int32(0); i < tailLines; i++ {
_, err := suite.Client.Stats(suite.nodeCtx, constants.SystemContainerdNamespace, common.ContainerDriver_CONTAINERD)
_, err := suite.Client.Stats(
suite.nodeCtx,
constants.SystemContainerdNamespace,
common.ContainerDriver_CONTAINERD,
)
suite.Require().NoError(err)
}
}

View File

@ -24,7 +24,7 @@ import (
type RebootSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -62,9 +62,11 @@ func (suite *RebootSuite) TestRebootNodeByNode() {
for _, node := range nodes {
suite.T().Log("rebooting node", node)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
return base.IgnoreGRPCUnavailable(suite.Client.Reboot(nodeCtx))
}, 10*time.Minute)
}, 10*time.Minute,
)
}
}
@ -123,7 +125,8 @@ func (suite *RebootSuite) TestRebootAllNodes() {
nodeCtx := client.WithNodes(suite.ctx, node)
return retry.Constant(10 * time.Minute).Retry(func() error {
return retry.Constant(10 * time.Minute).Retry(
func() error {
requestCtx, requestCtxCancel := context.WithTimeout(nodeCtx, 5*time.Second)
defer requestCtxCancel()
@ -135,11 +138,19 @@ func (suite *RebootSuite) TestRebootAllNodes() {
if bootIDAfter == bootIDBefore {
// bootID should be different after reboot
return retry.ExpectedError(fmt.Errorf("bootID didn't change for node %q: before %s, after %s", node, bootIDBefore, bootIDAfter))
return retry.ExpectedError(
fmt.Errorf(
"bootID didn't change for node %q: before %s, after %s",
node,
bootIDBefore,
bootIDAfter,
),
)
}
return nil
})
},
)
}()
}(node)
}

View File

@ -23,7 +23,7 @@ import (
type ResetSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -88,10 +88,12 @@ func (suite *ResetSuite) TestResetNodeByNode() {
preReset, err := suite.HashKubeletCert(suite.ctx, node)
suite.Require().NoError(err)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
// force reboot after reset, as this is the only mode we can test
return base.IgnoreGRPCUnavailable(suite.Client.Reset(nodeCtx, true, true))
}, 10*time.Minute)
}, 10*time.Minute,
)
suite.ClearConnectionRefused(suite.ctx, node)
@ -118,10 +120,12 @@ func (suite *ResetSuite) testResetNoGraceful(nodeType machine.Type) {
preReset, err := suite.HashKubeletCert(suite.ctx, node)
suite.Require().NoError(err)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
// force reboot after reset, as this is the only mode we can test
return base.IgnoreGRPCUnavailable(suite.Client.Reset(nodeCtx, false, true))
}, 5*time.Minute)
}, 5*time.Minute,
)
suite.ClearConnectionRefused(suite.ctx, node)
@ -162,9 +166,12 @@ func (suite *ResetSuite) TestResetWithSpecEphemeral() {
preReset, err := suite.HashKubeletCert(suite.ctx, node)
suite.Require().NoError(err)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
// force reboot after reset, as this is the only mode we can test
return base.IgnoreGRPCUnavailable(suite.Client.ResetGeneric(nodeCtx, &machineapi.ResetRequest{
return base.IgnoreGRPCUnavailable(
suite.Client.ResetGeneric(
nodeCtx, &machineapi.ResetRequest{
Reboot: true,
Graceful: true,
SystemPartitionsToWipe: []*machineapi.ResetPartitionSpec{
@ -173,8 +180,11 @@ func (suite *ResetSuite) TestResetWithSpecEphemeral() {
Wipe: true,
},
},
}))
}, 5*time.Minute)
},
),
)
}, 5*time.Minute,
)
suite.ClearConnectionRefused(suite.ctx, node)
@ -205,9 +215,12 @@ func (suite *ResetSuite) TestResetWithSpecState() {
preReset, err := suite.HashKubeletCert(suite.ctx, node)
suite.Require().NoError(err)
suite.AssertRebooted(suite.ctx, node, func(nodeCtx context.Context) error {
suite.AssertRebooted(
suite.ctx, node, func(nodeCtx context.Context) error {
// force reboot after reset, as this is the only mode we can test
return base.IgnoreGRPCUnavailable(suite.Client.ResetGeneric(nodeCtx, &machineapi.ResetRequest{
return base.IgnoreGRPCUnavailable(
suite.Client.ResetGeneric(
nodeCtx, &machineapi.ResetRequest{
Reboot: true,
Graceful: true,
SystemPartitionsToWipe: []*machineapi.ResetPartitionSpec{
@ -216,8 +229,11 @@ func (suite *ResetSuite) TestResetWithSpecState() {
Wipe: true,
},
},
}))
}, 5*time.Minute)
},
),
)
}, 5*time.Minute,
)
suite.ClearConnectionRefused(suite.ctx, node)

View File

@ -22,7 +22,7 @@ import (
type VersionSuite struct {
base.APISuite
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}

View File

@ -88,7 +88,12 @@ func upgradePreviousToStable() upgradeSpec {
ShortName: fmt.Sprintf("%s-%s", previousRelease, stableRelease),
SourceKernelPath: helpers.ArtifactPath(filepath.Join(trimVersion(previousRelease), constants.KernelAsset)),
SourceInitramfsPath: helpers.ArtifactPath(filepath.Join(trimVersion(previousRelease), constants.InitramfsAsset)),
SourceInitramfsPath: helpers.ArtifactPath(
filepath.Join(
trimVersion(previousRelease),
constants.InitramfsAsset,
),
),
SourceInstallerImage: fmt.Sprintf("%s:%s", "ghcr.io/siderolabs/installer", previousRelease),
SourceVersion: previousRelease,
SourceK8sVersion: previousK8sVersion,
@ -116,7 +121,12 @@ func upgradeStableToCurrent() upgradeSpec {
SourceVersion: stableRelease,
SourceK8sVersion: stableK8sVersion,
TargetInstallerImage: fmt.Sprintf("%s/%s:%s", DefaultSettings.TargetInstallImageRegistry, images.DefaultInstallerImageName, DefaultSettings.CurrentVersion),
TargetInstallerImage: fmt.Sprintf(
"%s/%s:%s",
DefaultSettings.TargetInstallImageRegistry,
images.DefaultInstallerImageName,
DefaultSettings.CurrentVersion,
),
TargetVersion: DefaultSettings.CurrentVersion,
TargetK8sVersion: currentK8sVersion,
@ -127,7 +137,12 @@ func upgradeStableToCurrent() upgradeSpec {
// upgradeCurrentToCurrent upgrades the current version to itself.
func upgradeCurrentToCurrent() upgradeSpec {
installerImage := fmt.Sprintf("%s/%s:%s", DefaultSettings.TargetInstallImageRegistry, images.DefaultInstallerImageName, DefaultSettings.CurrentVersion)
installerImage := fmt.Sprintf(
"%s/%s:%s",
DefaultSettings.TargetInstallImageRegistry,
images.DefaultInstallerImageName,
DefaultSettings.CurrentVersion,
)
return upgradeSpec{
ShortName: fmt.Sprintf("%s-%s", DefaultSettings.CurrentVersion, DefaultSettings.CurrentVersion),
@ -160,7 +175,12 @@ func upgradeStableToCurrentPreserve() upgradeSpec {
SourceVersion: stableRelease,
SourceK8sVersion: stableK8sVersion,
TargetInstallerImage: fmt.Sprintf("%s/%s:%s", DefaultSettings.TargetInstallImageRegistry, images.DefaultInstallerImageName, DefaultSettings.CurrentVersion),
TargetInstallerImage: fmt.Sprintf(
"%s/%s:%s",
DefaultSettings.TargetInstallImageRegistry,
images.DefaultInstallerImageName,
DefaultSettings.CurrentVersion,
),
TargetVersion: DefaultSettings.CurrentVersion,
TargetK8sVersion: currentK8sVersion,
@ -181,7 +201,12 @@ func upgradeStableToCurrentPreserveStage() upgradeSpec {
SourceVersion: stableRelease,
SourceK8sVersion: stableK8sVersion,
TargetInstallerImage: fmt.Sprintf("%s/%s:%s", DefaultSettings.TargetInstallImageRegistry, images.DefaultInstallerImageName, DefaultSettings.CurrentVersion),
TargetInstallerImage: fmt.Sprintf(
"%s/%s:%s",
DefaultSettings.TargetInstallImageRegistry,
images.DefaultInstallerImageName,
DefaultSettings.CurrentVersion,
),
TargetVersion: DefaultSettings.CurrentVersion,
TargetK8sVersion: currentK8sVersion,
@ -209,6 +234,7 @@ type UpgradeSuite struct {
clusterAccess *access.Adapter
controlPlaneEndpoint string
//nolint:containedctx
ctx context.Context
ctxCancel context.CancelFunc
@ -333,14 +359,20 @@ func (suite *UpgradeSuite) setupCluster() {
}
if DefaultSettings.CustomCNIURL != "" {
genOptions = append(genOptions, generate.WithClusterCNIConfig(&v1alpha1.CNIConfig{
genOptions = append(
genOptions, generate.WithClusterCNIConfig(
&v1alpha1.CNIConfig{
CNIName: constants.CustomCNI,
CNIUrls: []string{DefaultSettings.CustomCNIURL},
}))
},
),
)
}
if suite.spec.WithEncryption {
genOptions = append(genOptions, generate.WithSystemDiskEncryption(&v1alpha1.SystemDiskEncryptionConfig{
genOptions = append(
genOptions, generate.WithSystemDiskEncryption(
&v1alpha1.SystemDiskEncryptionConfig{
StatePartition: &v1alpha1.EncryptionConfig{
EncryptionProvider: encryption.LUKS2,
EncryptionKeys: []*v1alpha1.EncryptionKey{
@ -359,13 +391,16 @@ func (suite *UpgradeSuite) setupCluster() {
},
},
},
}))
},
),
)
}
versionContract, err := config.ParseContractFromVersion(suite.spec.SourceVersion)
suite.Require().NoError(err)
suite.configBundle, err = bundle.NewConfigBundle(bundle.WithInputOptions(
suite.configBundle, err = bundle.NewConfigBundle(
bundle.WithInputOptions(
&bundle.InputOptions{
ClusterName: clusterName,
Endpoint: suite.controlPlaneEndpoint,
@ -377,11 +412,14 @@ func (suite *UpgradeSuite) setupCluster() {
generate.WithDNSDomain("cluster.local"),
generate.WithVersionContract(versionContract),
),
}))
},
),
)
suite.Require().NoError(err)
for i := 0; i < suite.spec.MasterNodes; i++ {
request.Nodes = append(request.Nodes,
request.Nodes = append(
request.Nodes,
provision.NodeRequest{
Name: fmt.Sprintf("master-%d", i+1),
Type: machine.TypeControlPlane,
@ -394,11 +432,13 @@ func (suite *UpgradeSuite) setupCluster() {
},
},
Config: suite.configBundle.ControlPlane(),
})
},
)
}
for i := 1; i <= suite.spec.WorkerNodes; i++ {
request.Nodes = append(request.Nodes,
request.Nodes = append(
request.Nodes,
provision.NodeRequest{
Name: fmt.Sprintf("worker-%d", i),
Type: machine.TypeWorker,
@ -411,10 +451,12 @@ func (suite *UpgradeSuite) setupCluster() {
},
},
Config: suite.configBundle.Worker(),
})
},
)
}
suite.Cluster, err = suite.provisioner.Create(suite.ctx, request,
suite.Cluster, err = suite.provisioner.Create(
suite.ctx, request,
provision.WithBootlader(true),
provision.WithUEFI(true),
provision.WithTalosConfig(suite.configBundle.TalosConfig()),
@ -457,7 +499,14 @@ func (suite *UpgradeSuite) waitForClusterHealth() {
checkCtx, checkCtxCancel := context.WithTimeout(suite.ctx, 15*time.Minute)
defer checkCtxCancel()
suite.Require().NoError(check.Wait(checkCtx, suite.clusterAccess, check.DefaultClusterChecks(), check.StderrReporter()))
suite.Require().NoError(
check.Wait(
checkCtx,
suite.clusterAccess,
check.DefaultClusterChecks(),
check.StderrReporter(),
),
)
}
}
@ -487,12 +536,14 @@ func (suite *UpgradeSuite) assertSameVersionCluster(client *talosclient.Client,
err := retry.Constant(
time.Minute,
).Retry(func() error {
).Retry(
func() error {
var e error
v, e = client.Version(ctx)
return retry.ExpectedError(e)
})
},
)
suite.Require().NoError(err)
@ -503,7 +554,10 @@ func (suite *UpgradeSuite) assertSameVersionCluster(client *talosclient.Client,
}
}
func (suite *UpgradeSuite) readVersion(nodeCtx context.Context, client *talosclient.Client) (version string, err error) {
func (suite *UpgradeSuite) readVersion(nodeCtx context.Context, client *talosclient.Client) (
version string,
err error,
) {
var v *machineapi.VersionResponse
v, err = client.Version(nodeCtx)
@ -526,8 +580,15 @@ func (suite *UpgradeSuite) upgradeNode(client *talosclient.Client, node provisio
err error
)
err = retry.Constant(time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error {
resp, err = client.Upgrade(nodeCtx, suite.spec.TargetInstallerImage, suite.spec.UpgradePreserve, suite.spec.UpgradeStage, false)
err = retry.Constant(time.Minute, retry.WithUnits(10*time.Second)).Retry(
func() error {
resp, err = client.Upgrade(
nodeCtx,
suite.spec.TargetInstallerImage,
suite.spec.UpgradePreserve,
suite.spec.UpgradeStage,
false,
)
if err != nil {
if strings.Contains(err.Error(), "leader changed") {
return retry.ExpectedError(err)
@ -541,7 +602,8 @@ func (suite *UpgradeSuite) upgradeNode(client *talosclient.Client, node provisio
}
return nil
})
},
)
err = base.IgnoreGRPCUnavailable(err)
suite.Require().NoError(err)
@ -554,7 +616,9 @@ func (suite *UpgradeSuite) upgradeNode(client *talosclient.Client, node provisio
time.Sleep(10 * time.Second)
// wait for the version to be equal to target version
suite.Require().NoError(retry.Constant(10 * time.Minute).Retry(func() error {
suite.Require().NoError(
retry.Constant(10 * time.Minute).Retry(
func() error {
var version string
version, err = suite.readVersion(nodeCtx, client)
@ -565,11 +629,20 @@ func (suite *UpgradeSuite) upgradeNode(client *talosclient.Client, node provisio
if version != suite.spec.TargetVersion {
// upgrade not finished yet
return retry.ExpectedError(fmt.Errorf("node %q version doesn't match expected: expected %q, got %q", node.IPs[0].String(), suite.spec.TargetVersion, version))
return retry.ExpectedError(
fmt.Errorf(
"node %q version doesn't match expected: expected %q, got %q",
node.IPs[0].String(),
suite.spec.TargetVersion,
version,
),
)
}
return nil
}))
},
),
)
suite.waitForClusterHealth()
}
@ -622,7 +695,13 @@ func (suite *UpgradeSuite) untaint(name string) {
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, corev1.Node{})
suite.Require().NoError(err)
_, err = client.CoreV1().Nodes().Patch(suite.ctx, n.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{})
_, err = client.CoreV1().Nodes().Patch(
suite.ctx,
n.Name,
types.StrategicMergePatchType,
patchBytes,
metav1.PatchOptions{},
)
suite.Require().NoError(err)
}
@ -670,7 +749,8 @@ func (suite *UpgradeSuite) SuiteName() string {
}
func init() {
allSuites = append(allSuites,
allSuites = append(
allSuites,
&UpgradeSuite{specGen: upgradePreviousToStable, track: 0},
&UpgradeSuite{specGen: upgradeStableToCurrent, track: 1},
&UpgradeSuite{specGen: upgradeCurrentToCurrent, track: 2},

View File

@ -29,6 +29,7 @@ import (
type inspector struct {
client *containerd.Client
//nolint:containedctx
nsctx context.Context
}
@ -97,7 +98,11 @@ func (i *inspector) Images() (map[string]string, error) {
}
//nolint:gocyclo,cyclop
func (i *inspector) containerInfo(cntr containerd.Container, imageList map[string]string, singleLookup bool) (*ctrs.Container, error) {
func (i *inspector) containerInfo(
cntr containerd.Container,
imageList map[string]string,
singleLookup bool,
) (*ctrs.Container, error) {
cp := &ctrs.Container{}
info, err := cntr.Info(i.nsctx)
@ -222,7 +227,11 @@ func (i *inspector) containerInfo(cntr containerd.Container, imageList map[strin
cp.IsPodSandbox = true
} else if singleLookup && cns != "" && cname != "" {
// try to find matching infrastructure container and pull sandbox from it
query := fmt.Sprintf("labels.\"io.kubernetes.pod.namespace\"==%q,labels.\"io.kubernetes.pod.name\"==%q", cns, cname)
query := fmt.Sprintf(
"labels.\"io.kubernetes.pod.namespace\"==%q,labels.\"io.kubernetes.pod.name\"==%q",
cns,
cname,
)
infraContainers, err := i.client.Containers(i.nsctx, query)
if err == nil {
@ -274,7 +283,11 @@ func (i *inspector) Container(id string) (*ctrs.Container, error) {
pod = pod[:semicolonIdx]
}
query = fmt.Sprintf("labels.\"io.kubernetes.pod.namespace\"==%q,labels.\"io.kubernetes.pod.name\"==%q", namespace, pod)
query = fmt.Sprintf(
"labels.\"io.kubernetes.pod.namespace\"==%q,labels.\"io.kubernetes.pod.name\"==%q",
namespace,
pod,
)
if name != "" {
query += fmt.Sprintf(",labels.\"io.kubernetes.container.name\"==%q", name)

View File

@ -21,7 +21,7 @@ import (
type inspector struct {
client *criclient.Client
ctx context.Context
ctx context.Context //nolint:containedctx
}
type inspectorOptions struct {
@ -112,7 +112,8 @@ func (i *inspector) Container(id string) (*ctrs.Container, error) {
}
if name == "" { // request for a pod sandbox
sandboxes, err := i.client.ListPodSandbox(i.ctx, &runtimeapi.PodSandboxFilter{
sandboxes, err := i.client.ListPodSandbox(
i.ctx, &runtimeapi.PodSandboxFilter{
State: &runtimeapi.PodSandboxStateValue{
State: runtimeapi.PodSandboxState_SANDBOX_READY,
},
@ -120,7 +121,8 @@ func (i *inspector) Container(id string) (*ctrs.Container, error) {
"io.kubernetes.pod.name": pod,
"io.kubernetes.pod.namespace": namespace,
},
})
},
)
if err != nil {
return nil, err
}
@ -138,13 +140,15 @@ func (i *inspector) Container(id string) (*ctrs.Container, error) {
}
// request for a container
containers, err := i.client.ListContainers(i.ctx, &runtimeapi.ContainerFilter{
containers, err := i.client.ListContainers(
i.ctx, &runtimeapi.ContainerFilter{
LabelSelector: map[string]string{
"io.kubernetes.pod.name": pod,
"io.kubernetes.pod.namespace": namespace,
"io.kubernetes.container.name": name,
},
})
},
)
if err != nil {
return nil, err
}
@ -242,11 +246,13 @@ func (i *inspector) buildContainer(container *runtimeapi.Container) (*ctrs.Conta
//
//nolint:gocyclo
func (i *inspector) Pods() ([]*ctrs.Pod, error) {
sandboxes, err := i.client.ListPodSandbox(i.ctx, &runtimeapi.PodSandboxFilter{
sandboxes, err := i.client.ListPodSandbox(
i.ctx, &runtimeapi.PodSandboxFilter{
State: &runtimeapi.PodSandboxStateValue{
State: runtimeapi.PodSandboxState_SANDBOX_READY,
},
})
},
)
if err != nil {
return nil, err
}

View File

@ -50,7 +50,7 @@ type CRISuite struct {
containerdAddress string
client *criclient.Client
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
inspector ctrs.Inspector
@ -175,12 +175,15 @@ func (suite *CRISuite) SetupTest() {
suite.pods = append(suite.pods, podSandboxID)
suite.Require().Len(podSandboxID, 64)
imageRef, err := suite.client.PullImage(suite.ctx, &runtimeapi.ImageSpec{
imageRef, err := suite.client.PullImage(
suite.ctx, &runtimeapi.ImageSpec{
Image: busyboxImage,
}, podSandboxConfig)
}, podSandboxConfig,
)
suite.Require().NoError(err)
ctrID, err := suite.client.CreateContainer(suite.ctx, podSandboxID,
ctrID, err := suite.client.CreateContainer(
suite.ctx, podSandboxID,
&runtimeapi.ContainerConfig{
Metadata: &runtimeapi.ContainerMetadata{
Name: "etcd",
@ -197,7 +200,8 @@ func (suite *CRISuite) SetupTest() {
Image: imageRef,
},
Command: []string{"/bin/sh", "-c", "sleep 3600"},
}, podSandboxConfig)
}, podSandboxConfig,
)
suite.Require().NoError(err)
suite.Require().Len(ctrID, 64)

View File

@ -47,7 +47,7 @@ type CRISuite struct {
containerdAddress string
client *cri.Client
ctx context.Context
ctx context.Context //nolint:containedctx
ctxCancel context.CancelFunc
}
@ -165,17 +165,22 @@ func (suite *CRISuite) TestRunSandboxContainer() {
suite.Require().NoError(err)
suite.Require().Len(podSandboxID, 64)
imageRef, err := suite.client.PullImage(suite.ctx, &runtimeapi.ImageSpec{
imageRef, err := suite.client.PullImage(
suite.ctx, &runtimeapi.ImageSpec{
Image: busyboxImage,
}, podSandboxConfig)
}, podSandboxConfig,
)
suite.Require().NoError(err)
_, err = suite.client.ImageStatus(suite.ctx, &runtimeapi.ImageSpec{
_, err = suite.client.ImageStatus(
suite.ctx, &runtimeapi.ImageSpec{
Image: imageRef,
})
},
)
suite.Require().NoError(err)
ctrID, err := suite.client.CreateContainer(suite.ctx, podSandboxID,
ctrID, err := suite.client.CreateContainer(
suite.ctx, podSandboxID,
&runtimeapi.ContainerConfig{
Metadata: &runtimeapi.ContainerMetadata{
Name: "etcd",
@ -192,7 +197,8 @@ func (suite *CRISuite) TestRunSandboxContainer() {
Image: imageRef,
},
Command: []string{"/bin/sh", "-c", "sleep 3600"},
}, podSandboxConfig)
}, podSandboxConfig,
)
suite.Require().NoError(err)
suite.Require().Len(ctrID, 64)

View File

@ -25,12 +25,15 @@ type Connection struct {
bootstrapEndpoint string
nodeClient *client.Client
bootstrapClient *client.Client
nodeCtx context.Context
bootstrapCtx context.Context
nodeCtx context.Context //nolint:containedctx
bootstrapCtx context.Context //nolint:containedctx
}
// NewConnection creates new installer connection.
func NewConnection(ctx context.Context, nodeClient *client.Client, endpoint string, options ...Option) (*Connection, error) {
func NewConnection(ctx context.Context, nodeClient *client.Client, endpoint string, options ...Option) (
*Connection,
error,
) {
c := &Connection{
nodeEndpoint: endpoint,
nodeClient: nodeClient,
@ -48,7 +51,10 @@ func NewConnection(ctx context.Context, nodeClient *client.Client, endpoint stri
}
// GenerateConfiguration calls GenerateConfiguration on the target/bootstrap node.
func (c *Connection) GenerateConfiguration(req *machine.GenerateConfigurationRequest, callOptions ...grpc.CallOption) (*machine.GenerateConfigurationResponse, error) {
func (c *Connection) GenerateConfiguration(
req *machine.GenerateConfigurationRequest,
callOptions ...grpc.CallOption,
) (*machine.GenerateConfigurationResponse, error) {
if c.bootstrapClient != nil {
return c.bootstrapClient.GenerateConfiguration(c.bootstrapCtx, req, callOptions...)
}
@ -57,7 +63,10 @@ func (c *Connection) GenerateConfiguration(req *machine.GenerateConfigurationReq
}
// ApplyConfiguration calls ApplyConfiguration on the target node using appropriate node context.
func (c *Connection) ApplyConfiguration(req *machine.ApplyConfigurationRequest, callOptions ...grpc.CallOption) (*machine.ApplyConfigurationResponse, error) {
func (c *Connection) ApplyConfiguration(
req *machine.ApplyConfigurationRequest,
callOptions ...grpc.CallOption,
) (*machine.ApplyConfigurationResponse, error) {
return c.nodeClient.ApplyConfiguration(c.nodeCtx, req, callOptions...)
}

View File

@ -41,7 +41,7 @@ type Installer struct {
app *tview.Application
wg sync.WaitGroup
err error
ctx context.Context
ctx context.Context //nolint:containedctx
cancel context.CancelFunc
addedPages map[string]bool
state *State
@ -204,7 +204,8 @@ func (installer *Installer) configure() error {
}
capture := installer.app.GetInputCapture()
installer.app.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
installer.app.SetInputCapture(
func(e *tcell.EventKey) *tcell.EventKey {
//nolint:exhaustive
switch e.Key() {
case tcell.KeyCtrlN:
@ -227,7 +228,8 @@ func (installer *Installer) configure() error {
}
return e
})
},
)
defer installer.app.SetInputCapture(capture)
@ -240,9 +242,11 @@ func (installer *Installer) configure() error {
button.SetInactiveColors(inactiveColor, tcell.ColorIvory)
func(page int) {
button.SetSelectedFunc(func() {
button.SetSelectedFunc(
func() {
setPage(page)
})
},
)
}(index)
menu.AddItem(button, len(name)+4, 1, false)
@ -267,9 +271,11 @@ func (installer *Installer) configure() error {
if index > 0 {
back := form.AddMenuButton("[::u]B[::-]ack", false)
back.SetSelectedFunc(func() {
back.SetSelectedFunc(
func() {
setPage(index - 1)
})
},
)
}
addMenuItem(p.name, index)
@ -278,15 +284,19 @@ func (installer *Installer) configure() error {
if index < len(state.pages)-1 {
next := form.AddMenuButton("[::u]N[::-]ext", index == 0)
next.SetSelectedFunc(func() {
next.SetSelectedFunc(
func() {
setPage(index + 1)
})
},
)
} else {
install := form.AddMenuButton("Install", false)
install.SetBackgroundColor(tcell.ColorGreen)
install.SetSelectedFunc(func() {
install.SetSelectedFunc(
func() {
close(done)
})
},
)
}
installer.addPage(p.name, form, index == 0, menu)
@ -362,9 +372,11 @@ func (installer *Installer) apply(conn *Connection) error {
// TODO: progress bar, logs?
list.AddItem(s, 1, 1, false)
_, err = conn.ApplyConfiguration(&machineapi.ApplyConfigurationRequest{
_, err = conn.ApplyConfiguration(
&machineapi.ApplyConfigurationRequest{
Data: config,
})
},
)
s.Stop(err == nil)
@ -453,7 +465,8 @@ func (installer *Installer) writeTalosconfig(list *tview.Flex, talosconfig *clie
func (installer *Installer) awaitKey(keys ...tcell.Key) {
done := make(chan struct{})
installer.app.SetInputCapture(func(e *tcell.EventKey) *tcell.EventKey {
installer.app.SetInputCapture(
func(e *tcell.EventKey) *tcell.EventKey {
for _, key := range keys {
if e.Key() == key {
close(done)
@ -465,7 +478,8 @@ func (installer *Installer) awaitKey(keys ...tcell.Key) {
}
return e
})
},
)
select {
case <-done:
@ -482,10 +496,12 @@ func (installer *Installer) showModal(title, text string, buttons ...string) int
modal := tview.NewModal().
SetText(text).
AddButtons(buttons).
SetDoneFunc(func(buttonIndex int, buttonLabel string) {
SetDoneFunc(
func(buttonIndex int, buttonLabel string) {
index = buttonIndex
close(done)
})
},
)
installer.addPage(title, modal, true, nil)
installer.app.SetFocus(modal)
@ -524,8 +540,10 @@ func (installer *Installer) addPage(name string, primitive tview.Primitive, swit
if switchToPage {
installer.pages.AddAndSwitchToPage(name, frame, true)
} else {
installer.pages.AddPage(name,
frame, true, false)
installer.pages.AddPage(
name,
frame, true, false,
)
}
} else if switchToPage {
installer.pages.SwitchToPage(name)

View File

@ -32,7 +32,7 @@ type Stream struct {
source Source
options *Options
ctx context.Context
ctx context.Context //nolint:containedctx
}
// Source is an interface describing the source of a Stream.

View File

@ -184,9 +184,11 @@ func upgradeKubeletOnNode(ctx context.Context, cluster UpgradeProvider, options
options.Log(" > %q: waiting for node update", node)
if err = retry.Constant(3*time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error {
if err = retry.Constant(3*time.Minute, retry.WithUnits(10*time.Second)).Retry(
func() error {
return checkNodeKubeletVersion(ctx, cluster, node, "v"+options.ToVersion)
}); err != nil {
},
); err != nil {
return err
}
@ -195,7 +197,10 @@ func upgradeKubeletOnNode(ctx context.Context, cluster UpgradeProvider, options
return nil
}
func upgradeKubeletPatcher(options UpgradeOptions, kubeletSpec resource.Resource) func(config *v1alpha1config.Config) error {
func upgradeKubeletPatcher(
options UpgradeOptions,
kubeletSpec resource.Resource,
) func(config *v1alpha1config.Config) error {
return func(config *v1alpha1config.Config) error {
if config.MachineConfig == nil {
config.MachineConfig = &v1alpha1config.MachineConfig{}
@ -206,15 +211,15 @@ func upgradeKubeletPatcher(options UpgradeOptions, kubeletSpec resource.Resource
}
var (
any *resource.Any
anyResource *resource.Any
ok bool
)
if any, ok = kubeletSpec.(*resource.Any); !ok {
if anyResource, ok = kubeletSpec.(*resource.Any); !ok {
return fmt.Errorf("unexpected resource type")
}
oldImage := any.Value().(map[string]interface{})["image"].(string) //nolint:errcheck,forcetypeassert
oldImage := anyResource.Value().(map[string]interface{})["image"].(string) //nolint:errcheck,forcetypeassert
logUpdate := func(oldImage string) {
parts := strings.Split(oldImage, ":")
@ -287,7 +292,13 @@ func checkNodeKubeletVersion(ctx context.Context, cluster UpgradeProvider, nodeT
nodeFound = true
if node.Status.NodeInfo.KubeletVersion != version {
return retry.ExpectedError(fmt.Errorf("node version mismatch: got %q, expected %q", node.Status.NodeInfo.KubeletVersion, version))
return retry.ExpectedError(
fmt.Errorf(
"node version mismatch: got %q, expected %q",
node.Status.NodeInfo.KubeletVersion,
version,
),
)
}
ready := false

View File

@ -22,6 +22,7 @@ import (
type Reader struct {
source *os.File
//nolint:containedctx
ctx context.Context
ctxCancel context.CancelFunc

View File

@ -23,7 +23,7 @@ import (
"google.golang.org/grpc/reflection"
"google.golang.org/grpc/status"
_ "github.com/talos-systems/talos/pkg/grpc/codec" //nolint:gci // register codec
_ "github.com/talos-systems/talos/pkg/grpc/codec" // register codec
grpclog "github.com/talos-systems/talos/pkg/grpc/middleware/log"
)
@ -150,19 +150,32 @@ func NewDefaultOptions(setters ...Option) *Options {
// Recovery is installed as the the first middleware in the chain to handle panics (via defer and recover()) in all subsequent middlewares.
recoveryOpt := grpc_recovery.WithRecoveryHandler(recoveryHandler(logger))
opts.UnaryInterceptors = append([]grpc.UnaryServerInterceptor{grpc_recovery.UnaryServerInterceptor(recoveryOpt)}, opts.UnaryInterceptors...)
opts.StreamInterceptors = append([]grpc.StreamServerInterceptor{grpc_recovery.StreamServerInterceptor(recoveryOpt)}, opts.StreamInterceptors...)
opts.UnaryInterceptors = append(
[]grpc.UnaryServerInterceptor{grpc_recovery.UnaryServerInterceptor(recoveryOpt)},
opts.UnaryInterceptors...,
)
opts.StreamInterceptors = append(
[]grpc.StreamServerInterceptor{grpc_recovery.StreamServerInterceptor(recoveryOpt)},
opts.StreamInterceptors...,
)
if logger != nil {
// Logging is installed as the first middleware (even before recovery middleware) in the chain
// so that request in the form it was received and status sent on the wire is logged (error/success).
// It also tracks the whole duration of the request, including other middleware overhead.
logMiddleware := grpclog.NewMiddleware(logger)
opts.UnaryInterceptors = append([]grpc.UnaryServerInterceptor{logMiddleware.UnaryInterceptor()}, opts.UnaryInterceptors...)
opts.StreamInterceptors = append([]grpc.StreamServerInterceptor{logMiddleware.StreamInterceptor()}, opts.StreamInterceptors...)
opts.UnaryInterceptors = append(
[]grpc.UnaryServerInterceptor{logMiddleware.UnaryInterceptor()},
opts.UnaryInterceptors...,
)
opts.StreamInterceptors = append(
[]grpc.StreamServerInterceptor{logMiddleware.StreamInterceptor()},
opts.StreamInterceptors...,
)
}
opts.ServerOptions = append(opts.ServerOptions,
opts.ServerOptions = append(
opts.ServerOptions,
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(opts.UnaryInterceptors...)),
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(opts.StreamInterceptors...)),
)

Some files were not shown because too many files have changed in this diff Show More