diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6cd0c77..5345665 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-05-13T15:08:28Z by kres ce88e1c. +# Generated on 2024-05-27T16:57:15Z by kres bcb280a. name: default concurrency: @@ -29,16 +29,32 @@ jobs: - self-hosted - generic if: (!startsWith(github.head_ref, 'renovate/') && !startsWith(github.head_ref, 'dependabot/')) - services: - buildkitd: - image: moby/buildkit:v0.13.2 - options: --privileged - ports: - - 1234:1234 - volumes: - - /var/lib/buildkit/${{ github.repository }}:/var/lib/buildkit - - /usr/etc/buildkit/buildkitd.toml:/etc/buildkit/buildkitd.toml steps: + - name: gather-system-info + id: system-info + uses: kenchan0130/actions-system-info@v1.3.0 + continue-on-error: true + - name: print-system-info + run: | + MEMORY_GB=$((${{ steps.system-info.outputs.totalmem }}/1024/1024/1024)) + + OUTPUTS=( + "CPU Core: ${{ steps.system-info.outputs.cpu-core }}" + "CPU Model: ${{ steps.system-info.outputs.cpu-model }}" + "Hostname: ${{ steps.system-info.outputs.hostname }}" + "NodeName: ${NODE_NAME}" + "Kernel release: ${{ steps.system-info.outputs.kernel-release }}" + "Kernel version: ${{ steps.system-info.outputs.kernel-version }}" + "Name: ${{ steps.system-info.outputs.name }}" + "Platform: ${{ steps.system-info.outputs.platform }}" + "Release: ${{ steps.system-info.outputs.release }}" + "Total memory: ${MEMORY_GB} GB" + ) + + for OUTPUT in "${OUTPUTS[@]}";do + echo "${OUTPUT}" + done + continue-on-error: true - name: checkout uses: actions/checkout@v4 - name: Unshallow @@ -49,7 +65,7 @@ jobs: uses: docker/setup-buildx-action@v3 with: driver: remote - endpoint: tcp://127.0.0.1:1234 + endpoint: tcp://buildkit-amd64.ci.svc.cluster.local:1234 timeout-minutes: 10 - name: base run: | diff --git a/.golangci.yml b/.golangci.yml index e9f943d..227ad44 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-05-13T15:08:28Z by kres ce88e1c. +# Generated on 2024-05-27T16:57:15Z by kres bcb280a. # options for analysis running run: @@ -35,7 +35,7 @@ linters-settings: sections: - standard # Standard section: captures all standard packages. - default # Default section: contains all imports that could not be matched to another section type. - - prefix(github.com/siderolabs/siderolink/) # Custom section: groups all imports with the specified Prefix. + - localmodule # Imports from the same module. gocognit: min-complexity: 30 nestif: @@ -51,8 +51,6 @@ linters-settings: scope: declarations gofmt: simplify: true - goimports: - local-prefixes: github.com/siderolabs/siderolink/ gomodguard: { } govet: enable-all: true @@ -145,6 +143,7 @@ linters: - varcheck # disabled as it seems to be broken - goes into imported libraries and reports issues there - musttag + - goimports # same as gci issues: exclude: [ ] diff --git a/Dockerfile b/Dockerfile index e447337..a5b4fbd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,14 +2,14 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-05-13T15:08:28Z by kres ce88e1c. +# Generated on 2024-05-27T16:57:15Z by kres bcb280a. ARG TOOLCHAIN # runs markdownlint -FROM docker.io/node:21.7.3-alpine3.19 AS lint-markdown +FROM docker.io/node:22.2.0-alpine3.19 AS lint-markdown WORKDIR /src -RUN npm i -g markdownlint-cli@0.39.0 +RUN npm i -g markdownlint-cli@0.41.0 RUN npm i sentences-per-line@0.2.1 COPY .markdownlint.json . COPY ./README.md ./README.md @@ -22,7 +22,7 @@ ADD api/siderolink/provision.proto /api/siderolink/ ADD api/siderolink/wireguard.proto /api/siderolink/ # base toolchain image -FROM ${TOOLCHAIN} AS toolchain +FROM --platform=${BUILDPLATFORM} ${TOOLCHAIN} AS toolchain RUN apk --update --no-cache add bash curl build-base protoc protobuf-dev # build tools @@ -44,6 +44,9 @@ RUN mv /go/bin/protoc-gen-go-grpc /bin ARG GRPC_GATEWAY_VERSION RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@v${GRPC_GATEWAY_VERSION} RUN mv /go/bin/protoc-gen-grpc-gateway /bin +ARG GOIMPORTS_VERSION +RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/tools/cmd/goimports@v${GOIMPORTS_VERSION} +RUN mv /go/bin/goimports /bin ARG VTPROTOBUF_VERSION RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v${VTPROTOBUF_VERSION} RUN mv /go/bin/protoc-gen-go-vtproto /bin @@ -55,9 +58,6 @@ RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/g && mv /go/bin/golangci-lint /bin/golangci-lint RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/vuln/cmd/govulncheck@latest \ && mv /go/bin/govulncheck /bin/govulncheck -ARG GOIMPORTS_VERSION -RUN --mount=type=cache,target=/root/.cache/go-build --mount=type=cache,target=/go/pkg go install golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION} \ - && mv /go/bin/goimports /bin/goimports ARG GOFUMPT_VERSION RUN go install mvdan.cc/gofumpt@${GOFUMPT_VERSION} \ && mv /go/bin/gofumpt /bin/gofumpt @@ -90,10 +90,6 @@ RUN gofumpt -w /api FROM base AS lint-gofumpt RUN FILES="$(gofumpt -l .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'gofumpt -w .':\n${FILES}"; exit 1) -# runs goimports -FROM base AS lint-goimports -RUN FILES="$(goimports -l -local github.com/siderolabs/siderolink/ .)" && test -z "${FILES}" || (echo -e "Source code is not formatted with 'goimports -w -local github.com/siderolabs/siderolink/ .':\n${FILES}"; exit 1) - # runs golangci-lint FROM base AS lint-golangci-lint WORKDIR /src diff --git a/Makefile b/Makefile index 2faaf2c..ba57f57 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-05-13T15:08:28Z by kres ce88e1c. +# Generated on 2024-05-27T16:57:15Z by kres bcb280a. # common variables @@ -10,20 +10,22 @@ ABBREV_TAG := $(shell git describe --tags >/dev/null 2>/dev/null && git describe BRANCH := $(shell git rev-parse --abbrev-ref HEAD) ARTIFACTS := _out IMAGE_TAG ?= $(TAG) +OPERATING_SYSTEM := $(shell uname -s | tr '[:upper:]' '[:lower:]') +GOARCH := $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') WITH_DEBUG ?= false WITH_RACE ?= false REGISTRY ?= ghcr.io USERNAME ?= siderolabs REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME) -PROTOBUF_GO_VERSION ?= 1.33.0 +PROTOBUF_GO_VERSION ?= 1.34.1 GRPC_GO_VERSION ?= 1.3.0 -GRPC_GATEWAY_VERSION ?= 2.19.1 +GRPC_GATEWAY_VERSION ?= 2.20.0 VTPROTOBUF_VERSION ?= 0.6.0 +GOIMPORTS_VERSION ?= 0.21.0 DEEPCOPY_VERSION ?= v0.5.6 -GOLANGCILINT_VERSION ?= v1.58.0 +GOLANGCILINT_VERSION ?= v1.59.0 GOFUMPT_VERSION ?= v0.6.0 GO_VERSION ?= 1.22.3 -GOIMPORTS_VERSION ?= v0.20.0 GO_BUILDFLAGS ?= GO_LDFLAGS ?= CGO_ENABLED ?= 0 @@ -60,9 +62,9 @@ COMMON_ARGS += --build-arg=PROTOBUF_GO_VERSION="$(PROTOBUF_GO_VERSION)" COMMON_ARGS += --build-arg=GRPC_GO_VERSION="$(GRPC_GO_VERSION)" COMMON_ARGS += --build-arg=GRPC_GATEWAY_VERSION="$(GRPC_GATEWAY_VERSION)" COMMON_ARGS += --build-arg=VTPROTOBUF_VERSION="$(VTPROTOBUF_VERSION)" +COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" COMMON_ARGS += --build-arg=DEEPCOPY_VERSION="$(DEEPCOPY_VERSION)" COMMON_ARGS += --build-arg=GOLANGCILINT_VERSION="$(GOLANGCILINT_VERSION)" -COMMON_ARGS += --build-arg=GOIMPORTS_VERSION="$(GOIMPORTS_VERSION)" COMMON_ARGS += --build-arg=GOFUMPT_VERSION="$(GOFUMPT_VERSION)" COMMON_ARGS += --build-arg=TESTPKGS="$(TESTPKGS)" TOOLCHAIN ?= docker.io/golang:1.22-alpine @@ -131,6 +133,9 @@ endif all: unit-tests siderolink-agent lint +$(ARTIFACTS): ## Creates artifacts directory. + @mkdir -p $(ARTIFACTS) + .PHONY: clean clean: ## Cleans up all artifacts. @rm -rf $(ARTIFACTS) @@ -161,9 +166,6 @@ fmt: ## Formats the source code lint-govulncheck: ## Runs govulncheck linter. @$(MAKE) target-$@ -lint-goimports: ## Runs goimports linter. - @$(MAKE) target-$@ - .PHONY: base base: ## Prepare base toolchain @$(MAKE) target-$@ @@ -226,7 +228,7 @@ lint-markdown: ## Runs markdownlint. @$(MAKE) target-$@ .PHONY: lint -lint: lint-golangci-lint lint-gofumpt lint-govulncheck lint-goimports lint-markdown ## Run all linters for the project. +lint: lint-golangci-lint lint-gofumpt lint-govulncheck lint-markdown ## Run all linters for the project. .PHONY: rekres rekres: @@ -239,8 +241,7 @@ help: ## This help menu. @grep -E '^[a-zA-Z%_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' .PHONY: release-notes -release-notes: - mkdir -p $(ARTIFACTS) +release-notes: $(ARTIFACTS) @ARTIFACTS=$(ARTIFACTS) ./hack/release.sh $@ $(ARTIFACTS)/RELEASE_NOTES.md $(TAG) .PHONY: conformance diff --git a/pkg/wireguard/wireguard.go b/pkg/wireguard/wireguard.go index ef497a0..b1eccc6 100644 --- a/pkg/wireguard/wireguard.go +++ b/pkg/wireguard/wireguard.go @@ -561,6 +561,10 @@ func checkDuplicateUpdates(seq iter.Seq[PeerEvent], oldCfg *wgtypes.Device, logg break } + if peerEvent.Remove { + return true + } + if prefix, ok := netipx.FromStdIPNet(&oldPeer.AllowedIPs[0]); ok { if prefix.Addr() == peerEvent.Address && // check address match & keepalive settings match (peerEvent.PersistentKeepAliveInterval == nil || pointer.SafeDeref(peerEvent.PersistentKeepAliveInterval) == oldPeer.PersistentKeepaliveInterval) { @@ -575,6 +579,13 @@ func checkDuplicateUpdates(seq iter.Seq[PeerEvent], oldCfg *wgtypes.Device, logg } } + // the peer wasn't found in the existing peers, so skip it + if peerEvent.Remove { + logger.Info("skipping peer remove", zap.String("public_key", pubKey)) + + return false + } + return true }) } diff --git a/pkg/wireguard/wireguard_test.go b/pkg/wireguard/wireguard_test.go index dccb82b..bc71dc0 100644 --- a/pkg/wireguard/wireguard_test.go +++ b/pkg/wireguard/wireguard_test.go @@ -25,6 +25,7 @@ import ( "github.com/siderolabs/siderolink/pkg/wireguard" ) +//nolint:maintidx func TestPrepareDeviceConfig(t *testing.T) { //nolint:govet tests := map[string]struct { @@ -112,7 +113,59 @@ func TestPrepareDeviceConfig(t *testing.T) { }, check: check.NoError(), }, - "deduplicate and remove": { + "remove skipped": { + peerEvents: []wireguard.PeerEvent{ + { + PubKey: keys[0].PublicKey(), + Remove: true, + Endpoint: endpoints[0], + Address: addresses1[0], + PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), + }, + }, + oldCfg: &wgtypes.Device{ + Name: "if9", + Type: wgtypes.Userspace, + Peers: []wgtypes.Peer{}, + }, + check: check.NoError(), + }, + "just remove": { + peerEvents: []wireguard.PeerEvent{ + { + PubKey: keys[0].PublicKey(), + Remove: true, + Endpoint: endpoints[0], + Address: addresses1[0], + PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), + }, + }, + oldCfg: &wgtypes.Device{ + Name: "if9", + Type: wgtypes.Userspace, + Peers: []wgtypes.Peer{ + { + PublicKey: keys[0].PublicKey(), + AllowedIPs: []net.IPNet{ + *netipx.PrefixIPNet(netip.PrefixFrom(addresses1[0], addresses1[0].BitLen())), + }, + PersistentKeepaliveInterval: persistentKeepaliveInterval, + }, + }, + }, + expectedCfgs: []wgtypes.PeerConfig{ + { + PublicKey: keys[0].PublicKey(), + Remove: true, + Endpoint: nil, + PersistentKeepaliveInterval: nil, + ReplaceAllowedIPs: false, + AllowedIPs: nil, + }, + }, + check: check.NoError(), + }, + "add remove add": { peerEvents: []wireguard.PeerEvent{ { PubKey: keys[0].PublicKey(), @@ -122,13 +175,13 @@ func TestPrepareDeviceConfig(t *testing.T) { }, { PubKey: keys[0].PublicKey(), + Remove: true, Endpoint: endpoints[1], Address: addresses1[1], PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), }, { PubKey: keys[0].PublicKey(), - Remove: true, Endpoint: endpoints[1], Address: addresses1[1], PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), @@ -139,6 +192,55 @@ func TestPrepareDeviceConfig(t *testing.T) { Type: wgtypes.Userspace, Peers: []wgtypes.Peer{}, }, + expectedCfgs: []wgtypes.PeerConfig{ + { + PublicKey: keys[0].PublicKey(), + Endpoint: wireguard.AsUDP(netip.MustParseAddrPort(endpoints[1])), + PersistentKeepaliveInterval: pointer.To(persistentKeepaliveInterval), + ReplaceAllowedIPs: true, + AllowedIPs: []net.IPNet{ + *netipx.PrefixIPNet(netip.PrefixFrom(addresses1[1], addresses1[1].BitLen())), + }, + }, + }, + check: check.NoError(), + }, + "deduplicate and remove": { + peerEvents: []wireguard.PeerEvent{ + { + PubKey: keys[0].PublicKey(), + Endpoint: endpoints[0], + Address: addresses1[0], + PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), + }, + { + PubKey: keys[0].PublicKey(), + Endpoint: endpoints[1], + Address: addresses1[1], + PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), + }, + { + PubKey: keys[0].PublicKey(), + Remove: true, + Endpoint: endpoints[1], + Address: addresses1[1], + PersistentKeepAliveInterval: pointer.To(persistentKeepaliveInterval), + }, + }, + oldCfg: &wgtypes.Device{ + Name: "if9", + Type: wgtypes.Userspace, + Peers: []wgtypes.Peer{ + { + PublicKey: keys[0].PublicKey(), + Endpoint: wireguard.AsUDP(netip.MustParseAddrPort(endpoints[2])), + PersistentKeepaliveInterval: persistentKeepaliveInterval, + AllowedIPs: []net.IPNet{ + *netipx.PrefixIPNet(netip.PrefixFrom(addresses1[2], addresses1[2].BitLen())), + }, + }, + }, + }, expectedCfgs: []wgtypes.PeerConfig{ { PublicKey: keys[0].PublicKey(),