From 09fde884efe7b21de0efdf136c387a47569f4378 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Tue, 27 Aug 2024 13:57:32 +0900 Subject: [PATCH 01/36] change directory structure Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- cmd/nat-gateway/main.go | 4 ++-- internal/controller/pod_watcher.go | 4 ++-- internal/controller/pod_watcher_test.go | 4 ++-- {internal => pkg}/nat/mock/mock.go | 0 {internal => pkg}/nat/nat.go | 2 +- {internal => pkg}/tunnel/fou/fou.go | 4 ++-- {internal => pkg}/tunnel/mock/mock.go | 0 {internal => pkg}/tunnel/tunnel.go | 0 {internal => pkg}/util/netiputil/netiputil.go | 0 9 files changed, 9 insertions(+), 9 deletions(-) rename {internal => pkg}/nat/mock/mock.go (100%) rename {internal => pkg}/nat/nat.go (98%) rename {internal => pkg}/tunnel/fou/fou.go (99%) rename {internal => pkg}/tunnel/mock/mock.go (100%) rename {internal => pkg}/tunnel/tunnel.go (100%) rename {internal => pkg}/util/netiputil/netiputil.go (100%) diff --git a/cmd/nat-gateway/main.go b/cmd/nat-gateway/main.go index 21ad7d9..d267bbb 100644 --- a/cmd/nat-gateway/main.go +++ b/cmd/nat-gateway/main.go @@ -24,8 +24,8 @@ import ( ponav1beta1 "github.com/cybozu-go/pona/api/v1beta1" "github.com/cybozu-go/pona/internal/controller" - "github.com/cybozu-go/pona/internal/nat" - "github.com/cybozu-go/pona/internal/tunnel/fou" + "github.com/cybozu-go/pona/pkg/nat" + "github.com/cybozu-go/pona/pkg/tunnel/fou" // +kubebuilder:scaffold:imports ) diff --git a/internal/controller/pod_watcher.go b/internal/controller/pod_watcher.go index 8a56837..bfff27e 100644 --- a/internal/controller/pod_watcher.go +++ b/internal/controller/pod_watcher.go @@ -9,8 +9,8 @@ import ( "strings" "sync" - "github.com/cybozu-go/pona/internal/nat" - "github.com/cybozu-go/pona/internal/tunnel" + "github.com/cybozu-go/pona/pkg/nat" + "github.com/cybozu-go/pona/pkg/tunnel" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" diff --git a/internal/controller/pod_watcher_test.go b/internal/controller/pod_watcher_test.go index 1db774c..ae3ad2d 100644 --- a/internal/controller/pod_watcher_test.go +++ b/internal/controller/pod_watcher_test.go @@ -5,8 +5,8 @@ import ( "net/netip" "path/filepath" - natmock "github.com/cybozu-go/pona/internal/nat/mock" - tunnelmock "github.com/cybozu-go/pona/internal/tunnel/mock" + natmock "github.com/cybozu-go/pona/pkg/nat/mock" + tunnelmock "github.com/cybozu-go/pona/pkg/tunnel/mock" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" diff --git a/internal/nat/mock/mock.go b/pkg/nat/mock/mock.go similarity index 100% rename from internal/nat/mock/mock.go rename to pkg/nat/mock/mock.go diff --git a/internal/nat/nat.go b/pkg/nat/nat.go similarity index 98% rename from internal/nat/nat.go rename to pkg/nat/nat.go index 5dd8c37..e649cac 100644 --- a/internal/nat/nat.go +++ b/pkg/nat/nat.go @@ -6,7 +6,7 @@ import ( "net/netip" "github.com/coreos/go-iptables/iptables" - "github.com/cybozu-go/pona/internal/util/netiputil" + "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/vishvananda/netlink" ) diff --git a/internal/tunnel/fou/fou.go b/pkg/tunnel/fou/fou.go similarity index 99% rename from internal/tunnel/fou/fou.go rename to pkg/tunnel/fou/fou.go index 2013d03..bc05773 100644 --- a/internal/tunnel/fou/fou.go +++ b/pkg/tunnel/fou/fou.go @@ -11,8 +11,8 @@ import ( "github.com/containernetworking/plugins/pkg/ip" "github.com/containernetworking/plugins/pkg/utils/sysctl" "github.com/coreos/go-iptables/iptables" - "github.com/cybozu-go/pona/internal/tunnel" - "github.com/cybozu-go/pona/internal/util/netiputil" + "github.com/cybozu-go/pona/pkg/tunnel" + "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/vishvananda/netlink" ) diff --git a/internal/tunnel/mock/mock.go b/pkg/tunnel/mock/mock.go similarity index 100% rename from internal/tunnel/mock/mock.go rename to pkg/tunnel/mock/mock.go diff --git a/internal/tunnel/tunnel.go b/pkg/tunnel/tunnel.go similarity index 100% rename from internal/tunnel/tunnel.go rename to pkg/tunnel/tunnel.go diff --git a/internal/util/netiputil/netiputil.go b/pkg/util/netiputil/netiputil.go similarity index 100% rename from internal/util/netiputil/netiputil.go rename to pkg/util/netiputil/netiputil.go From c6ea953d97d76ad291799f6c2693e0d8240e46a0 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:00:17 +0900 Subject: [PATCH 02/36] fix Dockerfiles Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- dockerfiles/Dockerfile.egress-controller | 1 + dockerfiles/Dockerfile.nat-gateway | 1 + 2 files changed, 2 insertions(+) diff --git a/dockerfiles/Dockerfile.egress-controller b/dockerfiles/Dockerfile.egress-controller index bdf1001..b4bd368 100644 --- a/dockerfiles/Dockerfile.egress-controller +++ b/dockerfiles/Dockerfile.egress-controller @@ -15,6 +15,7 @@ RUN go mod download COPY cmd/egress-controller/main.go cmd/egress-controller/main.go COPY api/ api/ COPY internal/ internal/ +COPY pkg/ pkg/ RUN --mount=type=cache,target=/go/pkg/mod/ \ CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o egress-controller cmd/egress-controller/main.go diff --git a/dockerfiles/Dockerfile.nat-gateway b/dockerfiles/Dockerfile.nat-gateway index 2e10461..94dd8bc 100644 --- a/dockerfiles/Dockerfile.nat-gateway +++ b/dockerfiles/Dockerfile.nat-gateway @@ -15,6 +15,7 @@ RUN go mod download COPY cmd/nat-gateway/main.go cmd/nat-gateway/main.go COPY api/ api/ COPY internal/ internal/ +COPY pkg/ pkg/ RUN --mount=type=cache,target=/go/pkg/mod/ \ CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o nat-gateway cmd/nat-gateway/main.go From 1cacc45cb586ad16b7c79365528c2df8f4a6b1b0 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Tue, 27 Aug 2024 14:14:41 +0900 Subject: [PATCH 03/36] add protobuf Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- .gitignore | 3 +++ Makefile | 26 ++++++++++++++++++++ pkg/cnirpc/cni.proto | 57 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 pkg/cnirpc/cni.proto diff --git a/.gitignore b/.gitignore index ada68ff..92b4dd7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ go.work *.swp *.swo *~ + +# protobuf downloaded files +include diff --git a/Makefile b/Makefile index 7ea3294..39d8eaf 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,8 @@ IMG_GATEWAY ?= nat-gateway:$(IMG_TAG) # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.30.0 +SUDO ?= sudo + # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) GOBIN=$(shell go env GOPATH)/bin @@ -179,6 +181,10 @@ CONTROLLER_TOOLS_VERSION ?= v0.15.0 ENVTEST_VERSION ?= release-0.18 GOLANGCI_LINT_VERSION ?= v1.59.1 YQ_VERSION ?= 4.44.3 +PROTOC_VERSION=27.3 +PROTOC_GEN_GO_VERSION := $(shell awk '/google.golang.org\/protobuf/ {print substr($$2, 2)}' go.mod) +PROTOC_GEN_GO_GRPC_VERSON=1.5.1 +PROTOC_GEN_DOC_VERSION=1.5.1 .PHONY: kustomize kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. @@ -200,6 +206,26 @@ golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. $(GOLANGCI_LINT): $(LOCALBIN) $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) +.PHONY: setup +setup: + $(SUDO) apt-get update + $(SUDO) apt-get -y install --no-install-recommends unzip + + curl -sfL -o protoc.zip https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-linux-x86_64.zip + unzip -o protoc.zip bin/protoc 'include/*' + rm -f protoc.zip + go install google.golang.org/protobuf/cmd/protoc-gen-go@v$(PROTOC_GEN_GO_VERSION) + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v$(PROTOC_GEN_GO_GRPC_VERSON) + go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v$(PROTOC_GEN_DOC_VERSION) + +pkg/cnirpc/cni.pb.go: pkg/cnirpc/cni.proto + $(PROTOC) --go_out=module=github.com/cybozu-go/pona:. $< + +pkg/cnirpc/cni_grpc.pb.go: pkg/cnirpc/cni.proto + $(PROTOC) --go-grpc_out=module=github.com/cybozu-go/pona:. $< + +../docs/cni-grpc.md: pkg/cnirpc/cni.proto + $(PROTOC) --doc_out=../docs --doc_opt=markdown,$@ $< .PHONY: yq yq: $(YQ) diff --git a/pkg/cnirpc/cni.proto b/pkg/cnirpc/cni.proto new file mode 100644 index 0000000..df327f6 --- /dev/null +++ b/pkg/cnirpc/cni.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; +package pkg.cnirpc; + +import "google/protobuf/empty.proto"; + +option go_package = "github.com/cybozu-go/coil/v2/pkg/cnirpc"; + +// CNIArgs is a mirror of cni.pkg.skel.CmdArgs struct. +// https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/skel?tab=doc#CmdArgs +message CNIArgs { + string container_id = 1; + string netns = 2; + string ifname = 3; + map args = 4; // Key-Value pairs parsed from CNI_ARGS + string path = 5; + bytes stdin_data = 6; +} + +// ErrorCode enumerates errors for CNIError +enum ErrorCode { + UNKNOWN = 0; + INCOMPATIBLE_CNI_VERSION = 1; + UNSUPPORTED_FIELD = 2; + UNKNOWN_CONTAINER = 3; + INVALID_ENVIRONMENT_VARIABLES = 4; + IO_FAILURE = 5; + DECODING_FAILURE = 6; + INVALID_NETWORK_CONFIG = 7; + TRY_AGAIN_LATER = 11; + INTERNAL = 999; +} + +// CNIError is a mirror of cin.pkg.types.Error struct. +// https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/types?tab=doc#Error +// +// This should be added to *grpc.Status by WithDetails() +// https://pkg.go.dev/google.golang.org/grpc@v1.31.0/internal/status?tab=doc#Status.WithDetails +message CNIError { + ErrorCode code = 1; + string msg = 2; + string details = 3; +} + +// AddResponse represents the response for ADD command. +// +// `result` is a types.current.Result serialized into JSON. +// https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/types/current?tab=doc#Result +message AddResponse { + bytes result = 1; +} + +// CNI implements CNI commands over gRPC. +service CNI { + rpc Add(CNIArgs) returns (AddResponse); + rpc Del(CNIArgs) returns (google.protobuf.Empty); + rpc Check(CNIArgs) returns (google.protobuf.Empty); +} From 3b03d0539a911df24ca28008b66863a9355afd5b Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Tue, 27 Aug 2024 15:05:34 +0900 Subject: [PATCH 04/36] [WIP] add ponad Signed-off-by: walnuts1018 --- Makefile | 11 +- cmd/ponad/main.go | 25 ++ docs/cni-grpc.md | 163 +++++++++++++ go.mod | 13 +- go.sum | 45 ++-- internal/ponad/server.go | 7 + pkg/cnirpc/cni.pb.go | 465 ++++++++++++++++++++++++++++++++++++++ pkg/cnirpc/cni.proto | 2 +- pkg/cnirpc/cni_grpc.pb.go | 202 +++++++++++++++++ 9 files changed, 891 insertions(+), 42 deletions(-) create mode 100644 cmd/ponad/main.go create mode 100644 docs/cni-grpc.md create mode 100644 internal/ponad/server.go create mode 100644 pkg/cnirpc/cni.pb.go create mode 100644 pkg/cnirpc/cni_grpc.pb.go diff --git a/Makefile b/Makefile index 39d8eaf..066f5e5 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ IMG_GATEWAY ?= nat-gateway:$(IMG_TAG) ENVTEST_K8S_VERSION = 1.30.0 SUDO ?= sudo +PROTOC_OUTPUTS = pkg/cnirpc/cni.pb.go pkg/cnirpc/cni_grpc.pb.go docs/cni-grpc.md # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) @@ -54,6 +55,7 @@ manifests: controller-gen yq ## Generate WebhookConfiguration, ClusterRole and C .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. + $(MAKE) $(PROTOC_OUTPUTS) $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." .PHONY: fmt @@ -73,7 +75,9 @@ test: envtest manifests generate fmt vet mod ## Run tests. KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out .PHONY: check-generate -check-generate: manifests generate fmt mod +check-generate: manifests fmt mod + -rm $(ROLES) $(PROTOC_OUTPUTS) + $(MAKE) generate git diff --exit-code --name-only # Utilize Kind or modify the e2e tests to load the image locally, enabling compatibility with other vendors. @@ -174,6 +178,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint YQ = $(LOCALBIN)/yq WGET_OPTIONS := --retry-on-http-error=503 --retry-connrefused --no-verbose WGET = wget $(WGET_OPTIONS) +PROTOC := PATH=$(LOCALBIN):'$(PATH)' $(LOCALBIN)/protoc -I=$(PWD)/include:. ## Tool Versions KUSTOMIZE_VERSION ?= v5.4.2 @@ -224,8 +229,8 @@ pkg/cnirpc/cni.pb.go: pkg/cnirpc/cni.proto pkg/cnirpc/cni_grpc.pb.go: pkg/cnirpc/cni.proto $(PROTOC) --go-grpc_out=module=github.com/cybozu-go/pona:. $< -../docs/cni-grpc.md: pkg/cnirpc/cni.proto - $(PROTOC) --doc_out=../docs --doc_opt=markdown,$@ $< +docs/cni-grpc.md: pkg/cnirpc/cni.proto + $(PROTOC) --doc_out=docs --doc_opt=markdown,$@ $< .PHONY: yq yq: $(YQ) diff --git a/cmd/ponad/main.go b/cmd/ponad/main.go new file mode 100644 index 0000000..48971fe --- /dev/null +++ b/cmd/ponad/main.go @@ -0,0 +1,25 @@ +package main + +import ( + "flag" +) + +type Config struct { + metricsAddr string + healthAddr string + socketPath string + egressPort int +} + +const defaultSocketPath = "/run/ponad.sock" + +func main() { + var config Config + + flag.StringVar(&config.metricsAddr, "metrics-addr", ":9384", "bind address of metrics endpoint") + flag.StringVar(&config.healthAddr, "health-addr", ":9385", "bind address of health/readiness probes") + flag.StringVar(&config.socketPath, "socket", defaultSocketPath, "UNIX domain socket path") + flag.IntVar(&config.egressPort, "egress-port", 5555, "UDP port number for egress NAT") + + flag.Parse() +} diff --git a/docs/cni-grpc.md b/docs/cni-grpc.md new file mode 100644 index 0000000..954c3ba --- /dev/null +++ b/docs/cni-grpc.md @@ -0,0 +1,163 @@ +# Protocol Documentation + + +## Table of Contents + +- [pkg/cnirpc/cni.proto](#pkg_cnirpc_cni-proto) + - [AddResponse](#pkg-cnirpc-AddResponse) + - [CNIArgs](#pkg-cnirpc-CNIArgs) + - [CNIArgs.ArgsEntry](#pkg-cnirpc-CNIArgs-ArgsEntry) + - [CNIError](#pkg-cnirpc-CNIError) + + - [ErrorCode](#pkg-cnirpc-ErrorCode) + + - [CNI](#pkg-cnirpc-CNI) + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## pkg/cnirpc/cni.proto + + + + + +### AddResponse +AddResponse represents the response for ADD command. + +`result` is a types.current.Result serialized into JSON. +https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/types/current?tab=doc#Result + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| result | [bytes](#bytes) | | | + + + + + + + + +### CNIArgs +CNIArgs is a mirror of cni.pkg.skel.CmdArgs struct. +https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/skel?tab=doc#CmdArgs + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| container_id | [string](#string) | | | +| netns | [string](#string) | | | +| ifname | [string](#string) | | | +| args | [CNIArgs.ArgsEntry](#pkg-cnirpc-CNIArgs-ArgsEntry) | repeated | Key-Value pairs parsed from CNI_ARGS | +| path | [string](#string) | | | +| stdin_data | [bytes](#bytes) | | | + + + + + + + + +### CNIArgs.ArgsEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [string](#string) | | | + + + + + + + + +### CNIError +CNIError is a mirror of cin.pkg.types.Error struct. +https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/types?tab=doc#Error + +This should be added to *grpc.Status by WithDetails() +https://pkg.go.dev/google.golang.org/grpc@v1.31.0/internal/status?tab=doc#Status.WithDetails + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| code | [ErrorCode](#pkg-cnirpc-ErrorCode) | | | +| msg | [string](#string) | | | +| details | [string](#string) | | | + + + + + + + + + + +### ErrorCode +ErrorCode enumerates errors for CNIError + +| Name | Number | Description | +| ---- | ------ | ----------- | +| UNKNOWN | 0 | | +| INCOMPATIBLE_CNI_VERSION | 1 | | +| UNSUPPORTED_FIELD | 2 | | +| UNKNOWN_CONTAINER | 3 | | +| INVALID_ENVIRONMENT_VARIABLES | 4 | | +| IO_FAILURE | 5 | | +| DECODING_FAILURE | 6 | | +| INVALID_NETWORK_CONFIG | 7 | | +| TRY_AGAIN_LATER | 11 | | +| INTERNAL | 999 | | + + + + + + + + + +### CNI +CNI implements CNI commands over gRPC. + +| Method Name | Request Type | Response Type | Description | +| ----------- | ------------ | ------------- | ------------| +| Add | [CNIArgs](#pkg-cnirpc-CNIArgs) | [AddResponse](#pkg-cnirpc-AddResponse) | | +| Del | [CNIArgs](#pkg-cnirpc-CNIArgs) | [.google.protobuf.Empty](#google-protobuf-Empty) | | +| Check | [CNIArgs](#pkg-cnirpc-CNIArgs) | [.google.protobuf.Empty](#google-protobuf-Empty) | | + + + + + +## Scalar Value Types + +| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby | +| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- | +| double | | double | double | float | float64 | double | float | Float | +| float | | float | float | float | float32 | float | float | Float | +| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) | +| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) | +| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) | +| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum | +| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) | +| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum | +| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | +| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) | +| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) | + diff --git a/go.mod b/go.mod index 23e4161..75e676a 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,8 @@ require ( github.com/coreos/go-iptables v0.7.0 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 k8s.io/api v0.30.1 k8s.io/apimachinery v0.30.1 k8s.io/client-go v0.30.1 @@ -26,7 +28,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect @@ -76,7 +78,7 @@ require ( go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/net v0.25.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/term v0.20.0 // indirect @@ -84,11 +86,8 @@ require ( golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.21.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/grpc v1.62.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 5171c35..1d001bf 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -51,8 +51,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -164,7 +164,6 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= @@ -190,31 +189,26 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= 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.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -229,22 +223,16 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/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.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -254,7 +242,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -263,16 +250,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= -google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= -google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -281,8 +264,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/ponad/server.go b/internal/ponad/server.go new file mode 100644 index 0000000..3ae4908 --- /dev/null +++ b/internal/ponad/server.go @@ -0,0 +1,7 @@ +package ponad + +import "github.com/cybozu-go/pona/pkg/cnirpc" + +type server struct { + cnirpc.UnimplementedCNIServer +} diff --git a/pkg/cnirpc/cni.pb.go b/pkg/cnirpc/cni.pb.go new file mode 100644 index 0000000..8873895 --- /dev/null +++ b/pkg/cnirpc/cni.pb.go @@ -0,0 +1,465 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.33.0 +// protoc v5.27.3 +// source: pkg/cnirpc/cni.proto + +package cnirpc + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// ErrorCode enumerates errors for CNIError +type ErrorCode int32 + +const ( + ErrorCode_UNKNOWN ErrorCode = 0 + ErrorCode_INCOMPATIBLE_CNI_VERSION ErrorCode = 1 + ErrorCode_UNSUPPORTED_FIELD ErrorCode = 2 + ErrorCode_UNKNOWN_CONTAINER ErrorCode = 3 + ErrorCode_INVALID_ENVIRONMENT_VARIABLES ErrorCode = 4 + ErrorCode_IO_FAILURE ErrorCode = 5 + ErrorCode_DECODING_FAILURE ErrorCode = 6 + ErrorCode_INVALID_NETWORK_CONFIG ErrorCode = 7 + ErrorCode_TRY_AGAIN_LATER ErrorCode = 11 + ErrorCode_INTERNAL ErrorCode = 999 +) + +// Enum value maps for ErrorCode. +var ( + ErrorCode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "INCOMPATIBLE_CNI_VERSION", + 2: "UNSUPPORTED_FIELD", + 3: "UNKNOWN_CONTAINER", + 4: "INVALID_ENVIRONMENT_VARIABLES", + 5: "IO_FAILURE", + 6: "DECODING_FAILURE", + 7: "INVALID_NETWORK_CONFIG", + 11: "TRY_AGAIN_LATER", + 999: "INTERNAL", + } + ErrorCode_value = map[string]int32{ + "UNKNOWN": 0, + "INCOMPATIBLE_CNI_VERSION": 1, + "UNSUPPORTED_FIELD": 2, + "UNKNOWN_CONTAINER": 3, + "INVALID_ENVIRONMENT_VARIABLES": 4, + "IO_FAILURE": 5, + "DECODING_FAILURE": 6, + "INVALID_NETWORK_CONFIG": 7, + "TRY_AGAIN_LATER": 11, + "INTERNAL": 999, + } +) + +func (x ErrorCode) Enum() *ErrorCode { + p := new(ErrorCode) + *p = x + return p +} + +func (x ErrorCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ErrorCode) Descriptor() protoreflect.EnumDescriptor { + return file_pkg_cnirpc_cni_proto_enumTypes[0].Descriptor() +} + +func (ErrorCode) Type() protoreflect.EnumType { + return &file_pkg_cnirpc_cni_proto_enumTypes[0] +} + +func (x ErrorCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ErrorCode.Descriptor instead. +func (ErrorCode) EnumDescriptor() ([]byte, []int) { + return file_pkg_cnirpc_cni_proto_rawDescGZIP(), []int{0} +} + +// CNIArgs is a mirror of cni.pkg.skel.CmdArgs struct. +// https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/skel?tab=doc#CmdArgs +type CNIArgs struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + Netns string `protobuf:"bytes,2,opt,name=netns,proto3" json:"netns,omitempty"` + Ifname string `protobuf:"bytes,3,opt,name=ifname,proto3" json:"ifname,omitempty"` + Args map[string]string `protobuf:"bytes,4,rep,name=args,proto3" json:"args,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Key-Value pairs parsed from CNI_ARGS + Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"` + StdinData []byte `protobuf:"bytes,6,opt,name=stdin_data,json=stdinData,proto3" json:"stdin_data,omitempty"` +} + +func (x *CNIArgs) Reset() { + *x = CNIArgs{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_cnirpc_cni_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CNIArgs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CNIArgs) ProtoMessage() {} + +func (x *CNIArgs) ProtoReflect() protoreflect.Message { + mi := &file_pkg_cnirpc_cni_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CNIArgs.ProtoReflect.Descriptor instead. +func (*CNIArgs) Descriptor() ([]byte, []int) { + return file_pkg_cnirpc_cni_proto_rawDescGZIP(), []int{0} +} + +func (x *CNIArgs) GetContainerId() string { + if x != nil { + return x.ContainerId + } + return "" +} + +func (x *CNIArgs) GetNetns() string { + if x != nil { + return x.Netns + } + return "" +} + +func (x *CNIArgs) GetIfname() string { + if x != nil { + return x.Ifname + } + return "" +} + +func (x *CNIArgs) GetArgs() map[string]string { + if x != nil { + return x.Args + } + return nil +} + +func (x *CNIArgs) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *CNIArgs) GetStdinData() []byte { + if x != nil { + return x.StdinData + } + return nil +} + +// CNIError is a mirror of cin.pkg.types.Error struct. +// https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/types?tab=doc#Error +// +// This should be added to *grpc.Status by WithDetails() +// https://pkg.go.dev/google.golang.org/grpc@v1.31.0/internal/status?tab=doc#Status.WithDetails +type CNIError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code ErrorCode `protobuf:"varint,1,opt,name=code,proto3,enum=pkg.cnirpc.ErrorCode" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Details string `protobuf:"bytes,3,opt,name=details,proto3" json:"details,omitempty"` +} + +func (x *CNIError) Reset() { + *x = CNIError{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_cnirpc_cni_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CNIError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CNIError) ProtoMessage() {} + +func (x *CNIError) ProtoReflect() protoreflect.Message { + mi := &file_pkg_cnirpc_cni_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CNIError.ProtoReflect.Descriptor instead. +func (*CNIError) Descriptor() ([]byte, []int) { + return file_pkg_cnirpc_cni_proto_rawDescGZIP(), []int{1} +} + +func (x *CNIError) GetCode() ErrorCode { + if x != nil { + return x.Code + } + return ErrorCode_UNKNOWN +} + +func (x *CNIError) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +func (x *CNIError) GetDetails() string { + if x != nil { + return x.Details + } + return "" +} + +// AddResponse represents the response for ADD command. +// +// `result` is a types.current.Result serialized into JSON. +// https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/types/current?tab=doc#Result +type AddResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Result []byte `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` +} + +func (x *AddResponse) Reset() { + *x = AddResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_pkg_cnirpc_cni_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AddResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AddResponse) ProtoMessage() {} + +func (x *AddResponse) ProtoReflect() protoreflect.Message { + mi := &file_pkg_cnirpc_cni_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AddResponse.ProtoReflect.Descriptor instead. +func (*AddResponse) Descriptor() ([]byte, []int) { + return file_pkg_cnirpc_cni_proto_rawDescGZIP(), []int{2} +} + +func (x *AddResponse) GetResult() []byte { + if x != nil { + return x.Result + } + return nil +} + +var File_pkg_cnirpc_cni_proto protoreflect.FileDescriptor + +var file_pkg_cnirpc_cni_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x6e, 0x69, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6e, 0x69, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x70, 0x6b, 0x67, 0x2e, 0x63, 0x6e, 0x69, 0x72, + 0x70, 0x63, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, + 0xf9, 0x01, 0x0a, 0x07, 0x43, 0x4e, 0x49, 0x41, 0x72, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x65, 0x74, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, + 0x65, 0x74, 0x6e, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x69, 0x66, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x04, + 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x6b, 0x67, + 0x2e, 0x63, 0x6e, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x4e, 0x49, 0x41, 0x72, 0x67, 0x73, 0x2e, + 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, + 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, + 0x61, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x44, 0x61, + 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x41, 0x72, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x61, 0x0a, 0x08, 0x43, + 0x4e, 0x49, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x29, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x63, 0x6e, 0x69, 0x72, + 0x70, 0x63, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6d, 0x73, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x25, + 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2a, 0xed, 0x01, 0x0a, 0x09, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, + 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x41, 0x54, 0x49, 0x42, 0x4c, 0x45, + 0x5f, 0x43, 0x4e, 0x49, 0x5f, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x15, + 0x0a, 0x11, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x49, + 0x45, 0x4c, 0x44, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x03, 0x12, 0x21, 0x0a, 0x1d, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x45, 0x4e, 0x56, 0x49, 0x52, 0x4f, 0x4e, 0x4d, + 0x45, 0x4e, 0x54, 0x5f, 0x56, 0x41, 0x52, 0x49, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x04, 0x12, + 0x0e, 0x0a, 0x0a, 0x49, 0x4f, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x55, 0x52, 0x45, 0x10, 0x05, 0x12, + 0x14, 0x0a, 0x10, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x41, 0x49, 0x4c, + 0x55, 0x52, 0x45, 0x10, 0x06, 0x12, 0x1a, 0x0a, 0x16, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x10, + 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x52, 0x59, 0x5f, 0x41, 0x47, 0x41, 0x49, 0x4e, 0x5f, 0x4c, + 0x41, 0x54, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, + 0x41, 0x4c, 0x10, 0xe7, 0x07, 0x32, 0xa4, 0x01, 0x0a, 0x03, 0x43, 0x4e, 0x49, 0x12, 0x33, 0x0a, + 0x03, 0x41, 0x64, 0x64, 0x12, 0x13, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x63, 0x6e, 0x69, 0x72, 0x70, + 0x63, 0x2e, 0x43, 0x4e, 0x49, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x17, 0x2e, 0x70, 0x6b, 0x67, 0x2e, + 0x63, 0x6e, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x32, 0x0a, 0x03, 0x44, 0x65, 0x6c, 0x12, 0x13, 0x2e, 0x70, 0x6b, 0x67, 0x2e, + 0x63, 0x6e, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x4e, 0x49, 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, 0x05, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, + 0x13, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x63, 0x6e, 0x69, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x4e, 0x49, + 0x41, 0x72, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x26, 0x5a, 0x24, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x79, 0x62, 0x6f, 0x7a, + 0x75, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x63, 0x6e, + 0x69, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pkg_cnirpc_cni_proto_rawDescOnce sync.Once + file_pkg_cnirpc_cni_proto_rawDescData = file_pkg_cnirpc_cni_proto_rawDesc +) + +func file_pkg_cnirpc_cni_proto_rawDescGZIP() []byte { + file_pkg_cnirpc_cni_proto_rawDescOnce.Do(func() { + file_pkg_cnirpc_cni_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_cnirpc_cni_proto_rawDescData) + }) + return file_pkg_cnirpc_cni_proto_rawDescData +} + +var file_pkg_cnirpc_cni_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pkg_cnirpc_cni_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_pkg_cnirpc_cni_proto_goTypes = []interface{}{ + (ErrorCode)(0), // 0: pkg.cnirpc.ErrorCode + (*CNIArgs)(nil), // 1: pkg.cnirpc.CNIArgs + (*CNIError)(nil), // 2: pkg.cnirpc.CNIError + (*AddResponse)(nil), // 3: pkg.cnirpc.AddResponse + nil, // 4: pkg.cnirpc.CNIArgs.ArgsEntry + (*emptypb.Empty)(nil), // 5: google.protobuf.Empty +} +var file_pkg_cnirpc_cni_proto_depIdxs = []int32{ + 4, // 0: pkg.cnirpc.CNIArgs.args:type_name -> pkg.cnirpc.CNIArgs.ArgsEntry + 0, // 1: pkg.cnirpc.CNIError.code:type_name -> pkg.cnirpc.ErrorCode + 1, // 2: pkg.cnirpc.CNI.Add:input_type -> pkg.cnirpc.CNIArgs + 1, // 3: pkg.cnirpc.CNI.Del:input_type -> pkg.cnirpc.CNIArgs + 1, // 4: pkg.cnirpc.CNI.Check:input_type -> pkg.cnirpc.CNIArgs + 3, // 5: pkg.cnirpc.CNI.Add:output_type -> pkg.cnirpc.AddResponse + 5, // 6: pkg.cnirpc.CNI.Del:output_type -> google.protobuf.Empty + 5, // 7: pkg.cnirpc.CNI.Check:output_type -> google.protobuf.Empty + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_pkg_cnirpc_cni_proto_init() } +func file_pkg_cnirpc_cni_proto_init() { + if File_pkg_cnirpc_cni_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pkg_cnirpc_cni_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CNIArgs); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_cnirpc_cni_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CNIError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pkg_cnirpc_cni_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pkg_cnirpc_cni_proto_rawDesc, + NumEnums: 1, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_pkg_cnirpc_cni_proto_goTypes, + DependencyIndexes: file_pkg_cnirpc_cni_proto_depIdxs, + EnumInfos: file_pkg_cnirpc_cni_proto_enumTypes, + MessageInfos: file_pkg_cnirpc_cni_proto_msgTypes, + }.Build() + File_pkg_cnirpc_cni_proto = out.File + file_pkg_cnirpc_cni_proto_rawDesc = nil + file_pkg_cnirpc_cni_proto_goTypes = nil + file_pkg_cnirpc_cni_proto_depIdxs = nil +} diff --git a/pkg/cnirpc/cni.proto b/pkg/cnirpc/cni.proto index df327f6..c7b3efc 100644 --- a/pkg/cnirpc/cni.proto +++ b/pkg/cnirpc/cni.proto @@ -3,7 +3,7 @@ package pkg.cnirpc; import "google/protobuf/empty.proto"; -option go_package = "github.com/cybozu-go/coil/v2/pkg/cnirpc"; +option go_package = "github.com/cybozu-go/pona/pkg/cnirpc"; // CNIArgs is a mirror of cni.pkg.skel.CmdArgs struct. // https://pkg.go.dev/github.com/containernetworking/cni@v0.8.0/pkg/skel?tab=doc#CmdArgs diff --git a/pkg/cnirpc/cni_grpc.pb.go b/pkg/cnirpc/cni_grpc.pb.go new file mode 100644 index 0000000..4b57081 --- /dev/null +++ b/pkg/cnirpc/cni_grpc.pb.go @@ -0,0 +1,202 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 +// source: pkg/cnirpc/cni.proto + +package cnirpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + CNI_Add_FullMethodName = "/pkg.cnirpc.CNI/Add" + CNI_Del_FullMethodName = "/pkg.cnirpc.CNI/Del" + CNI_Check_FullMethodName = "/pkg.cnirpc.CNI/Check" +) + +// CNIClient is the client API for CNI service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +// +// CNI implements CNI commands over gRPC. +type CNIClient interface { + Add(ctx context.Context, in *CNIArgs, opts ...grpc.CallOption) (*AddResponse, error) + Del(ctx context.Context, in *CNIArgs, opts ...grpc.CallOption) (*emptypb.Empty, error) + Check(ctx context.Context, in *CNIArgs, opts ...grpc.CallOption) (*emptypb.Empty, error) +} + +type cNIClient struct { + cc grpc.ClientConnInterface +} + +func NewCNIClient(cc grpc.ClientConnInterface) CNIClient { + return &cNIClient{cc} +} + +func (c *cNIClient) Add(ctx context.Context, in *CNIArgs, opts ...grpc.CallOption) (*AddResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AddResponse) + err := c.cc.Invoke(ctx, CNI_Add_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cNIClient) Del(ctx context.Context, in *CNIArgs, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, CNI_Del_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *cNIClient) Check(ctx context.Context, in *CNIArgs, opts ...grpc.CallOption) (*emptypb.Empty, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, CNI_Check_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// CNIServer is the server API for CNI service. +// All implementations must embed UnimplementedCNIServer +// for forward compatibility. +// +// CNI implements CNI commands over gRPC. +type CNIServer interface { + Add(context.Context, *CNIArgs) (*AddResponse, error) + Del(context.Context, *CNIArgs) (*emptypb.Empty, error) + Check(context.Context, *CNIArgs) (*emptypb.Empty, error) + mustEmbedUnimplementedCNIServer() +} + +// UnimplementedCNIServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedCNIServer struct{} + +func (UnimplementedCNIServer) Add(context.Context, *CNIArgs) (*AddResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Add not implemented") +} +func (UnimplementedCNIServer) Del(context.Context, *CNIArgs) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Del not implemented") +} +func (UnimplementedCNIServer) Check(context.Context, *CNIArgs) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") +} +func (UnimplementedCNIServer) mustEmbedUnimplementedCNIServer() {} +func (UnimplementedCNIServer) testEmbeddedByValue() {} + +// UnsafeCNIServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to CNIServer will +// result in compilation errors. +type UnsafeCNIServer interface { + mustEmbedUnimplementedCNIServer() +} + +func RegisterCNIServer(s grpc.ServiceRegistrar, srv CNIServer) { + // If the following call pancis, it indicates UnimplementedCNIServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&CNI_ServiceDesc, srv) +} + +func _CNI_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CNIArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CNIServer).Add(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CNI_Add_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CNIServer).Add(ctx, req.(*CNIArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _CNI_Del_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CNIArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CNIServer).Del(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CNI_Del_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CNIServer).Del(ctx, req.(*CNIArgs)) + } + return interceptor(ctx, in, info, handler) +} + +func _CNI_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CNIArgs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(CNIServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: CNI_Check_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(CNIServer).Check(ctx, req.(*CNIArgs)) + } + return interceptor(ctx, in, info, handler) +} + +// CNI_ServiceDesc is the grpc.ServiceDesc for CNI service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var CNI_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "pkg.cnirpc.CNI", + HandlerType: (*CNIServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Add", + Handler: _CNI_Add_Handler, + }, + { + MethodName: "Del", + Handler: _CNI_Del_Handler, + }, + { + MethodName: "Check", + Handler: _CNI_Check_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "pkg/cnirpc/cni.proto", +} From d665447ebee7ec6bb2747ea8b4661c6983cb0d3b Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Tue, 27 Aug 2024 15:40:40 +0900 Subject: [PATCH 05/36] [WIP] implementing ponad Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- cmd/ponad/main.go | 34 +++++++++++++++++++++++++++++++++ go.mod | 7 ++++--- go.sum | 14 ++++++++------ internal/ponad/server.go | 41 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 86 insertions(+), 10 deletions(-) diff --git a/cmd/ponad/main.go b/cmd/ponad/main.go index 48971fe..cc22cde 100644 --- a/cmd/ponad/main.go +++ b/cmd/ponad/main.go @@ -1,7 +1,16 @@ package main import ( + "context" "flag" + "log/slog" + "os" + + "github.com/cybozu-go/pona/internal/ponad" + "github.com/cybozu-go/pona/pkg/cnirpc" + "github.com/cybozu-go/pona/pkg/tunnel/fou" + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" + "google.golang.org/grpc" ) type Config struct { @@ -13,6 +22,14 @@ type Config struct { const defaultSocketPath = "/run/ponad.sock" +// InterceptorLogger adapts slog logger to interceptor logger. +// This code is simple enough to be copied and not imported. +func InterceptorLogger(l *slog.Logger) logging.Logger { + return logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) { + l.Log(ctx, slog.Level(lvl), msg, fields...) + }) +} + func main() { var config Config @@ -22,4 +39,21 @@ func main() { flag.IntVar(&config.egressPort, "egress-port", 5555, "UDP port number for egress NAT") flag.Parse() + logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + + fc, err := fou.NewFoUTunnelController(config.egressPort, ipv4, ipv6) + if err != nil { + logger.Error("failed to generate FoU Tunnel Controller", slog.Any("error", err)) + os.Exit(1) + } + if err := fc.Init(); err != nil { + logger.Error("failed to initialize FoU Tunnel Controller", slog.Any("error", err)) + os.Exit(1) + } + + s := ponad.NewServer(fc) + server := grpc.NewServer(grpc.ChainUnaryInterceptor( + logging.UnaryServerInterceptor(InterceptorLogger(logger)), + )) + cnirpc.RegisterCNIServer(server, s) } diff --git a/go.mod b/go.mod index 75e676a..7d57f5f 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.6 require ( github.com/containernetworking/plugins v1.5.1 github.com/coreos/go-iptables v0.7.0 + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 google.golang.org/grpc v1.65.0 @@ -24,7 +25,7 @@ require ( ) require ( - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect @@ -64,7 +65,7 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stoewer/go-strcase v1.2.0 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect github.com/vishvananda/netlink v1.2.1 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect @@ -76,7 +77,7 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect diff --git a/go.sum b/go.sum index 1d001bf..b5dc6a4 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk= +github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -85,6 +85,8 @@ github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQN github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -146,8 +148,8 @@ github.com/safchain/ethtool v0.4.0 h1:vq1i2HCjshJNywOXFZ1BpwIjyeFR/kvNdHiRzqSElD github.com/safchain/ethtool v0.4.0/go.mod h1:XLLnZmy4OCRTkksP/UiMjij96YmIsBfmBQcs7H6tA48= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -189,8 +191,8 @@ go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= 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.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 3ae4908..ad20ce9 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -1,7 +1,46 @@ package ponad -import "github.com/cybozu-go/pona/pkg/cnirpc" +import ( + "context" + + "github.com/cybozu-go/pona/pkg/cnirpc" + "github.com/cybozu-go/pona/pkg/tunnel" + "google.golang.org/protobuf/types/known/emptypb" +) + +// Keys in CNI_ARGS +const ( + PodNameKey = "K8S_POD_NAME" + PodNamespaceKey = "K8S_POD_NAMESPACE" + PodContainerKey = "K8S_POD_INFRA_CONTAINER_ID" +) type server struct { cnirpc.UnimplementedCNIServer + tun tunnel.Controller +} + +func NewServer(tun tunnel.Controller) *server { + return &server{ + tun: tun, + } +} + +var _ cnirpc.CNIServer = &server{} + +func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResponse, error) { + podName := args.Args[PodNameKey] + podNS := args.Args[PodNamespaceKey] + if podName == "" || podNS == "" { + + } + t := s.tun.AddPeer() +} + +func (s *server) Del(ctx context.Context, args *cnirpc.CNIArgs) (*emptypb.Empty, error) { + +} + +func (s *server) Check(ctx context.Context, args *cnirpc.CNIArgs) (*emptypb.Empty, error) { + } From d7b635f5f513403217df2344e3ec9f00b3c75a49 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Tue, 27 Aug 2024 16:20:57 +0900 Subject: [PATCH 06/36] [WIP] ponad Add Signed-off-by: walnuts1018 --- cmd/ponad/main.go | 89 +++++++++++++++++++++++++++++++--------- internal/ponad/server.go | 47 ++++++++++++++++++--- 2 files changed, 111 insertions(+), 25 deletions(-) diff --git a/cmd/ponad/main.go b/cmd/ponad/main.go index cc22cde..94c519b 100644 --- a/cmd/ponad/main.go +++ b/cmd/ponad/main.go @@ -1,16 +1,20 @@ package main import ( - "context" "flag" "log/slog" + "net" "os" + "time" "github.com/cybozu-go/pona/internal/ponad" - "github.com/cybozu-go/pona/pkg/cnirpc" - "github.com/cybozu-go/pona/pkg/tunnel/fou" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "google.golang.org/grpc" + "github.com/go-logr/logr" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/healthz" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" ) type Config struct { @@ -22,12 +26,19 @@ type Config struct { const defaultSocketPath = "/run/ponad.sock" -// InterceptorLogger adapts slog logger to interceptor logger. -// This code is simple enough to be copied and not imported. -func InterceptorLogger(l *slog.Logger) logging.Logger { - return logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) { - l.Log(ctx, slog.Level(lvl), msg, fields...) - }) +const ( + gracefulTimeout = 20 * time.Second +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + + // +kubebuilder:scaffold:scheme } func main() { @@ -40,20 +51,58 @@ func main() { flag.Parse() logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + slog.SetDefault(logger) + ctrl.SetLogger(logr.FromSlogHandler(logger.Handler())) - fc, err := fou.NewFoUTunnelController(config.egressPort, ipv4, ipv6) + mgr, err := setupManager(config) if err != nil { - logger.Error("failed to generate FoU Tunnel Controller", slog.Any("error", err)) + setupLog.Error(err, "failed to setup manager") os.Exit(1) } - if err := fc.Init(); err != nil { - logger.Error("failed to initialize FoU Tunnel Controller", slog.Any("error", err)) + + if err := startPonad(config, mgr); err != nil { + setupLog.Error(err, "failed to start ponad") os.Exit(1) } +} + +func setupManager(config Config) (ctrl.Manager, error) { + timeout := gracefulTimeout + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + Scheme: scheme, + LeaderElection: false, + Metrics: metricsserver.Options{ + BindAddress: config.metricsAddr, + }, + GracefulShutdownTimeout: &timeout, + HealthProbeBindAddress: config.healthAddr, + }) + if err != nil { + return nil, err + } + + if err := mgr.AddHealthzCheck("ping", healthz.Ping); err != nil { + return nil, err + } + if err := mgr.AddReadyzCheck("ping", healthz.Ping); err != nil { + return nil, err + } + return mgr, nil +} + +func startPonad(config Config, mgr ctrl.Manager) error { + l, err := net.Listen("unix", config.socketPath) + if err != nil { + return err + } + + s := ponad.NewServer(l, mgr.GetAPIReader()) + if err := mgr.Add(s); err != nil { + return err + } + + ctx := ctrl.SetupSignalHandler() + slog.Info("starting manager") - s := ponad.NewServer(fc) - server := grpc.NewServer(grpc.ChainUnaryInterceptor( - logging.UnaryServerInterceptor(InterceptorLogger(logger)), - )) - cnirpc.RegisterCNIServer(server, s) + return mgr.Start(ctx) } diff --git a/internal/ponad/server.go b/internal/ponad/server.go index ad20ce9..723c22f 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -2,10 +2,17 @@ package ponad import ( "context" + "fmt" + "log/slog" + "net" "github.com/cybozu-go/pona/pkg/cnirpc" - "github.com/cybozu-go/pona/pkg/tunnel" + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" + "google.golang.org/grpc" "google.golang.org/protobuf/types/known/emptypb" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "sigs.k8s.io/controller-runtime/pkg/client" ) // Keys in CNI_ARGS @@ -15,26 +22,56 @@ const ( PodContainerKey = "K8S_POD_INFRA_CONTAINER_ID" ) +// InterceptorLogger adapts slog logger to interceptor logger. +// This code is simple enough to be copied and not imported. +func InterceptorLogger(l *slog.Logger) logging.Logger { + return logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) { + l.Log(ctx, slog.Level(lvl), msg, fields...) + }) +} + type server struct { cnirpc.UnimplementedCNIServer - tun tunnel.Controller + listener net.Listener + apiReader client.Reader } -func NewServer(tun tunnel.Controller) *server { +func NewServer(l net.Listener, r client.Reader) *server { return &server{ - tun: tun, + listener: l, + apiReader: r, } } var _ cnirpc.CNIServer = &server{} +func (s *server) Start(ctx context.Context) error { + grpcServer := grpc.NewServer(grpc.ChainUnaryInterceptor( + logging.UnaryServerInterceptor(InterceptorLogger(slog.Default())), + )) + cnirpc.RegisterCNIServer(grpcServer, s) + + go func() { + <-ctx.Done() + grpcServer.GracefulStop() + }() + + return grpcServer.Serve(s.listener) +} + func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResponse, error) { podName := args.Args[PodNameKey] podNS := args.Args[PodNamespaceKey] if podName == "" || podNS == "" { + return nil, fmt.Errorf("missing pod name or namespace, args: %#v", args.Args) + } + pod := &corev1.Pod{} + if err := s.apiReader.Get(ctx, client.ObjectKey{Namespace: podNS, Name: podName}, pod); err != nil { + if apierrors.IsNotFound(err) { + } } - t := s.tun.AddPeer() + } func (s *server) Del(ctx context.Context, args *cnirpc.CNIArgs) (*emptypb.Empty, error) { From c654629a204dfe2699150a6bca1325b588893bf9 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Tue, 27 Aug 2024 17:04:30 +0900 Subject: [PATCH 07/36] [WIP] implementing ponad Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- internal/constants/constants.go | 5 ++ internal/controller/pod_watcher.go | 9 +- internal/controller/pod_watcher_test.go | 3 +- internal/ponad/server.go | 106 ++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 internal/constants/constants.go diff --git a/internal/constants/constants.go b/internal/constants/constants.go new file mode 100644 index 0000000..a700d13 --- /dev/null +++ b/internal/constants/constants.go @@ -0,0 +1,5 @@ +package constants + +const ( + EgressAnnotationPrefix = "egress.pona.cybozu.com/" +) diff --git a/internal/controller/pod_watcher.go b/internal/controller/pod_watcher.go index bfff27e..e3e677f 100644 --- a/internal/controller/pod_watcher.go +++ b/internal/controller/pod_watcher.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "github.com/cybozu-go/pona/internal/constants" "github.com/cybozu-go/pona/pkg/nat" "github.com/cybozu-go/pona/pkg/tunnel" corev1 "k8s.io/api/core/v1" @@ -20,10 +21,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ) -const ( - EgressAnnotationPrefix = "egress.pona.cybozu.com/" -) - // PodWatcher reconciles a Pod object type PodWatcher struct { client.Client @@ -238,11 +235,11 @@ func (r *PodWatcher) existsOtherLiveTunnels(namespacedName types.NamespacedName, func (r *PodWatcher) hasEgressAnnotation(pod *corev1.Pod) bool { for k, name := range pod.Annotations { - if !strings.HasPrefix(k, EgressAnnotationPrefix) { + if !strings.HasPrefix(k, constants.EgressAnnotationPrefix) { continue } - if k[len(EgressAnnotationPrefix):] != r.EgressNamespace { + if k[len(constants.EgressAnnotationPrefix):] != r.EgressNamespace { continue } diff --git a/internal/controller/pod_watcher_test.go b/internal/controller/pod_watcher_test.go index ae3ad2d..5c9d5cb 100644 --- a/internal/controller/pod_watcher_test.go +++ b/internal/controller/pod_watcher_test.go @@ -5,6 +5,7 @@ import ( "net/netip" "path/filepath" + "github.com/cybozu-go/pona/internal/constants" natmock "github.com/cybozu-go/pona/pkg/nat/mock" tunnelmock "github.com/cybozu-go/pona/pkg/tunnel/mock" . "github.com/onsi/ginkgo/v2" @@ -49,7 +50,7 @@ var _ = Describe("Pod Watcher", func() { } pod.Annotations = map[string]string{ - filepath.Join(EgressAnnotationPrefix, egressNamespace): egressName, + filepath.Join(constants.EgressAnnotationPrefix, egressNamespace): egressName, } By("create pod") diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 723c22f..6cc3a92 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -5,10 +5,15 @@ import ( "fmt" "log/slog" "net" + "net/netip" + "strings" + "github.com/cybozu-go/pona/internal/constants" "github.com/cybozu-go/pona/pkg/cnirpc" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/emptypb" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -22,6 +27,20 @@ const ( PodContainerKey = "K8S_POD_INFRA_CONTAINER_ID" ) +func newError(c codes.Code, cniCode cnirpc.ErrorCode, msg, details string) error { + st := status.New(c, msg) + st, err := st.WithDetails(&cnirpc.CNIError{Code: cniCode, Msg: msg, Details: details}) + if err != nil { + panic(err) + } + + return st.Err() +} + +func newInternalError(err error, msg string) error { + return newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, msg, err.Error()) +} + // InterceptorLogger adapts slog logger to interceptor logger. // This code is simple enough to be copied and not imported. func InterceptorLogger(l *slog.Logger) logging.Logger { @@ -32,6 +51,7 @@ func InterceptorLogger(l *slog.Logger) logging.Logger { type server struct { cnirpc.UnimplementedCNIServer + listener net.Listener apiReader client.Reader } @@ -69,7 +89,93 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp pod := &corev1.Pod{} if err := s.apiReader.Get(ctx, client.ObjectKey{Namespace: podNS, Name: podName}, pod); err != nil { if apierrors.IsNotFound(err) { + return nil, newError(codes.NotFound, cnirpc.ErrorCode_UNKNOWN_CONTAINER, "pod not found", err.Error()) } + return nil, newInternalError(err, "failed to get pod") + } + + egNames, err := s.listEgress(pod) + if err != nil { + return nil, newInternalError(err, "failed to list eggress from annotations") + } + if len(egNames) == 0 { + return nil, nil + } + +} + +func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { + if pod.Spec.HostNetwork { + // pods running in the host network cannot use egress NAT. + // In fact, such a pod won't call CNI, so this is just a safeguard. + return nil, nil + } + + var egNames []client.ObjectKey + + for k, v := range pod.Annotations { + if !strings.HasPrefix(k, constants.EgressAnnotationPrefix) { + continue + } + + ns := k[len(constants.EgressAnnotationPrefix):] + for _, name := range strings.Split(v, ",") { + egNames = append(egNames, client.ObjectKey{Namespace: ns, Name: name}) + } + } + return egNames, nil +} + +type gateway netip.Addr +type destination netip.Prefix +type gwToDests map[gateway][]destination + +func (s *server) collectDestinationsForEgress(ctx context.Context, egName client.ObjectKey) (*gateway, []destination, error) { + eg := &ponav1.Egress{} + svc := &corev1.Service{} + + if err := s.apiReader.Get(ctx, egName, eg); err != nil { + return nil, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, + "failed to get Egress "+egName.Name, err.Error()) + } + if err := s.client.Get(ctx, n, svc); err != nil { + return nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, + "failed to get Service "+n.String(), err.Error()) + } + + // coil doesn't support dual stack services for now, although it's stable from k8s 1.23 + // https://kubernetes.io/docs/concepts/services-networking/dual-stack/ + svcIP := net.ParseIP(svc.Spec.ClusterIP) + if svcIP == nil { + return nil, newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, + "invalid ClusterIP in Service "+n.String(), svc.Spec.ClusterIP) + } + var subnets []*net.IPNet + if ip4 := svcIP.To4(); ip4 != nil { + svcIP = ip4 + for _, sn := range eg.Spec.Destinations { + _, subnet, err := net.ParseCIDR(sn) + if err != nil { + return nil, newInternalError(err, "invalid network in Egress "+n.String()) + } + if subnet.IP.To4() != nil { + subnets = append(subnets, subnet) + } + } + } else { + for _, sn := range eg.Spec.Destinations { + _, subnet, err := net.ParseCIDR(sn) + if err != nil { + return nil, newInternalError(err, "invalid network in Egress "+n.String()) + } + if subnet.IP.To4() == nil { + subnets = append(subnets, subnet) + } + } + } + + if len(subnets) > 0 { + gwlist = append(gwlist, GWNets{Gateway: svcIP, Networks: subnets, SportAuto: eg.Spec.FouSourcePortAuto}) } } From 15fd8361fe21208eaaada6adc609bffe81688d45 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Tue, 27 Aug 2024 17:32:21 +0900 Subject: [PATCH 08/36] implemented collectDestinationsForEgress Signed-off-by: walnuts1018 --- internal/ponad/server.go | 68 +++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 6cc3a92..e529da5 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -2,12 +2,14 @@ package ponad import ( "context" + "errors" "fmt" "log/slog" "net" "net/netip" "strings" + ponav1beta1 "github.com/cybozu-go/pona/api/v1beta1" "github.com/cybozu-go/pona/internal/constants" "github.com/cybozu-go/pona/pkg/cnirpc" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" @@ -102,6 +104,13 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, nil } + for _, egName := range egNames { + g, ds, err := s.collectDestinationsForEgress(ctx, egName) + if err != nil { + return nil, newInternalError(err, "failed to collect destinations for egress") + } + + } } func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { @@ -130,54 +139,55 @@ type gateway netip.Addr type destination netip.Prefix type gwToDests map[gateway][]destination -func (s *server) collectDestinationsForEgress(ctx context.Context, egName client.ObjectKey) (*gateway, []destination, error) { - eg := &ponav1.Egress{} +func (s *server) collectDestinationsForEgress(ctx context.Context, egName client.ObjectKey) (gateway, []destination, error) { + eg := &ponav1beta1.Egress{} svc := &corev1.Service{} if err := s.apiReader.Get(ctx, egName, eg); err != nil { - return nil, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, - "failed to get Egress "+egName.Name, err.Error()) + return gateway{}, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, + "failed to get Egress "+egName.String(), err.Error()) } - if err := s.client.Get(ctx, n, svc); err != nil { - return nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, - "failed to get Service "+n.String(), err.Error()) + + if err := s.apiReader.Get(ctx, egName, svc); err != nil { + return gateway{}, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, + "failed to get Service "+egName.String(), err.Error()) } - // coil doesn't support dual stack services for now, although it's stable from k8s 1.23 + // pona doesn't support dual stack services for now, although it's stable from k8s 1.23 // https://kubernetes.io/docs/concepts/services-networking/dual-stack/ - svcIP := net.ParseIP(svc.Spec.ClusterIP) - if svcIP == nil { - return nil, newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, - "invalid ClusterIP in Service "+n.String(), svc.Spec.ClusterIP) + svcIP, err := netip.ParseAddr(svc.Spec.ClusterIP) + if err != nil { + return gateway{}, nil, newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, + "invalid ClusterIP in Service "+egName.String(), svc.Spec.ClusterIP) } - var subnets []*net.IPNet - if ip4 := svcIP.To4(); ip4 != nil { - svcIP = ip4 + + var subnets []destination + if svcIP.Is4() { for _, sn := range eg.Spec.Destinations { - _, subnet, err := net.ParseCIDR(sn) + prefix, err := netip.ParsePrefix(sn) if err != nil { - return nil, newInternalError(err, "invalid network in Egress "+n.String()) + return gateway{}, nil, newInternalError(err, "invalid network in Egress "+egName.String()) } - if subnet.IP.To4() != nil { - subnets = append(subnets, subnet) + + if prefix.Addr().Is4() { + subnets = append(subnets, destination(prefix)) } } - } else { + } else if svcIP.Is6() { for _, sn := range eg.Spec.Destinations { - _, subnet, err := net.ParseCIDR(sn) + prefix, err := netip.ParsePrefix(sn) if err != nil { - return nil, newInternalError(err, "invalid network in Egress "+n.String()) + return gateway{}, nil, newInternalError(err, "invalid network in Egress "+egName.String()) } - if subnet.IP.To4() == nil { - subnets = append(subnets, subnet) + + if prefix.Addr().Is6() { + subnets = append(subnets, destination(prefix)) } } + } else { + return gateway{}, []destination{}, errors.New("invalid service ip") } - - if len(subnets) > 0 { - gwlist = append(gwlist, GWNets{Gateway: svcIP, Networks: subnets, SportAuto: eg.Spec.FouSourcePortAuto}) - } - + return gateway(svcIP), subnets, nil } func (s *server) Del(ctx context.Context, args *cnirpc.CNIArgs) (*emptypb.Empty, error) { From a5a4a9f7b4cce5e0a1b8c55110353c80a4154ca3 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Wed, 28 Aug 2024 09:47:15 +0900 Subject: [PATCH 09/36] add pkg/cni Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- internal/ponad/server.go | 4 +++- pkg/cni/cni.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 pkg/cni/cni.go diff --git a/internal/ponad/server.go b/internal/ponad/server.go index e529da5..9f1f347 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -104,13 +104,15 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, nil } + gwToDests := make(gwToDests) for _, egName := range egNames { g, ds, err := s.collectDestinationsForEgress(ctx, egName) if err != nil { return nil, newInternalError(err, "failed to collect destinations for egress") } - + gwToDests[g] = ds } + } func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { diff --git a/pkg/cni/cni.go b/pkg/cni/cni.go new file mode 100644 index 0000000..1380dd7 --- /dev/null +++ b/pkg/cni/cni.go @@ -0,0 +1,33 @@ +package cni + +import ( + "encoding/json" + "fmt" + + "github.com/containernetworking/cni/pkg/types" + "github.com/containernetworking/cni/pkg/version" + "github.com/cybozu-go/pona/pkg/cnirpc" +) + +type PluginConf struct { + types.NetConf + + // Socket contains unix domain socket to communicate with coild + Socket string `json:"socket"` +} + +func ParseConfig(cniargs *cnirpc.CNIArgs) error { + conf := &PluginConf{} + + if err := json.Unmarshal(cniargs.StdinData, conf); err != nil { + return fmt.Errorf("failed to unmarshal NetConf: %w", err) + } + + if err := version.ParsePrevResult(&conf.NetConf); err != nil { + return fmt.Errorf("failed to parse prev result: %w", err) + } + result, err := conf.PrevResult.GetAsVersion(conf.CNIVersion) + if err != nil { + return fmt.Errorf("failed to") + } +} From e3d6b2df63e149dae80477e2b2e800b559167ae1 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Wed, 28 Aug 2024 10:18:30 +0900 Subject: [PATCH 10/36] [WIP] Add Signed-off-by: walnuts1018 --- cmd/ponad/main.go | 2 +- internal/ponad/server.go | 38 ++++++++++++++++++++++++++------- pkg/cni/cni.go | 13 ++++++----- pkg/nat/nat.go | 8 +++---- pkg/tunnel/fou/fou.go | 8 +++---- pkg/util/netiputil/netiputil.go | 10 ++++++++- 6 files changed, 56 insertions(+), 23 deletions(-) diff --git a/cmd/ponad/main.go b/cmd/ponad/main.go index 94c519b..8590474 100644 --- a/cmd/ponad/main.go +++ b/cmd/ponad/main.go @@ -96,7 +96,7 @@ func startPonad(config Config, mgr ctrl.Manager) error { return err } - s := ponad.NewServer(l, mgr.GetAPIReader()) + s := ponad.NewServer(l, mgr.GetAPIReader(), config.egressPort) if err := mgr.Add(s); err != nil { return err } diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 9f1f347..dc304bb 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -11,7 +11,10 @@ import ( ponav1beta1 "github.com/cybozu-go/pona/api/v1beta1" "github.com/cybozu-go/pona/internal/constants" + "github.com/cybozu-go/pona/pkg/cni" "github.com/cybozu-go/pona/pkg/cnirpc" + "github.com/cybozu-go/pona/pkg/tunnel/fou" + "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -54,14 +57,16 @@ func InterceptorLogger(l *slog.Logger) logging.Logger { type server struct { cnirpc.UnimplementedCNIServer - listener net.Listener - apiReader client.Reader + listener net.Listener + apiReader client.Reader + egressPort int } -func NewServer(l net.Listener, r client.Reader) *server { +func NewServer(l net.Listener, r client.Reader, egressPort int) *server { return &server{ - listener: l, - apiReader: r, + listener: l, + apiReader: r, + egressPort: egressPort, } } @@ -104,15 +109,32 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, nil } - gwToDests := make(gwToDests) + p, err := cni.GetPrevResult(args) + if err != nil { + return nil, newInternalError(err, "failed to get previous result") + } + for _, egName := range egNames { g, ds, err := s.collectDestinationsForEgress(ctx, egName) if err != nil { return nil, newInternalError(err, "failed to collect destinations for egress") } - gwToDests[g] = ds - } + var clientIP netip.Addr + for _, ipc := range p.IPs { + ip, ok := netiputil.ToAddr(ipc.Gateway) + if !ok { + return nil, newInternalError(errors.New("failed to parse ip"), "failed to parse ip") + } + + if netiputil.IsFamilyMatched(netip.Addr(g), ip) { + clientIP = ip + break + } + } + + ft, err := fou.NewFoUTunnelController(s.egressPort) + } } func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { diff --git a/pkg/cni/cni.go b/pkg/cni/cni.go index 1380dd7..36cdc88 100644 --- a/pkg/cni/cni.go +++ b/pkg/cni/cni.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/containernetworking/cni/pkg/types" + cni100 "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/cni/pkg/version" "github.com/cybozu-go/pona/pkg/cnirpc" ) @@ -16,18 +17,20 @@ type PluginConf struct { Socket string `json:"socket"` } -func ParseConfig(cniargs *cnirpc.CNIArgs) error { +func GetPrevResult(cniargs *cnirpc.CNIArgs) (*cni100.Result, error) { conf := &PluginConf{} if err := json.Unmarshal(cniargs.StdinData, conf); err != nil { - return fmt.Errorf("failed to unmarshal NetConf: %w", err) + return nil, fmt.Errorf("failed to unmarshal NetConf: %w", err) } if err := version.ParsePrevResult(&conf.NetConf); err != nil { - return fmt.Errorf("failed to parse prev result: %w", err) + return nil, fmt.Errorf("failed to parse prev result: %w", err) } - result, err := conf.PrevResult.GetAsVersion(conf.CNIVersion) + r, err := cni100.GetResult(conf.NetConf.PrevResult) if err != nil { - return fmt.Errorf("failed to") + return nil, fmt.Errorf("failed to get prevresult") } + + return r, nil } diff --git a/pkg/nat/nat.go b/pkg/nat/nat.go index e649cac..d6b46b3 100644 --- a/pkg/nat/nat.go +++ b/pkg/nat/nat.go @@ -70,7 +70,7 @@ func (c *controller) Init() error { if err != nil { return err } - ipn := netlink.NewIPNet(netiputil.ConvNetIP(*c.ipv4)) + ipn := netlink.NewIPNet(netiputil.FromAddr(*c.ipv4)) err = ipt.Append("nat", "POSTROUTING", "!", "-s", ipn.String(), "-o", c.iface, "-j", "MASQUERADE") if err != nil { return fmt.Errorf("failed to setup masquerade rule for IPv4: %w", err) @@ -86,7 +86,7 @@ func (c *controller) Init() error { if err != nil { return err } - ipn := netlink.NewIPNet(netiputil.ConvNetIP(*c.ipv6)) + ipn := netlink.NewIPNet(netiputil.FromAddr(*c.ipv6)) err = ipt.Append("nat", "POSTROUTING", "!", "-s", ipn.String(), "-o", c.iface, "-j", "MASQUERADE") if err != nil { return fmt.Errorf("failed to setup masquerade rule for IPv6: %w", err) @@ -135,7 +135,7 @@ func (c *controller) AddClient(addr netip.Addr, link netlink.Link) error { if r.Dst == nil { continue } - if r.Dst.IP.Equal(netiputil.ConvNetIP(addr)) { + if r.Dst.IP.Equal(netiputil.FromAddr(addr)) { return nil } } @@ -146,7 +146,7 @@ func (c *controller) AddClient(addr netip.Addr, link netlink.Link) error { return fmt.Errorf("netlink: failed to link up %s: %w", link.Attrs().Name, err) } if err := netlink.RouteAdd(&netlink.Route{ - Dst: netlink.NewIPNet(netiputil.ConvNetIP(addr)), + Dst: netlink.NewIPNet(netiputil.FromAddr(addr)), LinkIndex: link.Attrs().Index, Table: egressTableID, Protocol: egressProtocolID, diff --git a/pkg/tunnel/fou/fou.go b/pkg/tunnel/fou/fou.go index bc05773..ec76412 100644 --- a/pkg/tunnel/fou/fou.go +++ b/pkg/tunnel/fou/fou.go @@ -202,8 +202,8 @@ func (t *FouTunnelController) addPeer4(addr netip.Addr) (netlink.Link, error) { EncapType: netlink.FOU_ENCAP_DIRECT, EncapDport: uint16(t.port), EncapSport: 0, // sportauto is always on - Remote: netiputil.ConvNetIP(addr), - Local: netiputil.ConvNetIP(*t.local4), + Remote: netiputil.FromAddr(addr), + Local: netiputil.FromAddr(*t.local4), } if err := netlink.LinkAdd(link); err != nil { return nil, fmt.Errorf("netlink: failed to add fou link: %w", err) @@ -244,8 +244,8 @@ func (t *FouTunnelController) addPeer6(addr netip.Addr) (netlink.Link, error) { EncapType: netlink.FOU_ENCAP_DIRECT, EncapDport: uint16(t.port), EncapSport: 0, // sportauto is always on - Remote: netiputil.ConvNetIP(addr), - Local: netiputil.ConvNetIP(*t.local6), + Remote: netiputil.FromAddr(addr), + Local: netiputil.FromAddr(*t.local6), } if err := netlink.LinkAdd(link); err != nil { return nil, fmt.Errorf("netlink: failed to add fou link: %w", err) diff --git a/pkg/util/netiputil/netiputil.go b/pkg/util/netiputil/netiputil.go index 5f78955..113eb86 100644 --- a/pkg/util/netiputil/netiputil.go +++ b/pkg/util/netiputil/netiputil.go @@ -5,6 +5,14 @@ import ( "net/netip" ) -func ConvNetIP(addr netip.Addr) net.IP { +func FromAddr(addr netip.Addr) net.IP { return net.IP(addr.AsSlice()) } + +func ToAddr(ip net.IP) (netip.Addr, bool) { + return netip.AddrFromSlice(ip) +} + +func IsFamilyMatched(a, b netip.Addr) bool { + return (a.Is4() && b.Is4()) || (a.Is6() && b.Is6()) +} From ebbc3f70fe138b0158ae02bed979a5ca60232f2b Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Wed, 28 Aug 2024 10:53:18 +0900 Subject: [PATCH 11/36] [WIP] add nat client Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- cmd/nat-gateway/main.go | 2 +- internal/controller/pod_watcher.go | 4 ++-- internal/ponad/server.go | 18 +++++++++++++----- pkg/nat/client.go | 5 +++++ pkg/nat/{nat.go => gateway.go} | 14 +++++++------- pkg/tunnel/fou/fou.go | 3 +++ pkg/tunnel/tunnel.go | 1 + 7 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 pkg/nat/client.go rename pkg/nat/{nat.go => gateway.go} (92%) diff --git a/cmd/nat-gateway/main.go b/cmd/nat-gateway/main.go index d267bbb..8f6cd6c 100644 --- a/cmd/nat-gateway/main.go +++ b/cmd/nat-gateway/main.go @@ -185,7 +185,7 @@ func main() { setupLog.Error(err, "failed to Initialize FoUTunnelController") os.Exit(1) } - nc, err := nat.NewController("eth0", ipv4, ipv6) + nc, err := nat.NewGateway("eth0", ipv4, ipv6) if err != nil { setupLog.Error(err, "unable to create nat.Controller") os.Exit(1) diff --git a/internal/controller/pod_watcher.go b/internal/controller/pod_watcher.go index e3e677f..10c44b2 100644 --- a/internal/controller/pod_watcher.go +++ b/internal/controller/pod_watcher.go @@ -35,12 +35,12 @@ type PodWatcher struct { podIPToPod map[netip.Addr]Set[types.NamespacedName] tun tunnel.Controller - nat nat.Controller + nat nat.Gateway } type Set[T comparable] map[T]struct{} -func NewPodWatcher(client client.Client, scheme *runtime.Scheme, egressName, egressNamespace string, t tunnel.Controller, n nat.Controller) *PodWatcher { +func NewPodWatcher(client client.Client, scheme *runtime.Scheme, egressName, egressNamespace string, t tunnel.Controller, n nat.Gateway) *PodWatcher { return &PodWatcher{ Client: client, Scheme: scheme, diff --git a/internal/ponad/server.go b/internal/ponad/server.go index dc304bb..b3495ed 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -120,20 +120,28 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, newInternalError(err, "failed to collect destinations for egress") } - var clientIP netip.Addr + var local4, local6 *netip.Addr for _, ipc := range p.IPs { ip, ok := netiputil.ToAddr(ipc.Gateway) if !ok { return nil, newInternalError(errors.New("failed to parse ip"), "failed to parse ip") } - if netiputil.IsFamilyMatched(netip.Addr(g), ip) { - clientIP = ip - break + if local4 == nil && ip.Is4() { + local4 = &ip + } + if local6 == nil && ip.Is6() { + local6 = &ip } } - ft, err := fou.NewFoUTunnelController(s.egressPort) + ft, err := fou.NewFoUTunnelController(s.egressPort, local4, local6) + if err != nil { + return nil, newInternalError(err, "failed to create FoUTunnelController") + } + if err := ft.Init(); err != nil { + return nil, newInternalError(err, "failed to initialize FoUTunnel") + } } } diff --git a/pkg/nat/client.go b/pkg/nat/client.go new file mode 100644 index 0000000..6f336b3 --- /dev/null +++ b/pkg/nat/client.go @@ -0,0 +1,5 @@ +package nat + +// Client configures routes for NAT Gateway +type Client interface { +} diff --git a/pkg/nat/nat.go b/pkg/nat/gateway.go similarity index 92% rename from pkg/nat/nat.go rename to pkg/nat/gateway.go index d6b46b3..c8653de 100644 --- a/pkg/nat/nat.go +++ b/pkg/nat/gateway.go @@ -18,12 +18,12 @@ const ( egressDummy = "nat-dummy" ) -type Controller interface { +type Gateway interface { Init() error AddClient(netip.Addr, netlink.Link) error } -type controller struct { +type gateway struct { iface string ipv4 *netip.Addr ipv6 *netip.Addr @@ -31,7 +31,7 @@ type controller struct { var ErrIPFamilyMismatch = errors.New("no matching IP family") -func NewController(iface string, ipv4, ipv6 *netip.Addr) (Controller, error) { +func NewGateway(iface string, ipv4, ipv6 *netip.Addr) (Gateway, error) { if ipv4 != nil && !ipv4.Is4() { return nil, fmt.Errorf("invalid IPv4 address, ip=%s", ipv4.String()) } @@ -39,14 +39,14 @@ func NewController(iface string, ipv4, ipv6 *netip.Addr) (Controller, error) { return nil, fmt.Errorf("invalid IPv6 address, ip=%s", ipv6.String()) } - return &controller{ + return &gateway{ iface: iface, ipv4: ipv4, ipv6: ipv6, }, nil } -func (c *controller) newRule(family int) *netlink.Rule { +func (c *gateway) newRule(family int) *netlink.Rule { r := netlink.NewRule() r.Family = family r.IifName = c.iface @@ -55,7 +55,7 @@ func (c *controller) newRule(family int) *netlink.Rule { return r } -func (c *controller) Init() error { +func (c *gateway) Init() error { // avoid double initialization in case the program restarts _, err := netlink.LinkByName(egressDummy) if err == nil { @@ -107,7 +107,7 @@ func (c *controller) Init() error { return nil } -func (c *controller) AddClient(addr netip.Addr, link netlink.Link) error { +func (c *gateway) AddClient(addr netip.Addr, link netlink.Link) error { // Note: // The following checks are not necessary in fact because, // prior to this point, the support for the IP family is tested diff --git a/pkg/tunnel/fou/fou.go b/pkg/tunnel/fou/fou.go index ec76412..9119162 100644 --- a/pkg/tunnel/fou/fou.go +++ b/pkg/tunnel/fou/fou.go @@ -70,6 +70,9 @@ func NewFoUTunnelController(port int, localIPv4, localIPv6 *netip.Addr) (*FouTun if localIPv6 != nil && !localIPv6.Is6() { return nil, tunnel.ErrIPFamilyMismatch } + if localIPv4 == nil && localIPv6 == nil { + return nil, tunnel.ErrNoIPProvided + } return &FouTunnelController{ port: port, local4: localIPv4, diff --git a/pkg/tunnel/tunnel.go b/pkg/tunnel/tunnel.go index be3d3fb..840b2aa 100644 --- a/pkg/tunnel/tunnel.go +++ b/pkg/tunnel/tunnel.go @@ -24,3 +24,4 @@ type Controller interface { } var ErrIPFamilyMismatch = errors.New("no matching IP family") +var ErrNoIPProvided = errors.New("both of IPs are nil") From ee3d11350e67d1f444865fc75ba01d42ca5aea6b Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Wed, 28 Aug 2024 11:28:08 +0900 Subject: [PATCH 12/36] [WIP] nc Signed-off-by: walnuts1018 --- pkg/nat/client.go | 176 ++++++++++++++++++++++++++++++++ pkg/util/netiputil/netiputil.go | 5 + 2 files changed, 181 insertions(+) diff --git a/pkg/nat/client.go b/pkg/nat/client.go index 6f336b3..a9802ed 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -1,5 +1,181 @@ package nat +import ( + "errors" + "fmt" + "net" + "net/netip" + "sync" + + "github.com/vishvananda/netlink" +) + +// IDs +const ( + ncProtocolID = 30 + + ncTableID = 117 + mainTableID = 254 +) + +// rule priorities +const ( + ncPrio = 1900 +) + +// special subnets +var ( + v4PrivateList = []netip.Prefix{ + netip.MustParsePrefix("10.0.0.0/8"), + netip.MustParsePrefix("172.16.0.0/32"), + netip.MustParsePrefix("192.168.0.0/16"), + } + + v6PrivateList = []netip.Prefix{ + netip.MustParsePrefix("fc00::/7"), + } + + v4LinkLocal = netip.MustParsePrefix("169.254.0.0/16") + v6LinkLocal = netip.MustParsePrefix("fe80::/10") + + v4DefaultGW = netip.MustParsePrefix("0.0.0.0/0") + v6DefaultGW = netip.MustParsePrefix("::/0") +) + // Client configures routes for NAT Gateway type Client interface { + Init() error + IsInitialized() (bool, error) + AddEgress(link netlink.Link, subnets []netip.Prefix) error +} + +type natClient struct { + ipv4 bool + ipv6 bool + + v4priv []*netip.Prefix + v6priv []*netip.Prefix + + mu sync.Mutex +} + +func NewNatClient(ipv4, ipv6 netip.Addr, podNodeNet []netip.Prefix) (Client, error) { + if !ipv4.Is4() { + return nil, errors.New("invalid ipv4 address") + } + if !ipv6.Is6() { + return nil, errors.New("invalid ipv6 address") + } + + var v4priv, v6priv []netip.Prefix + if len(podNodeNet) > 0 { + for _, n := range podNodeNet { + if n.Addr().Is4() { + v4priv = append(v4priv, n) + } else if n.Addr().Is6() { + v6priv = append(v6priv, n) + } + } + } else { + v4priv = v4PrivateList + v6priv = v6PrivateList + } + + return &natClient{ + ipv4: ipv4 != nil, + ipv6: ipv6 != nil, + + v4priv: v4priv, + v6priv: v4priv, + }, nil +} + +func newRuleForClient(family, table, prio int) *netlink.Rule { + r := netlink.NewRule() + r.Family = family + r.Table = table + r.Priority = prio + return r +} + +func (c *natClient) clear(family int) error { + var defaultGW netip.Prefix + if family == netlink.FAMILY_V4 { + defaultGW = v4DefaultGW + } else { + defaultGW = v6DefaultGW + } + + rules, err := netlink.RuleList(family) + if err != nil { + return fmt.Errorf("netlink: rule list failed: %w", err) + } + for _, r := range rules { + if r.Priority != ncPrio { + continue + } + if r.Dst == nil { + // workaround for a library issue + r.Dst = net.IPNet + defaultGW + } + if err := netlink.RuleDel(&r); err != nil { + return fmt.Errorf("netlink: failed to delete a rule: %+v, %w", r, err) + } + } + + routes, err := netlink.RouteListFiltered(family, &netlink.Route{Table: ncNarrowTableID}, netlink.RT_FILTER_TABLE) + if err != nil { + return fmt.Errorf("netlink: route list failed: %w", err) + } + for _, r := range routes { + if r.Dst == nil { + // workaround for a library issue + r.Dst = defaultGW + } + if err := netlink.RouteDel(&r); err != nil { + return fmt.Errorf("netlink: failed to delete a route in table %d: %+v, %w", ncNarrowTableID, r, err) + } + } + + routes, err = netlink.RouteListFiltered(family, &netlink.Route{Table: ncWideTableID}, netlink.RT_FILTER_TABLE) + if err != nil { + return fmt.Errorf("netlink: route list failed: %w", err) + } + for _, r := range routes { + if r.Dst == nil { + // workaround for a library issue + r.Dst = defaultGW + } + if err := netlink.RouteDel(&r); err != nil { + return fmt.Errorf("netlink: failed to delete a route in table %d: %+v, %w", ncWideTableID, r, err) + } + } + + return nil +} + +func (c *natClient) Init() error { + if c.ipv4 { + if err := c.clear(netlink.FAMILY_V4); err != nil { + return err + } + rule := newRuleForClient(netlink.FAMILY_V4, ncTableID, ncPrio) + if err := netlink.RuleAdd(rule); err != nil { + return fmt.Errorf("netlink: failed to add v4 natclient rule: %w", err) + } + } + + if c.ipv6 { + if err := c.clear(netlink.FAMILY_V6); err != nil { + return err + } + + rule := newRuleForClient(netlink.FAMILY_V6, ncTableID, ncPrio) + if err := netlink.RuleAdd(rule); err != nil { + return fmt.Errorf("netlink: failed to add v6 natclient rule: %w", err) + } + } + + return nil } diff --git a/pkg/util/netiputil/netiputil.go b/pkg/util/netiputil/netiputil.go index 113eb86..2ad97c3 100644 --- a/pkg/util/netiputil/netiputil.go +++ b/pkg/util/netiputil/netiputil.go @@ -16,3 +16,8 @@ func ToAddr(ip net.IP) (netip.Addr, bool) { func IsFamilyMatched(a, b netip.Addr) bool { return (a.Is4() && b.Is4()) || (a.Is6() && b.Is6()) } + +func ToIPNet(prefix netip.Prefix) net.IPNet { + ip := FromAddr(prefix.Addr()) + return net.IPNet{IP: ip, Mask: net.CIDRMask(prefix.Bits(), prefix.Addr().BitLen())} +} From ab0840b5a3568d02c3fa467eacd2550f037ef9a9 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:37:29 +0900 Subject: [PATCH 13/36] [WIP] implement updateroutes Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- pkg/nat/client.go | 111 +++++++++++++++++++++++++------- pkg/util/netiputil/netiputil.go | 8 +++ 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/pkg/nat/client.go b/pkg/nat/client.go index a9802ed..27047a0 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -3,10 +3,12 @@ package nat import ( "errors" "fmt" - "net" + "maps" "net/netip" + "slices" "sync" + "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/vishvananda/netlink" ) @@ -46,7 +48,7 @@ var ( type Client interface { Init() error IsInitialized() (bool, error) - AddEgress(link netlink.Link, subnets []netip.Prefix) error + UpdateRoutes(link netlink.Link, subnets []netip.Prefix) error } type natClient struct { @@ -116,42 +118,28 @@ func (c *natClient) clear(family int) error { } if r.Dst == nil { // workaround for a library issue - r.Dst = net.IPNet - defaultGW + n := netiputil.ToIPNet(defaultGW) + r.Dst = &n } if err := netlink.RuleDel(&r); err != nil { return fmt.Errorf("netlink: failed to delete a rule: %+v, %w", r, err) } } - routes, err := netlink.RouteListFiltered(family, &netlink.Route{Table: ncNarrowTableID}, netlink.RT_FILTER_TABLE) + routes, err := netlink.RouteListFiltered(family, &netlink.Route{Table: ncTableID}, netlink.RT_FILTER_TABLE) if err != nil { return fmt.Errorf("netlink: route list failed: %w", err) } for _, r := range routes { if r.Dst == nil { // workaround for a library issue - r.Dst = defaultGW + n := netiputil.ToIPNet(defaultGW) + r.Dst = &n } if err := netlink.RouteDel(&r); err != nil { - return fmt.Errorf("netlink: failed to delete a route in table %d: %+v, %w", ncNarrowTableID, r, err) + return fmt.Errorf("netlink: failed to delete a route in table %d: %+v, %w", ncTableID, r, err) } } - - routes, err = netlink.RouteListFiltered(family, &netlink.Route{Table: ncWideTableID}, netlink.RT_FILTER_TABLE) - if err != nil { - return fmt.Errorf("netlink: route list failed: %w", err) - } - for _, r := range routes { - if r.Dst == nil { - // workaround for a library issue - r.Dst = defaultGW - } - if err := netlink.RouteDel(&r); err != nil { - return fmt.Errorf("netlink: failed to delete a route in table %d: %+v, %w", ncWideTableID, r, err) - } - } - return nil } @@ -176,6 +164,83 @@ func (c *natClient) Init() error { return fmt.Errorf("netlink: failed to add v6 natclient rule: %w", err) } } - return nil } + +func (c *natClient) IsInitialized() (bool, error) { + if c.ipv4 { + // check whether exact one rule exists + rules, err := netlink.RuleListFiltered(netlink.FAMILY_V4, &netlink.Rule{Table: ncTableID}, netlink.RT_FILTER_TABLE) + if err != nil { + return false, fmt.Errorf("netlink: failed to list v4 rule: %w", err) + } + if len(rules) != 1 { + return false, nil + } + return true, nil + } + if c.ipv6 { + // check whether exact one rule exists + rules, err := netlink.RuleListFiltered(netlink.FAMILY_V6, &netlink.Rule{Table: ncTableID}, netlink.RT_FILTER_TABLE) + if err != nil { + return false, fmt.Errorf("netlink: failed to list v6 rule: %w", err) + } + if len(rules) != 1 { + return false, nil + } + return true, nil + } + return true, nil +} + +func (c *natClient) UpdateRoutes(link netlink.Link, subnets []netip.Prefix) error { + routes, err := collectRoutes(link.Attrs().Index) + if err != nil { + return fmt.Errorf("failed to collect routes: %w", err) + } + + var adds []netip.Prefix + var dels []netip.Prefix + + for _, n := range subnets { + if _, ok := routes[n]; !ok { + adds = append(adds, n) + } + } + + slices.DeleteFunc(routes, func(p netip.Prefix) bool { + + }) +} + +func collectRoutes(linkIndex int) (map[netip.Prefix]netlink.Route, error) { + r4, err := collectRoute1(linkIndex, netlink.FAMILY_V4) + if err != nil { + return nil, fmt.Errorf("failed to collect routes: %w", err) + } + r6, err := collectRoute1(linkIndex, netlink.FAMILY_V6) + if err != nil { + return nil, fmt.Errorf("failed to collect routes: %w", err) + } + maps.Copy(r4, r6) + return r4, nil +} + +func collectRoute1(linkIndex, family int) (map[netip.Prefix]netlink.Route, error) { + routes := make(map[netip.Prefix]netlink.Route) + + ro, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{Table: ncTableID}, netlink.RT_FILTER_TABLE) + if err != nil { + return nil, fmt.Errorf("netlink: failed to list v4 routes: %w", err) + } + for _, r := range ro { + if r.LinkIndex == linkIndex && r.Dst != nil { + d, ok := netiputil.FromIPNet(*r.Dst) + if !ok { + return nil, fmt.Errorf("failed to convert to netip.Addr from net.IP: %w", err) + } + routes[d] = r + } + } + return routes, nil +} diff --git a/pkg/util/netiputil/netiputil.go b/pkg/util/netiputil/netiputil.go index 2ad97c3..42cc89c 100644 --- a/pkg/util/netiputil/netiputil.go +++ b/pkg/util/netiputil/netiputil.go @@ -21,3 +21,11 @@ func ToIPNet(prefix netip.Prefix) net.IPNet { ip := FromAddr(prefix.Addr()) return net.IPNet{IP: ip, Mask: net.CIDRMask(prefix.Bits(), prefix.Addr().BitLen())} } +func FromIPNet(from net.IPNet) (to netip.Prefix, ok bool) { + ip, ok := ToAddr(from.IP) + if !ok { + return netip.Prefix{}, false + } + ones, _ := from.Mask.Size() + return netip.PrefixFrom(ip, ones), true +} From e865a5c036342d273806f4e7a29a0ad925f78456 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Wed, 28 Aug 2024 15:10:38 +0900 Subject: [PATCH 14/36] [WIP] UpdateRoutes Signed-off-by: walnuts1018 --- pkg/nat/client.go | 117 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 106 insertions(+), 11 deletions(-) diff --git a/pkg/nat/client.go b/pkg/nat/client.go index 27047a0..38d91eb 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -5,11 +5,11 @@ import ( "fmt" "maps" "net/netip" - "slices" "sync" "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/vishvananda/netlink" + "golang.org/x/sys/unix" ) // IDs @@ -55,20 +55,25 @@ type natClient struct { ipv4 bool ipv6 bool - v4priv []*netip.Prefix - v6priv []*netip.Prefix + v4priv []netip.Prefix + v6priv []netip.Prefix mu sync.Mutex } -func NewNatClient(ipv4, ipv6 netip.Addr, podNodeNet []netip.Prefix) (Client, error) { - if !ipv4.Is4() { +func NewNatClient(ipv4, ipv6 *netip.Addr, podNodeNet []netip.Prefix) (Client, error) { + if ipv4 != nil && !ipv4.Is4() { return nil, errors.New("invalid ipv4 address") } - if !ipv6.Is6() { + + if ipv6 != nil && !ipv6.Is6() { return nil, errors.New("invalid ipv6 address") } + if ipv4 == nil && ipv6 == nil { + return nil, errors.New("invalid arguments") + } + var v4priv, v6priv []netip.Prefix if len(podNodeNet) > 0 { for _, n := range podNodeNet { @@ -194,23 +199,46 @@ func (c *natClient) IsInitialized() (bool, error) { } func (c *natClient) UpdateRoutes(link netlink.Link, subnets []netip.Prefix) error { - routes, err := collectRoutes(link.Attrs().Index) + current, err := collectRoutes(link.Attrs().Index) if err != nil { return fmt.Errorf("failed to collect routes: %w", err) } var adds []netip.Prefix - var dels []netip.Prefix + var dels []netlink.Route for _, n := range subnets { - if _, ok := routes[n]; !ok { + if _, ok := current[n]; !ok { adds = append(adds, n) } } - slices.DeleteFunc(routes, func(p netip.Prefix) bool { + subnetsSet := subnetsSet(subnets) + for subnet, route := range current { + if _, ok := subnetsSet[subnet]; !ok { + dels = append(dels, route) + } + } + + // link up here to minimize the down time + // See https://github.com/cybozu-go/coil/issues/287. + if err := netlink.LinkSetUp(link); err != nil { + return fmt.Errorf("netlink: failed to link up %s: %w", link.Attrs().Name, err) + } + + for _, v := range v4PrivateList { + c.addThrow(link, v) + } + for _, v := range v6PrivateList { + c.addThrow(link, v) + } + + for _, n := range adds { + if err := c.addRoute(link, n); err != nil { + return err + } + } - }) } func collectRoutes(linkIndex int) (map[netip.Prefix]netlink.Route, error) { @@ -244,3 +272,70 @@ func collectRoute1(linkIndex, family int) (map[netip.Prefix]netlink.Route, error } return routes, nil } + +func subnetsSet(subnets []netip.Prefix) map[netip.Prefix]struct{} { + subnetsSet := make(map[netip.Prefix]struct{}) + for _, subnet := range subnets { + subnetsSet[subnet] = struct{}{} + } + return subnetsSet +} + +func (c *natClient) addThrow(link netlink.Link, n netip.Prefix) error { + dst := netiputil.ToIPNet(n) + err := netlink.RouteAdd(&netlink.Route{ + Table: ncTableID, + Dst: &dst, + Type: unix.RTN_THROW, + LinkIndex: link.Attrs().Index, + Protocol: ncProtocolID, + }) + if err != nil { + return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncTableID, n.String(), err) + } + + return nil +} + +func (c *natClient) addRoute(link netlink.Link, n netip.Prefix) error { + var priv []netip.Prefix + if n.Addr().Is4() { + if !c.ipv4 { + return nil + } + priv = c.v4priv + } else { + if !c.ipv6 { + return nil + } + priv = c.v6priv + } + + for _, p := range priv { + if !p.Contains(n.IP) { + continue + } + + err := netlink.RouteAdd(&netlink.Route{ + Table: ncNarrowTableID, + Dst: n, + LinkIndex: link.Attrs().Index, + Protocol: ncProtocolID, + }) + if err != nil { + return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncNarrowTableID, n.String(), err) + } + return nil + } + + err := netlink.RouteAdd(&netlink.Route{ + Table: ncWideTableID, + Dst: n, + LinkIndex: link.Attrs().Index, + Protocol: ncProtocolID, + }) + if err != nil { + return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncWideTableID, n.String(), err) + } + return nil +} From 61977a773f90ff13503af5ade9f6ad47424e7e23 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Wed, 28 Aug 2024 15:37:17 +0900 Subject: [PATCH 15/36] implemented nat client Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- internal/ponad/server.go | 57 +++++++++++-------- pkg/nat/client.go | 119 +++++++++++---------------------------- 2 files changed, 68 insertions(+), 108 deletions(-) diff --git a/internal/ponad/server.go b/internal/ponad/server.go index b3495ed..d224dff 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -13,6 +13,7 @@ import ( "github.com/cybozu-go/pona/internal/constants" "github.com/cybozu-go/pona/pkg/cni" "github.com/cybozu-go/pona/pkg/cnirpc" + "github.com/cybozu-go/pona/pkg/nat" "github.com/cybozu-go/pona/pkg/tunnel/fou" "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" @@ -114,34 +115,46 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, newInternalError(err, "failed to get previous result") } + var local4, local6 *netip.Addr + for _, ipc := range p.IPs { + ip, ok := netiputil.ToAddr(ipc.Gateway) + if !ok { + return nil, newInternalError(errors.New("failed to parse ip"), "failed to parse ip") + } + if local4 == nil && ip.Is4() { + local4 = &ip + } + if local6 == nil && ip.Is6() { + local6 = &ip + } + } + + ft, err := fou.NewFoUTunnelController(s.egressPort, local4, local6) + if err != nil { + return nil, newInternalError(err, "failed to create FoUTunnelController") + } + if err := ft.Init(); err != nil { + return nil, newInternalError(err, "failed to initialize FoUTunnel") + } + nt, err := nat.NewNatClient(local4 != nil, local6 != nil) + if err != nil { + return nil, newInternalError(err, "failed to create Nat client") + } + if err := nt.Init(); err != nil { + return nil, newInternalError(err, "failed to initialize Nat client") + } + for _, egName := range egNames { g, ds, err := s.collectDestinationsForEgress(ctx, egName) if err != nil { return nil, newInternalError(err, "failed to collect destinations for egress") } - var local4, local6 *netip.Addr - for _, ipc := range p.IPs { - ip, ok := netiputil.ToAddr(ipc.Gateway) - if !ok { - return nil, newInternalError(errors.New("failed to parse ip"), "failed to parse ip") - } - - if local4 == nil && ip.Is4() { - local4 = &ip - } - if local6 == nil && ip.Is6() { - local6 = &ip - } - } - - ft, err := fou.NewFoUTunnelController(s.egressPort, local4, local6) + link, err := ft.AddPeer(netip.Addr(g)) if err != nil { - return nil, newInternalError(err, "failed to create FoUTunnelController") - } - if err := ft.Init(); err != nil { - return nil, newInternalError(err, "failed to initialize FoUTunnel") + return nil, newInternalError(err, fmt.Sprintf("failed to add peer for %v", g)) } + nt.UpdateRoutes(link, []netip.Addr(ds)) } } @@ -167,9 +180,7 @@ func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { return egNames, nil } -type gateway netip.Addr -type destination netip.Prefix -type gwToDests map[gateway][]destination +type gwToDests map[netip.Addr][]netip.Prefix func (s *server) collectDestinationsForEgress(ctx context.Context, egName client.ObjectKey) (gateway, []destination, error) { eg := &ponav1beta1.Egress{} diff --git a/pkg/nat/client.go b/pkg/nat/client.go index 38d91eb..9e170c3 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -1,11 +1,10 @@ package nat import ( - "errors" "fmt" "maps" "net/netip" - "sync" + "slices" "github.com/cybozu-go/pona/pkg/util/netiputil" "github.com/vishvananda/netlink" @@ -18,6 +17,8 @@ const ( ncTableID = 117 mainTableID = 254 + throwMetric = 500 + routeMetric = 100 ) // rule priorities @@ -52,48 +53,14 @@ type Client interface { } type natClient struct { - ipv4 bool - ipv6 bool - - v4priv []netip.Prefix - v6priv []netip.Prefix - - mu sync.Mutex + useipv4 bool + useipv6 bool } -func NewNatClient(ipv4, ipv6 *netip.Addr, podNodeNet []netip.Prefix) (Client, error) { - if ipv4 != nil && !ipv4.Is4() { - return nil, errors.New("invalid ipv4 address") - } - - if ipv6 != nil && !ipv6.Is6() { - return nil, errors.New("invalid ipv6 address") - } - - if ipv4 == nil && ipv6 == nil { - return nil, errors.New("invalid arguments") - } - - var v4priv, v6priv []netip.Prefix - if len(podNodeNet) > 0 { - for _, n := range podNodeNet { - if n.Addr().Is4() { - v4priv = append(v4priv, n) - } else if n.Addr().Is6() { - v6priv = append(v6priv, n) - } - } - } else { - v4priv = v4PrivateList - v6priv = v6PrivateList - } - +func NewNatClient(useipv4, useipv6 bool) (Client, error) { return &natClient{ - ipv4: ipv4 != nil, - ipv6: ipv6 != nil, - - v4priv: v4priv, - v6priv: v4priv, + useipv4: useipv4, + useipv6: useipv6, }, nil } @@ -149,7 +116,7 @@ func (c *natClient) clear(family int) error { } func (c *natClient) Init() error { - if c.ipv4 { + if c.useipv4 { if err := c.clear(netlink.FAMILY_V4); err != nil { return err } @@ -159,7 +126,7 @@ func (c *natClient) Init() error { } } - if c.ipv6 { + if c.useipv6 { if err := c.clear(netlink.FAMILY_V6); err != nil { return err } @@ -173,7 +140,7 @@ func (c *natClient) Init() error { } func (c *natClient) IsInitialized() (bool, error) { - if c.ipv4 { + if c.useipv4 { // check whether exact one rule exists rules, err := netlink.RuleListFiltered(netlink.FAMILY_V4, &netlink.Rule{Table: ncTableID}, netlink.RT_FILTER_TABLE) if err != nil { @@ -184,7 +151,7 @@ func (c *natClient) IsInitialized() (bool, error) { } return true, nil } - if c.ipv6 { + if c.useipv6 { // check whether exact one rule exists rules, err := netlink.RuleListFiltered(netlink.FAMILY_V6, &netlink.Rule{Table: ncTableID}, netlink.RT_FILTER_TABLE) if err != nil { @@ -226,19 +193,23 @@ func (c *natClient) UpdateRoutes(link netlink.Link, subnets []netip.Prefix) erro return fmt.Errorf("netlink: failed to link up %s: %w", link.Attrs().Name, err) } - for _, v := range v4PrivateList { - c.addThrow(link, v) - } - for _, v := range v6PrivateList { + for _, v := range slices.Concat(v4PrivateList, v6PrivateList, + []netip.Prefix{v4LinkLocal, v6LinkLocal}, + ) { c.addThrow(link, v) } - for _, n := range adds { - if err := c.addRoute(link, n); err != nil { + for _, r := range adds { + if err := c.addRoute(link, r); err != nil { return err } } - + for _, r := range dels { + if err := c.delRoute(r); err != nil { + return err + } + } + return nil } func collectRoutes(linkIndex int) (map[netip.Prefix]netlink.Route, error) { @@ -257,7 +228,7 @@ func collectRoutes(linkIndex int) (map[netip.Prefix]netlink.Route, error) { func collectRoute1(linkIndex, family int) (map[netip.Prefix]netlink.Route, error) { routes := make(map[netip.Prefix]netlink.Route) - ro, err := netlink.RouteListFiltered(netlink.FAMILY_V4, &netlink.Route{Table: ncTableID}, netlink.RT_FILTER_TABLE) + ro, err := netlink.RouteListFiltered(family, &netlink.Route{Table: ncTableID}, netlink.RT_FILTER_TABLE) if err != nil { return nil, fmt.Errorf("netlink: failed to list v4 routes: %w", err) } @@ -289,6 +260,7 @@ func (c *natClient) addThrow(link netlink.Link, n netip.Prefix) error { Type: unix.RTN_THROW, LinkIndex: link.Attrs().Index, Protocol: ncProtocolID, + Priority: throwMetric, }) if err != nil { return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncTableID, n.String(), err) @@ -298,44 +270,21 @@ func (c *natClient) addThrow(link netlink.Link, n netip.Prefix) error { } func (c *natClient) addRoute(link netlink.Link, n netip.Prefix) error { - var priv []netip.Prefix - if n.Addr().Is4() { - if !c.ipv4 { - return nil - } - priv = c.v4priv - } else { - if !c.ipv6 { - return nil - } - priv = c.v6priv - } - - for _, p := range priv { - if !p.Contains(n.IP) { - continue - } - - err := netlink.RouteAdd(&netlink.Route{ - Table: ncNarrowTableID, - Dst: n, - LinkIndex: link.Attrs().Index, - Protocol: ncProtocolID, - }) - if err != nil { - return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncNarrowTableID, n.String(), err) - } - return nil - } + a := netiputil.ToIPNet(n) err := netlink.RouteAdd(&netlink.Route{ - Table: ncWideTableID, - Dst: n, + Table: ncTableID, + Dst: &a, LinkIndex: link.Attrs().Index, Protocol: ncProtocolID, + Priority: routeMetric, }) if err != nil { - return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncWideTableID, n.String(), err) + return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncTableID, n.String(), err) } return nil } + +func (c *natClient) delRoute(n netlink.Route) error { + return netlink.RouteDel(&n) +} From 5aeadc92d1383f9bcb7b05e9ecf8bc4645732353 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Wed, 28 Aug 2024 15:54:04 +0900 Subject: [PATCH 16/36] implement Add Signed-off-by: walnuts1018 --- internal/ponad/server.go | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/internal/ponad/server.go b/internal/ponad/server.go index d224dff..3d9c9f4 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -2,6 +2,7 @@ package ponad import ( "context" + "encoding/json" "errors" "fmt" "log/slog" @@ -154,8 +155,17 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp if err != nil { return nil, newInternalError(err, fmt.Sprintf("failed to add peer for %v", g)) } - nt.UpdateRoutes(link, []netip.Addr(ds)) + if err := nt.UpdateRoutes(link, ds); err != nil { + return nil, newInternalError(err, "failed to update routes") + } + } + + b, err := json.Marshal(p) + if err != nil { + return nil, newInternalError(err, "failed to marshal result") } + + return &cnirpc.AddResponse{Result: b}, nil } func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { @@ -180,19 +190,17 @@ func (s *server) listEgress(pod *corev1.Pod) ([]client.ObjectKey, error) { return egNames, nil } -type gwToDests map[netip.Addr][]netip.Prefix - -func (s *server) collectDestinationsForEgress(ctx context.Context, egName client.ObjectKey) (gateway, []destination, error) { +func (s *server) collectDestinationsForEgress(ctx context.Context, egName client.ObjectKey) (netip.Addr, []netip.Prefix, error) { eg := &ponav1beta1.Egress{} svc := &corev1.Service{} if err := s.apiReader.Get(ctx, egName, eg); err != nil { - return gateway{}, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, + return netip.Addr{}, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, "failed to get Egress "+egName.String(), err.Error()) } if err := s.apiReader.Get(ctx, egName, svc); err != nil { - return gateway{}, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, + return netip.Addr{}, nil, newError(codes.FailedPrecondition, cnirpc.ErrorCode_INTERNAL, "failed to get Service "+egName.String(), err.Error()) } @@ -200,43 +208,43 @@ func (s *server) collectDestinationsForEgress(ctx context.Context, egName client // https://kubernetes.io/docs/concepts/services-networking/dual-stack/ svcIP, err := netip.ParseAddr(svc.Spec.ClusterIP) if err != nil { - return gateway{}, nil, newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, + return netip.Addr{}, nil, newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, "invalid ClusterIP in Service "+egName.String(), svc.Spec.ClusterIP) } - var subnets []destination + var subnets []netip.Prefix if svcIP.Is4() { for _, sn := range eg.Spec.Destinations { prefix, err := netip.ParsePrefix(sn) if err != nil { - return gateway{}, nil, newInternalError(err, "invalid network in Egress "+egName.String()) + return netip.Addr{}, nil, newInternalError(err, "invalid network in Egress "+egName.String()) } if prefix.Addr().Is4() { - subnets = append(subnets, destination(prefix)) + subnets = append(subnets, prefix) } } } else if svcIP.Is6() { for _, sn := range eg.Spec.Destinations { prefix, err := netip.ParsePrefix(sn) if err != nil { - return gateway{}, nil, newInternalError(err, "invalid network in Egress "+egName.String()) + return netip.Addr{}, nil, newInternalError(err, "invalid network in Egress "+egName.String()) } if prefix.Addr().Is6() { - subnets = append(subnets, destination(prefix)) + subnets = append(subnets, prefix) } } } else { - return gateway{}, []destination{}, errors.New("invalid service ip") + return netip.Addr{}, []netip.Prefix{}, errors.New("invalid service ip") } - return gateway(svcIP), subnets, nil + return svcIP, subnets, nil } func (s *server) Del(ctx context.Context, args *cnirpc.CNIArgs) (*emptypb.Empty, error) { - + return nil, nil } func (s *server) Check(ctx context.Context, args *cnirpc.CNIArgs) (*emptypb.Empty, error) { - + return nil, nil } From 3e7872e3d2ef5946b03c61cc928bbb99019ae2de Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Wed, 28 Aug 2024 16:02:02 +0900 Subject: [PATCH 17/36] [WIP] add pona cni Signed-off-by: walnuts1018 --- cmd/pona/main.go | 19 ++++++++++++++ go.mod | 6 ++--- go.sum | 64 ++---------------------------------------------- version.go | 5 ++++ 4 files changed, 29 insertions(+), 65 deletions(-) create mode 100644 cmd/pona/main.go create mode 100644 version.go diff --git a/cmd/pona/main.go b/cmd/pona/main.go new file mode 100644 index 0000000..cc5b9a9 --- /dev/null +++ b/cmd/pona/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "fmt" + + "github.com/containernetworking/cni/pkg/skel" + "github.com/containernetworking/cni/pkg/version" + "github.com/cybozu-go/pona" +) + +func cmdAdd(args *skel.CmdArgs) error + +func cmdDel(args *skel.CmdArgs) error + +func cmdCheck(args *skel.CmdArgs) error + +func main() { + skel.PluginMainFuncs(skel.CNIFuncs{Add: cmdAdd, Del: cmdDel, Check: cmdCheck, GC: nil, Status: nil}, version.PluginSupports("0.3.1", "0.4.0", "1.0.0"), fmt.Sprintf("coil %s", pona.Version)) +} diff --git a/go.mod b/go.mod index 7d57f5f..4acc1fe 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/cybozu-go/pona go 1.22.6 require ( + github.com/containernetworking/cni v1.2.3 github.com/containernetworking/plugins v1.5.1 github.com/coreos/go-iptables v0.7.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 @@ -18,7 +19,6 @@ require ( ) require ( - github.com/containernetworking/cni v1.1.2 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/safchain/ethtool v0.4.0 // indirect github.com/vishvananda/netns v0.0.4 // indirect @@ -35,7 +35,7 @@ require ( github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.1 github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect @@ -81,7 +81,7 @@ require ( golang.org/x/net v0.25.0 // indirect golang.org/x/oauth2 v0.20.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.21.0 golang.org/x/term v0.20.0 // indirect golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.3.0 // indirect diff --git a/go.sum b/go.sum index b5dc6a4..69af64c 100644 --- a/go.sum +++ b/go.sum @@ -8,11 +8,8 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ= -github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= +github.com/containernetworking/cni v1.2.3 h1:hhOcjNVUQTnzdRJ6alC5XF+wd9mfGIUaj8FuJbEslXM= +github.com/containernetworking/cni v1.2.3/go.mod h1:DuLgF+aPd3DzcTQTtp/Nvl1Kim23oFKdm2okJzBQA5M= github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ= github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM= github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8= @@ -29,8 +26,6 @@ github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0 github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -46,7 +41,6 @@ github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2Kv github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -56,31 +50,18 @@ github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwm github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -89,8 +70,6 @@ github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwn github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -117,17 +96,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -154,7 +124,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -195,46 +164,31 @@ golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERs golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -242,7 +196,6 @@ golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= @@ -258,27 +211,14 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/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.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/version.go b/version.go new file mode 100644 index 0000000..09b87f2 --- /dev/null +++ b/version.go @@ -0,0 +1,5 @@ +package pona + +var ( + Version = "" // set at compile time with -ldflags "-X pona.Version=x.y.yz" +) From e33d5ce8abebca3558db712423f362cb552b7cfc Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Wed, 28 Aug 2024 16:02:44 +0900 Subject: [PATCH 18/36] add netip utility test Signed-off-by: walnuts1018 --- pkg/util/netiputil/netiputil_test.go | 144 +++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 pkg/util/netiputil/netiputil_test.go diff --git a/pkg/util/netiputil/netiputil_test.go b/pkg/util/netiputil/netiputil_test.go new file mode 100644 index 0000000..1649de2 --- /dev/null +++ b/pkg/util/netiputil/netiputil_test.go @@ -0,0 +1,144 @@ +package netiputil + +import ( + "net" + "net/netip" + "reflect" + "testing" +) + +func TestToIPNet(t *testing.T) { + type args struct { + prefix netip.Prefix + } + tests := []struct { + name string + args args + want net.IPNet + }{ + { + name: "192.168.0.0/16", + args: args{ + prefix: netip.MustParsePrefix("192.168.0.0/16"), + }, + want: net.IPNet{ + IP: net.ParseIP("192.168.0.0").To4(), Mask: net.CIDRMask(16, 32), + }, + }, + { + name: "fc00::/7", + args: args{ + prefix: netip.MustParsePrefix("fc00::/7"), + }, + want: net.IPNet{ + IP: net.ParseIP("fc00::"), + Mask: net.CIDRMask(7, 128), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ToIPNet(tt.args.prefix); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToIPNet() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestFromIPNet(t *testing.T) { + type args struct { + from net.IPNet + } + tests := []struct { + name string + args args + wantTo netip.Prefix + wantOk bool + }{ + { + name: "192.168.0.0/16", + args: args{ + from: net.IPNet{ + IP: net.ParseIP("192.168.0.0").To4(), Mask: net.CIDRMask(16, 32), + }, + }, + wantTo: netip.MustParsePrefix("192.168.0.0/16"), + wantOk: true, + }, + { + name: "fc00::/7", + args: args{ + from: net.IPNet{ + IP: net.ParseIP("fc00::"), + Mask: net.CIDRMask(7, 128), + }, + }, + wantTo: netip.MustParsePrefix("fc00::/7"), + wantOk: true, + }, + { + name: "invalid", + args: args{ + from: net.IPNet{}, + }, + wantTo: netip.Prefix{}, + wantOk: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotTo, gotOk := FromIPNet(tt.args.from) + if !reflect.DeepEqual(gotTo, tt.wantTo) { + t.Errorf("FromIPNet() gotTo = %v, want %v", gotTo, tt.wantTo) + } + if gotOk != tt.wantOk { + t.Errorf("FromIPNet() gotOk = %v, want %v", gotOk, tt.wantOk) + } + }) + } +} + +func TestFromAddr(t *testing.T) { + type args struct { + addr netip.Addr + } + tests := []struct { + name string + args args + want net.IP + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := FromAddr(tt.args.addr); !reflect.DeepEqual(got, tt.want) { + t.Errorf("FromAddr() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestToAddr(t *testing.T) { + type args struct { + ip net.IP + } + tests := []struct { + name string + args args + want netip.Addr + want1 bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1 := ToAddr(tt.args.ip) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ToAddr() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("ToAddr() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} From a88ebdc3775c0c2c7e4fb03c1ad26057ed9647ec Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:39:23 +0900 Subject: [PATCH 19/36] [WIP] implementing cni add Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- cmd/pona/main.go | 31 ++++++++++++++++- cmd/pona/rpc.go | 61 +++++++++++++++++++++++++++++++++ internal/constants/constants.go | 7 ++++ internal/ponad/server.go | 11 ++---- pkg/cni/cni.go | 23 +++++++++---- 5 files changed, 116 insertions(+), 17 deletions(-) create mode 100644 cmd/pona/rpc.go diff --git a/cmd/pona/main.go b/cmd/pona/main.go index cc5b9a9..23e99c4 100644 --- a/cmd/pona/main.go +++ b/cmd/pona/main.go @@ -1,14 +1,43 @@ package main import ( + "context" "fmt" + "time" "github.com/containernetworking/cni/pkg/skel" + "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/version" "github.com/cybozu-go/pona" + "github.com/cybozu-go/pona/pkg/cni" + "github.com/cybozu-go/pona/pkg/cnirpc" ) -func cmdAdd(args *skel.CmdArgs) error +func cmdAdd(args *skel.CmdArgs) error { + conf, err := cni.ParseConfig(args.StdinData) + if err != nil { + return types.NewError(types.ErrDecodingFailure, "failed to parse config from stdin data", err.Error()) + } + if conf.PrevResult == nil { + return types.NewError(types.ErrInternal, "ponad must be called as chained plugin", "") + } + + cniArgs, err := makeCNIArgs(args) + if err != nil { + return types.NewError(types.ErrInvalidNetworkConfig, "failed to transform args to RPC arg", err.Error()) + } + + conn, err := connect(conf.Socket) + if err != nil { + return types.NewError(types.ErrTryAgainLater, "failed to connect to socket", err.Error()) + } + + client := cnirpc.NewCNIClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) + defer cancel() + + resp, err := client.Add(ctx, cni) +} func cmdDel(args *skel.CmdArgs) error diff --git a/cmd/pona/rpc.go b/cmd/pona/rpc.go new file mode 100644 index 0000000..09745b3 --- /dev/null +++ b/cmd/pona/rpc.go @@ -0,0 +1,61 @@ +package main + +import ( + "context" + "fmt" + "net" + + "github.com/containernetworking/cni/pkg/skel" + "github.com/containernetworking/cni/pkg/types" + "github.com/cybozu-go/pona/internal/constants" + "github.com/cybozu-go/pona/pkg/cnirpc" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/resolver" +) + +// PluginEnvArgs represents CNI_ARG +type PluginEnvArgs struct { + types.CommonArgs + K8S_POD_NAMESPACE types.UnmarshallableString + K8S_POD_NAME types.UnmarshallableString + K8S_POD_INFRA_CONTAINER_ID types.UnmarshallableString +} + +// Map returns a map[string]string +func (e PluginEnvArgs) Map() map[string]string { + return map[string]string{ + constants.PodNamespaceKey: string(e.K8S_POD_NAMESPACE), + constants.PodNameKey: string(e.K8S_POD_NAME), + constants.PodContainerKey: string(e.K8S_POD_INFRA_CONTAINER_ID), + } +} + +func makeCNIArgs(args *skel.CmdArgs) (*cnirpc.CNIArgs, error) { + a := &PluginEnvArgs{} + if err := types.LoadArgs(args.Args, a); err != nil { + return nil, fmt.Errorf("failed to load args: %w", err) + } + return &cnirpc.CNIArgs{ + ContainerId: args.ContainerID, + Netns: args.Netns, + Ifname: args.IfName, + Args: a.Map(), + Path: args.Path, + StdinData: args.StdinData, + }, nil +} + +func connect(sockPath string) (*grpc.ClientConn, error) { + dialer := &net.Dialer{} + dialFunc := func(ctx context.Context, a string) (net.Conn, error) { + return dialer.DialContext(ctx, "unix", a) + } + resolver.SetDefaultScheme("passthrough") + + conn, err := grpc.NewClient(sockPath, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(dialFunc)) + if err != nil { + return nil, fmt.Errorf("failed to connect to %s: %w", sockPath, err) + } + return conn, nil +} diff --git a/internal/constants/constants.go b/internal/constants/constants.go index a700d13..233f1bd 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -3,3 +3,10 @@ package constants const ( EgressAnnotationPrefix = "egress.pona.cybozu.com/" ) + +// Keys in CNI_ARGS +const ( + PodNameKey = "K8S_POD_NAME" + PodNamespaceKey = "K8S_POD_NAMESPACE" + PodContainerKey = "K8S_POD_INFRA_CONTAINER_ID" +) diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 3d9c9f4..57ae1d7 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -27,13 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -// Keys in CNI_ARGS -const ( - PodNameKey = "K8S_POD_NAME" - PodNamespaceKey = "K8S_POD_NAMESPACE" - PodContainerKey = "K8S_POD_INFRA_CONTAINER_ID" -) - func newError(c codes.Code, cniCode cnirpc.ErrorCode, msg, details string) error { st := status.New(c, msg) st, err := st.WithDetails(&cnirpc.CNIError{Code: cniCode, Msg: msg, Details: details}) @@ -89,8 +82,8 @@ func (s *server) Start(ctx context.Context) error { } func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResponse, error) { - podName := args.Args[PodNameKey] - podNS := args.Args[PodNamespaceKey] + podName := args.Args[constants.PodNameKey] + podNS := args.Args[constants.PodNamespaceKey] if podName == "" || podNS == "" { return nil, fmt.Errorf("missing pod name or namespace, args: %#v", args.Args) } diff --git a/pkg/cni/cni.go b/pkg/cni/cni.go index 36cdc88..71ab349 100644 --- a/pkg/cni/cni.go +++ b/pkg/cni/cni.go @@ -18,19 +18,28 @@ type PluginConf struct { } func GetPrevResult(cniargs *cnirpc.CNIArgs) (*cni100.Result, error) { + conf, err := ParseConfig(cniargs.StdinData) + if err != nil { + return nil, fmt.Errorf("failed to parse config") + } + r, err := cni100.GetResult(conf.NetConf.PrevResult) + if err != nil { + return nil, fmt.Errorf("failed to get prevresult") + } + + return r, nil +} + +func ParseConfig(stdin []byte) (*PluginConf, error) { conf := &PluginConf{} - if err := json.Unmarshal(cniargs.StdinData, conf); err != nil { - return nil, fmt.Errorf("failed to unmarshal NetConf: %w", err) + if err := json.Unmarshal(stdin, conf); err != nil { + return nil, fmt.Errorf("failed to parse network configuration: %w", err) } if err := version.ParsePrevResult(&conf.NetConf); err != nil { return nil, fmt.Errorf("failed to parse prev result: %w", err) } - r, err := cni100.GetResult(conf.NetConf.PrevResult) - if err != nil { - return nil, fmt.Errorf("failed to get prevresult") - } - return r, nil + return conf, nil } From 8f59337671c603c43233c86e06160cdd90f9c16b Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 09:46:41 +0900 Subject: [PATCH 20/36] implement pona cmdAdd Signed-off-by: walnuts1018 --- cmd/pona/main.go | 22 +++++++++++++++++++--- cmd/pona/rpc.go | 17 +++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/cmd/pona/main.go b/cmd/pona/main.go index 23e99c4..fa9477d 100644 --- a/cmd/pona/main.go +++ b/cmd/pona/main.go @@ -7,6 +7,8 @@ import ( "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/types" + cni100 "github.com/containernetworking/cni/pkg/types/100" + "github.com/containernetworking/cni/pkg/version" "github.com/cybozu-go/pona" "github.com/cybozu-go/pona/pkg/cni" @@ -36,12 +38,26 @@ func cmdAdd(args *skel.CmdArgs) error { ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) defer cancel() - resp, err := client.Add(ctx, cni) + resp, err := client.Add(ctx, cniArgs) + if err != nil { + return convertError(err) + } + + result, err := cni100.NewResult(resp.Result) + if err != nil { + return types.NewError(types.ErrDecodingFailure, "failed to unmarshal result", err.Error()) + } + + return types.PrintResult(result, conf.CNIVersion) } -func cmdDel(args *skel.CmdArgs) error +func cmdDel(args *skel.CmdArgs) error { + return nil +} -func cmdCheck(args *skel.CmdArgs) error +func cmdCheck(args *skel.CmdArgs) error { + return nil +} func main() { skel.PluginMainFuncs(skel.CNIFuncs{Add: cmdAdd, Del: cmdDel, Check: cmdCheck, GC: nil, Status: nil}, version.PluginSupports("0.3.1", "0.4.0", "1.0.0"), fmt.Sprintf("coil %s", pona.Version)) diff --git a/cmd/pona/rpc.go b/cmd/pona/rpc.go index 09745b3..b1c7d1e 100644 --- a/cmd/pona/rpc.go +++ b/cmd/pona/rpc.go @@ -12,6 +12,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/resolver" + "google.golang.org/grpc/status" ) // PluginEnvArgs represents CNI_ARG @@ -59,3 +60,19 @@ func connect(sockPath string) (*grpc.ClientConn, error) { } return conn, nil } + +// convertError turns err returned from gRPC library into CNI's types.Error +func convertError(err error) error { + st := status.Convert(err) + details := st.Details() + if len(details) != 1 { + return types.NewError(types.ErrInternal, st.Message(), err.Error()) + } + + cniErr, ok := details[0].(*cnirpc.CNIError) + if !ok { + types.NewError(types.ErrInternal, st.Message(), err.Error()) + } + + return types.NewError(uint(cniErr.Code), cniErr.Msg, cniErr.Details) +} From dd9a82078915b2e0bf5d59073cf36dd4b83c8088 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 10:13:34 +0900 Subject: [PATCH 21/36] implement pona & create pona-installer Signed-off-by: walnuts1018 --- Makefile | 4 ++ cmd/pona-installer/main.go | 19 ++++++++ config/manager/ponad.yaml | 94 ++++++++++++++++++++++++++++++++++++ config/rbac/role.yaml | 15 ++++++ dockerfiles/Dockerfile.ponad | 31 ++++++++++++ internal/ponad/server.go | 4 ++ 6 files changed, 167 insertions(+) create mode 100644 cmd/pona-installer/main.go create mode 100644 config/manager/ponad.yaml create mode 100644 dockerfiles/Dockerfile.ponad diff --git a/Makefile b/Makefile index 066f5e5..8984b85 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ IMG_TAG ?= dev IMG_CONTROLLER ?= egress-controller:$(IMG_TAG) IMG_GATEWAY ?= nat-gateway:$(IMG_TAG) +IMG_PONAD ?= ponad:$(IMG_TAG) + # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.30.0 @@ -110,11 +112,13 @@ run: manifests generate fmt vet mod ## Run a controller from your host. docker-build: ## Build docker image with the manager. $(CONTAINER_TOOL) build -t ${IMG_CONTROLLER} -f ./dockerfiles/Dockerfile.egress-controller . $(CONTAINER_TOOL) build -t ${IMG_GATEWAY} -f ./dockerfiles/Dockerfile.nat-gateway . + $(CONTAINER_TOOL) build -t ${IMG_PONAD} -f ./dockerfiles/Dockerfile.ponad . .PHONY: docker-push docker-push: ## Push docker image with the manager. $(CONTAINER_TOOL) push ${IMG_CONTROLLER} $(CONTAINER_TOOL) push ${IMG_GATEWAY} + $(CONTAINER_TOOL) push ${IMG_PONAD} # PLATFORMS defines the target platforms for the manager image be built to provide support to multiple # architectures. (i.e. make docker-buildx IMG=myregistry/mypoperator:0.0.1). To use this option you need to: diff --git a/cmd/pona-installer/main.go b/cmd/pona-installer/main.go new file mode 100644 index 0000000..bb4000b --- /dev/null +++ b/cmd/pona-installer/main.go @@ -0,0 +1,19 @@ +package main + +import ( + "github.com/caarlos0/env/v10" + _ "github.com/joho/godotenv/autoload" +) + +type Config struct { + CniConfName string `env:"CNI_CONF_NAME,required"` + // cniEtcDir := viper.GetString("CNI_ETC_DIR") + // cniBinDir := viper.GetString("CNI_BIN_DIR") + // coilPath := viper.GetString("COIL_PATH") + // cniNetConf := viper.GetString("CNI_NETCONF") + // cniNetConfFile := viper.GetString("CNI_NETCONF_FILE") +} + +func main() { + +} diff --git a/config/manager/ponad.yaml b/config/manager/ponad.yaml new file mode 100644 index 0000000..89fad89 --- /dev/null +++ b/config/manager/ponad.yaml @@ -0,0 +1,94 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: ponad + labels: + app.kubernetes.io/component: ponad +spec: + selector: + matchLabels: + app.kubernetes.io/component: ponad + template: + metadata: + labels: + app.kubernetes.io/component: ponad + spec: + hostNetwork: true + hostPID: true # to see netns file under /proc + priorityClassName: system-node-critical + tolerations: + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + serviceAccountName: ponad + terminationGracePeriodSeconds: 1 + containers: + - name: ponad + image: ponad:dev + env: + - name: COIL_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + securityContext: + privileged: true + ports: + - name: metrics + containerPort: 9384 + protocol: TCP + - name: health + containerPort: 9385 + protocol: TCP + resources: + requests: + cpu: 100m + memory: 200Mi + readinessProbe: + httpGet: + path: /readyz + port: health + host: localhost + livenessProbe: + httpGet: + path: /healthz + port: health + host: localhost + volumeMounts: + - mountPath: /run + name: run + mountPropagation: HostToContainer # to see bind mount netns file under /run/netns + - mountPath: /lib/modules + name: modules + readOnly: true + initContainers: + - name: pona-installer + image: ponad:dev + command: + - "/pona-installer" + env: + - name: CNI_NETCONF + valueFrom: + configMapKeyRef: + name: pona-config + key: cni_netconf + securityContext: + privileged: true + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/net.d + name: cni-net-dir + volumes: + - name: run + hostPath: + path: /run + - name: modules + hostPath: + path: /lib/modules + - name: cni-bin-dir + hostPath: + path: /opt/cni/bin + - name: cni-net-dir + hostPath: + path: /etc/cni/net.d diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 3ba8c4d..4408309 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -4,6 +4,21 @@ kind: ClusterRole metadata: name: egress-controller-role rules: +- apiGroups: + - "" + resources: + - namespaces + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get - apiGroups: - apps resources: diff --git a/dockerfiles/Dockerfile.ponad b/dockerfiles/Dockerfile.ponad new file mode 100644 index 0000000..7c0fef4 --- /dev/null +++ b/dockerfiles/Dockerfile.ponad @@ -0,0 +1,31 @@ +# Build the manager binary +FROM ghcr.io/cybozu/golang:1.22-jammy AS builder +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /workspace + +RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ + --mount=type=bind,source=go.sum,target=go.sum \ + --mount=type=bind,source=go.mod,target=go.mod \ + go mod download -x + +# Copy the go source + +RUN --mount=type=cache,target=/go/pkg/mod/ \ + --mount=type=bind,target=. \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ponad cmd/ponad/main.go && \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona cmd/pona/main.go && \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona-installer cmd/pona-installer/main.go + + +FROM ghcr.io/cybozu/ubuntu:22.04 +WORKDIR / +RUN --mount=type=cache,target=/var/lib/apt,sharing=locked \ + --mount=type=cache,target=/var/cache/apt,sharing=locked \ + apt-get -yy update && apt-get install -yy netbase kmod iptables iproute2 + +COPY --from=builder /workspace/ponad /workspace/pona /workspace/pona-installer / +USER 0:0 + +ENTRYPOINT ["/ponad"] diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 57ae1d7..632ccb2 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -49,6 +49,10 @@ func InterceptorLogger(l *slog.Logger) logging.Logger { }) } +// +kubebuilder:rbac:groups="",resources=pods,verbs=get +// +kubebuilder:rbac:groups="",resources=namespaces;services,verbs=get;list;watch +// +kubebuilder:rbac:groups=pona.cybozu.com,resources=egresses,verbs=get;list;watch + type server struct { cnirpc.UnimplementedCNIServer From b8b15aa977969fade0b6f78d8ed7a72417e25d47 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:45:14 +0900 Subject: [PATCH 22/36] [WIP] pona-installer Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- cmd/pona-installer/install.go | 47 +++++++++++++++++++++++++++++++++++ cmd/pona-installer/main.go | 14 ++++++++++- config/manager/ponad.yaml | 2 +- go.mod | 2 ++ go.sum | 4 +++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 cmd/pona-installer/install.go diff --git a/cmd/pona-installer/install.go b/cmd/pona-installer/install.go new file mode 100644 index 0000000..93ca64c --- /dev/null +++ b/cmd/pona-installer/install.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "io" + "os" + "path/filepath" +) + +func installPona(ponaPath, cniBinDir string) error { + f, err := os.Open(ponaPath) + if err != nil { + return fmt.Errorf("failed to read pona %w", err) + } + if err := os.MkdirAll(cniBinDir, 0755); err != nil { + return fmt.Errorf("failed to MkdirAll: %w", err) + } + + g, err := os.CreateTemp(cniBinDir, ".tmp") + if err != nil { + return fmt.Errorf("failed to CreateTemp: %w", err) + } + defer func() { + g.Close() + os.Remove(g.Name()) + }() + + _, err = io.Copy(g, f) + if err != nil { + return fmt.Errorf("failed to io.Copy: %w", err) + } + + err = g.Chmod(0755) + if err != nil { + return fmt.Errorf("failed to chmod: %w", err) + } + + err = g.Sync() + if err != nil { + return fmt.Errorf("failed to Sync: %w", err) + } + + if err := os.Rename(g.Name(), filepath.Join(cniBinDir, "coil")); err != nil { + return fmt.Errorf("failed to rename: %w", err) + } + return nil +} diff --git a/cmd/pona-installer/main.go b/cmd/pona-installer/main.go index bb4000b..b3a88de 100644 --- a/cmd/pona-installer/main.go +++ b/cmd/pona-installer/main.go @@ -1,12 +1,20 @@ package main import ( + "log/slog" + "os" + "github.com/caarlos0/env/v10" _ "github.com/joho/godotenv/autoload" ) type Config struct { CniConfName string `env:"CNI_CONF_NAME,required"` + CniEtcDir string `env:"CNI_ETC_DIR" envDefault:"/host/etc/cni/net.d"` + CniBinDir string `env:"CNI_BIN_DIR" envDefault:"/host/opt/cni/bin"` + PonaPath string `env:"CNI_PATH" envDefault:"/pona"` + CniNetConf string `env:"CNI_NET_CONF,required"` + // cniEtcDir := viper.GetString("CNI_ETC_DIR") // cniBinDir := viper.GetString("CNI_BIN_DIR") // coilPath := viper.GetString("COIL_PATH") @@ -15,5 +23,9 @@ type Config struct { } func main() { - + var cfg Config + if err := env.Parse(&cfg); err != nil { + slog.Error("failed to parse config", slog.Any("error", err)) + os.Exit(1) + } } diff --git a/config/manager/ponad.yaml b/config/manager/ponad.yaml index 89fad89..a26852e 100644 --- a/config/manager/ponad.yaml +++ b/config/manager/ponad.yaml @@ -21,7 +21,7 @@ spec: operator: Exists - effect: NoExecute operator: Exists - serviceAccountName: ponad + serviceAccountName: egress-controller terminationGracePeriodSeconds: 1 containers: - name: ponad diff --git a/go.mod b/go.mod index 4acc1fe..825c794 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,12 @@ module github.com/cybozu-go/pona go 1.22.6 require ( + github.com/caarlos0/env/v10 v10.0.0 github.com/containernetworking/cni v1.2.3 github.com/containernetworking/plugins v1.5.1 github.com/coreos/go-iptables v0.7.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 + github.com/joho/godotenv v1.5.1 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 google.golang.org/grpc v1.65.0 diff --git a/go.sum b/go.sum index 69af64c..95f9b1d 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/caarlos0/env/v10 v10.0.0 h1:yIHUBZGsyqCnpTkbjk8asUlx6RFhhEs+h7TOBdgdzXA= +github.com/caarlos0/env/v10 v10.0.0/go.mod h1:ZfulV76NvVPw3tm591U4SwL3Xx9ldzBP9aGxzeN7G18= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -72,6 +74,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rH github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= From b5a2b1a8bbbdf73c3af6f3535db1f5510fd37c1e Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 11:21:45 +0900 Subject: [PATCH 23/36] implement installer Signed-off-by: walnuts1018 --- Makefile | 6 ++++++ cmd/pona-installer/install.go | 2 +- cmd/pona-installer/main.go | 22 +++++++++++----------- cmd/pona/main.go | 2 +- config/manager/kustomization.yaml | 5 +++-- config/manager/ponad.yaml | 12 ++++++------ dockerfiles/Dockerfile.egress-controller | 16 ++++++---------- dockerfiles/Dockerfile.nat-gateway | 16 ++++++---------- dockerfiles/Dockerfile.ponad | 8 ++++---- 9 files changed, 44 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index 8984b85..0a23ee2 100644 --- a/Makefile +++ b/Makefile @@ -114,6 +114,12 @@ docker-build: ## Build docker image with the manager. $(CONTAINER_TOOL) build -t ${IMG_GATEWAY} -f ./dockerfiles/Dockerfile.nat-gateway . $(CONTAINER_TOOL) build -t ${IMG_PONAD} -f ./dockerfiles/Dockerfile.ponad . +.PHONY: kind-load +kind-load: + kind load docker-image ${IMG_CONTROLLER} + kind load docker-image ${IMG_GATEWAY} + kind load docker-image ${IMG_PONAD} + .PHONY: docker-push docker-push: ## Push docker image with the manager. $(CONTAINER_TOOL) push ${IMG_CONTROLLER} diff --git a/cmd/pona-installer/install.go b/cmd/pona-installer/install.go index 93ca64c..d3c5d79 100644 --- a/cmd/pona-installer/install.go +++ b/cmd/pona-installer/install.go @@ -40,7 +40,7 @@ func installPona(ponaPath, cniBinDir string) error { return fmt.Errorf("failed to Sync: %w", err) } - if err := os.Rename(g.Name(), filepath.Join(cniBinDir, "coil")); err != nil { + if err := os.Rename(g.Name(), filepath.Join(cniBinDir, "pona")); err != nil { return fmt.Errorf("failed to rename: %w", err) } return nil diff --git a/cmd/pona-installer/main.go b/cmd/pona-installer/main.go index b3a88de..02ecd5c 100644 --- a/cmd/pona-installer/main.go +++ b/cmd/pona-installer/main.go @@ -9,17 +9,11 @@ import ( ) type Config struct { - CniConfName string `env:"CNI_CONF_NAME,required"` - CniEtcDir string `env:"CNI_ETC_DIR" envDefault:"/host/etc/cni/net.d"` - CniBinDir string `env:"CNI_BIN_DIR" envDefault:"/host/opt/cni/bin"` - PonaPath string `env:"CNI_PATH" envDefault:"/pona"` - CniNetConf string `env:"CNI_NET_CONF,required"` - - // cniEtcDir := viper.GetString("CNI_ETC_DIR") - // cniBinDir := viper.GetString("CNI_BIN_DIR") - // coilPath := viper.GetString("COIL_PATH") - // cniNetConf := viper.GetString("CNI_NETCONF") - // cniNetConfFile := viper.GetString("CNI_NETCONF_FILE") + CniEtcDir string `env:"CNI_ETC_DIR" envDefault:"/host/etc/cni/net.d"` + CniBinDir string `env:"CNI_BIN_DIR" envDefault:"/host/opt/cni/bin"` + PonaPath string `env:"CNI_PATH" envDefault:"/pona"` + // CniNetConf string `env:"CNI_NET_CONF"` + // CniConfName string `env:"CNI_CONF_NAME"` } func main() { @@ -28,4 +22,10 @@ func main() { slog.Error("failed to parse config", slog.Any("error", err)) os.Exit(1) } + + if err := installPona(cfg.PonaPath, cfg.CniBinDir); err != nil { + slog.Error("failed to install pona", + slog.Any("error", err), + ) + } } diff --git a/cmd/pona/main.go b/cmd/pona/main.go index fa9477d..e9e3b1a 100644 --- a/cmd/pona/main.go +++ b/cmd/pona/main.go @@ -60,5 +60,5 @@ func cmdCheck(args *skel.CmdArgs) error { } func main() { - skel.PluginMainFuncs(skel.CNIFuncs{Add: cmdAdd, Del: cmdDel, Check: cmdCheck, GC: nil, Status: nil}, version.PluginSupports("0.3.1", "0.4.0", "1.0.0"), fmt.Sprintf("coil %s", pona.Version)) + skel.PluginMainFuncs(skel.CNIFuncs{Add: cmdAdd, Del: cmdDel, Check: cmdCheck, GC: nil, Status: nil}, version.PluginSupports("0.3.1", "0.4.0", "1.0.0", "1.1.0"), fmt.Sprintf("pona %s", pona.Version)) } diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index e639dea..643d43f 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -1,8 +1,9 @@ -resources: -- egress-controller.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization images: - name: egress-controller newName: egress-controller newTag: dev +resources: +- egress-controller.yaml +- ponad.yaml diff --git a/config/manager/ponad.yaml b/config/manager/ponad.yaml index a26852e..d3a876f 100644 --- a/config/manager/ponad.yaml +++ b/config/manager/ponad.yaml @@ -66,12 +66,12 @@ spec: image: ponad:dev command: - "/pona-installer" - env: - - name: CNI_NETCONF - valueFrom: - configMapKeyRef: - name: pona-config - key: cni_netconf + # env: + # - name: CNI_NETCONF + # valueFrom: + # configMapKeyRef: + # name: pona-config + # key: cni_netconf securityContext: privileged: true volumeMounts: diff --git a/dockerfiles/Dockerfile.egress-controller b/dockerfiles/Dockerfile.egress-controller index b4bd368..fb3844f 100644 --- a/dockerfiles/Dockerfile.egress-controller +++ b/dockerfiles/Dockerfile.egress-controller @@ -4,18 +4,14 @@ ARG TARGETOS ARG TARGETARCH WORKDIR /workspace -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer -RUN go mod download + +RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ + --mount=type=bind,source=go.sum,target=go.sum \ + --mount=type=bind,source=go.mod,target=go.mod \ + go mod download -x # Copy the go source -COPY cmd/egress-controller/main.go cmd/egress-controller/main.go -COPY api/ api/ -COPY internal/ internal/ -COPY pkg/ pkg/ +COPY . . RUN --mount=type=cache,target=/go/pkg/mod/ \ CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o egress-controller cmd/egress-controller/main.go diff --git a/dockerfiles/Dockerfile.nat-gateway b/dockerfiles/Dockerfile.nat-gateway index 94dd8bc..259c175 100644 --- a/dockerfiles/Dockerfile.nat-gateway +++ b/dockerfiles/Dockerfile.nat-gateway @@ -4,18 +4,14 @@ ARG TARGETOS ARG TARGETARCH WORKDIR /workspace -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -# cache deps before building and copying source so that we don't need to re-download as much -# and so that source changes don't invalidate our downloaded layer -RUN go mod download + +RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ + --mount=type=bind,source=go.sum,target=go.sum \ + --mount=type=bind,source=go.mod,target=go.mod \ + go mod download -x # Copy the go source -COPY cmd/nat-gateway/main.go cmd/nat-gateway/main.go -COPY api/ api/ -COPY internal/ internal/ -COPY pkg/ pkg/ +COPY . . RUN --mount=type=cache,target=/go/pkg/mod/ \ CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o nat-gateway cmd/nat-gateway/main.go diff --git a/dockerfiles/Dockerfile.ponad b/dockerfiles/Dockerfile.ponad index 7c0fef4..bdab4ed 100644 --- a/dockerfiles/Dockerfile.ponad +++ b/dockerfiles/Dockerfile.ponad @@ -11,12 +11,12 @@ RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ go mod download -x # Copy the go source +COPY . . RUN --mount=type=cache,target=/go/pkg/mod/ \ - --mount=type=bind,target=. \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ponad cmd/ponad/main.go && \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona cmd/pona/main.go && \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona-installer cmd/pona-installer/main.go + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ponad ./cmd/ponad/main.go && \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona ./cmd/pona && \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona-installer ./cmd/pona-installer FROM ghcr.io/cybozu/ubuntu:22.04 From 2f6319caf09dcdf53596a19bf72d86d0c921f2cb Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 11:21:53 +0900 Subject: [PATCH 24/36] use netns Signed-off-by: walnuts1018 --- internal/ponad/server.go | 52 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 632ccb2..19f913b 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -10,6 +10,7 @@ import ( "net/netip" "strings" + "github.com/containernetworking/plugins/pkg/ns" ponav1beta1 "github.com/cybozu-go/pona/api/v1beta1" "github.com/cybozu-go/pona/internal/constants" "github.com/cybozu-go/pona/pkg/cni" @@ -127,34 +128,45 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp } } - ft, err := fou.NewFoUTunnelController(s.egressPort, local4, local6) + containerNS, err := ns.GetNS(args.Netns) if err != nil { - return nil, newInternalError(err, "failed to create FoUTunnelController") - } - if err := ft.Init(); err != nil { - return nil, newInternalError(err, "failed to initialize FoUTunnel") - } - nt, err := nat.NewNatClient(local4 != nil, local6 != nil) - if err != nil { - return nil, newInternalError(err, "failed to create Nat client") - } - if err := nt.Init(); err != nil { - return nil, newInternalError(err, "failed to initialize Nat client") + return nil, fmt.Errorf("failed to open netns path %s: %w", args.Netns, err) } + defer containerNS.Close() - for _, egName := range egNames { - g, ds, err := s.collectDestinationsForEgress(ctx, egName) + if err := containerNS.Do(func(hostNS ns.NetNS) error { + ft, err := fou.NewFoUTunnelController(s.egressPort, local4, local6) if err != nil { - return nil, newInternalError(err, "failed to collect destinations for egress") + return newInternalError(err, "failed to create FoUTunnelController") } - - link, err := ft.AddPeer(netip.Addr(g)) + if err := ft.Init(); err != nil { + return newInternalError(err, "failed to initialize FoUTunnel") + } + nt, err := nat.NewNatClient(local4 != nil, local6 != nil) if err != nil { - return nil, newInternalError(err, fmt.Sprintf("failed to add peer for %v", g)) + return newInternalError(err, "failed to create Nat client") + } + if err := nt.Init(); err != nil { + return newInternalError(err, "failed to initialize Nat client") } - if err := nt.UpdateRoutes(link, ds); err != nil { - return nil, newInternalError(err, "failed to update routes") + + for _, egName := range egNames { + g, ds, err := s.collectDestinationsForEgress(ctx, egName) + if err != nil { + return newInternalError(err, "failed to collect destinations for egress") + } + + link, err := ft.AddPeer(netip.Addr(g)) + if err != nil { + return newInternalError(err, fmt.Sprintf("failed to add peer for %v", g)) + } + if err := nt.UpdateRoutes(link, ds); err != nil { + return newInternalError(err, "failed to update routes") + } } + return nil + }); err != nil { + return nil, err } b, err := json.Marshal(p) From 80cbe71f884eef9ba0a3c7c2007697184fd9d5b9 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:02:28 +0900 Subject: [PATCH 25/36] [WIP] ponad debugging Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- cmd/ponad/main.go | 3 ++- internal/ponad/server.go | 28 ++++++++++----------- netconf.json | 37 ++++++++++++++++++++++++++++ pkg/util/netiputil/netiputil_test.go | 26 +++++++++++++------ 4 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 netconf.json diff --git a/cmd/ponad/main.go b/cmd/ponad/main.go index 8590474..1752b4c 100644 --- a/cmd/ponad/main.go +++ b/cmd/ponad/main.go @@ -7,6 +7,7 @@ import ( "os" "time" + ponav1beta1 "github.com/cybozu-go/pona/api/v1beta1" "github.com/cybozu-go/pona/internal/ponad" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" @@ -37,7 +38,7 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - + utilruntime.Must(ponav1beta1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } diff --git a/internal/ponad/server.go b/internal/ponad/server.go index 19f913b..ff1b0b5 100644 --- a/internal/ponad/server.go +++ b/internal/ponad/server.go @@ -30,7 +30,7 @@ import ( func newError(c codes.Code, cniCode cnirpc.ErrorCode, msg, details string) error { st := status.New(c, msg) - st, err := st.WithDetails(&cnirpc.CNIError{Code: cniCode, Msg: msg, Details: details}) + st, err := st.WithDetails(&cnirpc.CNIError{Code: cniCode, Msg: msg + details, Details: details}) if err != nil { panic(err) } @@ -39,7 +39,7 @@ func newError(c codes.Code, cniCode cnirpc.ErrorCode, msg, details string) error } func newInternalError(err error, msg string) error { - return newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, msg, err.Error()) + return newError(codes.Internal, cnirpc.ErrorCode_INTERNAL, msg+err.Error(), err.Error()) } // InterceptorLogger adapts slog logger to interceptor logger. @@ -101,22 +101,27 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, newInternalError(err, "failed to get pod") } - egNames, err := s.listEgress(pod) + p, err := cni.GetPrevResult(args) if err != nil { - return nil, newInternalError(err, "failed to list eggress from annotations") + return nil, newInternalError(err, "failed to get previous result") } - if len(egNames) == 0 { - return nil, nil + + b, err := json.Marshal(p) + if err != nil { + return nil, newInternalError(err, "failed to marshal result") } - p, err := cni.GetPrevResult(args) + egNames, err := s.listEgress(pod) if err != nil { - return nil, newInternalError(err, "failed to get previous result") + return nil, newInternalError(err, "failed to list eggress from annotations") + } + if len(egNames) == 0 { + return &cnirpc.AddResponse{Result: b}, nil } var local4, local6 *netip.Addr for _, ipc := range p.IPs { - ip, ok := netiputil.ToAddr(ipc.Gateway) + ip, ok := netiputil.ToAddr(ipc.Address.IP) if !ok { return nil, newInternalError(errors.New("failed to parse ip"), "failed to parse ip") } @@ -169,11 +174,6 @@ func (s *server) Add(ctx context.Context, args *cnirpc.CNIArgs) (*cnirpc.AddResp return nil, err } - b, err := json.Marshal(p) - if err != nil { - return nil, newInternalError(err, "failed to marshal result") - } - return &cnirpc.AddResponse{Result: b}, nil } diff --git a/netconf.json b/netconf.json new file mode 100644 index 0000000..7734d6d --- /dev/null +++ b/netconf.json @@ -0,0 +1,37 @@ +{ + "cniVersion": "0.3.1", + "name": "kindnet", + "plugins": [ + { + "type": "ptp", + "ipMasq": false, + "ipam": { + "type": "host-local", + "dataDir": "/run/cni-ipam-state", + "routes": [ + + + { "dst": "0.0.0.0/0" } + ], + "ranges": [ + + + [ { "subnet": "10.244.0.0/24" } ] + ] + } + , + "mtu": 1500 + + }, + { + "type": "pona", + "socket": "/run/ponad.sock" + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] +} diff --git a/pkg/util/netiputil/netiputil_test.go b/pkg/util/netiputil/netiputil_test.go index 1649de2..577c03f 100644 --- a/pkg/util/netiputil/netiputil_test.go +++ b/pkg/util/netiputil/netiputil_test.go @@ -123,12 +123,24 @@ func TestToAddr(t *testing.T) { ip net.IP } tests := []struct { - name string - args args - want netip.Addr - want1 bool + name string + args args + want netip.Addr }{ - // TODO: Add test cases. + { + name: "1", + args: args{ + ip: net.ParseIP("10.244.0.1"), + }, + want: netip.MustParseAddr("10.244.0.1"), + }, + { + name: "2", + args: args{ + ip: net.ParseIP("ffcc::1"), + }, + want: netip.MustParseAddr("ffcc::1"), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -136,8 +148,8 @@ func TestToAddr(t *testing.T) { if !reflect.DeepEqual(got, tt.want) { t.Errorf("ToAddr() got = %v, want %v", got, tt.want) } - if got1 != tt.want1 { - t.Errorf("ToAddr() got1 = %v, want %v", got1, tt.want1) + if !got1 { + t.Errorf("ToAddr() got1 = %v, want true", got1) } }) } From a141c874974af933c8c3d8f766b708bd4633d7e4 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 12:11:20 +0900 Subject: [PATCH 26/36] fix netiputil Signed-off-by: walnuts1018 --- pkg/util/netiputil/netiputil.go | 7 ++++++- pkg/util/netiputil/netiputil_test.go | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pkg/util/netiputil/netiputil.go b/pkg/util/netiputil/netiputil.go index 42cc89c..031ab72 100644 --- a/pkg/util/netiputil/netiputil.go +++ b/pkg/util/netiputil/netiputil.go @@ -10,7 +10,12 @@ func FromAddr(addr netip.Addr) net.IP { } func ToAddr(ip net.IP) (netip.Addr, bool) { - return netip.AddrFromSlice(ip) + if f := ip.To4(); f != nil { + return netip.AddrFromSlice(f) + } else if f := ip.To16(); f != nil { + return netip.AddrFromSlice(f) + } + return netip.Addr{}, false } func IsFamilyMatched(a, b netip.Addr) bool { diff --git a/pkg/util/netiputil/netiputil_test.go b/pkg/util/netiputil/netiputil_test.go index 577c03f..6e1b04f 100644 --- a/pkg/util/netiputil/netiputil_test.go +++ b/pkg/util/netiputil/netiputil_test.go @@ -107,7 +107,20 @@ func TestFromAddr(t *testing.T) { args args want net.IP }{ - // TODO: Add test cases. + { + name: "1", + args: args{ + addr: netip.MustParseAddr("10.244.0.1"), + }, + want: net.ParseIP("10.244.0.1").To4(), + }, + { + name: "2", + args: args{ + addr: netip.MustParseAddr("ffcc::1"), + }, + want: net.ParseIP("ffcc::1").To16(), + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 5a93bde078d1aa4dffd87ab0eab5d9cbfd4ad33b Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:31:50 +0900 Subject: [PATCH 27/36] coil -> pona Signed-off-by: walnuts1018 --- config/manager/ponad.yaml | 2 +- internal/controller/egress_controller.go | 12 ++++++------ pkg/cni/cni.go | 2 +- pkg/tunnel/fou/fou.go | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/config/manager/ponad.yaml b/config/manager/ponad.yaml index d3a876f..fd7e382 100644 --- a/config/manager/ponad.yaml +++ b/config/manager/ponad.yaml @@ -27,7 +27,7 @@ spec: - name: ponad image: ponad:dev env: - - name: COIL_NODE_NAME + - name: PONA_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName diff --git a/internal/controller/egress_controller.go b/internal/controller/egress_controller.go index fc34416..4e65205 100644 --- a/internal/controller/egress_controller.go +++ b/internal/controller/egress_controller.go @@ -39,11 +39,11 @@ const ( // TODO: Change this const ( - EnvNode = "COIL_NODE_NAME" - EnvAddresses = "COIL_POD_ADDRESSES" - EnvPodNamespace = "COIL_POD_NAMESPACE" - EnvPodName = "COIL_POD_NAME" - EnvEgressName = "COIL_EGRESS_NAME" + EnvNode = "PONA_NODE_NAME" + EnvAddresses = "PONA_POD_ADDRESSES" + EnvPodNamespace = "PONA_POD_NAMESPACE" + EnvPodName = "PONA_POD_NAME" + EnvEgressName = "PONA_EGRESS_NAME" ) // EgressReconciler reconciles a Egress object @@ -549,7 +549,7 @@ func (r *EgressReconciler) updateStatus(ctx context.Context, eg *ponav1beta1.Egr return r.Status().Update(ctx, eg) } -// addVolumes adds volumes required by coil +// addVolumes adds volumes required by pona // TODO: change this func (r *EgressReconciler) addVolumes(vols []corev1.Volume) []corev1.Volume { noRun := true diff --git a/pkg/cni/cni.go b/pkg/cni/cni.go index 71ab349..412f18f 100644 --- a/pkg/cni/cni.go +++ b/pkg/cni/cni.go @@ -13,7 +13,7 @@ import ( type PluginConf struct { types.NetConf - // Socket contains unix domain socket to communicate with coild + // Socket contains unix domain socket to communicate with ponad Socket string `json:"socket"` } diff --git a/pkg/tunnel/fou/fou.go b/pkg/tunnel/fou/fou.go index 9119162..77f5e39 100644 --- a/pkg/tunnel/fou/fou.go +++ b/pkg/tunnel/fou/fou.go @@ -284,7 +284,7 @@ func (t *FouTunnelController) DelPeer(addr netip.Addr) error { // the router Pods. // // Calling this function may result in tunl0 (v4) or ip6tnl0 (v6) -// fallback interface being renamed to coil_tunl or coil_ip6tnl. +// fallback interface being renamed to pona_tunl or pona_ip6tnl. // This is to communicate to the user that this plugin has taken // control of the encapsulation stack on the netns, as it currently // doesn't explicitly support sharing it with other tools/CNIs. @@ -297,7 +297,7 @@ func (t *FouTunnelController) DelPeer(addr netip.Addr) error { // By default, these interfaces will be created in new network namespaces, // but this behavior can be disabled by setting net.core.fb_tunnels_only_for_init_net = 2. func setupFlowBasedIP4TunDevice() error { - ipip4Device := "coil_ipip4" + ipip4Device := "pona_ipip4" // Set up IPv4 tunnel device if requested. if err := setupDevice(&netlink.Iptun{ LinkAttrs: netlink.LinkAttrs{Name: ipip4Device}, @@ -317,7 +317,7 @@ func setupFlowBasedIP4TunDevice() error { // See setupFlowBasedIP4TunDevice func setupFlowBasedIP6TunDevice() error { - ipip6Device := "coil_ipip6" + ipip6Device := "pona_ipip6" // Set up IPv6 tunnel device if requested. if err := setupDevice(&netlink.Ip6tnl{ @@ -329,7 +329,7 @@ func setupFlowBasedIP6TunDevice() error { // Rename fallback device created by potential kernel module load after // creating tunnel interface. - if err := renameDevice("ip6tnl0", "coil_ip6tnl"); err != nil { + if err := renameDevice("ip6tnl0", "pona_ip6tnl"); err != nil { return fmt.Errorf("renaming fallback device %s: %w", "tunl0", err) } From 65df05378d9af086c3ab5d59d28042541a7b750c Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:32:49 +0900 Subject: [PATCH 28/36] add version Signed-off-by: walnuts1018 --- Makefile | 7 ++++--- dockerfiles/Dockerfile.egress-controller | 3 ++- dockerfiles/Dockerfile.nat-gateway | 3 ++- dockerfiles/Dockerfile.ponad | 7 ++++--- version.go | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 0a23ee2..147bd48 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ IMG_TAG ?= dev IMG_CONTROLLER ?= egress-controller:$(IMG_TAG) IMG_GATEWAY ?= nat-gateway:$(IMG_TAG) IMG_PONAD ?= ponad:$(IMG_TAG) +PONA_VERSION ?= dev-$(shell git rev-parse --short HEAD) # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.30.0 @@ -110,9 +111,9 @@ run: manifests generate fmt vet mod ## Run a controller from your host. # More info: https://docs.docker.com/develop/develop-images/build_enhancements/ .PHONY: docker-build docker-build: ## Build docker image with the manager. - $(CONTAINER_TOOL) build -t ${IMG_CONTROLLER} -f ./dockerfiles/Dockerfile.egress-controller . - $(CONTAINER_TOOL) build -t ${IMG_GATEWAY} -f ./dockerfiles/Dockerfile.nat-gateway . - $(CONTAINER_TOOL) build -t ${IMG_PONAD} -f ./dockerfiles/Dockerfile.ponad . + $(CONTAINER_TOOL) build -t ${IMG_CONTROLLER} --build-arg PONA_VERSION=${PONA_VERSION} -f ./dockerfiles/Dockerfile.egress-controller . + $(CONTAINER_TOOL) build -t ${IMG_GATEWAY} --build-arg PONA_VERSION=${PONA_VERSION} -f ./dockerfiles/Dockerfile.nat-gateway . + $(CONTAINER_TOOL) build -t ${IMG_PONAD} --build-arg PONA_VERSION=${PONA_VERSION} -f ./dockerfiles/Dockerfile.ponad . .PHONY: kind-load kind-load: diff --git a/dockerfiles/Dockerfile.egress-controller b/dockerfiles/Dockerfile.egress-controller index fb3844f..7c5b471 100644 --- a/dockerfiles/Dockerfile.egress-controller +++ b/dockerfiles/Dockerfile.egress-controller @@ -2,6 +2,7 @@ FROM ghcr.io/cybozu/golang:1.22-jammy AS builder ARG TARGETOS ARG TARGETARCH +ARG PONA_VERSION WORKDIR /workspace @@ -14,7 +15,7 @@ RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ COPY . . RUN --mount=type=cache,target=/go/pkg/mod/ \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o egress-controller cmd/egress-controller/main.go + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o egress-controller -ldflags "-X github.com/cybozu-go/pona.Version=${PONA_VERSION}" cmd/egress-controller/main.go FROM ghcr.io/cybozu/ubuntu:22.04 WORKDIR / diff --git a/dockerfiles/Dockerfile.nat-gateway b/dockerfiles/Dockerfile.nat-gateway index 259c175..96708c1 100644 --- a/dockerfiles/Dockerfile.nat-gateway +++ b/dockerfiles/Dockerfile.nat-gateway @@ -2,6 +2,7 @@ FROM ghcr.io/cybozu/golang:1.22-jammy AS builder ARG TARGETOS ARG TARGETARCH +ARG PONA_VERSION WORKDIR /workspace @@ -14,7 +15,7 @@ RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ COPY . . RUN --mount=type=cache,target=/go/pkg/mod/ \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o nat-gateway cmd/nat-gateway/main.go + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o nat-gateway -ldflags "-X github.com/cybozu-go/pona.Version=${PONA_VERSION}" cmd/nat-gateway/main.go FROM ghcr.io/cybozu/ubuntu:22.04 WORKDIR / diff --git a/dockerfiles/Dockerfile.ponad b/dockerfiles/Dockerfile.ponad index bdab4ed..c04595f 100644 --- a/dockerfiles/Dockerfile.ponad +++ b/dockerfiles/Dockerfile.ponad @@ -2,6 +2,7 @@ FROM ghcr.io/cybozu/golang:1.22-jammy AS builder ARG TARGETOS ARG TARGETARCH +ARG PONA_VERSION WORKDIR /workspace @@ -14,9 +15,9 @@ RUN --mount=type=cache,target=/go/pkg/mod/,sharing=locked \ COPY . . RUN --mount=type=cache,target=/go/pkg/mod/ \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ponad ./cmd/ponad/main.go && \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona ./cmd/pona && \ - CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona-installer ./cmd/pona-installer + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ponad -ldflags "-X github.com/cybozu-go/pona.Version=${PONA_VERSION}" ./cmd/ponad/main.go && \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona -ldflags "-X github.com/cybozu-go/pona.Version=${PONA_VERSION}" ./cmd/pona && \ + CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o pona-installer -ldflags "-X github.com/cybozu-go/pona.Version=${PONA_VERSION}" ./cmd/pona-installer FROM ghcr.io/cybozu/ubuntu:22.04 diff --git a/version.go b/version.go index 09b87f2..ca33a2f 100644 --- a/version.go +++ b/version.go @@ -1,5 +1,5 @@ package pona var ( - Version = "" // set at compile time with -ldflags "-X pona.Version=x.y.yz" + Version = "" // set at compile time with -ldflags "-X github.com/cybozu-go/pona.Version=x.y.yz" ) From cf1b35e8e52cf6d66795a3bfd93d8a83f025a127 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:35:53 +0900 Subject: [PATCH 29/36] check-generate Signed-off-by: walnuts1018 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 147bd48..60ee695 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ test: envtest manifests generate fmt vet mod ## Run tests. KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out .PHONY: check-generate -check-generate: manifests fmt mod +check-generate: setup manifests fmt mod -rm $(ROLES) $(PROTOC_OUTPUTS) $(MAKE) generate git diff --exit-code --name-only From 22e669fed8d0b727502a1e7bac4e8bf3a513f4a8 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:36:29 +0900 Subject: [PATCH 30/36] update protoc-gen-go Signed-off-by: walnuts1018 --- pkg/cnirpc/cni.pb.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/cnirpc/cni.pb.go b/pkg/cnirpc/cni.pb.go index 8873895..0900049 100644 --- a/pkg/cnirpc/cni.pb.go +++ b/pkg/cnirpc/cni.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 +// protoc-gen-go v1.34.2 // protoc v5.27.3 // source: pkg/cnirpc/cni.proto @@ -376,7 +376,7 @@ func file_pkg_cnirpc_cni_proto_rawDescGZIP() []byte { var file_pkg_cnirpc_cni_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_pkg_cnirpc_cni_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_pkg_cnirpc_cni_proto_goTypes = []interface{}{ +var file_pkg_cnirpc_cni_proto_goTypes = []any{ (ErrorCode)(0), // 0: pkg.cnirpc.ErrorCode (*CNIArgs)(nil), // 1: pkg.cnirpc.CNIArgs (*CNIError)(nil), // 2: pkg.cnirpc.CNIError @@ -406,7 +406,7 @@ func file_pkg_cnirpc_cni_proto_init() { return } if !protoimpl.UnsafeEnabled { - file_pkg_cnirpc_cni_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_pkg_cnirpc_cni_proto_msgTypes[0].Exporter = func(v any, i int) any { switch v := v.(*CNIArgs); i { case 0: return &v.state @@ -418,7 +418,7 @@ func file_pkg_cnirpc_cni_proto_init() { return nil } } - file_pkg_cnirpc_cni_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_pkg_cnirpc_cni_proto_msgTypes[1].Exporter = func(v any, i int) any { switch v := v.(*CNIError); i { case 0: return &v.state @@ -430,7 +430,7 @@ func file_pkg_cnirpc_cni_proto_init() { return nil } } - file_pkg_cnirpc_cni_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_pkg_cnirpc_cni_proto_msgTypes[2].Exporter = func(v any, i int) any { switch v := v.(*AddResponse); i { case 0: return &v.state From 71c0c034f33d9c8dfe31997da6ac23ac467b3c8e Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:40:18 +0900 Subject: [PATCH 31/36] change error Signed-off-by: walnuts1018 --- cmd/pona-installer/install.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cmd/pona-installer/install.go b/cmd/pona-installer/install.go index d3c5d79..0951973 100644 --- a/cmd/pona-installer/install.go +++ b/cmd/pona-installer/install.go @@ -25,18 +25,15 @@ func installPona(ponaPath, cniBinDir string) error { os.Remove(g.Name()) }() - _, err = io.Copy(g, f) - if err != nil { + if _, err := io.Copy(g, f); err != nil { return fmt.Errorf("failed to io.Copy: %w", err) } - err = g.Chmod(0755) - if err != nil { + if err := g.Chmod(0755); err != nil { return fmt.Errorf("failed to chmod: %w", err) } - err = g.Sync() - if err != nil { + if err := g.Sync(); err != nil { return fmt.Errorf("failed to Sync: %w", err) } From 88b24ef224156086f6714703c264241d47f10f10 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:42:54 +0900 Subject: [PATCH 32/36] rm unused env Signed-off-by: walnuts1018 --- config/manager/ponad.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/config/manager/ponad.yaml b/config/manager/ponad.yaml index fd7e382..905d0d6 100644 --- a/config/manager/ponad.yaml +++ b/config/manager/ponad.yaml @@ -66,12 +66,6 @@ spec: image: ponad:dev command: - "/pona-installer" - # env: - # - name: CNI_NETCONF - # valueFrom: - # configMapKeyRef: - # name: pona-config - # key: cni_netconf securityContext: privileged: true volumeMounts: From f911e66082e916b1d3cc27bf4aadcbf7502d2d00 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:50:28 +0900 Subject: [PATCH 33/36] rm unused conf Signed-off-by: walnuts1018 --- cmd/pona-installer/main.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/pona-installer/main.go b/cmd/pona-installer/main.go index 02ecd5c..8ffd1fa 100644 --- a/cmd/pona-installer/main.go +++ b/cmd/pona-installer/main.go @@ -12,8 +12,6 @@ type Config struct { CniEtcDir string `env:"CNI_ETC_DIR" envDefault:"/host/etc/cni/net.d"` CniBinDir string `env:"CNI_BIN_DIR" envDefault:"/host/opt/cni/bin"` PonaPath string `env:"CNI_PATH" envDefault:"/pona"` - // CniNetConf string `env:"CNI_NET_CONF"` - // CniConfName string `env:"CNI_CONF_NAME"` } func main() { From 87e8e5b208bf75875131ee2879a3d51a8cba8f52 Mon Sep 17 00:00:00 2001 From: walnuts1018 Date: Thu, 29 Aug 2024 14:59:37 +0900 Subject: [PATCH 34/36] add addthrow error Signed-off-by: walnuts1018 --- pkg/nat/client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/nat/client.go b/pkg/nat/client.go index 9e170c3..b192de7 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -196,7 +196,9 @@ func (c *natClient) UpdateRoutes(link netlink.Link, subnets []netip.Prefix) erro for _, v := range slices.Concat(v4PrivateList, v6PrivateList, []netip.Prefix{v4LinkLocal, v6LinkLocal}, ) { - c.addThrow(link, v) + if err := c.addThrow(link, v); err != nil { + return err + } } for _, r := range adds { From 29f76748d91f3786b35ce1d942704ef76252c438 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:08:29 +0900 Subject: [PATCH 35/36] fix throw route failure Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- pkg/nat/client.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pkg/nat/client.go b/pkg/nat/client.go index b192de7..20abdf2 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -254,15 +254,14 @@ func subnetsSet(subnets []netip.Prefix) map[netip.Prefix]struct{} { return subnetsSet } -func (c *natClient) addThrow(link netlink.Link, n netip.Prefix) error { +func (c *natClient) addThrow(n netip.Prefix) error { dst := netiputil.ToIPNet(n) err := netlink.RouteAdd(&netlink.Route{ - Table: ncTableID, - Dst: &dst, - Type: unix.RTN_THROW, - LinkIndex: link.Attrs().Index, - Protocol: ncProtocolID, - Priority: throwMetric, + Table: ncTableID, + Dst: &dst, + Type: unix.RTN_THROW, + Protocol: ncProtocolID, + Priority: throwMetric, }) if err != nil { return fmt.Errorf("netlink: failed to add route(table %d) to %s: %w", ncTableID, n.String(), err) From c3604fa2537122783528b1df14b24a0f60dc10f6 Mon Sep 17 00:00:00 2001 From: gotti <18141824+gotti@users.noreply.github.com> Date: Thu, 29 Aug 2024 15:21:07 +0900 Subject: [PATCH 36/36] fix localip config Signed-off-by: gotti <18141824+gotti@users.noreply.github.com> --- pkg/nat/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/nat/client.go b/pkg/nat/client.go index 20abdf2..86bb5ca 100644 --- a/pkg/nat/client.go +++ b/pkg/nat/client.go @@ -30,7 +30,7 @@ const ( var ( v4PrivateList = []netip.Prefix{ netip.MustParsePrefix("10.0.0.0/8"), - netip.MustParsePrefix("172.16.0.0/32"), + netip.MustParsePrefix("172.16.0.0/12"), netip.MustParsePrefix("192.168.0.0/16"), } @@ -196,7 +196,7 @@ func (c *natClient) UpdateRoutes(link netlink.Link, subnets []netip.Prefix) erro for _, v := range slices.Concat(v4PrivateList, v6PrivateList, []netip.Prefix{v4LinkLocal, v6LinkLocal}, ) { - if err := c.addThrow(link, v); err != nil { + if err := c.addThrow(v); err != nil { return err } }