From 6f26cc4b0c98be0fa094e49a151b5abc01fb1ae8 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Sun, 11 May 2025 15:44:22 +0200 Subject: [PATCH 01/17] update: modules, makefile --- Makefile | 2 +- go.mod | 30 ++++++++++++++++++++++++++++-- go.sum | 23 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index a360cfc..2be2003 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ all: clean lint build .PHONY: build build: - GOOS=linux GOARCH=amd64 go build -o dist/${BINARY_NAME} ipvsctl.go + GOOS=linux GOARCH=arm64 go build -o dist/${BINARY_NAME} ipvsctl.go lint: @for file in ${SOURCES} ; do \ diff --git a/go.mod b/go.mod index 78a0142..4d5d943 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/aschmidt75/ipvsctl -go 1.16 +go 1.23.0 + +toolchain go1.24.2 require ( github.com/aschmidt75/go-dynamic-params v0.0.1 @@ -9,6 +11,30 @@ require ( github.com/stretchr/testify v1.7.0 github.com/vishvananda/netlink v1.0.0 github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f - golang.org/x/sys v0.1.0 + golang.org/x/sys v0.32.0 gopkg.in/yaml.v2 v2.2.4 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect + github.com/jtolds/gls v4.20.0+incompatible // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect + github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect + github.com/stretchr/objx v0.2.0 // indirect + github.com/yuin/goldmark v1.4.13 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect + golang.org/x/mod v0.24.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sync v0.13.0 // indirect + golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 // indirect + golang.org/x/term v0.31.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.32.0 // indirect + golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/go.sum b/go.sum index 36963d0..ab9f43c 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,7 @@ github.com/caarlos0/env/v6 v6.0.0/go.mod h1:+wdyOmtjoZIW2GJOc2OYa5NoOFuWD/bIpWqm github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/jawher/mow.cli v1.1.0 h1:NdtHXRc0CwZQ507wMvQ/IS+Q3W3x2fycn973/b8Zuk8= @@ -26,13 +27,35 @@ github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCO github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I= github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/lint v0.0.0-20241112194109-818c5a804067 h1:adDmSQyFTCiv19j015EGKJBoaa7ElV0Q1Wovb/4G7NA= +golang.org/x/lint v0.0.0-20241112194109-818c5a804067/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU= +golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= From 222e09b4d6c05351519fa2baa2c511904bd6fd3f Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Sun, 11 May 2025 15:57:50 +0200 Subject: [PATCH 02/17] add: gh workflow --- .github/workflows/ci.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2ec0594 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + push: + branches: + - master + - dev + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: 1.24 + + - name: Install dependencies + run: go mod download && go install golang.org/x/lint/golint + + - name: Build + run: make + From 1084cbb89e3cc36dca1fcbcab7824f020599912a Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Sun, 11 May 2025 15:59:47 +0200 Subject: [PATCH 03/17] remove: circleci --- .circleci/config.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index b307787..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,30 +0,0 @@ -version: 2 -jobs: - build: - docker: - - image: circleci/golang:1.16 - parallelism: 1 - - steps: - - checkout - - - restore_cache: - keys: - - go-mod-v4-{{ checksum "go.sum" }} - - - run: - name: build - command: GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -v -o release/ipvsctl ipvsctl.go - - - save_cache: - key: go-mod-v4-{{ checksum "go.sum" }} - paths: - - "/go/pkg/mod" - - -workflows: - version: 2 - build-workflow: - jobs: - - build - From f71fac72790052a29f651be4072ecc7e2bc3cd07 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Sun, 11 May 2025 16:00:54 +0200 Subject: [PATCH 04/17] update: readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7aebad..98ee34e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ It is meant as an add-on to ipvsadm, where changes can be applied from models instead of ad-hoc commands. -[![CircleCI](https://circleci.com/gh/aschmidt75/ipvsctl/tree/master.svg?style=svg)](https://circleci.com/gh/aschmidt75/ipvsctl/tree/master) +[![CI](https://github.com/aschmidt75/ipvsctl/actions/workflows/ci.yml/badge.svg)](https://github.com/aschmidt75/ipvsctl/actions/workflows/ci.yml) [![Go Report Card](https://goreportcard.com/badge/github.com/aschmidt75/ipvsctl)](https://goreportcard.com/report/github.com/aschmidt75/ipvsctl) ## Features From 07c20ad24ecd54e05104edd3688c8caeae855109 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Mon, 12 May 2025 20:35:08 +0200 Subject: [PATCH 05/17] update: build action --- .github/workflows/ci.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ec0594..d93c3b3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,8 +23,23 @@ jobs: go-version: 1.24 - name: Install dependencies - run: go mod download && go install golang.org/x/lint/golint + run: | + go install honnef.co/go/tools/cmd/staticcheck@latest + go install golang.org/x/lint/golint + go mod download + echo "$HOME/go/bin" >> $GITHUB_PATH + - name: Run staticcheck + run: | + staticcheck ./... + golint ./... + - name: Build - run: make + run: GOOS=linux go build -o dist/${BINARY_NAME} ipvsctl.go + + - name: Run tests + run: | + go test -v -coverprofile=cover.out ./... + go tool -v cover -func=cover.out + From 64693e0d7ee1366e666a46172acc3ebb41a7f35a Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Mon, 12 May 2025 20:40:29 +0200 Subject: [PATCH 06/17] update: staticcheck findings, pipeline --- .github/workflows/ci.yml | 8 ++++++-- cmd/apply.go | 2 +- cmd/common.go | 4 ++-- integration/changeset.go | 20 ++++++++++---------- integration/model.go | 4 ++-- integration/validate_test.go | 8 ++++---- 6 files changed, 25 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d93c3b3..c13597a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,8 +31,12 @@ jobs: - name: Run staticcheck run: | - staticcheck ./... - golint ./... + echo "::group::Running staticcheck" + staticcheck ./... || true + echo "::endgroup::" + echo "::group::Running lint" + golint ./... || true + echo "::endgroup::" - name: Build run: GOOS=linux go build -o dist/${BINARY_NAME} ipvsctl.go diff --git a/cmd/apply.go b/cmd/apply.go index 3d834f4..cc581d1 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -28,7 +28,7 @@ func parseAllowedActions(actionSpec *string) (integration.ApplyActions, error) { res := make(integration.ApplyActions, len(actions)) for _, action := range actions { _, ex := all[integration.ApplyActionType(action)] - if ex == false { + if !ex { // no such action return integration.ApplyActions{}, fmt.Errorf("Invalid action: %s", action) } diff --git a/cmd/common.go b/cmd/common.go index 5617db1..76cbe9c 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -97,7 +97,7 @@ func resolveParams(ipvsconfig *integration.IPVSConfig) (*integration.IPVSConfig, cfg := config.Config() intfAddrMap := make(map[string]string) - if cfg.ParamsHostNetwork == true { + if cfg.ParamsHostNetwork { intfs, err := net.Interfaces() if err != nil { fmt.Fprintf(os.Stderr, "Specified dynamic parameter from local network interfaces, but unable to query them: %s\n", err) @@ -126,7 +126,7 @@ func resolveParams(ipvsconfig *integration.IPVSConfig) (*integration.IPVSConfig, } envMap := make(map[string]string) - if cfg.ParamsHostEnv == true { + if cfg.ParamsHostEnv { for _, e := range os.Environ() { a := strings.Split(e, "=") if len(a) == 2 { diff --git a/integration/changeset.go b/integration/changeset.go index c5c834a..ac1917b 100644 --- a/integration/changeset.go +++ b/integration/changeset.go @@ -20,12 +20,12 @@ func (ipvsconfig *IPVSConfig) ChangeSet(newconfig *IPVSConfig, opts ApplyOpts) ( if err != nil { return res, err } - if equal == true { + if equal { found = true } } - if found == false { + if !found { var adr string if service.service != nil { adr = MakeAdressStringFromIpvsService(service.service) @@ -53,12 +53,12 @@ func (ipvsconfig *IPVSConfig) ChangeSet(newconfig *IPVSConfig, opts ApplyOpts) ( if err != nil { return res, err } - if equal == true { + if equal { found = true } } - if found == false { + if !found { res.AddChange(ChangeSetItem{ Type: AddService, Description: fmt.Sprintf("Adding new service %s because it does not yet exist", newService.Address), @@ -77,7 +77,7 @@ func (ipvsconfig *IPVSConfig) ChangeSet(newconfig *IPVSConfig, opts ApplyOpts) ( if err != nil { return res, err } - if equal == true { + if equal { newSched := newService.SchedName if newSched == "" { // default given? @@ -111,12 +111,12 @@ func (ipvsconfig *IPVSConfig) ChangeSet(newconfig *IPVSConfig, opts ApplyOpts) ( if err != nil { return res, err } - if equal == true { + if equal { found = true } } - if found == false { + if !found { var adrService, adrDestination string if service.service != nil { adrService = MakeAdressStringFromIpvsService(service.service) @@ -147,11 +147,11 @@ func (ipvsconfig *IPVSConfig) ChangeSet(newconfig *IPVSConfig, opts ApplyOpts) ( if err != nil { return res, err } - if equal == true { + if equal { found = true } } - if found == false { + if !found { var adrService string if service.service != nil { adrService = MakeAdressStringFromIpvsService(service.service) @@ -178,7 +178,7 @@ func (ipvsconfig *IPVSConfig) ChangeSet(newconfig *IPVSConfig, opts ApplyOpts) ( if err != nil { return res, err } - if equal == false { + if !equal { var adrService string if service.service != nil { adrService = MakeAdressStringFromIpvsService(service.service) diff --git a/integration/model.go b/integration/model.go index 5c5c997..ac48b40 100644 --- a/integration/model.go +++ b/integration/model.go @@ -339,7 +339,7 @@ func CompareServicesEquality(ca *IPVSConfig, a *Service, cb *IPVSConfig, b *Serv if err != nil { return false, err } - if ident == false { + if !ident { return false, nil } @@ -444,7 +444,7 @@ func CompareDestinationsEquality(ca *IPVSConfig, a *Destination, cb *IPVSConfig, return false, nil } - if opts.KeepWeights == false { + if !opts.KeepWeights { // compare weight aw := a.Weight bw := b.Weight diff --git a/integration/validate_test.go b/integration/validate_test.go index cd550c9..3818bb3 100644 --- a/integration/validate_test.go +++ b/integration/validate_test.go @@ -102,11 +102,11 @@ services: t.Run(test.model, func(t *testing.T) { err := validate(t, test.model) if err == nil { - if test.ok == false { + if !test.ok { t.Error("Should have returned a validation error, but did not") } } else { - if test.ok == true { + if test.ok { t.Error("Should have passed but returned a validation error: %w", err) } @@ -166,11 +166,11 @@ defaults: t.Run(test.model, func(t *testing.T) { err := validate(t, test.model) if err == nil { - if test.ok == false { + if !test.ok { t.Error("Should have returned a validation error, but did not") } } else { - if test.ok == true { + if test.ok { t.Error("Should have passed but returned a validation error: %w", err) } From b3c2187a977726da3e0fe7b24653ab1bf07c1ac8 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Mon, 12 May 2025 20:46:07 +0200 Subject: [PATCH 07/17] update: fix tests, lint --- README.md | 2 +- integration/apply_test.go | 16 ++++++++-------- ipvs/ipvs.go | 3 ++- ipvs/netlink.go | 5 +++-- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 98ee34e..f5bb5ca 100644 --- a/README.md +++ b/README.md @@ -155,5 +155,5 @@ $ bats . ## License -(C) 2019 @aschmidt75, Apache 2.0 license +(C) 2019,2025 @aschmidt75, Apache 2.0 license except package ipvs, integrated from https://github.com/docker/libnetwork (C) 2015 Docker, Inc. Apache 2.0 license diff --git a/integration/apply_test.go b/integration/apply_test.go index 29016e1..0936708 100644 --- a/integration/apply_test.go +++ b/integration/apply_test.go @@ -60,17 +60,17 @@ func TestApplyGetOnEmptyModel(t *testing.T) { currentConfig := integration.NewIPVSConfigWithLogger(TestLogger) if err := currentConfig.Get(); err != nil { - t.Errorf("Unable to get current ipvs table: %w\n", err) + t.Errorf("Unable to get current ipvs table: %v\n", err) t.FailNow() } if err := currentConfig.Apply(&newConfig, opts); err != nil { - t.Errorf("Unable to apply test model: %w\n", err) + t.Errorf("Unable to apply test model: %v\n", err) t.FailNow() } updatedConfig := integration.NewIPVSConfigWithLogger(TestLogger) if err := updatedConfig.Get(); err != nil { - t.Errorf("Unable to get current ipvs table: %w\n", err) + t.Errorf("Unable to get current ipvs table: %v\n", err) t.FailNow() } @@ -108,17 +108,17 @@ func TestApplyGetOnServices(t *testing.T) { currentConfig := integration.NewIPVSConfigWithLogger(TestLogger) if err := currentConfig.Get(); err != nil { - t.Errorf("Unable to get current ipvs table: %w\n", err) + t.Errorf("Unable to get current ipvs table: %v\n", err) t.FailNow() } if err := currentConfig.Apply(&newConfig, opts); err != nil { - t.Errorf("Unable to apply test model: %w\n", err) + t.Errorf("Unable to apply test model: %v\n", err) t.FailNow() } updatedConfig := integration.NewIPVSConfigWithLogger(TestLogger) if err := updatedConfig.Get(); err != nil { - t.Errorf("Unable to get current ipvs table: %w\n", err) + t.Errorf("Unable to get current ipvs table: %v\n", err) t.FailNow() } @@ -137,13 +137,13 @@ func TestApplyGetOnServices(t *testing.T) { panic(err) } if err := updatedConfig.Apply(&newConfig, opts); err != nil { - t.Errorf("Unable to apply test model: %w\n", err) + t.Errorf("Unable to apply test model: %v\n", err) t.FailNow() } updatedConfig2 := integration.NewIPVSConfigWithLogger(TestLogger) if err := updatedConfig2.Get(); err != nil { - t.Errorf("Unable to get current ipvs table: %w\n", err) + t.Errorf("Unable to get current ipvs table: %v\n", err) t.FailNow() } diff --git a/ipvs/ipvs.go b/ipvs/ipvs.go index f64a5ea..8778a5a 100644 --- a/ipvs/ipvs.go +++ b/ipvs/ipvs.go @@ -2,6 +2,7 @@ // Code and documentation copyright 2015 Docker, inc. // Code released under the Apache 2.0 license. +//go:build linux // +build linux package ipvs @@ -193,7 +194,7 @@ func (i *Handle) GetService(s *Service) (*Service, error) { // We are looking for exactly one service otherwise error out if len(res) != 1 { - return nil, fmt.Errorf("Expected only one service obtained=%d", len(res)) + return nil, fmt.Errorf("expected only one service obtained=%d", len(res)) } return res[0], nil diff --git a/ipvs/netlink.go b/ipvs/netlink.go index 9305281..7d08501 100644 --- a/ipvs/netlink.go +++ b/ipvs/netlink.go @@ -1,6 +1,7 @@ // from libnetwork: https://github.com/docker/libnetwork // Code and documentation copyright 2015 Docker, inc. // Code released under the Apache 2.0 license. +//go:build linux // +build linux package ipvs @@ -228,7 +229,7 @@ done: msgs, err := s.Receive() if err != nil { if s.GetFd() == -1 { - return nil, fmt.Errorf("Socket got closed on receive") + return nil, fmt.Errorf("socket got closed on receive") } if err == syscall.EAGAIN { // timeout fired @@ -241,7 +242,7 @@ done: continue } if m.Header.Pid != pid { - return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid) + return nil, fmt.Errorf("wrong pid %d, expected %d", m.Header.Pid, pid) } if m.Header.Type == syscall.NLMSG_DONE { break done From 0564fb77cbc292f74012ff81c466d517b10db468 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Mon, 12 May 2025 20:55:05 +0200 Subject: [PATCH 08/17] update: fix tests --- .github/workflows/ci.yml | 10 +++++++--- cmd/apply.go | 2 +- integration/apply_test.go | 6 ++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c13597a..d87a39e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,11 @@ jobs: - name: Run tests run: | - go test -v -coverprofile=cover.out ./... - go tool -v cover -func=cover.out - + SKIP_IPVSKERNELREQ=1 go test -v -coverprofile=coverage.out ./... + go tool cover -html=coverage.out -o coverage.html + - name: Upload HTML coverage report + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: coverage.html diff --git a/cmd/apply.go b/cmd/apply.go index cc581d1..c13d1e2 100644 --- a/cmd/apply.go +++ b/cmd/apply.go @@ -30,7 +30,7 @@ func parseAllowedActions(actionSpec *string) (integration.ApplyActions, error) { _, ex := all[integration.ApplyActionType(action)] if !ex { // no such action - return integration.ApplyActions{}, fmt.Errorf("Invalid action: %s", action) + return integration.ApplyActions{}, fmt.Errorf("invalid action: %s", action) } res[integration.ApplyActionType(action)] = true } diff --git a/integration/apply_test.go b/integration/apply_test.go index 0936708..a9efa0e 100644 --- a/integration/apply_test.go +++ b/integration/apply_test.go @@ -48,6 +48,9 @@ func TestMain(m *testing.M) { } func TestApplyGetOnEmptyModel(t *testing.T) { + if os.Getenv("SKIP_IPVSKERNELREQ") == "1" { + t.Skip("Skipping tests that require kernel support") + } const targetModel string = "{}" var newConfig integration.IPVSConfig @@ -86,6 +89,9 @@ func TestApplyGetOnEmptyModel(t *testing.T) { } func TestApplyGetOnServices(t *testing.T) { + if os.Getenv("SKIP_IPVSKERNELREQ") == "1" { + t.Skip("Skipping tests that require kernel support") + } clearIPVS() From e26c2a3ec3b846c378463343289f23ddd1e7c945 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Mon, 12 May 2025 21:14:35 +0200 Subject: [PATCH 09/17] update: refactor --- integration/apply.go | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/integration/apply.go b/integration/apply.go index 8148d60..81c706e 100644 --- a/integration/apply.go +++ b/integration/apply.go @@ -19,6 +19,11 @@ func (e *IPVSApplyError) Error() string { return fmt.Sprintf("Unable to apply new config: %s\nReason: %s", e.what, e.origErr) } +func isActionAllowed(actions ApplyActions, action ApplyActionType) bool { + allowed, found := actions[action] + return found && allowed +} + // Apply compares new config to current config, builds a changeset and // applies the change set items within. func (ipvsconfig *IPVSConfig) Apply(newconfig *IPVSConfig, opts ApplyOpts) error { @@ -34,7 +39,7 @@ func (ipvsconfig *IPVSConfig) Apply(newconfig *IPVSConfig, opts ApplyOpts) error return ipvsconfig.ApplyChangeSet(newconfig, cs, opts) } -// ApplyChangeSet takes a chhange set and applies all change items to +// ApplyChangeSet takes a change set and applies all change items to // the given IPVSConfig func (ipvsconfig *IPVSConfig) ApplyChangeSet(newconfig *IPVSConfig, cs *ChangeSet, opts ApplyOpts) error { @@ -48,44 +53,40 @@ func (ipvsconfig *IPVSConfig) ApplyChangeSet(newconfig *IPVSConfig, cs *ChangeSe // check before hand wether all change set items are covered within allowedActions for _, csiIntf := range cs.Items { - csi := csiIntf.(ChangeSetItem) + csi, ok := csiIntf.(ChangeSetItem) + if !ok { + return fmt.Errorf("invalid item in change set: %v", csiIntf) + } switch csi.Type { case DeleteService: - allowed, found := allowedActions[ApplyActionDeleteService] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionDeleteService) { return &IPVSApplyError{what: "not allowed to delete a service"} } case AddService: - allowed, found := allowedActions[ApplyActionAddService] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionAddService) { return &IPVSApplyError{what: "not allowed to add a service"} } // if service has destinations, check as well if allowed if len(csi.Service.Destinations) > 0 { - allowed, found = allowedActions[ApplyActionAddDestination] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionAddDestination) { return &IPVSApplyError{what: "not allowed to add a destinations"} } } case UpdateService: - allowed, found := allowedActions[ApplyActionUpdateService] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionUpdateService) { return &IPVSApplyError{what: "not allowed to update a service"} } case AddDestination: - allowed, found := allowedActions[ApplyActionAddDestination] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionAddDestination) { return &IPVSApplyError{what: "not allowed to add a destination"} } case DeleteDestination: - allowed, found := allowedActions[ApplyActionDeleteDestination] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionDeleteDestination) { return &IPVSApplyError{what: "not allowed to delete a destination"} } case UpdateDestination: - allowed, found := allowedActions[ApplyActionUpdateDestination] - if !found || !allowed { + if !isActionAllowed(allowedActions, ApplyActionUpdateDestination) { return &IPVSApplyError{what: "not allowed to update a destination"} } default: @@ -94,7 +95,11 @@ func (ipvsconfig *IPVSConfig) ApplyChangeSet(newconfig *IPVSConfig, cs *ChangeSe } for _, csiIntf := range cs.Items { - csi := csiIntf.(ChangeSetItem) + csi, ok := csiIntf.(ChangeSetItem) + if !ok { + return fmt.Errorf("invalid item in change set: %v", csiIntf) + } + ipvsconfig.log.Printf("Applying change set item %#v\n", csi) switch csi.Type { From 6b7e509043c266f80739f7c65ea4c8488eb95cd6 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Mon, 12 May 2025 21:18:00 +0200 Subject: [PATCH 10/17] update: improve pipeline --- .github/workflows/ci.yml | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d87a39e..21832aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,8 @@ on: jobs: build: runs-on: ubuntu-latest + env: + BINARY_NAME: ipvsctl steps: - name: Checkout code @@ -22,10 +24,20 @@ jobs: with: go-version: 1.24 + - name: Cache Go modules + uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + - name: Install dependencies run: | - go install honnef.co/go/tools/cmd/staticcheck@latest - go install golang.org/x/lint/golint + go install honnef.co/go/tools/cmd/staticcheck@2023.1.6 + go install golang.org/x/lint/golint@v0.0.0-20201208152925-83fdc39ff7b5 go mod download echo "$HOME/go/bin" >> $GITHUB_PATH @@ -34,8 +46,17 @@ jobs: echo "::group::Running staticcheck" staticcheck ./... || true echo "::endgroup::" + + - name: Run golint + run: | echo "::group::Running lint" - golint ./... || true + golint ./... + echo "::endgroup::" + + - name: Run go vet + run: | + echo "::group::Running go vet" + go vet ./... echo "::endgroup::" - name: Build From 7d5833c46024dbb9f60886a4f21bcd55beb3c3b6 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Thu, 15 May 2025 20:44:26 +0200 Subject: [PATCH 11/17] update: goreleaser --- .github/workflows/release.yml | 35 +++++++++++++++++++++++++++++++++++ .goreleaser.yml | 25 +++++++++++++++++-------- 2 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f063ab7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,35 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') && github.ref_type == 'tag' && github.base_ref == 'main' + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + + - name: Install dependencies + run: go mode download + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + distribution: goreleaser + version: "lastest" + args: release --snapshot --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + diff --git a/.goreleaser.yml b/.goreleaser.yml index 33dbf49..2191aaa 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,18 +1,27 @@ +project_name: ipvsdsc +version: 2 before: hooks: - go mod download builds: - - goos: + - id: ipvsdsc + binary: ipvsdsc + ldflags: + - -s -w -X main.version=v{{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} + env: + - CGO_ENABLED=0 + goos: - linux -archives: - - replacements: - linux: Linux - 386: i386 - amd64: x86_64 + goarch: + - amd64 + - arm64 + mod_timestamp: '{{ .CommitTimestamp }}' + checksum: - name_template: 'checksums.txt' + name_template: "{{ .ProjectName }}-{{ .Version }}_checksums.txt" + algorithm: sha512 snapshot: - name_template: "{{ .Tag }}-next" + version_template: "{{ .Tag }}-next" changelog: sort: asc filters: From 7e3db7caab407c9a6a26cbfc0d726b85b8780063 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Thu, 15 May 2025 20:48:50 +0200 Subject: [PATCH 12/17] update: fix msg output, go vet --- ipvs/netlink.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ipvs/netlink.go b/ipvs/netlink.go index 7d08501..7efa165 100644 --- a/ipvs/netlink.go +++ b/ipvs/netlink.go @@ -11,6 +11,7 @@ import ( "encoding/binary" "fmt" "net" + "os" "os/exec" "strings" "sync" @@ -65,7 +66,8 @@ func setup() { ipvsOnce.Do(func() { var err error if out, err := exec.Command("modprobe", "-va", "ip_vs").CombinedOutput(); err != nil { - fmt.Sprintf("Running modprobe ip_vs failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + fmt.Fprintf(os.Stderr, "Running modprobe ip_vs failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + os.Exit(1) } ipvsFamily, err = getIPVSFamily() From b0119fbdcd263b5b92e3c649e557ad8ae556a7ec Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Thu, 15 May 2025 21:06:58 +0200 Subject: [PATCH 13/17] update: fix msg output, go vet (2) --- ipvs/netlink.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ipvs/netlink.go b/ipvs/netlink.go index 7efa165..bd6f87e 100644 --- a/ipvs/netlink.go +++ b/ipvs/netlink.go @@ -66,8 +66,10 @@ func setup() { ipvsOnce.Do(func() { var err error if out, err := exec.Command("modprobe", "-va", "ip_vs").CombinedOutput(); err != nil { - fmt.Fprintf(os.Stderr, "Running modprobe ip_vs failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) - os.Exit(1) + if os.Getenv("SKIP_IPVSKERNELREQ") != "1" { + fmt.Fprintf(os.Stderr, "Running modprobe ip_vs failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) + os.Exit(1) + } } ipvsFamily, err = getIPVSFamily() From d76d3307f335373c7dd3bbc8bed668f927153683 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Thu, 15 May 2025 21:41:52 +0200 Subject: [PATCH 14/17] update: modules --- doc/libraryexample1/main.go | 1 - go.mod | 17 ++++++++--------- go.sum | 26 +++++++++++++++++++++++++- ipvs/netlink.go | 2 +- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/doc/libraryexample1/main.go b/doc/libraryexample1/main.go index ad647f8..a6511a8 100644 --- a/doc/libraryexample1/main.go +++ b/doc/libraryexample1/main.go @@ -1,6 +1,5 @@ // libraryexample1 applies a model as a whole on top of an existing // ipvs tables model. -// package main import ( diff --git a/go.mod b/go.mod index 4d5d943..dd5ac70 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,18 @@ module github.com/aschmidt75/ipvsctl -go 1.23.0 +go 1.24 -toolchain go1.24.2 +toolchain go1.24.3 require ( github.com/aschmidt75/go-dynamic-params v0.0.1 - github.com/caarlos0/env/v6 v6.0.0 - github.com/jawher/mow.cli v1.1.0 + github.com/caarlos0/env/v6 v6.10.1 + github.com/jawher/mow.cli v1.2.0 github.com/stretchr/testify v1.7.0 - github.com/vishvananda/netlink v1.0.0 - github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f - golang.org/x/sys v0.32.0 - gopkg.in/yaml.v2 v2.2.4 + github.com/vishvananda/netlink v1.3.1 + github.com/vishvananda/netns v0.0.5 + golang.org/x/sys v0.33.0 + gopkg.in/yaml.v2 v2.2.8 ) require ( @@ -36,5 +36,4 @@ require ( golang.org/x/tools v0.32.0 // indirect golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index ab9f43c..10ef6aa 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,11 @@ github.com/aschmidt75/go-dynamic-params v0.0.1 h1:+ty7MB0v+HH8yWHv7ECmh3A6KrH4e6uqvQCPEUmz67g= github.com/aschmidt75/go-dynamic-params v0.0.1/go.mod h1:T4JuTxSbzqbkPwtzbMYS4JVrtm85Yn5bCKvFsSCPO1c= +github.com/aschmidt75/go-dynamic-params v0.1.0 h1:7NnVApr4vyZJE38+fDG6fEOoBrgLfVlZc7qOKE5EXzM= +github.com/aschmidt75/go-dynamic-params v0.1.0/go.mod h1:vRyDB+9vb2CO36RbRiK5pkchW7fJe4H/ffZSEtA4Mqg= github.com/caarlos0/env/v6 v6.0.0 h1:NZt6FAoB8ieKO5lEwRdwCzYxWFx7ZYF2R7UcoyaWtyc= github.com/caarlos0/env/v6 v6.0.0/go.mod h1:+wdyOmtjoZIW2GJOc2OYa5NoOFuWD/bIpWqm30NgtRk= +github.com/caarlos0/env/v6 v6.10.1 h1:t1mPSxNpei6M5yAeu1qtRdPAK29Nbcf/n3G7x+b3/II= +github.com/caarlos0/env/v6 v6.10.1/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -10,6 +14,8 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGa github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/jawher/mow.cli v1.1.0 h1:NdtHXRc0CwZQ507wMvQ/IS+Q3W3x2fycn973/b8Zuk8= github.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg= +github.com/jawher/mow.cli v1.2.0 h1:e6ViPPy+82A/NFF/cfbq3Lr6q4JHKT9tyHwTCcUQgQw= +github.com/jawher/mow.cli v1.2.0/go.mod h1:y+pcA3jBAdo/GIZx/0rFjw/K2bVEODP9rfZOfaiq8Ko= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -21,12 +27,17 @@ github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:s github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= +github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f h1:nBX3nTcmxEtHSERBJaIo1Qa26VwRaopnZmfDQUXsF4I= github.com/vishvananda/netns v0.0.0-20190625233234-7109fa855b0f/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -45,8 +56,12 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -58,7 +73,16 @@ golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v2 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v2 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v3.0.0-20220521103104-8f96da9f5d5e h1:3i3ny04XV6HbZ2N1oIBw1UBYATHAOpo4tfTF83JM3Z0= +gopkg.in/yaml.v2 v3.0.0-20220521103104-8f96da9f5d5e/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/ipvs/netlink.go b/ipvs/netlink.go index bd6f87e..0e15a9c 100644 --- a/ipvs/netlink.go +++ b/ipvs/netlink.go @@ -230,7 +230,7 @@ func execute(s *nl.NetlinkSocket, req *nl.NetlinkRequest, resType uint16) ([][]b done: for { - msgs, err := s.Receive() + msgs, _, err := s.Receive() if err != nil { if s.GetFd() == -1 { return nil, fmt.Errorf("socket got closed on receive") From edda81ae35b8acfd37700888ebfb053c63259a2a Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Thu, 15 May 2025 21:42:46 +0200 Subject: [PATCH 15/17] update: modules (2) --- go.mod | 1 + go.sum | 1 + 2 files changed, 2 insertions(+) diff --git a/go.mod b/go.mod index dd5ac70..8de19ac 100644 --- a/go.mod +++ b/go.mod @@ -36,4 +36,5 @@ require ( golang.org/x/tools v0.32.0 // indirect golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/go.sum b/go.sum index 10ef6aa..29005be 100644 --- a/go.sum +++ b/go.sum @@ -85,4 +85,5 @@ gopkg.in/yaml.v2 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v2 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v2 v3.0.0-20220521103104-8f96da9f5d5e h1:3i3ny04XV6HbZ2N1oIBw1UBYATHAOpo4tfTF83JM3Z0= gopkg.in/yaml.v2 v3.0.0-20220521103104-8f96da9f5d5e/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 0031fee0676a905d2dd156cfb5ebd2ef535a1def Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Fri, 16 May 2025 19:15:09 +0200 Subject: [PATCH 16/17] update: fix name --- .goreleaser.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 2191aaa..488afe4 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,11 +1,11 @@ -project_name: ipvsdsc +project_name: ipvsctl version: 2 before: hooks: - go mod download builds: - - id: ipvsdsc - binary: ipvsdsc + - id: ipvsctl + binary: ipvsctl ldflags: - -s -w -X main.version=v{{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} env: From dd24c63806e9d9b61892df5da34ad29a0b0179e7 Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Fri, 16 May 2025 19:20:40 +0200 Subject: [PATCH 17/17] update: fix int16 conversion with bounds check --- integration/model.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integration/model.go b/integration/model.go index ac48b40..9c06fcb 100644 --- a/integration/model.go +++ b/integration/model.go @@ -235,6 +235,10 @@ func (c *IPVSConfig) NewIpvsServiceStruct(s *Service) (*ipvs.Service, error) { port = *c.Defaults.Port } } + // Ensure the parsed port is within the valid range for uint16 + if port < 0 || port > 65535 { + return nil, errors.New("port out of range") + } var protoAsNum uint16 switch proto { @@ -295,6 +299,10 @@ func (c *IPVSConfig) NewIpvsDestinationStruct(destination *Destination) (*ipvs.D p = *c.Defaults.Port } } + // Ensure the parsed port is within the valid range for uint16 + if p < 0 || p > 65535 { + return nil, errors.New("port out of range") + } df := destination.Forward if df == "" {